badline 0.17.0 → 0.19.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 +193 -0
- data/CLAUDE.md +19 -7
- data/CONTRIBUTING.md +11 -1
- data/README.md +178 -26
- data/doc/library.md +5 -1
- data/doc/media.md +3 -2
- data/doc/pinned-behaviour.md +169 -1
- data/doc/snapshot-format.md +302 -35
- data/doc/snapshots.md +97 -26
- data/doc/vice.md +344 -0
- data/exe/badline-ruby +5 -0
- data/lib/badline/audio/renderer.rb +4 -8
- data/lib/badline/audio/terminal.rb +34 -2
- data/lib/badline/c128/keyed_state.rb +2 -0
- data/lib/badline/c128.rb +5 -0
- data/lib/badline/c64/bus/fittings.rb +6 -0
- data/lib/badline/c64/keyed_state.rb +2 -0
- data/lib/badline/c64.rb +7 -0
- data/lib/badline/cbm2/keyed_state.rb +4 -0
- data/lib/badline/cbm2/p500.rb +9 -3
- data/lib/badline/cbm2.rb +10 -3
- data/lib/badline/chips/cia/timer.rb +2 -2
- data/lib/badline/chips/cpu/core.rb +29 -4
- data/lib/badline/chips/cpu/instruction_set.rb +1 -1
- data/lib/badline/chips/cpu/interrupts.rb +9 -0
- data/lib/badline/chips/cpu/keyed_state.rb +15 -9
- data/lib/badline/chips/cpu/microcode.rb +10 -0
- 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 +8 -3
- data/lib/badline/chips/sid/decimator.rb +1 -1
- data/lib/badline/chips/sid/filter.rb +4 -4
- data/lib/badline/chips/sid/keyed_parts.rb +51 -18
- data/lib/badline/chips/sid/waveform.rb +6 -6
- data/lib/badline/chips/sid.rb +6 -2
- data/lib/badline/chips/vic_i/keyed_parts.rb +12 -2
- data/lib/badline/chips/vic_i/light_pen.rb +89 -0
- data/lib/badline/chips/vic_i.rb +91 -23
- 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/model1541/sector_reader.rb +20 -3
- data/lib/badline/drives/model1541.rb +1 -0
- data/lib/badline/drives/model1551.rb +1 -0
- data/lib/badline/drives/model1571.rb +1 -0
- data/lib/badline/drives/model1581.rb +1 -0
- data/lib/badline/drives/model2031.rb +7 -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 +195 -0
- data/lib/badline/drives/model4040/parts.rb +20 -0
- data/lib/badline/drives/model4040.rb +195 -0
- data/lib/badline/drives/model8050/board.rb +79 -0
- data/lib/badline/drives/model8050/dos_board.rb +134 -0
- data/lib/badline/drives/model8050/fdc_bus.rb +7 -0
- data/lib/badline/drives/model8050/idle.rb +148 -31
- data/lib/badline/drives/model8050/keyed_state.rb +5 -2
- data/lib/badline/drives/model8050.rb +32 -130
- data/lib/badline/drives/model9060/idle.rb +169 -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 +197 -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/input/joystick.rb +15 -2
- 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 +118 -0
- data/lib/badline/kim1/teletype.rb +193 -0
- data/lib/badline/kim1.rb +194 -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 +49 -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 +52 -45
- data/lib/badline/media/vic20_media.rb +4 -2
- data/lib/badline/media.rb +16 -6
- data/lib/badline/memory.rb +2 -4
- data/lib/badline/options/family.rb +98 -8
- data/lib/badline/options/help.rb +44 -12
- data/lib/badline/options/table.rb +44 -12
- 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 +92 -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 +221 -0
- data/lib/badline/pet.rb +23 -3
- data/lib/badline/plus4/keyed_state.rb +2 -0
- data/lib/badline/plus4.rb +5 -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 +176 -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 +8 -4
- data/lib/badline/snapshot/field_doc/markdown.rb +1 -1
- data/lib/badline/snapshot/field_doc.rb +35 -10
- data/lib/badline/snapshot/image.rb +19 -7
- 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 +14 -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_dongle.rb +72 -0
- data/lib/badline/snapshot/vice/pet_drive8050.rb +188 -68
- data/lib/badline/snapshot/vice/pet_mem.rb +55 -5
- data/lib/badline/snapshot/vice/pet_restore.rb +40 -11
- data/lib/badline/snapshot/vice/vic20.rb +70 -0
- data/lib/badline/snapshot/vice/vic20_cpu.rb +61 -0
- data/lib/badline/snapshot/vice/vic20_mem.rb +85 -0
- data/lib/badline/snapshot/vice/vic20_restore.rb +124 -0
- data/lib/badline/snapshot/vice/vic20_vici.rb +200 -0
- data/lib/badline/snapshot/vice.rb +1 -0
- data/lib/badline/snapshot.rb +8 -4
- 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/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/port_wiring.rb +11 -0
- data/lib/badline/vic20.rb +30 -12
- data/lib/badline.rb +1 -0
- metadata +85 -1
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Chips
|
|
5
|
+
class M6809
|
|
6
|
+
# Every plan the CPU runs and every tail it keeps, by the name a
|
|
7
|
+
# snapshot gives it: the plans of their own by name, an indexed
|
|
8
|
+
# postbyte's, a PSH's and a PUL's by postbyte, and an opcode's by its
|
|
9
|
+
# page and opcode. A plan that has several names goes by the first.
|
|
10
|
+
module PlanNames
|
|
11
|
+
OWN = { "fetch" => FETCH_PLAN, "reset" => RESET_PLAN, "prefix" => PREFIX_PLAN, "none" => NO_TAIL,
|
|
12
|
+
"jump" => JUMP_TAIL, "interrupt" => INTERRUPT_PLAN, "fast_interrupt" => FAST_INTERRUPT_PLAN,
|
|
13
|
+
"waited_interrupt" => WAITED_INTERRUPT_PLAN, "return_entire" => RETURN_ENTIRE_PLAN,
|
|
14
|
+
"return_fast" => RETURN_FAST_PLAN, "long_branch_taken" => LONG_BRANCH_TAKEN_PLAN,
|
|
15
|
+
"sync_end" => SYNC_END_PLAN }.freeze
|
|
16
|
+
|
|
17
|
+
PAGES = [PAGE1, PAGE2, PAGE3].freeze
|
|
18
|
+
|
|
19
|
+
TABLE = (OWN.to_a +
|
|
20
|
+
{ "indexed" => INDEXED_PLANS, "push" => PUSH_PLANS, "pull" => PULL_PLANS }.flat_map do |kind, plans|
|
|
21
|
+
Array.new(256) { |post| ["#{kind}.#{post}", plans[post]] }
|
|
22
|
+
end +
|
|
23
|
+
Array.new(PAGES.length * 256) do |slot|
|
|
24
|
+
entry = PAGES[slot >> 8][slot & 0xff]
|
|
25
|
+
name = "op.#{(slot >> 8) + 1}.#{slot & 0xff}"
|
|
26
|
+
[["#{name}.plan", entry.plan], ["#{name}.tail", entry.tail]]
|
|
27
|
+
end.flatten(1)).freeze
|
|
28
|
+
|
|
29
|
+
NAMES = TABLE.map(&:first).freeze
|
|
30
|
+
PLANS = TABLE.map(&:last).freeze
|
|
31
|
+
|
|
32
|
+
# What the opcodes and the interrupts run, by name.
|
|
33
|
+
OPERATIONS = (%w[none enter_nmi enter_firq enter_irq] +
|
|
34
|
+
PAGES.flat_map { |page| page.map { |entry| entry.operation.to_s } }).uniq.freeze
|
|
35
|
+
|
|
36
|
+
module_function
|
|
37
|
+
|
|
38
|
+
def name_of(plan)
|
|
39
|
+
index = PLANS.index { |each_plan| each_plan.equal?(plan) }
|
|
40
|
+
index.nil? ? "fetch" : NAMES[index]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def named(name)
|
|
44
|
+
index = NAMES.index(name)
|
|
45
|
+
index.nil? ? nil : PLANS[index]
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# The CPU's fields in a keyed snapshot module (Snapshot::Keyed): the
|
|
50
|
+
# registers, the interrupt lines and what the CPU has sampled of
|
|
51
|
+
# them, the cycle count, the working registers the steps share, and
|
|
52
|
+
# off an instruction boundary the plan running, the step in it and
|
|
53
|
+
# the tail to follow, by PlanNames. A plan it doesn't know puts the
|
|
54
|
+
# CPU on a boundary.
|
|
55
|
+
module KeyedState
|
|
56
|
+
def save_fields(out)
|
|
57
|
+
out.int("a", @a).int("b", @b).int("x", @x).int("y", @y).int("u", @u).int("s", @s).int("pc", @pc)
|
|
58
|
+
out.int("dp", @dp).int("cc", @cc).int("cycles", @cycles)
|
|
59
|
+
out.bool("irq", @irq).bool("firq", @firq).bool("nmi", @nmi).bool("halt", @halt)
|
|
60
|
+
out.bool("irq.latched", @irq_latched).bool("irq.seen", @irq_seen)
|
|
61
|
+
out.bool("firq.latched", @firq_latched).bool("firq.seen", @firq_seen)
|
|
62
|
+
out.bool("nmi.edge", @nmi_edge).bool("nmi.latched", @nmi_latched).bool("nmi.seen", @nmi_seen)
|
|
63
|
+
out.bool("nmi.armed", @nmi_armed).bool("halt.latched", @halt_latched).bool("halt.seen", @halt_seen)
|
|
64
|
+
save_working_fields(out)
|
|
65
|
+
out
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def load_fields(input)
|
|
69
|
+
load_registers(input)
|
|
70
|
+
load_lines(input)
|
|
71
|
+
load_working_fields(input)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def restored! = nil
|
|
75
|
+
|
|
76
|
+
private
|
|
77
|
+
|
|
78
|
+
def save_working_fields(out)
|
|
79
|
+
out.int("ea", @ea).int("value", @value).int("post", @post).int("opcode", @opcode)
|
|
80
|
+
out.text("operation", @operation.to_s).int("page", PlanNames::PAGES.index { |page| page.equal?(@page) } + 1)
|
|
81
|
+
out.int("group", @group).int("previous_group", @previous_group).int("alu_word", @alu_word)
|
|
82
|
+
out.int("vector", @vector).int("interrupt_mask", @interrupt_mask).bool("stack_u", @stack_u)
|
|
83
|
+
return if boundary?
|
|
84
|
+
|
|
85
|
+
out.text("pos.plan", PlanNames.name_of(@plan)).int("pos.index", @index)
|
|
86
|
+
out.text("pos.tail", PlanNames.name_of(@tail))
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def load_registers(input)
|
|
90
|
+
@a = input.byte("a", @a)
|
|
91
|
+
@b = input.byte("b", @b)
|
|
92
|
+
@x = input.word("x", @x)
|
|
93
|
+
@y = input.word("y", @y)
|
|
94
|
+
@u = input.word("u", @u)
|
|
95
|
+
@s = input.word("s", @s)
|
|
96
|
+
@pc = input.word("pc", @pc)
|
|
97
|
+
@dp = input.byte("dp", @dp)
|
|
98
|
+
@cc = input.byte("cc", @cc)
|
|
99
|
+
@cycles = input.int("cycles", @cycles)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def load_lines(input)
|
|
103
|
+
@irq = input.bool("irq", false)
|
|
104
|
+
@firq = input.bool("firq", false)
|
|
105
|
+
@nmi = input.bool("nmi", false)
|
|
106
|
+
@halt = input.bool("halt", false)
|
|
107
|
+
@irq_latched = input.bool("irq.latched", false)
|
|
108
|
+
@irq_seen = input.bool("irq.seen", false)
|
|
109
|
+
@firq_latched = input.bool("firq.latched", false)
|
|
110
|
+
@firq_seen = input.bool("firq.seen", false)
|
|
111
|
+
@nmi_edge = input.bool("nmi.edge", false)
|
|
112
|
+
@nmi_latched = input.bool("nmi.latched", false)
|
|
113
|
+
@nmi_seen = input.bool("nmi.seen", false)
|
|
114
|
+
@nmi_armed = input.bool("nmi.armed", @nmi_armed)
|
|
115
|
+
@halt_latched = input.bool("halt.latched", false)
|
|
116
|
+
@halt_seen = input.bool("halt.seen", false)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def load_working_fields(input)
|
|
120
|
+
@ea = input.word("ea", 0)
|
|
121
|
+
@value = input.word("value", 0)
|
|
122
|
+
@post = input.byte("post", 0)
|
|
123
|
+
@opcode = input.byte("opcode", 0)
|
|
124
|
+
@operation = input.choice("operation", PlanNames::OPERATIONS, "none").to_sym
|
|
125
|
+
@page = PlanNames::PAGES.fetch(input.int("page", 1).clamp(1, 3) - 1)
|
|
126
|
+
@group = input.int("group", GROUP_OTHER)
|
|
127
|
+
@previous_group = input.int("previous_group", GROUP_OTHER)
|
|
128
|
+
@alu_word = input.int("alu_word", 0)
|
|
129
|
+
@vector = input.word("vector", 0xfffe)
|
|
130
|
+
@interrupt_mask = input.byte("interrupt_mask", 0)
|
|
131
|
+
@stack_u = input.bool("stack_u", false)
|
|
132
|
+
load_position(input)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def load_position(input)
|
|
136
|
+
plan = PlanNames.named(input.text("pos.plan", "fetch"))
|
|
137
|
+
tail = PlanNames.named(input.text("pos.tail", "none"))
|
|
138
|
+
return boundary if plan.nil? || tail.nil? || plan.empty?
|
|
139
|
+
|
|
140
|
+
@plan = plan
|
|
141
|
+
@index = input.int("pos.index", 0).clamp(0, plan.length - 1)
|
|
142
|
+
@tail = tail
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "badline/chips/m6809/plans"
|
|
4
|
+
|
|
5
|
+
module Badline
|
|
6
|
+
module Chips
|
|
7
|
+
class M6809
|
|
8
|
+
# The read-modify-write group: $00-$0F direct, $60-$6F indexed and
|
|
9
|
+
# $70-$7F extended, and $40-$4F and $50-$5F on A and B.
|
|
10
|
+
MEMORY_GROUP = %i[neg neg xnc com lsr lsr ror asr asl rol dec xdec inc tst jmp clr].freeze
|
|
11
|
+
A_GROUP = %i[nega nega xnca coma lsra lsra rora asra asla rola deca xdeca inca tsta xclra clra].freeze
|
|
12
|
+
B_GROUP = %i[negb negb xncb comb lsrb lsrb rorb asrb aslb rolb decb xdecb incb tstb xclrb clrb].freeze
|
|
13
|
+
|
|
14
|
+
# $80-$BF and $C0-$FF by low nibble: the instruction and its kind.
|
|
15
|
+
A_COLUMN = [%i[suba read8], %i[cmpa read8], %i[sbca read8], %i[subd read16_dead], %i[anda read8],
|
|
16
|
+
%i[bita read8], %i[lda read8], %i[sta write8], %i[eora read8], %i[adca read8], %i[ora read8],
|
|
17
|
+
%i[adda read8], %i[cmpx read16_dead], %i[jsr subroutine], %i[ldx read16], %i[stx write16]].freeze
|
|
18
|
+
B_COLUMN = [%i[subb read8], %i[cmpb read8], %i[sbcb read8], %i[addd read16_dead], %i[andb read8],
|
|
19
|
+
%i[bitb read8], %i[ldb read8], %i[stb write8], %i[eorb read8], %i[adcb read8], %i[orb read8],
|
|
20
|
+
%i[addb read8], %i[ldd read16], %i[std write16], %i[ldu read16], %i[stu write16]].freeze
|
|
21
|
+
PAGE2_COLUMN = { 0x3 => %i[cmpd read16_dead], 0xc => %i[cmpy read16_dead], 0xe => %i[ldy read16],
|
|
22
|
+
0xf => %i[sty write16] }.freeze
|
|
23
|
+
PAGE2_B_COLUMN = { 0x3 => %i[xaddd read16_dead], 0xe => %i[lds read16], 0xf => %i[sts write16] }.freeze
|
|
24
|
+
PAGE3_COLUMN = { 0x3 => %i[cmpu read16_dead], 0xc => %i[cmps read16_dead] }.freeze
|
|
25
|
+
PAGE3_B_COLUMN = { 0x3 => %i[xaddu read16_dead] }.freeze
|
|
26
|
+
|
|
27
|
+
# Opcodes with a plan of their own, after the opcode fetch.
|
|
28
|
+
INHERENT = {
|
|
29
|
+
0x12 => [:nop, %i[dead_pc_exec]],
|
|
30
|
+
0x13 => [:sync, %i[dead_pc sync_wait]],
|
|
31
|
+
0x14 => [:none, %i[free_run]],
|
|
32
|
+
0x15 => [:none, %i[free_run]],
|
|
33
|
+
0x16 => [:jmp, %i[offset_hi offset_lo_pc dead_v dead_v_exec]],
|
|
34
|
+
0x17 => [:jsr, %i[offset_hi offset_lo_pc dead_v dead_v dead_ea dead_v push_pcl push_pch_exec]],
|
|
35
|
+
0x18 => [:x18, %i[next_byte_exec dead_v]],
|
|
36
|
+
0x19 => [:daa, %i[dead_pc_exec]],
|
|
37
|
+
0x1a => [:orcc, %i[immediate_exec dead_pc]],
|
|
38
|
+
0x1b => [:nop, %i[dead_pc_exec]],
|
|
39
|
+
0x1c => [:andcc, %i[immediate_exec dead_pc]],
|
|
40
|
+
0x1d => [:sex, %i[dead_pc_exec]],
|
|
41
|
+
0x1e => [:exg, %i[read_post dead_v dead_v dead_v dead_v dead_v dead_v_exec]],
|
|
42
|
+
0x1f => [:tfr, %i[read_post dead_v dead_v dead_v dead_v_exec]],
|
|
43
|
+
0x34 => [:none, %i[push_s_post]],
|
|
44
|
+
0x35 => [:none, %i[pull_s_post]],
|
|
45
|
+
0x36 => [:none, %i[push_u_post]],
|
|
46
|
+
0x37 => [:none, %i[pull_u_post]],
|
|
47
|
+
0x38 => [:andcc, %i[idle immediate_exec dead_pc]],
|
|
48
|
+
0x39 => [:none, %i[dead_pc pull_pch pull_pcl dead_v]],
|
|
49
|
+
0x3a => [:abx, %i[dead_pc dead_v_exec]],
|
|
50
|
+
0x3b => [:none, %i[dead_pc return_cc]],
|
|
51
|
+
0x3c => [:none, [:cwai_mask, :dead_pc, :dead_v, *PUSH_ALL, :cwai_wait]],
|
|
52
|
+
0x3d => [:mul, %i[dead_pc dead_v dead_v dead_v dead_v dead_v dead_v dead_v dead_v dead_v_exec]],
|
|
53
|
+
0x3e => [:xres, SOFTWARE_INTERRUPT_TAIL],
|
|
54
|
+
0x3f => [:swi, SOFTWARE_INTERRUPT_TAIL],
|
|
55
|
+
0x87 => [:xsta, %i[immediate_exec]],
|
|
56
|
+
0x8d => [:jsr, %i[offset8_branch dead_v dead_ea dead_v push_pcl push_pch_exec]],
|
|
57
|
+
0x8f => [:xstx, %i[immediate_discard store_immediate]],
|
|
58
|
+
0xc7 => [:xstb, %i[immediate_exec]],
|
|
59
|
+
0xcd => [:none, %i[free_run]],
|
|
60
|
+
0xcf => [:xstu, %i[immediate_discard store_immediate]]
|
|
61
|
+
}.freeze
|
|
62
|
+
|
|
63
|
+
PAGE2_INHERENT = {
|
|
64
|
+
0x3e => [:xswi2, SOFTWARE_INTERRUPT_TAIL],
|
|
65
|
+
0x3f => [:swi2, SOFTWARE_INTERRUPT_TAIL],
|
|
66
|
+
0x87 => [:xsta2, %i[immediate_exec]],
|
|
67
|
+
0x8f => [:xsty, %i[immediate_discard store_immediate]],
|
|
68
|
+
0xc7 => [:xstb2, %i[immediate_exec]],
|
|
69
|
+
0xcf => [:xsts, %i[immediate_discard store_immediate]]
|
|
70
|
+
}.freeze
|
|
71
|
+
|
|
72
|
+
PAGE3_INHERENT = {
|
|
73
|
+
0x3e => [:xfirq, SOFTWARE_INTERRUPT_TAIL],
|
|
74
|
+
0x3f => [:swi3, SOFTWARE_INTERRUPT_TAIL],
|
|
75
|
+
0x87 => [:xsta2, %i[immediate_exec]],
|
|
76
|
+
0x8f => [:xstx2, %i[immediate_discard store_immediate]],
|
|
77
|
+
0xc7 => [:xstb2, %i[immediate_exec]],
|
|
78
|
+
0xcf => [:xstu2, %i[immediate_discard store_immediate]]
|
|
79
|
+
}.freeze
|
|
80
|
+
|
|
81
|
+
SHORT_BRANCH_TAIL = %i[offset8_branch dead_v_branch].freeze
|
|
82
|
+
LONG_BRANCH_TAIL = %i[offset_hi offset_lo_pc dead_v_long_branch].freeze
|
|
83
|
+
LEA = { 0x30 => :leax, 0x31 => :leay, 0x32 => :leas, 0x33 => :leau }.freeze
|
|
84
|
+
|
|
85
|
+
# Builds the opcode tables.
|
|
86
|
+
module Opcodes
|
|
87
|
+
MODES = [nil, DIRECT_PLAN, INDEXED_PLAN, EXTENDED_PLAN].freeze
|
|
88
|
+
|
|
89
|
+
module_function
|
|
90
|
+
|
|
91
|
+
def entry(operation, plan, tail)
|
|
92
|
+
Entry.new(operation, plan.freeze, tail.freeze, GROUPS.fetch(operation, GROUP_OTHER))
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def tail(kind, mode)
|
|
96
|
+
return IMMEDIATE_TAILS.fetch(kind) if mode.zero?
|
|
97
|
+
|
|
98
|
+
TAILS.fetch(kind)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def memory(opcode)
|
|
102
|
+
mode = if opcode < 0x10 then DIRECT_PLAN
|
|
103
|
+
elsif opcode < 0x70 then INDEXED_PLAN
|
|
104
|
+
else EXTENDED_PLAN
|
|
105
|
+
end
|
|
106
|
+
name = MEMORY_GROUP[opcode & 0x0f]
|
|
107
|
+
entry(name, mode, TAILS.fetch({ tst: :test, jmp: :jump }.fetch(name, :rmw)))
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# $80-$FF: immediate, direct, indexed and extended by bits 4 and 5.
|
|
111
|
+
def column(opcode, column)
|
|
112
|
+
name, kind = column.fetch(opcode & 0x0f)
|
|
113
|
+
mode = (opcode >> 4) & 0x3
|
|
114
|
+
return entry(:none, [], NO_TAIL) if mode.zero? && !IMMEDIATE_TAILS.key?(kind)
|
|
115
|
+
|
|
116
|
+
entry(name, mode.zero? ? [] : MODES.fetch(mode), tail(kind, mode))
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def page1(opcode)
|
|
120
|
+
if (inherent = INHERENT[opcode]) then entry(inherent[0], [], inherent[1])
|
|
121
|
+
elsif opcode < 0x10 || (0x60..0x7f).cover?(opcode) then memory(opcode)
|
|
122
|
+
elsif (0x40..0x5f).cover?(opcode) then inherent_register(opcode)
|
|
123
|
+
elsif (0x20..0x2f).cover?(opcode) then entry(:none, [], SHORT_BRANCH_TAIL)
|
|
124
|
+
elsif LEA.key?(opcode) then entry(LEA[opcode], INDEXED_PLAN, TAILS[:load_address])
|
|
125
|
+
elsif opcode >= 0x80 then column(opcode, opcode >= 0xc0 ? B_COLUMN : A_COLUMN)
|
|
126
|
+
else entry(:none, [], NO_TAIL)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def inherent_register(opcode)
|
|
131
|
+
name = (opcode < 0x50 ? A_GROUP : B_GROUP)[opcode & 0x0f]
|
|
132
|
+
entry(name, [], %i[dead_pc_exec])
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Pages 2 and 3. An opcode a page doesn't define runs as on page 1,
|
|
136
|
+
# after the prefix's cycle.
|
|
137
|
+
def paged(opcode, page1, inherent, columns)
|
|
138
|
+
return entry(inherent[opcode][0], [], inherent[opcode][1]) if inherent.key?(opcode)
|
|
139
|
+
return entry(:none, [], LONG_BRANCH_TAIL) if columns.first == PAGE2_COLUMN && (0x20..0x2f).cover?(opcode)
|
|
140
|
+
|
|
141
|
+
column = opcode >= 0xc0 ? columns[1] : columns[0]
|
|
142
|
+
return page1[opcode] if opcode < 0x80 || !column.key?(opcode & 0x0f)
|
|
143
|
+
|
|
144
|
+
name, kind = column[opcode & 0x0f]
|
|
145
|
+
mode = (opcode >> 4) & 0x3
|
|
146
|
+
entry(name, mode.zero? ? [] : MODES.fetch(mode), tail(kind, mode))
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
PAGE1 = Array.new(256) { |opcode| Opcodes.page1(opcode) }.freeze
|
|
151
|
+
PAGE2 = Array.new(256) do |opcode|
|
|
152
|
+
Opcodes.paged(opcode, PAGE1, PAGE2_INHERENT, [PAGE2_COLUMN, PAGE2_B_COLUMN])
|
|
153
|
+
end.freeze
|
|
154
|
+
PAGE3 = Array.new(256) do |opcode|
|
|
155
|
+
Opcodes.paged(opcode, PAGE1, PAGE3_INHERENT, [PAGE3_COLUMN, PAGE3_B_COLUMN])
|
|
156
|
+
end.freeze
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
@@ -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
|