1 // Commander X16 Emulator 2 // Copyright (c) 2019 Michael Steil 3 // All rights reserved. License: 2-clause BSD 4 5 #include <stdio.h> 6 #include <stdbool.h> 7 #include <time.h> 8 #include <stdlib.h> 9 #include "via.h" 10 #include "ps2.h" 11 #include "memory.h" 12 //XXX 13 #include "glue.h" 14 #include "joystick.h" 15 16 // 17 // VIA#1 18 // 19 // PA0-7 RAM bank 20 // PB0-2 ROM bank 21 // PB3 IECATT0 22 // PB4 IECCLK0 23 // PB5 IECDAT0 24 // PB6 IECCLK 25 // PB7 IECDAT 26 // CB1 IECSRQ 27 28 static uint8_t via1registers[16]; 29 30 void via1_init()31via1_init() 32 { 33 srand(time(NULL)); 34 35 // default banks are 0 36 memory_set_ram_bank(0); 37 memory_set_rom_bank(0); 38 } 39 40 uint8_t via1_read(uint8_t reg)41via1_read(uint8_t reg) 42 { 43 switch (reg) { 44 case 0: 45 return memory_get_rom_bank(); // PB: ROM bank, IEC 46 case 1: 47 return memory_get_ram_bank(); // PA: RAM bank 48 case 4: 49 case 5: 50 case 8: 51 case 9: 52 // timer A and B: return random numbers for RND(0) 53 // XXX TODO: these should be real timers :) 54 return rand() & 0xff; 55 default: 56 return via1registers[reg]; 57 } 58 } 59 60 void via1_write(uint8_t reg,uint8_t value)61via1_write(uint8_t reg, uint8_t value) 62 { 63 via1registers[reg] = value; 64 if (reg == 0) { // PB: ROM bank, IEC 65 memory_set_rom_bank(value & 7); 66 // TODO: IEC 67 } else if (reg == 1) { // PA: RAM bank 68 memory_set_ram_bank(value); 69 } else { 70 // TODO 71 } 72 } 73 74 // 75 // VIA#2 76 // 77 // PA0 PS/2 DAT 78 // PA1 PS/2 CLK 79 // PA2 LCD backlight 80 // PA3 NESJOY latch (for both joysticks) 81 // PA4 NESJOY joy1 data 82 // PA5 NESJOY joy1 CLK 83 // PA6 NESJOY joy2 data 84 // PA7 NESJOY joy2 CLK 85 86 static uint8_t via2registers[16]; 87 static uint8_t via2pb_in; 88 89 void via2_init()90via2_init() 91 { 92 } 93 94 uint8_t via2_read(uint8_t reg)95via2_read(uint8_t reg) 96 { 97 // DDR=0 (input) -> take input bit 98 // DDR=1 (output) -> take output bit 99 if (reg == 0) { // PB 100 uint8_t value = 101 (via2registers[2] & PS2_CLK_MASK ? 0 : ps2_port[1].clk_out << 1) | 102 (via2registers[2] & PS2_DATA_MASK ? 0 : ps2_port[1].data_out); 103 return value; 104 } else if (reg == 1) { // PA 105 uint8_t value = 106 (via2registers[3] & PS2_CLK_MASK ? 0 : ps2_port[0].clk_out << 1) | 107 (via2registers[3] & PS2_DATA_MASK ? 0 : ps2_port[0].data_out); 108 value = value | (joystick1_data ? JOY_DATA1_MASK : 0) | 109 (joystick2_data ? JOY_DATA2_MASK : 0); 110 return value; 111 } else { 112 return via2registers[reg]; 113 } 114 } 115 116 void via2_write(uint8_t reg,uint8_t value)117via2_write(uint8_t reg, uint8_t value) 118 { 119 via2registers[reg] = value; 120 121 if (reg == 0 || reg == 2) { 122 // PB 123 ps2_port[1].clk_in = via2registers[2] & PS2_CLK_MASK ? via2registers[0] & PS2_CLK_MASK : 1; 124 ps2_port[1].data_in = via2registers[2] & PS2_DATA_MASK ? via2registers[0] & PS2_DATA_MASK : 1; 125 } else if (reg == 1 || reg == 3) { 126 // PA 127 ps2_port[0].clk_in = via2registers[3] & PS2_CLK_MASK ? via2registers[1] & PS2_CLK_MASK : 1; 128 ps2_port[0].data_in = via2registers[3] & PS2_DATA_MASK ? via2registers[1] & PS2_DATA_MASK : 1; 129 joystick_latch = via2registers[1] & JOY_LATCH_MASK; 130 joystick_clock = via2registers[1] & JOY_CLK_MASK; 131 } 132 } 133 134 uint8_t via2_pb_get_out()135via2_pb_get_out() 136 { 137 return via2registers[2] /* DDR */ & via2registers[0]; /* PB */ 138 } 139 140 void via2_pb_set_in(uint8_t value)141via2_pb_set_in(uint8_t value) 142 { 143 via2pb_in = value; 144 } 145 146 void via2_sr_set(uint8_t value)147via2_sr_set(uint8_t value) 148 { 149 via2registers[10] = value; 150 } 151