- [FIX] font.bmp afegit - [NEW] Afegides regles de comprobació de memòria en la versió debug de compilació en el lagueirtofile - [FIX] la rom ha de carregar abans de atari2600::init() - [NEW] Implementació bàsica del PIA completada. - [FIX] El framebuffer intern en el mòdul TIA era incorrecte. - [NEW] Afegits accesors als registres del 6502 - [NEW] m6502::reset() - [FIX] [6502m] Corregits opcodes amb direccionament implicit: CLC, SEC, PHA, CLI, PLA, SEI, DEY, TXA, TYA, TXS, TAY, TAX, CLV, TSX, INY, DEX, CLD, INX, NOP i SED). Augmentaven el PC una posició de més.
127 lines
3.9 KiB
C++
127 lines
3.9 KiB
C++
#include "pia.h"
|
|
|
|
namespace pia
|
|
{
|
|
uint8_t ram[128];
|
|
bool timer_interrupt = false;
|
|
uint8_t timer_value = 0;
|
|
uint16_t prescaler = 0;
|
|
uint16_t divider = 0;
|
|
bool timer_underflow = false;
|
|
|
|
void reset()
|
|
{
|
|
|
|
}
|
|
|
|
void tick()
|
|
{
|
|
prescaler++;
|
|
|
|
if (!timer_underflow) {
|
|
if (prescaler >= divider) {
|
|
prescaler = 0;
|
|
if (timer_value == 0) {
|
|
timer_underflow = true;
|
|
timer_interrupt = true;
|
|
timer_value = 0xff;
|
|
} else {
|
|
timer_value--;
|
|
}
|
|
}
|
|
} else {
|
|
timer_value--;
|
|
}
|
|
}
|
|
|
|
uint8_t read(uint16_t address)
|
|
{
|
|
if (address & 0x200) {
|
|
if ( (address & 0x04) ) {
|
|
// Timer functions
|
|
if (address & 0x01) {
|
|
uint8_t flags = timer_interrupt ? 0x80 : 0x00;
|
|
timer_interrupt = false;
|
|
return flags;
|
|
} else {
|
|
return timer_value;
|
|
}
|
|
} else {
|
|
// I/O Ports
|
|
switch( address & 0x03) {
|
|
case 0x00: // [TODO] SWCHA
|
|
return 0xff;
|
|
case 0x01: // [TODO] DDRA
|
|
return 0x00;
|
|
case 0x02: // [TODO] SWCHB
|
|
return 0x03;
|
|
case 0x03: // [TODO] DDRB
|
|
return 0x00;
|
|
default:
|
|
return 0x00;
|
|
}
|
|
}
|
|
} else {
|
|
return ram[address & 0x7f];
|
|
}
|
|
}
|
|
|
|
void write(uint16_t address, uint8_t value)
|
|
{
|
|
if (address & 0x200) {
|
|
if ( (address & 0x04) ) {
|
|
if ( (address & 0x10) ) {
|
|
// Timer functions
|
|
switch( address & 0x03) {
|
|
case 0x00: // [TODO] TIM1T
|
|
divider = 1;
|
|
timer_value = value;
|
|
prescaler = 0;
|
|
timer_underflow = false;
|
|
timer_interrupt = false;
|
|
break;
|
|
case 0x01: // [TODO] TIM8T
|
|
divider = 8;
|
|
timer_value = value;
|
|
prescaler = 0;
|
|
timer_underflow = false;
|
|
timer_interrupt = false;
|
|
break;
|
|
case 0x02: // [TODO] TIM64T
|
|
divider = 64;
|
|
timer_value = value;
|
|
prescaler = 0;
|
|
timer_underflow = false;
|
|
timer_interrupt = false;
|
|
break;
|
|
case 0x03: // [TODO] TIM1024T
|
|
divider = 1024;
|
|
timer_value = value;
|
|
prescaler = 0;
|
|
timer_underflow = false;
|
|
timer_interrupt = false;
|
|
break;
|
|
}
|
|
} else {
|
|
// Funcionalitat relacionada amb les interrupcions. Ignorar per a la Atari 2600
|
|
}
|
|
} else {
|
|
// I/O Ports
|
|
switch( address & 0x03) {
|
|
case 0x00: // [TODO] SWCHA
|
|
break;
|
|
case 0x01: // [TODO] DDRA
|
|
break;
|
|
case 0x02: // [TODO] SWCHB
|
|
break;
|
|
case 0x03: // [TODO] DDRB
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
ram[address & 0x7f] = value;
|
|
}
|
|
}
|
|
|
|
}
|