Skip to content

Commit

Permalink
MEGA65 : New DMA-List features. Adaptions for new Kickstart
Browse files Browse the repository at this point in the history
  • Loading branch information
Benson_RSI authored and Benson_RSI committed Mar 20, 2018
1 parent 8aa46c9 commit f38f7bb
Show file tree
Hide file tree
Showing 5 changed files with 317 additions and 58 deletions.
55 changes: 45 additions & 10 deletions targets/mega65/mega65.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ struct Cia6526 cia1, cia2; // CIA emulation structures for the two CIAs
struct SidEmulation sid1, sid2; // the two SIDs
int cpu_linear_memory_addressing_is_enabled = 0;
static int nmi_level; // please read the comment at nmi_set() below
int alt_key_pressed = 1; // Is cleared on first call of Keyboard scan-routine


// We re-map I/O requests to a high address space does not exist for real. cpu_read() and cpu_write() should handle this as an IO space request
Expand Down Expand Up @@ -370,6 +371,7 @@ static void mega65_init ( int sid_cycles_per_sec, int sound_mix_freq )
p = emucfg_get_str("kickup");
if (emu_load_file(p, hypervisor_memory, 0x4001) == 0x4000) {
DEBUG("MEGA65: %s loaded into hypervisor memory." NL, p);
// ;$d67e = register for kickup-state (00=virgin, else already-kicked
} else {
WARNING_WINDOW("Kickstart %s cannot be found. Using the default (maybe outdated!) built-in version", p);
if (sizeof initial_kickup != 0x4000)
Expand Down Expand Up @@ -601,6 +603,10 @@ Uint8 io_read ( int addr )
if (addr >= 0xD680 && addr <= 0xD693) // SDcard controller etc of Mega65
return sdcard_read_register(addr - 0xD680);
switch (addr) {
case 0xD611: // Read extended Keyboard-Register ( ALT, CTRL, etc );
DEBUG ("Read of $d611. Would return 0x%02x" NL, gs_regs[addr & 0xFFF]);
return gs_regs[addr & 0xFFF];;
break;
case 0xD67E: // upgraded hypervisor signal
if (kicked_hypervisor == 0x80) // 0x80 means for Xemu (not for a real M65!): ask the user!
kicked_hypervisor = QUESTION_WINDOW(
Expand Down Expand Up @@ -715,14 +721,15 @@ void io_write ( int addr, Uint8 data )
if (vic_iomode == VIC4_IOMODE && addr >= 0xD609) { // D609 - D6FF: Mega65 suffs
gs_regs[addr & 0xFFF] = data;
DEBUG("MEGA65: writing Mega65 specific I/O range @ $%04X with $%02X" NL, addr, data);

if (!in_hypervisor && addr >= 0xD640 && addr <= 0xD67F) {
// In user mode, writing to $D640-$D67F (in VIC4 iomode) causes to enter hypervisor mode with
// the trap number given by the offset in this range
hypervisor_enter(addr & 0x3F);
return;
}
if (addr >= 0xD680 && addr <= 0xD693) {
sdcard_write_register(addr - 0xD680, data);
sdcard_write_register(addr - 0xD680, data);
return;
}
switch (addr) {
Expand Down Expand Up @@ -830,6 +837,9 @@ void write_phys_mem ( int addr, Uint8 data )
// Normal MAP stuffs does this, since it wraps within a single 1Mbyte "MB" already
// However this can be an issue for other users, ie DMA
// FIXME: check that at DMAgic, also the situation that DMAgic can/should/etc wrap at all on MB ranges, and on 256Mbyte too!

//printf ("Write 0x%02x to 0x%06x %d\n",data,addr,in_hypervisor); //0xfffbf10

addr &= 0xFFFFFFF; // warps around at 256Mbyte, for address bus of Mega65
if (addr < 0x000002) {
if ((CPU_PORT(addr) & 7) != (data & 7)) {
Expand Down Expand Up @@ -882,6 +892,7 @@ void write_phys_mem ( int addr, Uint8 data )
return;
}
if ((addr & 0xFFFC000) == 0xFFF8000) { // accessing of hypervisor memory
DEBUG ("Write 0x%02x to 0x%06x %d" NL,data,addr,in_hypervisor); //0xfffbf10
if (in_hypervisor) // hypervisor memory is unavailable from "user mode", FIXME: do we need to do trap/whatever if someone tries this?
hypervisor_memory[addr & 0x3FFF] = data;
return;
Expand Down Expand Up @@ -929,7 +940,9 @@ void write_phys_mem ( int addr, Uint8 data )

Uint8 read_phys_mem ( int addr )
{
// printf ("Read from 0x%06x %d\n",addr,in_hypervisor); //0xfffbf10
addr &= 0xFFFFFFF; // warps around at 256Mbyte, for address bus of Mega65

//Check for < 2 not needed anymore, as CPU port is really the memory, though it can be a problem if DMA sees this issue differently?!
//if (addr < 0x000002)
// return CPU_PORT(addr);
Expand Down Expand Up @@ -1065,6 +1078,8 @@ void reset_machine(void){
cpu_reset();
dma_reset();
nmi_level = 0;
io_write(0xD610,0); // Reset-keypresses
io_write(0xD611,0);
kicked_hypervisor = emucfg_get_num("kicked");
hypervisor_enter(TRAP_RESET);
DEBUG("RESET!" NL);
Expand All @@ -1075,15 +1090,35 @@ void reset_machine(void){
// Called by emutools_hid!!! to handle special private keys assigned to this emulator
int emu_callback_key ( int pos, SDL_Scancode key, int pressed, int handled )
{
// Check for special, emulator-related hot-keys (not C65 key)
if (pressed) {
if (key == SDL_SCANCODE_F10) {
reset_machine();
} else if (key == SDL_SCANCODE_KP_ENTER) {
c64_toggle_joy_emu();
}
}
return 0;
// Check for special, emulator-related hot-keys (not C65 key)
if (pressed) {
switch (key){
case SDL_SCANCODE_F10:
reset_machine();
break;
case SDL_SCANCODE_KP_ENTER:
c64_toggle_joy_emu();
break;
case SDL_SCANCODE_LALT:
io_write(0xD611,io_read(0xD611)|0x10);
alt_key_pressed=1;
break;
case SDL_SCANCODE_AC_HOME: // Is sent, when window is miniminized, ignore it
break;

default:
io_write(0xD610,key+0x13);
DEBUG ("KeyPressed : %d " NL,key+0x13);
break;
}
}else{
if (alt_key_pressed){
io_write(0xD611,io_read(0xD611)&0xEF);
alt_key_pressed=0;
}
}

return 0;
}


Expand Down
13 changes: 12 additions & 1 deletion targets/mega65/sdcard.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ static off_t sd_card_size;
static int sdcard_bytes_read = 0;
static int sd_is_read_only;
static int mounted;
static int illegal_access=0; // Kickstart detects a SDHC Card by reading from a sector adress, which isn't allowed on simple SD-Card.
// We detect it a do not clear the busy-flag. Let the kickstart-routine timeout.


static int open_external_d81 ( const char *fn )
Expand Down Expand Up @@ -249,6 +251,9 @@ static Uint8 sdcard_read_status ( void )
{
Uint8 ret = sd_status;
DEBUG("SDCARD: reading SD status $D680 result is $%02X PC=$%04X" NL, ret, cpu_pc);
if (illegal_access){
return (SD_ST_BUSY1 | SD_ST_BUSY0);
}
sd_status &= ~(SD_ST_BUSY1 | SD_ST_BUSY0);
return ret;
}
Expand Down Expand Up @@ -343,7 +348,13 @@ void sdcard_write_register ( int reg, Uint8 data )
case 0: // command/status register
sdcard_command(data);
break;
case 1: // sector address
case 1: // sector address, is devidable by 512 on a simple SD-card
if (data == 0x02){
illegal_access=1;
DEBUG("SDCARD: Illegal access to sector number register $%04X with $%02X PC=$%04X" NL, reg + 0xD680, data, cpu_pc);
}else{
illegal_access=0;
}
case 2: // sector address
case 3: // sector address
case 4: // sector address
Expand Down
68 changes: 68 additions & 0 deletions xemu/cpu65c02.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,71 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
* Can be distributed/used/modified under the terms of GNU/GPL 2 (or later), please see file COPYING
* or visit this page: http://www.gnu.org/licenses/gpl-2.0.html
*/
//#define DEBUG_CPU

#include "xemu/emutools_basicdefs.h"
#ifndef CPU_CUSTOM_INCLUDED
#include "xemu/cpu65c02.h"
#endif

#ifdef DEBUG_CPU
#ifdef CPU_65CE02
#include "xemu/cpu65ce02_disasm_tables.c"
//#include "cpu65ce02_disasm.c

static const char opcode_adm_off [] = {0 ,1 ,2 ,1 ,2 ,1 ,1 ,2 ,2 ,2 ,3 ,4 ,1 ,1 ,1 ,1 ,2 ,2 ,0 };
static const char *opcode_adm_pre [] = {"" ,"#$" ,"#$" ,"$" ,"$" ,"$" ,"$" ,"$" ,"$" ,"$" ,"$" ,"$" ,"($" ,"($" ,"($" ,"($" ,"($" ,"($" ," "};
static const char *opcode_adm_post[] = {"" ,"" ,"" ,"" ,",$rr" ,",X" ,",Y" ,"" ,",X" ,",Y" ,"" ,"" ,"),Y" ,"),Z" ,",SP),Y" ,",X)" ,")" ,",X)" ,"A"};
//{"","#$nn","#$nnnn","$nn","$nn,$rr","$nn,X","$nn,Y","$nnnn","$nnnn,X","$nnnn,Y","$rr","$rrrr","($nn),Y","($nn),Z","($nn,SP),Y","($nn,X)","($nnnn)","($nnnn,X)","A"};



/***************************************************************************/
/* Disassembler */
/***************************************************************************/


Uint16 print_disass_line(Uint16 disass_pc, Uint8 disass_op){

Uint16 addr_off=opcode_adm_off[opcode_adms[disass_op]];

switch (addr_off){
case 0: // no extra argument
printf(
"%04X %s %s%s \r\n", // PC , disambled opcode , prefix , postfix
disass_pc, opcode_names[disass_op], opcode_adm_pre[opcode_adms[disass_op]], opcode_adm_post[opcode_adms[disass_op]] );
break;
case 1: // 8-bit argument
printf(
"%04X %s %s%02X%s \r\n", // PC , disambled opcode , prefix , postfix
disass_pc, opcode_names[disass_op], opcode_adm_pre[opcode_adms[disass_op]],cpu_read(disass_pc+1)&0xff, opcode_adm_post[opcode_adms[disass_op]] );
break;
case 2: // 16-bit argument
printf(
"%04X %s %s%02X%02x%s \r\n", // PC , disambled opcode , prefix , postfix
disass_pc, opcode_names[disass_op], opcode_adm_pre[opcode_adms[disass_op]],cpu_read(disass_pc+2)&0xff,cpu_read(disass_pc+1)&0xff, opcode_adm_post[opcode_adms[disass_op]] );
break;
case 3: // 8-bit relative argument
printf(
"%04X %s %s%04X%s \r\n", // PC , disambled opcode , prefix , postfix
disass_pc, opcode_names[disass_op], opcode_adm_pre[opcode_adms[disass_op]],disass_pc+(char)(cpu_read(disass_pc+1)&0xff)+2, opcode_adm_post[opcode_adms[disass_op]] );
addr_off=1;
break;
case 4: // 16-bit releative argument
printf(
"%04X %s %s%04X%s \r\n", // PC , disambled opcode , prefix , postfix
disass_pc, opcode_names[disass_op], opcode_adm_pre[opcode_adms[disass_op]],disass_pc+(int16_t)((cpu_read(disass_pc+1)&0xff)+0x100*(cpu_read(disass_pc+2)&0xff))+3, opcode_adm_post[opcode_adms[disass_op]] );
addr_off=2;
break;
default:
printf ( "Unkonw opcode %02X at address $%0X4 ",disass_op,disass_pc);
break;
}
return (addr_off);
}


#endif
#endif

#ifdef DTV_CPU_HACK
Expand Down Expand Up @@ -437,8 +493,10 @@ static inline void _ROL(int addr) {

static Uint8 last_p;

extern int paused;

int cpu_step () {

if (cpu_nmiEdge
#ifdef CPU_65CE02
&& cpu_cycles != 1 && !cpu_inhibit_interrupts
Expand Down Expand Up @@ -482,12 +540,19 @@ int cpu_step () {
#endif
cpu_op = cpu_read(cpu_pc++);
#ifdef DEBUG_CPU
#ifdef CPU_65CE02
DEBUG("CPU: at $%04X opcode = $%02X %s %s A=%02X X=%02X Y=%02X Z=%02X SP=%02X" NL, (cpu_pc - 1) & 0xFFFF, cpu_op, opcode_names[cpu_op], opcode_adm_names[opcode_adms[cpu_op]],
cpu_a, cpu_x, cpu_y, cpu_z, cpu_sp
);
printf("CPU: at $%04X opcode = $%02X %s %s A=%02X X=%02X Y=%02X Z=%02X SP=%02X" NL, (cpu_pc - 1) & 0xFFFF, cpu_op, opcode_names[cpu_op], opcode_adm_names[opcode_adms[cpu_op]],
cpu_a, cpu_x, cpu_y, cpu_z, cpu_sp
);
print_disass_line(cpu_pc - 1,cpu_op);

if (cpu_op == 0x60)
DEBUG("CPU: SP before RTS is (SPHI=$%04X) SP=$%02X" NL, cpu_sphi, cpu_sp);
#endif
#endif
#ifdef CPU_TRAP
if (cpu_op == CPU_TRAP) {
int ret = cpu_trap(CPU_TRAP);
Expand Down Expand Up @@ -1175,6 +1240,9 @@ int cpu_step () {
break;
#endif
}



return cpu_cycles;
}

Expand Down
Loading

0 comments on commit f38f7bb

Please sign in to comment.