-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathpetio.cpp
More file actions
108 lines (82 loc) · 2.02 KB
/
petio.cpp
File metadata and controls
108 lines (82 loc) · 2.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include <stdint.h>
#include <machine.h>
#include <memory.h>
#include <serialio.h>
#include <filer.h>
#include <pia.h>
#include <via.h>
#include <debugging.h>
#include "petio.h"
#include "sound.h"
// see http://www.zimmers.net/anonftp/pub/cbm/firmware/computers/pet/PET-Interfaces.txt
// and http://www.6502.org/users/andre/petindex/progmod.html
// device offsets (base is 0xe800)
#define PIA1_OFFSET 0x0010
#define PIA2_OFFSET 0x0020
#define VIA_OFFSET 0x0040
// via port-b
#define VIDEO_RETRACE 0x20
// 1ms internal clock tick
#define TICK_PERIOD 1000
sound sound;
petio::petio(filer &files): files(files), _ticks(0), _timer(-1) {
put(pia1, PIA1_OFFSET);
put(pia2, PIA2_OFFSET);
put(via, VIA_OFFSET);
}
void petio::reset() {
sound.reset();
pia1.reset();
pia2.reset();
via.reset();
via.register_portb_input_handler([this]() { return _ticks >= 14? VIDEO_RETRACE: 0; });
if (_timer >= 0)
_machine->cancel_timer(_timer);
_timer = _machine->interval_timer(TICK_PERIOD, [this]() { tick(); });
}
// 60Hz is approx 16.67ms. Using 17 ticks @ 1ms = 58.8Hz.
// 0-13 = Active Display (14ms)
// 14-16 = Retrace (3ms)
void petio::tick() {
pia1.write_cb1(_ticks < 14);
if (++_ticks == 17)
_ticks = 0;
}
void petio::operator=(uint8_t r) {
Devices::operator=(r);
switch (_acc - VIA_OFFSET) {
case 0x08:
sound.frequency(r);
break;
case 0x0a:
sound.octave(r);
break;
case 0x0b:
sound.on_off((r & VIA::ACR_SHIFT_MASK) == VIA::ACR_SO_T2_RATE);
break;
}
}
bool petio::load_prg() {
extern Memory memory;
if (!files.more())
return false;
uint8_t lo = files.read();
uint8_t hi = files.read();
Memory::address a = lo + (hi << 8);
while (files.more())
memory[a++] = files.read();
// based on mem_get/set_basic_text() from vice/petmem.c
memory[0xc7] = memory[0x28];
memory[0xc8] = memory[0x29];
lo = (uint8_t)(a & 0xff);
memory[0x2a] = lo;
memory[0x2c] = lo;
memory[0x2e] = lo;
memory[0xc9] = lo;
hi = (uint8_t)(a >> 8);
memory[0x2b] = hi;
memory[0x2d] = hi;
memory[0x2f] = hi;
memory[0xca] = hi;
return true;
}