// // main.c // 6502 // // Created by Tamas Rudnai on 7/14/19. // Copyright © 2019, 2020 Tamas Rudnai. All rights reserved. // // This file is part of Steve ][ -- The Apple ][ Emulator. // // Steve ][ 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. // // Steve ][ 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 Steve ][. If not, see . // #ifndef __APPLE2_MMIO_H__ #define __APPLE2_MMIO_H__ #include "common.h" #include "6502.h" enum mmio { io_KBD = 0xC000, io_KBDSTRB = 0xC010, }; uint8_t RAM[ 64 * KB ] = {0}; #define PAGESIZE 256 #define PAGES 16 //uint8_t ram_0[PAGESIZE]; //uint8_t ram_1[PAGESIZE]; //uint8_t ram_2[PAGESIZE]; //uint8_t ram_3[PAGESIZE]; //uint8_t ram_4[PAGESIZE]; //uint8_t ram_5[PAGESIZE]; //uint8_t ram_6[PAGESIZE]; //uint8_t ram_7[PAGESIZE]; //uint8_t ram_8[PAGESIZE]; //uint8_t ram_9[PAGESIZE]; //uint8_t ram_A[PAGESIZE]; //uint8_t ram_B[PAGESIZE]; //uint8_t aui_C[PAGESIZE]; //uint8_t rom_D[PAGESIZE]; //uint8_t rom_E[PAGESIZE]; //uint8_t rom_F[PAGESIZE]; // //uint8_t * ram[PAGES] = { // ram_0, // ram_1, // ram_2, // ram_3, // ram_4, // ram_5, // ram_6, // ram_7, // ram_8, // ram_9, // ram_A, // ram_B, // aui_C, // rom_D, // rom_E, // rom_F, //}; //uint8_t ( * mmio_read [ 64 * KB ] )( uint16_t addr ); typedef union address16_u { uint16_t addr; struct { uint8_t offs; uint8_t page; }; } address16_t; INLINE uint8_t ioRead( uint16_t addr ) { // printf("mmio:%04X\n", addr); // C0xx switch ((uint8_t)addr) { case 0x00: return RAM[io_KBD]; case 0x10: // TODO: This is very slow! dbgPrintf("io_KBDSTRB\n"); return RAM[io_KBD] &= 0x7F; case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: case 0x08: case 0x09: case 0x0A: case 0x0B: case 0x0C: case 0x0D: case 0x0E: case 0x0F: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: case 0x18: case 0x19: case 0x1A: case 0x1B: case 0x1C: case 0x1D: case 0x1E: case 0x1F: case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29: case 0x2A: case 0x2B: case 0x2C: case 0x2D: case 0x2E: case 0x2F: case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: case 0x3A: case 0x3B: case 0x3C: case 0x3D: case 0x3E: case 0x3F: case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: case 0x48: case 0x49: case 0x4A: case 0x4B: case 0x4C: case 0x4D: case 0x4E: case 0x4F: case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: case 0x58: case 0x59: case 0x5A: case 0x5B: case 0x5C: case 0x5D: case 0x5E: case 0x5F: case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: case 0x68: case 0x69: case 0x6A: case 0x6B: case 0x6C: case 0x6D: case 0x6E: case 0x6F: case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: case 0x78: case 0x79: case 0x7A: case 0x7B: case 0x7C: case 0x7D: case 0x7E: case 0x7F: case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87: case 0x88: case 0x89: case 0x8A: case 0x8B: case 0x8C: case 0x8D: case 0x8E: case 0x8F: case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97: case 0x98: case 0x99: case 0x9A: case 0x9B: case 0x9C: case 0x9D: case 0x9E: case 0x9F: case 0xA0: case 0xA1: case 0xA2: case 0xA3: case 0xA4: case 0xA5: case 0xA6: case 0xA7: case 0xA8: case 0xA9: case 0xAA: case 0xAB: case 0xAC: case 0xAD: case 0xAE: case 0xAF: case 0xB0: case 0xB1: case 0xB2: case 0xB3: case 0xB4: case 0xB5: case 0xB6: case 0xB7: case 0xB8: case 0xB9: case 0xBA: case 0xBB: case 0xBC: case 0xBD: case 0xBE: case 0xBF: case 0xC0: case 0xC1: case 0xC2: case 0xC3: case 0xC4: case 0xC5: case 0xC6: case 0xC7: case 0xC8: case 0xC9: case 0xCA: case 0xCB: case 0xCC: case 0xCD: case 0xCE: case 0xCF: case 0xD0: case 0xD1: case 0xD2: case 0xD3: case 0xD4: case 0xD5: case 0xD6: case 0xD7: case 0xD8: case 0xD9: case 0xDA: case 0xDB: case 0xDC: case 0xDD: case 0xDE: case 0xDF: case 0xE0: case 0xE1: case 0xE2: case 0xE3: case 0xE4: case 0xE5: case 0xE6: case 0xE7: case 0xE8: case 0xE9: case 0xEA: case 0xEB: case 0xEC: case 0xED: case 0xEE: case 0xEF: case 0xF0: case 0xF1: case 0xF2: case 0xF3: case 0xF4: case 0xF5: case 0xF6: case 0xF7: case 0xF8: case 0xF9: case 0xFA: case 0xFB: case 0xFC: case 0xFD: case 0xFE: case 0xFF: default: break; } return 0; } INLINE void ioWrite( uint16_t addr ) { // printf("mmio:%04X\n", addr); switch (addr) { case io_KBD: return; default: break; } return; } /** Naive implementation of RAM read from address **/ INLINE uint8_t memread_zp( uint8_t addr ) { return RAM[ addr ]; } INLINE uint8_t memread( uint16_t addr ) { // switch ( ((address16_t)addr).page ) { // case 0xC0: // case 0xC1: // case 0xC2: // case 0xC3: // case 0xC4: // case 0xC5: // case 0xC6: // case 0xC7: // case 0xC8: // case 0xC9: // case 0xCA: // case 0xCB: // case 0xCC: // case 0xCD: // case 0xCE: // case 0xCF: // return ioRead(addr); // // defaut: // break; // } if ( (addr >= 0xC000) && (addr < 0xD000) ) { ioRead(addr); } return RAM[ addr ]; } /** Naive implementation of RAM read from address **/ INLINE uint16_t memread16( uint16_t addr ) { // if ( ( addr >= 0xC000 ) && ( addr < 0xD000 ) ) { // return mmioRead(addr); // } // dbgPrintf("%04X ", * (uint16_t*) (& RAM[ addr ])); return * (uint16_t*) (& RAM[ addr ]); } /** Naive implementation of RAM read from address **/ //INLINE uint16_t memioread16( uint16_t addr ) { // return (uint16_t)mmio_read[ addr ](addr); //} /** Naive implementation of RAM write to address **/ static void memwrite_zp( uint8_t addr, uint8_t byte ) { RAM[ addr ] = byte; } /** Naive implementation of RAM write to address **/ static void memwrite( uint16_t addr, uint8_t byte ) { // if ( addr >= 0xD000 ) { // // ROM // return; // } // if ( addr >= 0xC000 ) { // return mmioWrite(addr); // } // RAM[ addr ] = byte; } /** Fetching 1 byte from memory address pc (program counter) increase pc by one **/ INLINE uint8_t fetch() { dbgPrintf("%02X ", RAM[m6502.pc]); return memread( m6502.pc++ ); } /** Fetching 2 bytes as a 16 bit number from memory address pc (program counter) increase pc by one **/ INLINE uint16_t fetch16() { dbgPrintf("%04X ", memread16(m6502.pc)); uint16_t word = memread16( m6502.pc ); m6502.pc += 2; return word; } /** get a 16 bit address from the zp:zp+1 **/ INLINE uint16_t addr_zp_ind( uint8_t addr ) { return memread16(addr); } /** X,ind .... X-indexed, indirect OPC ($LL,X) operand is zeropage address; effective address is word in (LL + X, LL + X + 1), inc. without carry: C.w($00LL + X) **/ INLINE uint16_t addr_X_ind() { return addr_zp_ind( fetch() + m6502.X ); } INLINE uint8_t src_X_ind() { return memread( addr_X_ind() ); } INLINE uint8_t * dest_X_ind() { return & RAM[ addr_X_ind() ]; } /** ind,Y .... indirect, Y-indexed OPC ($LL),Y operand is zeropage address; effective address is word in (LL, LL + 1) incremented by Y with carry: C.w($00LL) + Y **/ INLINE uint16_t addr_ind_Y() { uint8_t a = fetch(); // dbgPrintf("addr_ind_Y: %04X + %02X = %04X ", addr_zpg_ind( a ), m6502.Y, addr_zpg_ind( a ) + m6502.Y); return addr_zp_ind( a ) + m6502.Y; } /** abs,X .... absolute, X-indexed OPC $LLHH,X operand is address; effective address is address incremented by X with carry ** **/ INLINE uint16_t addr_abs_X() { return fetch16() + m6502.X; } INLINE uint8_t src_abs_X() { return memread( addr_abs_X() ); } INLINE uint8_t * dest_abs_X() { return & RAM[ addr_abs_X() ]; } INLINE uint16_t abs_addr() { return fetch16(); } /** abs,Y .... absolute, Y-indexed OPC $LLHH,Y operand is address; effective address is address incremented by Y with carry ** **/ INLINE uint16_t addr_abs_Y() { return fetch16() + m6502.Y; } INLINE uint8_t src_abs_Y() { return memread(addr_abs_Y()); } INLINE uint8_t * dest_abs_Y() { return & RAM[ addr_abs_Y() ]; } /** zpg .... zeropage OPC $LL operand is zeropage address (hi-byte is zero, address = $00LL) **/ INLINE uint16_t addr_zp() { return fetch(); } INLINE uint8_t src_zp() { return memread_zp(addr_zp()); } INLINE uint8_t * dest_zp() { return & RAM[ addr_zp() ]; } /** zpg,X .... zeropage, X-indexed OPC $LL,X operand is zeropage address; effective address is address incremented by X without carry ** **/ INLINE uint16_t addr_zp_X() { return addr_zp() + m6502.X; } /** zpg,Y .... zeropage, Y-indexed OPC $LL,Y operand is zeropage address; effective address is address incremented by Y without carry ** **/ INLINE uint16_t addr_zp_Y() { return addr_zp() + m6502.Y; } #endif // __APPLE2_MMIO_H__