-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathp1.patch
More file actions
127 lines (127 loc) · 4.35 KB
/
p1.patch
File metadata and controls
127 lines (127 loc) · 4.35 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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
--- a/src/MOS6502Emulator/Instructions.hs
+++ b/src/MOS6502Emulator/Instructions.hs
@@ ... @@
- pc <- getReg rPC -- Get current PC
- b <- fetchByteMem pc -- Fetch byte at current PC
- -- REMOVE setPC (pc + 1) here
-
- -- Increment instruction count
- modify (\s -> s { instructionCount = instructionCount s + 1 })
- -- liftIO $ putStrLn $ "Executing opcode: " ++ show b
- -- TODO: Add cycle count increment based on opcode execution
- instructionSize <- execute b -- execute now returns instruction size
- -- liftIO $ putStrLn "Instruction executed."
- -- Increment PC by the instruction size after execution
- pcAfterExecution <- getReg rPC -- Get PC after execute might have changed it (e.g. JMP, JSR)
- setPC (pcAfterExecution + fromIntegral instructionSize)
-
- machineState' <- get
- return (not (halted machineState')) -- Continue if not halted after execution
+ pc <- getReg rPC -- Get current PC
+ b <- fetchByteMem pc -- Fetch opcode byte at PC
+ setPC (pc + 1) -- Move PC to next byte (like a real 6502)
+ modify (\s -> s { instructionCount = instructionCount s + 1 })
+ execute b
+ machineState' <- get
+ return (not (halted machineState'))
@@ ... @@
-
-fetchOperand :: AddressMode -> FDX Word8
--- Immediate mode fetches the byte at the current PC and increments the PC.
--- This is handled by fdxSingleCycle for the opcode fetch.
--- For immediate operands after the opcode, we need a way to fetch the *next* byte.
--- Let's create a helper for fetching the next byte and incrementing PC.
-fetchOperand Immediate = do
- pc <- getReg rPC
- b <- fetchByteMem pc
- -- REMOVE setPC (pc + 1)
- return b
-
-fetchOperand Zeropage = do
- addrByte <- fetchByteAtPC
- -- REMOVE setPC (pc + 1)
- fetchByteMem (toWord addrByte)
-fetchOperand ZeropageX = do
- addrByte <- fetchByteAtPC
- -- REMOVE setPC (pc + 1)
- x <- getReg rX
- fetchByteMem (toWord (addrByte + x)) -- stay on the zeropage but add x
-fetchOperand ZeropageY = do
- addrByte <- fetchByteAtPC
- -- REMOVE setPC (pc + 1)
- y <- getReg rY
- fetchByteMem (toWord (addrByte + y)) -- stay on the zeropage but add y
-fetchOperand Absolute = fetchWordAtPC >>= fetchByteMem
-fetchOperand AbsoluteX = do
- w <- fetchWordAtPC
- x <- getReg rX
- fetchByteMem (w + (toWord x))
-fetchOperand AbsoluteY = do
- w <- fetchWordAtPC
- y <- getReg rY
- fetchByteMem (w + (toWord y))
-fetchOperand IndirectX = do
- b <- fetchOperand Immediate
- x <- getReg rX
- addr <- fetchWordMem (b + x) -- zeropage index plus x
- fetchByteMem addr
-fetchOperand IndirectY = do
- -- In this case, we add the value in Y to the address pointed
- -- to by the zeropage address, and then fetch the byte there.
- b <- fetchOperand Immediate
- addr <- fetchWordMem b
- y <- getReg rY
- fetchByteMem (addr + toWord y)
-fetchOperand Accumulator = getReg rAC
-fetchOperand X = getReg rX
-fetchOperand Y = getReg rY
-fetchOperand SP = getReg rSP
+-- | Fetches the next byte from memory at PC, incrementing PC
+fetchAndIncPC :: FDX Word8
+fetchAndIncPC = do
+ pc <- getReg rPC
+ b <- fetchByteMem pc
+ setPC (pc + 1)
+ return b
+
+-- | Fetches the next two bytes from memory at PC (little-endian), incrementing PC twice
+fetchWordAndIncPC :: FDX Word16
+fetchWordAndIncPC = do
+ lo <- fetchAndIncPC
+ hi <- fetchAndIncPC
+ return $ mkWord lo hi
+
+fetchOperand :: AddressMode -> FDX Word8
+fetchOperand Immediate = fetchAndIncPC
+fetchOperand Zeropage = fetchAndIncPC >>= fetchByteMem . toWord
+fetchOperand ZeropageX = do
+ addrByte <- fetchAndIncPC
+ x <- getReg rX
+ fetchByteMem (toWord (addrByte + x))
+fetchOperand ZeropageY = do
+ addrByte <- fetchAndIncPC
+ y <- getReg rY
+ fetchByteMem (toWord (addrByte + y))
+fetchOperand Absolute = fetchWordAndIncPC >>= fetchByteMem
+fetchOperand AbsoluteX = do
+ w <- fetchWordAndIncPC
+ x <- getReg rX
+ fetchByteMem (w + toWord x)
+fetchOperand AbsoluteY = do
+ w <- fetchWordAndIncPC
+ y <- getReg rY
+ fetchByteMem (w + toWord y)
+fetchOperand IndirectX = do
+ b <- fetchAndIncPC
+ x <- getReg rX
+ addr <- fetchWordMem (b + x)
+ fetchByteMem addr
+fetchOperand IndirectY = do
+ b <- fetchAndIncPC
+ addr <- fetchWordMem b
+ y <- getReg rY
+ fetchByteMem (addr + toWord y)
+fetchOperand Accumulator = getReg rAC
+fetchOperand X = getReg rX
+fetchOperand Y = getReg rY
+fetchOperand SP = getReg rSP