Files
atari2600/source/pia.cpp
T
raimon@prometeo e245410c0a - [NEW] 6502dis i 6502debugger implementats
- [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.
2026-09-17 17:43:33 +02:00

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;
}
}
}