package com.dreamfabric.jac64; import java.io.BufferedReader; import java.net.URL; import java.io.DataInputStream; import java.io.InputStreamReader; /** * Describe class C1541Emu here. * * * Created: Tue Aug 01 12:29:57 2006 * * @author <a href="mailto:Joakim@BOTBOX"></a> * @version 1.0 */ public class C1541Emu extends MOS6510Core { public static final boolean DEBUG = false; //true; public static final boolean IODEBUG = false; public static final int C1541ROM = 0xc000; public static final int RESET_VECTOR = 0xfffc; public C1541Chips chips; public C1541Emu(IMonitor m, String cb) { super(m, cb); // Only single area of RAM memory = new int[0x10000]; chips = new C1541Chips(this); init(chips); loadDebug("c1541dbg.txt"); // For avoiding CPU debug info. debug = false; } public String getName() { return "C1541 CPU"; } public void setReader(C64Reader reader) { chips.setReader(reader); } // Reads the memory with all respect to all flags... protected final int fetchByte(int adr) { cycles++; if (adr < 0x800 || adr >= 0xc000) return memory[adr]; int c = adr & 0xff00; if (c == 0x1800 || c == 0x1c00) { int data = chips.performRead(adr, cycles); if (IODEBUG) System.out.println("C1541: Reading from " + Integer.toHexString(adr) + " PC = " + Integer.toHexString(pc) + " => " + Integer.toHexString(data)); return data; } return 0; } // A byte is written directly to memory or to ioChips protected final void writeByte(int adr, int data) { cycles++; if (adr < 0x800) { memory[adr] = data; } int c = adr & 0xff00; if (c == 0x1800 || c == 0x1c00) chips.performWrite(adr, data, cycles); } public void reset() { super.reset(); pc = memory[RESET_VECTOR] | (memory[RESET_VECTOR + 1] << 8); System.out.println("C1541: Reset to " + Integer.toHexString(pc)); } boolean byteReady = false; void triggerByteReady() { byteReady = true; } public void tick(long c64Cycles) { while (cycles < c64Cycles) { // Run one instruction! - with special overflow "patch" - // Always fake 'byte ready' for fast read! // boolean o = overflow; if (byteReady && chips.byteReadyOverflow) { // Set overflow and clear byte ready! overflow = true; byteReady = false; } // overflow = (chips.via2PerControl & 0x0e) == 0x0e ? true : o; // Debugging? if (DEBUG) { String msg; if ((msg = getDebug(pc)) != null) { System.out.println("C1541: " + Integer.toHexString(pc) + "****** " + msg + " Data: " + Integer.toHexString(memory[0x85]) + " => '" + (char) memory[0x85] + '\''); } } if (DEBUG && (monitor.isEnabled() || interruptInExec > 0)) { monitor.disAssemble(memory,pc,acc,x,y, (byte)getStatusByte(),interruptInExec, lastInterrupt); } emulateOp(); if (chips.nextCheck < cycles) { chips.clock(cycles); } // Back to what it was... // overflow = o; } } public void patchROM(PatchListener list) { } public void loadDebug(String resource) { try { URL url = getClass().getResource(resource); monitor.info("Loading debug from URL: " + url); if (url == null) url = new URL(codebase + resource); BufferedReader reader = new BufferedReader(new InputStreamReader(url.openConnection(). getInputStream())); String line = ""; while ((line = reader.readLine()) != null) { String[] parts = line.split("\t"); int adr = -1; try { adr = Integer.parseInt(parts[0].trim(), 16); } catch (Exception e) { } if (adr != -1) { // System.out.println("Found data for address: " + // Integer.toHexString(adr) + " => " + // parts[1].trim()); setDebug(adr, parts[1].trim()); } } } catch(Exception e) { System.out.println("Failed to load debug text: " + resource); } } protected void readROM(String resource, int startMem, int len) { try { URL url = getClass().getResource(resource); monitor.info("URL: " + url); monitor.info("Read ROM " + resource); if (url == null) url = new URL(codebase + resource); loadROM(new DataInputStream(url.openConnection().getInputStream()), startMem, len); } catch (Exception e) { e.printStackTrace(); } } protected void installROMS() { readROM("/roms/c1541.rom" , C1541ROM, 0x4000); } }