badline 0.17.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +153 -0
- data/CLAUDE.md +11 -7
- data/CONTRIBUTING.md +7 -1
- data/README.md +169 -20
- data/doc/pinned-behaviour.md +128 -0
- data/doc/snapshot-format.md +253 -18
- data/doc/snapshots.md +57 -23
- data/exe/badline-ruby +5 -0
- data/lib/badline/audio/terminal.rb +34 -2
- data/lib/badline/c128/keyed_state.rb +2 -0
- data/lib/badline/c128.rb +1 -0
- data/lib/badline/c64/keyed_state.rb +2 -0
- data/lib/badline/c64.rb +1 -0
- data/lib/badline/cbm2/keyed_state.rb +4 -0
- data/lib/badline/cbm2/p500.rb +5 -3
- data/lib/badline/cbm2.rb +6 -3
- data/lib/badline/chips/cia/timer.rb +2 -2
- data/lib/badline/chips/cpu/instruction_set.rb +1 -1
- data/lib/badline/chips/m6809/arithmetic.rb +140 -0
- data/lib/badline/chips/m6809/bus_steps.rb +223 -0
- data/lib/badline/chips/m6809/core.rb +149 -0
- data/lib/badline/chips/m6809/indexed.rb +82 -0
- data/lib/badline/chips/m6809/interrupts.rb +159 -0
- data/lib/badline/chips/m6809/keyed_state.rb +147 -0
- data/lib/badline/chips/m6809/opcodes.rb +159 -0
- data/lib/badline/chips/m6809/operations.rb +258 -0
- data/lib/badline/chips/m6809/plans.rb +143 -0
- data/lib/badline/chips/m6809/registers.rb +82 -0
- data/lib/badline/chips/m6809/stack.rb +140 -0
- data/lib/badline/chips/m6809.rb +13 -0
- data/lib/badline/chips/riot/timer.rb +14 -3
- data/lib/badline/chips/rriot.rb +4 -2
- data/lib/badline/chips/sid/filter.rb +4 -4
- data/lib/badline/chips/sid/waveform.rb +6 -6
- data/lib/badline/chips/vic_i/keyed_parts.rb +7 -2
- data/lib/badline/chips/vic_i.rb +84 -21
- data/lib/badline/data_path.rb +3 -3
- data/lib/badline/drives/ieee_models.rb +54 -0
- data/lib/badline/drives/model1001.rb +37 -0
- data/lib/badline/drives/model2031.rb +6 -0
- data/lib/badline/drives/model4040/disk.rb +62 -0
- data/lib/badline/drives/model4040/ip_bus.rb +46 -0
- data/lib/badline/drives/model4040/keyed_state.rb +57 -0
- data/lib/badline/drives/model4040/mechanism.rb +192 -0
- data/lib/badline/drives/model4040/parts.rb +20 -0
- data/lib/badline/drives/model4040.rb +179 -0
- data/lib/badline/drives/model8050/board.rb +77 -0
- data/lib/badline/drives/model8050/dos_board.rb +91 -0
- data/lib/badline/drives/model8050/idle.rb +11 -7
- data/lib/badline/drives/model8050/keyed_state.rb +5 -2
- data/lib/badline/drives/model8050.rb +18 -130
- data/lib/badline/drives/model9060/idle.rb +149 -0
- data/lib/badline/drives/model9060/keyed_state.rb +123 -0
- data/lib/badline/drives/model9060/parts.rb +98 -0
- data/lib/badline/drives/model9060/sasi_bus.rb +88 -0
- data/lib/badline/drives/model9060/sasi_commands.rb +168 -0
- data/lib/badline/drives/model9060/sasi_target.rb +161 -0
- data/lib/badline/drives/model9060.rb +195 -0
- data/lib/badline/frontend/app.rb +8 -0
- data/lib/badline/frontend/boot.rb +3 -2
- data/lib/badline/frontend/controls.rb +62 -6
- data/lib/badline/frontend/keys.rb +36 -0
- data/lib/badline/frontend/kim1_panel.rb +208 -0
- data/lib/badline/frontend/media_slots.rb +8 -1
- data/lib/badline/frontend/menu/drive_types.rb +56 -0
- data/lib/badline/frontend/menu/menu_dialogs.rb +61 -14
- data/lib/badline/frontend/menu/menu_media.rb +42 -12
- data/lib/badline/frontend/menu/menu_pages.rb +97 -2
- data/lib/badline/frontend/menu/menu_ports.rb +38 -1
- data/lib/badline/frontend/menu/pause_menu.rb +5 -1
- data/lib/badline/frontend/pet_keyboard.rb +23 -1
- data/lib/badline/frontend/screen.rb +1 -1
- data/lib/badline/frontend/screens.rb +40 -2
- data/lib/badline/frontend/teletype_pane.rb +152 -0
- data/lib/badline/frontend/timeline.rb +31 -2
- data/lib/badline/frontend.rb +3 -0
- data/lib/badline/kim1/bus.rb +117 -0
- data/lib/badline/kim1/cpu.rb +25 -0
- data/lib/badline/kim1/host_terminal.rb +74 -0
- data/lib/badline/kim1/key_entry.rb +74 -0
- data/lib/badline/kim1/keyed_modules.rb +53 -0
- data/lib/badline/kim1/keyed_state.rb +133 -0
- data/lib/badline/kim1/panel.rb +176 -0
- data/lib/badline/kim1/rriots.rb +28 -0
- data/lib/badline/kim1/sound.rb +29 -0
- data/lib/badline/kim1/tape.rb +116 -0
- data/lib/badline/kim1/teletype.rb +193 -0
- data/lib/badline/kim1.rb +190 -0
- data/lib/badline/machine/ieee_drives.rb +94 -117
- data/lib/badline/machine/keyboard_buffer.rb +20 -3
- data/lib/badline/machine/line_sound.rb +122 -0
- data/lib/badline/machine.rb +46 -15
- data/lib/badline/media/extensions.rb +8 -4
- data/lib/badline/media/kim1_media.rb +150 -0
- data/lib/badline/media/pet_media.rb +3 -1
- data/lib/badline/media/true_drive.rb +42 -45
- data/lib/badline/media.rb +12 -6
- data/lib/badline/options/family.rb +98 -8
- data/lib/badline/options/help.rb +44 -12
- data/lib/badline/options/table.rb +43 -11
- data/lib/badline/options/validation.rb +44 -8
- data/lib/badline/options.rb +27 -8
- data/lib/badline/pet/bus.rb +16 -2
- data/lib/badline/pet/keyboard_ports.rb +9 -2
- data/lib/badline/pet/keyed_state.rb +4 -0
- data/lib/badline/pet/model.rb +11 -2
- data/lib/badline/pet/rom_sets.rb +1 -0
- data/lib/badline/pet/sound.rb +5 -105
- data/lib/badline/pet/superpet/acia.rb +12 -0
- data/lib/badline/pet/superpet/board.rb +221 -0
- data/lib/badline/pet/superpet/dongle.rb +81 -0
- data/lib/badline/pet/superpet/keyed_modules.rb +63 -0
- data/lib/badline/pet/superpet/keyed_parts.rb +76 -0
- data/lib/badline/pet/superpet/m6809.rb +32 -0
- data/lib/badline/pet/superpet/waterloo_traps.rb +199 -0
- data/lib/badline/pet/superpet.rb +216 -0
- data/lib/badline/pet.rb +19 -3
- data/lib/badline/plus4/keyed_state.rb +2 -0
- data/lib/badline/plus4.rb +1 -0
- data/lib/badline/roms/1001/fdc-251257-02a.rom +0 -0
- data/lib/badline/roms/4040/dos-1.2.rom +0 -0
- data/lib/badline/roms/4040/dos-2.1-rev.rom +0 -0
- data/lib/badline/roms/4040/dos-2.1.rom +0 -0
- data/lib/badline/roms/4040/fdc-901466-02.rom +0 -0
- data/lib/badline/roms/4040/fdc-901466-04.rom +0 -0
- data/lib/badline/roms/9060/dos-3.0.rom +0 -0
- data/lib/badline/roms/9060/sasi-300515-revb.rom +0 -0
- data/lib/badline/roms/README +166 -0
- data/lib/badline/roms/kim1/6530-002.rom +0 -0
- data/lib/badline/roms/kim1/6530-003.rom +0 -0
- data/lib/badline/roms/pet/characters-superpet.rom +0 -0
- data/lib/badline/roms/pet/superpet-a000.rom +0 -0
- data/lib/badline/roms/pet/superpet-c000.rom +0 -0
- data/lib/badline/roms/pet/superpet-e000-50hz.rom +0 -0
- data/lib/badline/roms/pet/superpet-e000.rom +0 -0
- data/lib/badline/snapshot/container.rb +2 -0
- data/lib/badline/snapshot/field_doc/markdown.rb +1 -1
- data/lib/badline/snapshot/field_doc.rb +27 -6
- data/lib/badline/snapshot/image.rb +4 -1
- data/lib/badline/snapshot/kim1_setup.rb +28 -0
- data/lib/badline/snapshot/pet_setup.rb +27 -11
- data/lib/badline/snapshot/storage_setup.rb +4 -1
- data/lib/badline/snapshot/vic20_setup.rb +11 -7
- data/lib/badline/snapshot/vice/pet.rb +13 -7
- data/lib/badline/snapshot/vice/pet_cpu.rb +39 -5
- data/lib/badline/snapshot/vice/pet_crtc.rb +15 -2
- data/lib/badline/snapshot/vice/pet_drive8050.rb +188 -68
- data/lib/badline/snapshot/vice/pet_mem.rb +49 -5
- data/lib/badline/snapshot/vice/pet_restore.rb +40 -11
- data/lib/badline/snapshot.rb +4 -0
- data/lib/badline/status.rb +30 -30
- data/lib/badline/storage/d67_image.rb +55 -0
- data/lib/badline/storage/d90_image.rb +180 -0
- data/lib/badline/storage/disk_image/writing.rb +2 -2
- data/lib/badline/storage/kim_tape.rb +254 -0
- data/lib/badline/storage/papertape.rb +90 -0
- data/lib/badline/storage.rb +4 -0
- data/lib/badline/support/kim1_checkpoint.rb +41 -0
- data/lib/badline/support/superpet_checkpoint.rb +35 -0
- data/lib/badline/version.rb +1 -1
- data/lib/badline/vic20/keyed_modules.rb +6 -3
- data/lib/badline/vic20/keyed_state.rb +6 -4
- data/lib/badline/vic20.rb +26 -12
- data/lib/badline.rb +1 -0
- metadata +77 -1
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Chips
|
|
5
|
+
class M6809
|
|
6
|
+
# The instruction methods the plans' *_exec steps call. A read takes
|
|
7
|
+
# its operand from @value; a write and a read-modify-write leave the
|
|
8
|
+
# byte or word to write there.
|
|
9
|
+
module Operations
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def none; end
|
|
13
|
+
def nop; end
|
|
14
|
+
def sync; end
|
|
15
|
+
|
|
16
|
+
def neg = @value = neg8(@value)
|
|
17
|
+
def xnc = @value = xnc8(@value)
|
|
18
|
+
def com = @value = com8(@value)
|
|
19
|
+
def lsr = @value = lsr8(@value)
|
|
20
|
+
def ror = @value = ror8(@value)
|
|
21
|
+
def asr = @value = asr8(@value)
|
|
22
|
+
def asl = @value = asl8(@value)
|
|
23
|
+
def rol = @value = rol8(@value)
|
|
24
|
+
def dec = @value = dec8(@value)
|
|
25
|
+
def xdec = @value = xdec8(@value)
|
|
26
|
+
def inc = @value = inc8(@value)
|
|
27
|
+
def tst = logic8(@value)
|
|
28
|
+
def clr = @value = clr8
|
|
29
|
+
|
|
30
|
+
def jmp
|
|
31
|
+
@pc = @ea
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def nega = @a = neg8(@a)
|
|
35
|
+
def xnca = @a = xnc8(@a)
|
|
36
|
+
def coma = @a = com8(@a)
|
|
37
|
+
def lsra = @a = lsr8(@a)
|
|
38
|
+
def rora = @a = ror8(@a)
|
|
39
|
+
def asra = @a = asr8(@a)
|
|
40
|
+
def asla = @a = asl8(@a)
|
|
41
|
+
def rola = @a = rol8(@a)
|
|
42
|
+
def deca = @a = dec8(@a)
|
|
43
|
+
def xdeca = @a = xdec8(@a)
|
|
44
|
+
def inca = @a = inc8(@a)
|
|
45
|
+
def tsta = logic8(@a)
|
|
46
|
+
def xclra = @a = xclr8
|
|
47
|
+
def clra = @a = clr8
|
|
48
|
+
|
|
49
|
+
def negb = @b = neg8(@b)
|
|
50
|
+
def xncb = @b = xnc8(@b)
|
|
51
|
+
def comb = @b = com8(@b)
|
|
52
|
+
def lsrb = @b = lsr8(@b)
|
|
53
|
+
def rorb = @b = ror8(@b)
|
|
54
|
+
def asrb = @b = asr8(@b)
|
|
55
|
+
def aslb = @b = asl8(@b)
|
|
56
|
+
def rolb = @b = rol8(@b)
|
|
57
|
+
def decb = @b = dec8(@b)
|
|
58
|
+
def xdecb = @b = xdec8(@b)
|
|
59
|
+
def incb = @b = inc8(@b)
|
|
60
|
+
def tstb = logic8(@b)
|
|
61
|
+
def xclrb = @b = xclr8
|
|
62
|
+
def clrb = @b = clr8
|
|
63
|
+
|
|
64
|
+
def suba = @a = sub8(@a, @value, 0)
|
|
65
|
+
def cmpa = sub8(@a, @value, 0)
|
|
66
|
+
def sbca = @a = sub8(@a, @value, carry)
|
|
67
|
+
def anda = @a = logic8(@a & @value)
|
|
68
|
+
def bita = logic8(@a & @value)
|
|
69
|
+
def lda = @a = logic8(@value)
|
|
70
|
+
def sta = @value = logic8(@a)
|
|
71
|
+
def eora = @a = logic8(@a ^ @value)
|
|
72
|
+
def adca = @a = add8(@a, @value, carry)
|
|
73
|
+
def ora = @a = logic8(@a | @value)
|
|
74
|
+
def adda = @a = add8(@a, @value, 0)
|
|
75
|
+
|
|
76
|
+
def subb = @b = sub8(@b, @value, 0)
|
|
77
|
+
def cmpb = sub8(@b, @value, 0)
|
|
78
|
+
def sbcb = @b = sub8(@b, @value, carry)
|
|
79
|
+
def andb = @b = logic8(@b & @value)
|
|
80
|
+
def bitb = logic8(@b & @value)
|
|
81
|
+
def ldb = @b = logic8(@value)
|
|
82
|
+
def stb = @value = logic8(@b)
|
|
83
|
+
def eorb = @b = logic8(@b ^ @value)
|
|
84
|
+
def adcb = @b = add8(@b, @value, carry)
|
|
85
|
+
def orb = @b = logic8(@b | @value)
|
|
86
|
+
def addb = @b = add8(@b, @value, 0)
|
|
87
|
+
|
|
88
|
+
def subd = self.d = sub16(d, @value)
|
|
89
|
+
def addd = self.d = add16(d, @value)
|
|
90
|
+
def cmpd = sub16(d, @value)
|
|
91
|
+
def cmpx = sub16(@x, @value)
|
|
92
|
+
def cmpy = sub16(@y, @value)
|
|
93
|
+
def cmpu = sub16(@u, @value)
|
|
94
|
+
def cmps = sub16(@s, @value)
|
|
95
|
+
def xaddd = add16(d, @value)
|
|
96
|
+
def xaddu = add16(@u | 0xff00, @value)
|
|
97
|
+
|
|
98
|
+
def ldd = self.d = logic16(@value)
|
|
99
|
+
def ldx = @x = logic16(@value)
|
|
100
|
+
def ldy = @y = logic16(@value)
|
|
101
|
+
def ldu = @u = logic16(@value)
|
|
102
|
+
def lds = load_s(logic16(@value))
|
|
103
|
+
def std = @value = logic16(d)
|
|
104
|
+
def stx = @value = logic16(@x)
|
|
105
|
+
def sty = @value = logic16(@y)
|
|
106
|
+
def stu = @value = logic16(@u)
|
|
107
|
+
def sts = @value = logic16(@s)
|
|
108
|
+
|
|
109
|
+
# The undocumented stores immediate. Prefixed, they set N and clear
|
|
110
|
+
# Z and V. Unprefixed, their flags hang on the instruction before
|
|
111
|
+
# (Banks' "Flags for unprefixed Store Immediate"), and the 16-bit
|
|
112
|
+
# ones also clear Z unless the register's low byte is 0.
|
|
113
|
+
def xsta = flags(NEGATIVE | ZERO | OVERFLOW, previous_group_flags)
|
|
114
|
+
def xstb = flags(NEGATIVE | ZERO | OVERFLOW, previous_group_flags)
|
|
115
|
+
def xsta2 = flags(NEGATIVE | ZERO | OVERFLOW, NEGATIVE)
|
|
116
|
+
def xstb2 = flags(NEGATIVE | ZERO | OVERFLOW, NEGATIVE)
|
|
117
|
+
def xstx = @value = store_word_low(@x)
|
|
118
|
+
def xstu = @value = store_word_low(@u)
|
|
119
|
+
|
|
120
|
+
def xsty = @value = store_word_low_prefixed(@y)
|
|
121
|
+
def xsts = @value = store_word_low_prefixed(@s)
|
|
122
|
+
def xstx2 = @value = store_word_low_prefixed(@x)
|
|
123
|
+
def xstu2 = @value = store_word_low_prefixed(@u)
|
|
124
|
+
|
|
125
|
+
def store_word_low(word)
|
|
126
|
+
low = word & 0xff
|
|
127
|
+
set = previous_group_flags & (NEGATIVE | ZERO)
|
|
128
|
+
set &= ~ZERO unless low.zero?
|
|
129
|
+
flags(NEGATIVE | ZERO | OVERFLOW, set)
|
|
130
|
+
low
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def store_word_low_prefixed(word)
|
|
134
|
+
flags(NEGATIVE | ZERO | OVERFLOW, NEGATIVE)
|
|
135
|
+
word & 0xff
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def previous_group_flags
|
|
139
|
+
case @previous_group
|
|
140
|
+
when GROUP_N0_Z1 then ZERO
|
|
141
|
+
when GROUP_A_00 then nz8(@a)
|
|
142
|
+
when GROUP_A_FF then (@a == 0xff ? ZERO : 0) | (@a.anybits?(0x80) ? 0 : NEGATIVE)
|
|
143
|
+
when GROUP_A_01 then decremented_flags(@a)
|
|
144
|
+
when GROUP_B_01 then decremented_flags(@b)
|
|
145
|
+
when GROUP_WORD_01 then decremented_flags(@alu_word >> 8)
|
|
146
|
+
when GROUP_LEA then decremented_flags((@alu_word >> 8) | (@alu_word & 0xff))
|
|
147
|
+
else NEGATIVE
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# Z for 1, N for a negative value less one, V for $80.
|
|
152
|
+
def decremented_flags(value)
|
|
153
|
+
(value == 1 ? ZERO : 0) | ((value - 1).nobits?(0x80) ? 0 : NEGATIVE) | (value == 0x80 ? OVERFLOW : 0)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# JSR, BSR and LBSR, once the return address is stacked.
|
|
157
|
+
def jsr
|
|
158
|
+
@pc = @ea
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def leax
|
|
162
|
+
@alu_word = @ea
|
|
163
|
+
@x = @ea
|
|
164
|
+
flags(ZERO, @ea.zero? ? ZERO : 0)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def leay
|
|
168
|
+
@alu_word = @ea
|
|
169
|
+
@y = @ea
|
|
170
|
+
flags(ZERO, @ea.zero? ? ZERO : 0)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def leas
|
|
174
|
+
@alu_word = @ea
|
|
175
|
+
load_s(@ea)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def leau
|
|
179
|
+
@alu_word = @ea
|
|
180
|
+
@u = @ea
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def orcc = @cc |= @value
|
|
184
|
+
def andcc = @cc &= @value
|
|
185
|
+
|
|
186
|
+
def abx = @x = (@x + @b) & 0xffff
|
|
187
|
+
|
|
188
|
+
def mul
|
|
189
|
+
self.d = @a * @b
|
|
190
|
+
flags(ZERO | CARRY, (d.zero? ? ZERO : 0) | (@b >> 7))
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def sex
|
|
194
|
+
@a = @b.nobits?(0x80) ? 0 : 0xff
|
|
195
|
+
flags(NEGATIVE | ZERO, nz16(d))
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# DAA. V is C xor bit 7 of the result, as Banks found, where the
|
|
199
|
+
# datasheet clears it.
|
|
200
|
+
def daa
|
|
201
|
+
correction = 0
|
|
202
|
+
correction |= 0x06 if @cc.anybits?(HALF_CARRY) || (@a & 0x0f) > 0x09
|
|
203
|
+
high = @a & 0xf0
|
|
204
|
+
correction |= 0x60 if @cc.anybits?(CARRY) || high > 0x90 || (high > 0x80 && (@a & 0x0f) > 0x09)
|
|
205
|
+
result = (@a + correction) & 0xff
|
|
206
|
+
carry = correction >= 0x60 ? CARRY : 0
|
|
207
|
+
overflow = (carry == 1) == result.anybits?(0x80) ? 0 : OVERFLOW
|
|
208
|
+
flags(NEGATIVE | ZERO | OVERFLOW | CARRY, nz8(result) | overflow | carry)
|
|
209
|
+
@a = result
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
# The undocumented $18: each flag, ANDed with its bit of the byte
|
|
213
|
+
# after the opcode, moves one bit up, and V also takes Z ANDed with
|
|
214
|
+
# bit 2.
|
|
215
|
+
def x18
|
|
216
|
+
masked = @cc & @value
|
|
217
|
+
@cc = ((masked << 1) & 0xff) | (masked.nobits?(ZERO) ? 0 : OVERFLOW)
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def exg
|
|
221
|
+
first = @post >> 4
|
|
222
|
+
second = @post & 0x0f
|
|
223
|
+
value = transfer_register(second)
|
|
224
|
+
set_transfer_register(second, sized(transfer_register(first), first, second))
|
|
225
|
+
set_transfer_register(first, sized(value, second, first))
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def tfr
|
|
229
|
+
source = @post >> 4
|
|
230
|
+
destination = @post & 0x0f
|
|
231
|
+
set_transfer_register(destination, sized(transfer_register(source), source, destination))
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
# A value moved from register code +from+ to +to+: an 8-bit register
|
|
235
|
+
# fills a 16-bit one's high byte with $FF, and a 16-bit one gives an
|
|
236
|
+
# 8-bit one its low byte.
|
|
237
|
+
def sized(value, from, to)
|
|
238
|
+
return value & 0xff if to >= 8
|
|
239
|
+
return value | 0xff00 if from >= 8
|
|
240
|
+
|
|
241
|
+
value
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def swi = software_interrupt(0xfffa, IRQ_MASK | FIRQ_MASK, ENTIRE)
|
|
245
|
+
def swi2 = software_interrupt(0xfff4, 0, ENTIRE)
|
|
246
|
+
def swi3 = software_interrupt(0xfff2, 0, ENTIRE)
|
|
247
|
+
def xres = software_interrupt(0xfffe, 0, 0)
|
|
248
|
+
def xswi2 = software_interrupt(0xfff4, 0, 0)
|
|
249
|
+
def xfirq = software_interrupt(0xfff6, 0, 0)
|
|
250
|
+
|
|
251
|
+
def software_interrupt(vector, mask, entire)
|
|
252
|
+
@cc |= entire
|
|
253
|
+
interrupt_vector(vector, mask)
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
end
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Chips
|
|
5
|
+
class M6809
|
|
6
|
+
# The condition code bits.
|
|
7
|
+
CARRY = 0x01
|
|
8
|
+
OVERFLOW = 0x02
|
|
9
|
+
ZERO = 0x04
|
|
10
|
+
NEGATIVE = 0x08
|
|
11
|
+
IRQ_MASK = 0x10
|
|
12
|
+
HALF_CARRY = 0x20
|
|
13
|
+
FIRQ_MASK = 0x40
|
|
14
|
+
ENTIRE = 0x80
|
|
15
|
+
|
|
16
|
+
# What an opcode runs: the instruction method its *_exec step calls,
|
|
17
|
+
# the steps that work out its address, one a cycle, and the steps
|
|
18
|
+
# that follow them, and the group the undocumented stores immediate
|
|
19
|
+
# take their flags from when it ran before them. An indexed opcode's
|
|
20
|
+
# address steps end in the postbyte, which picks the rest from
|
|
21
|
+
# INDEXED_PLANS.
|
|
22
|
+
Entry = Struct.new(:operation, :plan, :tail, :group)
|
|
23
|
+
|
|
24
|
+
# The groups of David Banks' "Flags for unprefixed Store Immediate".
|
|
25
|
+
GROUP_OTHER = 0
|
|
26
|
+
GROUP_N0_Z1 = 1
|
|
27
|
+
GROUP_A_00 = 2
|
|
28
|
+
GROUP_A_FF = 3
|
|
29
|
+
GROUP_A_01 = 4
|
|
30
|
+
GROUP_B_01 = 5
|
|
31
|
+
GROUP_WORD_01 = 6
|
|
32
|
+
GROUP_LEA = 7
|
|
33
|
+
GROUPS = {
|
|
34
|
+
GROUP_N0_Z1 => %i[bita cmpa],
|
|
35
|
+
GROUP_A_00 => %i[lda ldd],
|
|
36
|
+
GROUP_A_FF => %i[adca adda anda eora ora sbca suba],
|
|
37
|
+
GROUP_A_01 => %i[asla asra coma daa deca inca lsra nega rola rora subd tsta xdeca xnca],
|
|
38
|
+
GROUP_B_01 => %i[sex],
|
|
39
|
+
GROUP_WORD_01 => %i[cmpd cmps cmpu cmpx cmpy xaddd xaddu],
|
|
40
|
+
GROUP_LEA => %i[leas leau leax leay]
|
|
41
|
+
}.flat_map { |group, operations| operations.map { |operation| [operation, group] } }.to_h.freeze
|
|
42
|
+
|
|
43
|
+
# The plan between instructions: the next cycle fetches an opcode.
|
|
44
|
+
FETCH_PLAN = %i[fetch].freeze
|
|
45
|
+
|
|
46
|
+
# The tail an instruction has once it is running its tail, never run.
|
|
47
|
+
# The empty tail, JUMP_TAIL, runs the instruction method as the
|
|
48
|
+
# address steps end.
|
|
49
|
+
NO_TAIL = %i[none].freeze
|
|
50
|
+
JUMP_TAIL = [].freeze
|
|
51
|
+
|
|
52
|
+
DIRECT_PLAN = %i[direct dead_v].freeze
|
|
53
|
+
EXTENDED_PLAN = %i[extended_hi extended_lo dead_v].freeze
|
|
54
|
+
INDEXED_PLAN = %i[postbyte].freeze
|
|
55
|
+
|
|
56
|
+
# The steps that read or write the address once it is known.
|
|
57
|
+
TAILS = {
|
|
58
|
+
read8: %i[read_exec],
|
|
59
|
+
read16: %i[read_hi read_lo_exec],
|
|
60
|
+
read16_dead: %i[read_hi read_lo_exec dead_v],
|
|
61
|
+
write8: %i[write_exec],
|
|
62
|
+
write16: %i[write_hi_exec write_lo],
|
|
63
|
+
rmw: %i[rmw_read dead_v rmw_write],
|
|
64
|
+
test: %i[read_exec dead_v dead_v],
|
|
65
|
+
jump: JUMP_TAIL,
|
|
66
|
+
subroutine: %i[dead_ea dead_v push_pcl push_pch_exec],
|
|
67
|
+
load_address: %i[dead_v_exec]
|
|
68
|
+
}.freeze
|
|
69
|
+
|
|
70
|
+
IMMEDIATE_TAILS = {
|
|
71
|
+
read8: %i[immediate_exec],
|
|
72
|
+
read16: %i[immediate_hi immediate_lo_exec],
|
|
73
|
+
read16_dead: %i[immediate_hi immediate_lo_exec dead_v]
|
|
74
|
+
}.freeze
|
|
75
|
+
|
|
76
|
+
# The 12 bytes SWI and the hardware interrupts other than FIRQ stack,
|
|
77
|
+
# in the order they go onto S.
|
|
78
|
+
PUSH_ALL = %i[push_pcl push_pch push_wl push_wh push_yl push_yh push_xl push_xh push_dp push_b push_a
|
|
79
|
+
push_cc].freeze
|
|
80
|
+
VECTOR_STEPS = %i[dead_v vector_hi vector_lo dead_v].freeze
|
|
81
|
+
|
|
82
|
+
# SWI, SWI2, SWI3 and the undocumented XRES, XSWI2 and XFIRQ, after
|
|
83
|
+
# the opcode. The instruction method picks the vector.
|
|
84
|
+
SOFTWARE_INTERRUPT_TAIL = [:dead_pc, :dead_v_exec, *PUSH_ALL, *VECTOR_STEPS].freeze
|
|
85
|
+
|
|
86
|
+
# IRQ and NMI after the cycle that would have fetched the opcode, and
|
|
87
|
+
# FIRQ, which stacks only PC and CC.
|
|
88
|
+
INTERRUPT_PLAN = [:dead_pc, :dead_v_exec, *PUSH_ALL, *VECTOR_STEPS].freeze
|
|
89
|
+
FAST_INTERRUPT_PLAN = [:dead_pc, :dead_v_exec, :push_pcl, :push_pch, :push_cc, *VECTOR_STEPS].freeze
|
|
90
|
+
|
|
91
|
+
# The interrupt CWAI was waiting for: its vector, no more stacking.
|
|
92
|
+
WAITED_INTERRUPT_PLAN = %i[vector_hi vector_lo dead_v].freeze
|
|
93
|
+
|
|
94
|
+
# RTI after pulling CC, with E set and with E clear.
|
|
95
|
+
RETURN_ENTIRE_PLAN = %i[pull_a pull_b pull_dp pull_xh pull_xl pull_yh pull_yl pull_wh pull_wl pull_pch pull_pcl
|
|
96
|
+
dead_stack].freeze
|
|
97
|
+
RETURN_FAST_PLAN = %i[pull_pch pull_pcl dead_stack].freeze
|
|
98
|
+
|
|
99
|
+
# The cycles after RESET goes high: two dead reads of $FFFE, the
|
|
100
|
+
# vector, and a dead cycle.
|
|
101
|
+
RESET_PLAN = %i[reset_dead reset_dead reset_hi reset_lo dead_v].freeze
|
|
102
|
+
|
|
103
|
+
LONG_BRANCH_TAKEN_PLAN = %i[dead_v_take].freeze
|
|
104
|
+
SYNC_END_PLAN = %i[idle].freeze
|
|
105
|
+
|
|
106
|
+
# PSH and PUL by postbyte: the bytes in the order they go onto or
|
|
107
|
+
# come off the stack, PC first on and last off.
|
|
108
|
+
PUSH_ORDER = [[0x80, %i[push_pcl push_pch]], [0x40, %i[push_wl push_wh]], [0x20, %i[push_yl push_yh]],
|
|
109
|
+
[0x10, %i[push_xl push_xh]], [0x08, %i[push_dp]], [0x04, %i[push_b]], [0x02, %i[push_a]],
|
|
110
|
+
[0x01, %i[push_cc]]].freeze
|
|
111
|
+
PULL_ORDER = [[0x01, %i[pull_cc]], [0x02, %i[pull_a]], [0x04, %i[pull_b]], [0x08, %i[pull_dp]],
|
|
112
|
+
[0x10, %i[pull_xh pull_xl]], [0x20, %i[pull_yh pull_yl]], [0x40, %i[pull_wh pull_wl]],
|
|
113
|
+
[0x80, %i[pull_pch pull_pcl]]].freeze
|
|
114
|
+
PUSH_PLANS = Array.new(256) do |mask|
|
|
115
|
+
[:dead_v, :dead_v, :dead_stack, *PUSH_ORDER.flat_map { |bit, steps| mask.nobits?(bit) ? [] : steps }].freeze
|
|
116
|
+
end.freeze
|
|
117
|
+
PULL_PLANS = Array.new(256) do |mask|
|
|
118
|
+
[:dead_v, :dead_v, *PULL_ORDER.flat_map { |bit, steps| mask.nobits?(bit) ? [] : steps }, :dead_stack].freeze
|
|
119
|
+
end.freeze
|
|
120
|
+
|
|
121
|
+
# The steps after the postbyte, by postbyte, Figure 17 sheet 4.
|
|
122
|
+
INDEXED_PLANS = Array.new(256) do |post|
|
|
123
|
+
next %i[dead_pc dead_v].freeze if post < 0x80
|
|
124
|
+
|
|
125
|
+
plan = case post & 0x0f
|
|
126
|
+
when 0x0, 0x2 then %i[dead_pc dead_v dead_v]
|
|
127
|
+
when 0x1, 0x3 then %i[dead_pc dead_v dead_v dead_v]
|
|
128
|
+
when 0x4 then %i[dead_pc]
|
|
129
|
+
when 0x5, 0x6 then %i[dead_pc dead_v]
|
|
130
|
+
when 0x8 then %i[offset8 dead_v]
|
|
131
|
+
when 0x9 then %i[offset_hi offset_lo_register dead_pc dead_v dead_v]
|
|
132
|
+
when 0xb then %i[dead_pc dead_pc_next dead_pc_next2 dead_v dead_v]
|
|
133
|
+
when 0xc then %i[offset8_pc dead_v]
|
|
134
|
+
when 0xd then %i[offset_hi offset_lo_pc dead_pc dead_v dead_v dead_v]
|
|
135
|
+
when 0xf then %i[offset_hi offset_lo_absolute dead_pc]
|
|
136
|
+
else []
|
|
137
|
+
end
|
|
138
|
+
plan += %i[indirect_hi indirect_lo dead_v] if post.anybits?(0x10)
|
|
139
|
+
plan.freeze
|
|
140
|
+
end.freeze
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Chips
|
|
5
|
+
class M6809
|
|
6
|
+
# The programmer's registers, and the codes TFR and EXG and the
|
|
7
|
+
# indexed postbyte name them by.
|
|
8
|
+
module Registers
|
|
9
|
+
attr_accessor :a, :b, :x, :y, :u, :s, :pc, :dp, :cc
|
|
10
|
+
|
|
11
|
+
def d = (@a << 8) | @b
|
|
12
|
+
|
|
13
|
+
def d=(value)
|
|
14
|
+
@a = value >> 8
|
|
15
|
+
@b = value & 0xff
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Whether NMI is armed: a load of S since reset.
|
|
19
|
+
def nmi_armed? = @nmi_armed
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def load_s(value)
|
|
24
|
+
@s = value
|
|
25
|
+
@nmi_armed = true
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# The register bits 5 and 6 of an indexed postbyte name.
|
|
29
|
+
def index_register
|
|
30
|
+
case @post & 0x60
|
|
31
|
+
when 0x00 then @x
|
|
32
|
+
when 0x20 then @y
|
|
33
|
+
when 0x40 then @u
|
|
34
|
+
else @s
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def index_register=(value)
|
|
39
|
+
case @post & 0x60
|
|
40
|
+
when 0x00 then @x = value
|
|
41
|
+
when 0x20 then @y = value
|
|
42
|
+
when 0x40 then @u = value
|
|
43
|
+
else load_s(value)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# A TFR or EXG register: D, X, Y, U, S and PC are 0 to 5, A, B, CC
|
|
48
|
+
# and DP 8 to 11. The other codes read as $FF or $FFFF.
|
|
49
|
+
def transfer_register(code)
|
|
50
|
+
case code
|
|
51
|
+
when 0x0 then d
|
|
52
|
+
when 0x1 then @x
|
|
53
|
+
when 0x2 then @y
|
|
54
|
+
when 0x3 then @u
|
|
55
|
+
when 0x4 then @s
|
|
56
|
+
when 0x5 then @pc
|
|
57
|
+
when 0x8 then @a
|
|
58
|
+
when 0x9 then @b
|
|
59
|
+
when 0xa then @cc
|
|
60
|
+
when 0xb then @dp
|
|
61
|
+
else code < 8 ? 0xffff : 0xff
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def set_transfer_register(code, value)
|
|
66
|
+
case code
|
|
67
|
+
when 0x0 then self.d = value
|
|
68
|
+
when 0x1 then @x = value
|
|
69
|
+
when 0x2 then @y = value
|
|
70
|
+
when 0x3 then @u = value
|
|
71
|
+
when 0x4 then load_s(value)
|
|
72
|
+
when 0x5 then @pc = value
|
|
73
|
+
when 0x8 then @a = value
|
|
74
|
+
when 0x9 then @b = value
|
|
75
|
+
when 0xa then @cc = value
|
|
76
|
+
when 0xb then @dp = value
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Chips
|
|
5
|
+
class M6809
|
|
6
|
+
# The stack steps of PSH, PUL, JSR, BSR, RTS, RTI, the software
|
|
7
|
+
# interrupts and the hardware ones. Each pushes onto or pulls off the
|
|
8
|
+
# stack @stack_u names: U for PSHU and PULU, S otherwise. The "other"
|
|
9
|
+
# stack pointer, w, is the one that isn't.
|
|
10
|
+
module Stack
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
def push(value)
|
|
14
|
+
if @stack_u
|
|
15
|
+
@u = (@u - 1) & 0xffff
|
|
16
|
+
@bus.write(@u, value)
|
|
17
|
+
else
|
|
18
|
+
@s = (@s - 1) & 0xffff
|
|
19
|
+
@bus.write(@s, value)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def pull
|
|
24
|
+
if @stack_u
|
|
25
|
+
value = @bus.read(@u)
|
|
26
|
+
@u = (@u + 1) & 0xffff
|
|
27
|
+
else
|
|
28
|
+
value = @bus.read(@s)
|
|
29
|
+
@s = (@s + 1) & 0xffff
|
|
30
|
+
end
|
|
31
|
+
value
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def dead_stack = @bus.read(@stack_u ? @u : @s)
|
|
35
|
+
|
|
36
|
+
def other_stack = @stack_u ? @s : @u
|
|
37
|
+
|
|
38
|
+
def other_stack=(value)
|
|
39
|
+
@stack_u ? load_s(value) : @u = value
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def push_s_post = stack_post(false, PUSH_PLANS)
|
|
43
|
+
|
|
44
|
+
def push_u_post = stack_post(true, PUSH_PLANS)
|
|
45
|
+
|
|
46
|
+
def pull_s_post = stack_post(false, PULL_PLANS)
|
|
47
|
+
|
|
48
|
+
def pull_u_post = stack_post(true, PULL_PLANS)
|
|
49
|
+
|
|
50
|
+
def stack_post(stack_u, plans)
|
|
51
|
+
@stack_u = stack_u
|
|
52
|
+
switch_to(plans[read_pc])
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def push_pcl = push(@pc & 0xff)
|
|
56
|
+
def push_pch = push(@pc >> 8)
|
|
57
|
+
def push_wl = push(other_stack & 0xff)
|
|
58
|
+
def push_wh = push(other_stack >> 8)
|
|
59
|
+
def push_yl = push(@y & 0xff)
|
|
60
|
+
def push_yh = push(@y >> 8)
|
|
61
|
+
def push_xl = push(@x & 0xff)
|
|
62
|
+
def push_xh = push(@x >> 8)
|
|
63
|
+
def push_dp = push(@dp)
|
|
64
|
+
def push_b = push(@b)
|
|
65
|
+
def push_a = push(@a)
|
|
66
|
+
def push_cc = push(@cc)
|
|
67
|
+
|
|
68
|
+
def push_pch_exec
|
|
69
|
+
push_pch
|
|
70
|
+
execute
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def pull_cc
|
|
74
|
+
@cc = pull
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def pull_a
|
|
78
|
+
@a = pull
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def pull_b
|
|
82
|
+
@b = pull
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def pull_dp
|
|
86
|
+
@dp = pull
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def pull_xh
|
|
90
|
+
@x = (pull << 8) | (@x & 0xff)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def pull_xl
|
|
94
|
+
@x = (@x & 0xff00) | pull
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def pull_yh
|
|
98
|
+
@y = (pull << 8) | (@y & 0xff)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def pull_yl
|
|
102
|
+
@y = (@y & 0xff00) | pull
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def pull_wh
|
|
106
|
+
self.other_stack = (pull << 8) | (other_stack & 0xff)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def pull_wl
|
|
110
|
+
self.other_stack = (other_stack & 0xff00) | pull
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def pull_pch
|
|
114
|
+
@pc = (pull << 8) | (@pc & 0xff)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def pull_pcl
|
|
118
|
+
@pc = (@pc & 0xff00) | pull
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# RTI after pulling CC: the whole state when E is set, else PC.
|
|
122
|
+
def return_cc
|
|
123
|
+
pull_cc
|
|
124
|
+
switch_to(@cc.nobits?(ENTIRE) ? RETURN_FAST_PLAN : RETURN_ENTIRE_PLAN)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# The vector of the interrupt or SWI being taken. The masks it sets
|
|
128
|
+
# take effect as its first byte is read.
|
|
129
|
+
def vector_hi
|
|
130
|
+
@value = @bus.read(@vector) << 8
|
|
131
|
+
@cc |= @interrupt_mask
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def vector_lo
|
|
135
|
+
@pc = @value | @bus.read(@vector + 1)
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "badline/chips/m6809/core"
|
|
4
|
+
|
|
5
|
+
module Badline
|
|
6
|
+
module Chips
|
|
7
|
+
# The Motorola 6809E, which the SuperPET has beside its 6502. It is not
|
|
8
|
+
# part of badline/core, so a machine that has one requires it.
|
|
9
|
+
class M6809
|
|
10
|
+
include Core
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -13,8 +13,12 @@ module Badline
|
|
|
13
13
|
# reads N - 1 until cycle T, 0 until cycle N x T, and $FF with the flag
|
|
14
14
|
# set on cycle N x T: 52 at ÷8 sets the flag on cycle 416. From there
|
|
15
15
|
# the counter counts every cycle, so it tells how long ago the flag
|
|
16
|
-
# set, and each count through 0 sets the flag again.
|
|
17
|
-
# the prescaler back.
|
|
16
|
+
# set, and each count through 0 sets the flag again. On the 6532 only
|
|
17
|
+
# a write puts the prescaler back. On the 6530, as the KIM-1 User
|
|
18
|
+
# Manual's appendix H has it, a read of the counter after the flag
|
|
19
|
+
# set does too, and the counter counts on from where it is at the
|
|
20
|
+
# interval written: a 6530 builds its timer with
|
|
21
|
+
# read_restores_divider. No test program has confirmed it.
|
|
18
22
|
#
|
|
19
23
|
# Reading or writing the counter clears the flag, except for a read on
|
|
20
24
|
# the cycle that sets it. Each access takes A3 as the interrupt enable.
|
|
@@ -24,7 +28,8 @@ module Badline
|
|
|
24
28
|
attr_reader :counter, :flag
|
|
25
29
|
attr_accessor :irq_enabled
|
|
26
30
|
|
|
27
|
-
def initialize
|
|
31
|
+
def initialize(read_restores_divider: false)
|
|
32
|
+
@read_restores_divider = read_restores_divider
|
|
28
33
|
@counter = 0
|
|
29
34
|
@divider = 1
|
|
30
35
|
@prescale = 1
|
|
@@ -50,6 +55,7 @@ module Badline
|
|
|
50
55
|
def read(irq_enabled)
|
|
51
56
|
@irq_enabled = irq_enabled
|
|
52
57
|
@flag = false unless @fired
|
|
58
|
+
restore_divider if @read_restores_divider && @expired
|
|
53
59
|
@counter
|
|
54
60
|
end
|
|
55
61
|
|
|
@@ -66,6 +72,11 @@ module Badline
|
|
|
66
72
|
|
|
67
73
|
private
|
|
68
74
|
|
|
75
|
+
def restore_divider
|
|
76
|
+
@expired = false
|
|
77
|
+
@prescale = @divider
|
|
78
|
+
end
|
|
79
|
+
|
|
69
80
|
def count
|
|
70
81
|
@counter = (@counter - 1) & 0xff
|
|
71
82
|
return unless @counter == 0xff
|
data/lib/badline/chips/rriot.rb
CHANGED
|
@@ -9,7 +9,9 @@ module Badline
|
|
|
9
9
|
# of RAM, two 8-bit ports, A and B, each with a direction register, a 1
|
|
10
10
|
# making the pin an output, and the 6532's interval timer (RIOT::Timer).
|
|
11
11
|
# It has no edge detector. The 8050 and 8250's floppy controller has
|
|
12
|
-
# one, its ROM the controller's program.
|
|
12
|
+
# one, its ROM the controller's program, and the KIM-1 two. Its timer
|
|
13
|
+
# reads its counter as the 6532's does, but a read after the flag sets
|
|
14
|
+
# puts the prescaler back (RIOT::Timer).
|
|
13
15
|
#
|
|
14
16
|
# Which addresses select the ROM, the RAM and the registers is part of
|
|
15
17
|
# the mask, so the board decodes them and calls read_rom (A9-A0),
|
|
@@ -36,7 +38,7 @@ module Badline
|
|
|
36
38
|
@peripheral = peripheral
|
|
37
39
|
@irq_on_pb7 = irq_on_pb7
|
|
38
40
|
@ram = Array.new(64, 0)
|
|
39
|
-
@timer = RIOT::Timer.new
|
|
41
|
+
@timer = RIOT::Timer.new(read_restores_divider: true)
|
|
40
42
|
reset!
|
|
41
43
|
end
|
|
42
44
|
|