Coverage for MC6809/components/mc6809_interrupt.py: 38%
50 statements
« prev ^ index » next coverage.py v7.2.1, created at 2023-03-06 19:50 +0100
« prev ^ index » next coverage.py v7.2.1, created at 2023-03-06 19:50 +0100
1#!/usr/bin/env python
3"""
4 MC6809 - 6809 CPU emulator in Python
5 =======================================
7 6809 is Big-Endian
9 Links:
10 http://dragondata.worldofdragon.org/Publications/inside-dragon.htm
11 http://www.burgins.com/m6809.html
12 http://koti.mbnet.fi/~atjs/mc6809/
14 :copyleft: 2013-2015 by the MC6809 team, see AUTHORS for more details.
15 :license: GNU GPL v3 or above, see LICENSE for more details.
17 Based on:
18 * ApplyPy by James Tauber (MIT license)
19 * XRoar emulator by Ciaran Anscomb (GPL license)
20 more info, see README
21"""
24from MC6809.components.cpu_utils.instruction_caller import opcode
27class InterruptMixin:
29 # ---- Not Implemented, yet. ----
31 @opcode( # AND condition code register, then wait for interrupt
32 0x3c, # CWAI (immediate)
33 )
34 def instruction_CWAI(self, opcode, m):
35 """
36 This instruction ANDs an immediate byte with the condition code register
37 which may clear the interrupt mask bits I and F, stacks the entire
38 machine state on the hardware stack and then looks for an interrupt.
39 When a non-masked interrupt occurs, no further machine state information
40 need be saved before vectoring to the interrupt handling routine. This
41 instruction replaced the MC6800 CLI WAI sequence, but does not place the
42 buses in a high-impedance state. A FIRQ (fast interrupt request) may
43 enter its interrupt handler with its entire machine state saved. The RTI
44 (return from interrupt) instruction will automatically return the entire
45 machine state after testing the E (entire) bit of the recovered
46 condition code register.
48 The following immediate values will have the following results: FF =
49 enable neither EF = enable IRQ BF = enable FIRQ AF = enable both
51 source code forms: CWAI #$XX E F H I N Z V C
53 CC bits "HNZVC": ddddd
54 """
55# log.error("$%x CWAI not implemented, yet!", opcode)
56 # Update CC bits: ddddd
58 @opcode( # Undocumented opcode!
59 0x3e, # RESET (inherent)
60 )
61 def instruction_RESET(self, opcode):
62 """
63 Build the ASSIST09 vector table and setup monitor defaults, then invoke
64 the monitor startup routine.
66 source code forms:
68 CC bits "HNZVC": *****
69 """
70 raise NotImplementedError(f"${opcode:x} RESET")
71 # Update CC bits: *****
73 # ---- Interrupt handling ----
75 irq_enabled = False
77 def irq(self):
78 if not self.irq_enabled or self.I == 1:
79 # log.critical("$%04x *** IRQ, ignore!\t%s" % (
80 # self.program_counter.value, self.get_cc_info()
81 # ))
82 return
84 if self.E:
85 self.push_irq_registers()
86 else:
87 self.push_firq_registers()
89 ea = self.memory.read_word(self.IRQ_VECTOR)
90 # log.critical("$%04x *** IRQ, set PC to $%04x\t%s" % (
91 # self.program_counter.value, ea, self.get_cc_info()
92 # ))
93 self.program_counter.set(ea)
95 def push_irq_registers(self):
96 """
97 push PC, U, Y, X, DP, B, A, CC on System stack pointer
98 """
99 self.cycles += 1
100 self.push_word(self.system_stack_pointer, self.program_counter.value) # PC
101 self.push_word(self.system_stack_pointer, self.user_stack_pointer.value) # U
102 self.push_word(self.system_stack_pointer, self.index_y.value) # Y
103 self.push_word(self.system_stack_pointer, self.index_x.value) # X
104 self.push_byte(self.system_stack_pointer, self.direct_page.value) # DP
105 self.push_byte(self.system_stack_pointer, self.accu_b.value) # B
106 self.push_byte(self.system_stack_pointer, self.accu_a.value) # A
107 self.push_byte(self.system_stack_pointer, self.get_cc_value()) # CC
109 def push_firq_registers(self):
110 """
111 FIRQ - Fast Interrupt Request
112 push PC and CC on System stack pointer
113 """
114 self.cycles += 1
115 self.push_word(self.system_stack_pointer, self.program_counter.value) # PC
116 self.push_byte(self.system_stack_pointer, self.get_cc_value()) # CC
118 @opcode( # Return from interrupt
119 0x3b, # RTI (inherent)
120 )
121 def instruction_RTI(self, opcode):
122 """
123 The saved machine state is recovered from the hardware stack and control
124 is returned to the interrupted program. If the recovered E (entire) bit
125 is clear, it indicates that only a subset of the machine state was saved
126 (return address and condition codes) and only that subset is recovered.
128 source code forms: RTI
130 CC bits "HNZVC": -----
131 """
132 cc = self.pull_byte(self.system_stack_pointer) # CC
133 self.set_cc(cc)
134 if self.E:
135 self.accu_a.set(
136 self.pull_byte(self.system_stack_pointer) # A
137 )
138 self.accu_b.set(
139 self.pull_byte(self.system_stack_pointer) # B
140 )
141 self.direct_page.set(
142 self.pull_byte(self.system_stack_pointer) # DP
143 )
144 self.index_x.set(
145 self.pull_word(self.system_stack_pointer) # X
146 )
147 self.index_y.set(
148 self.pull_word(self.system_stack_pointer) # Y
149 )
150 self.user_stack_pointer.set(
151 self.pull_word(self.system_stack_pointer) # U
152 )
154 self.program_counter.set(
155 self.pull_word(self.system_stack_pointer) # PC
156 )
157# log.critical("RTI to $%04x", self.program_counter.value)
159 @opcode( # Software interrupt (absolute indirect)
160 0x3f, # SWI (inherent)
161 )
162 def instruction_SWI(self, opcode):
163 """
164 All of the processor registers are pushed onto the hardware stack (with
165 the exception of the hardware stack pointer itself), and control is
166 transferred through the software interrupt vector. Both the normal and
167 fast interrupts are masked (disabled).
169 source code forms: SWI
171 CC bits "HNZVC": -----
172 """
173 raise NotImplementedError(f"${opcode:x} SWI")
175 @opcode( # Software interrupt (absolute indirect)
176 0x103f, # SWI2 (inherent)
177 )
178 def instruction_SWI2(self, opcode, ea, m):
179 """
180 All of the processor registers are pushed onto the hardware stack (with
181 the exception of the hardware stack pointer itself), and control is
182 transferred through the software interrupt 2 vector. This interrupt is
183 available to the end user and must not be used in packaged software.
184 This interrupt does not mask (disable) the normal and fast interrupts.
186 source code forms: SWI2
188 CC bits "HNZVC": -----
189 """
190 raise NotImplementedError(f"${opcode:x} SWI2")
192 @opcode( # Software interrupt (absolute indirect)
193 0x113f, # SWI3 (inherent)
194 )
195 def instruction_SWI3(self, opcode, ea, m):
196 """
197 All of the processor registers are pushed onto the hardware stack (with
198 the exception of the hardware stack pointer itself), and control is
199 transferred through the software interrupt 3 vector. This interrupt does
200 not mask (disable) the normal and fast interrupts.
202 source code forms: SWI3
204 CC bits "HNZVC": -----
205 """
206 raise NotImplementedError(f"${opcode:x} SWI3")
208 @opcode( # Synchronize with interrupt line
209 0x13, # SYNC (inherent)
210 )
211 def instruction_SYNC(self, opcode):
212 """
213 FAST SYNC WAIT FOR DATA Interrupt! LDA DISC DATA FROM DISC AND CLEAR
214 INTERRUPT STA ,X+ PUT IN BUFFER DECB COUNT IT, DONE? BNE FAST GO AGAIN
215 IF NOT.
217 source code forms: SYNC
219 CC bits "HNZVC": -----
220 """
221 raise NotImplementedError(f"${opcode:x} SYNC")