This is reu.c in view mode; [Download] [Up]
/* * reu.h - REU 1750 emulation. * * Written by * Jouko Valta (jopi@stekt.oulu.fi) * Richard Hable (K3027E7@edvz.uni-linz.ac.at) * * Fixes by * Ettore Perazzoli (ettore@comm2000.it) [EP] * * This file is part of VICE, the Versatile Commodore Emulator. * See README for copyright notice. * * 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 2 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, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA. * */ #include "vice.h" #include <stdio.h> #include <string.h> #ifndef NeXT #include <malloc.h> #endif #include "reu.h" #include "maincpu.h" #include "mem.h" #include "utils.h" /* #define REU_DEBUG */ #define REUSIZE 512 /* * Status and Command Registers * bit 7 6 5 4 3 2 1 0 * 00 Int EOB Fault RamSize ________ Version ________ * 01 Exec 0 Load Delayed 0 0 Mode */ /* global */ static int ReuSize = REUSIZE << 10; static BYTE reu[16]; /* REC registers */ static BYTE *reuram = 0; static char *reu_file_name; /* ------------------------------------------------------------------------- */ int reset_reu(int size) { int i; if (size > 0) ReuSize = size; for (i=0; i < 16; i++) reu[i] = 0; if (ReuSize >= 256) reu[0] = 0x50; else reu[0] = 0x40; reu[1] = 0x4A; if (reuram == NULL) { reuram = xmalloc(ReuSize); printf("REU: %dKB unit installed.\n", REUSIZE); if (load_file(reu_file_name, reuram, ReuSize) == 0) { printf ("REU: image `%s' loaded successfully.\n", reu_file_name); } else { printf ("REU: (no image loaded).\n"); } } return 0; } void activate_reu(void) { if (reuram == NULL) reset_reu(0); } void close_reu(void) { if (reuram == NULL || reu_file_name == NULL) return; if (save_file(reu_file_name, reuram, ReuSize) == 0) printf("REU: image `%s' saved successfully.\n", reu_file_name); else fprintf(stderr,"REU: cannot save image `%s'.\n", reu_file_name); } BYTE REGPARM1 read_reu(ADDRESS addr) { BYTE retval; if (reuram == NULL) reset_reu(0); switch (addr) { case 0x0: /* fixed by [EP], 04-16-97. */ retval = (reu[0] & 0x60) | (((ReuSize >> 10) >= 256) ? 0x10 : 0x00); reu[0] &= ~0xe0; /* Bits 7-5 are cleared when register is read. */ break; case 0x6: /* wrong address of bank register corrected - RH */ retval = reu[6] | 0xf8; break; case 0x9: retval = reu[6] | 0x3f; break; case 0xb: case 0xc: case 0xd: case 0xe: case 0xf: retval = 0xff; break; default: retval = reu[addr]; } #ifdef REU_DEBUG printf("REU: read [$%02X] => $%02X\n", addr, retval); #endif return retval; } void REGPARM2 store_reu(ADDRESS addr, BYTE byte) { if (reuram == NULL) reset_reu(0); reu[addr] = byte; #ifdef REU_DEBUG printf("REU: store [$%02X] <= $%02X\n", addr, (int) byte); #endif /* write REC command register * DMA only if execution bit (7) set - RH */ if ((addr == 0x1) && (byte & 0x80)) reu_dma(byte & 0x10); } /* This function is called when write to REC command register or memory * location FF00 is detected. * * If host address exceeds ffff transfer contiues at 0000. * If reu address exceeds 7ffff transfer continues at 00000. * If address is fixed the same value is used during the whole transfer. */ /* Added correct handling of fixed addresses with transfer length 1 - RH */ /* Added fixed address support - [EP] */ void reu_dma(int immed) { static int delay = 0; unsigned int len; int reu_step, host_step; ADDRESS host_addr; int reu_addr; BYTE c; if (!immed) { delay++; return; } else { if (!delay && (immed < 0)) return; delay = 0; } /* wrong address of bank register & calculations corrected - RH */ host_addr = (ADDRESS)(reu[2]) | ( (ADDRESS)( reu[3] ) << 8 ); reu_addr = (int)(reu[4]) | ((int)(reu[5]) << 8) | ((int)(reu[6] & 7) << 16); if (( len = (int)(reu[7]) | ( (int)(reu[8]) << 8)) == 0) len = 0x10000; /* Fixed addresses implemented -- [EP] 04-16-97. */ host_step = reu[0xA] & 0x80 ? 0 : 1; reu_step = reu[0xA] & 0x40 ? 0 : 1; /* clk += len; */ switch (reu[1] & 0x03) { case 0: /* C64 -> REU */ #ifdef REU_DEBUG printf("REU: copy ext $%05X %s<= main $%04X%s, $%04X (%d) bytes.\n", reu_addr, reu_step ? "" : "(fixed) ", host_addr, host_step ? "" : " (fixed)", len, len); #endif for (; len--; host_addr = (host_addr + host_step) & 0xffff, reu_addr += reu_step) { BYTE value = mem_read(host_addr); reuram[reu_addr % ReuSize] = value; } break; case 1: /* REU -> C64 */ #ifdef REU_DEBUG printf("REU: copy ext $%05X %s=> main $%04X%s, $%04X (%d) bytes.\n", reu_addr, reu_step ? "" : "(fixed) ", host_addr, host_step ? "" : " (fixed)", len, len); #endif for (; len--; host_addr += host_step, reu_addr += reu_step ) mem_store((host_addr & 0xffff), reuram[reu_addr % ReuSize]); break; case 2: /* swap */ /* for-loop corrected - RH */ /* clk += len; */ /* [EP] 04-16-97. */ #ifdef REU_DEBUG printf("REU: swap ext $%05X %s<=> main $%04X%s, $%04X (%d) bytes.\n", reu_addr, reu_step ? "" : "(fixed) ", host_addr, host_step ? "" : " (fixed)", len, len); #endif for (; len--; host_addr += host_step, reu_addr += reu_step ) { c = reuram[reu_addr % ReuSize]; reuram[reu_addr % ReuSize] = mem_read(host_addr & 0xffff); mem_store((host_addr & 0xffff), c); } break; case 3: /* compare */ #ifdef REU_DEBUG printf("REU: compare ext $%05X %s<=> main $%04X%s, $%04X (%d) bytes.\n", reu_addr, reu_step ? "" : "(fixed) ", host_addr, host_step ? "" : " (fixed)", len, len); #endif while (len--) { if (reuram[reu_addr % ReuSize] != mem_read(host_addr & 0xffff)) { reu[0] |= 0x20; /* FAULT */ break; } host_addr += host_step; reu_addr += reu_step; } break; } if (!(reu[1] & 0x20)) { /* not autoload * incr. of addr. disabled, as already pointing to correct addr. * address changes only if not fixed, correct reu base registers -RH */ #ifdef REU_DEBUG printf("No autoload\n"); #endif if ( !(reu[0xA] & 0x80)) { reu[2] = host_addr & 0xff; reu[3] = (host_addr >> 8) & 0xff; } if ( !(reu[0xA] & 0x40)) { reu[4] = reu_addr & 0xff; reu[5] = (reu_addr >> 8) & 0xff; reu[6] = (reu_addr>>16); } reu[7] = 1; reu[8] = 0; } /* [EP] 04-16-97. */ reu[0] |= 0x40; reu[1] &= 0x7f; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.