comparison Examples/6502/isp.mc6502 @ 0:cfb7c6b24319

Initial revision
author kono
date Thu, 30 Aug 2007 14:57:44 +0900
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:cfb7c6b24319
1 ! ISPS Description of the MOS Technology MCS 6502 Microprocessor
2
3 ! G.W.Leive
4 ! 10 July 1978 ISPS Version
5 ! COPYRIGHT (C) 1978
6
7 MC6502 :=
8 BEGIN
9
10 **MP.STATE**
11 MACRO romlow:= |"F800 |,
12 MACRO romhi := |"FFFF |,
13 MACRO ramlow:= |"0000 |,
14 MACRO ramhi := |"1000 |,
15 MACRO maxb := |"FFFF |, ! High end of byte memory
16
17 Mb[0:maxb]<7:0>, ! Primary memory range
18 ram[ramlow:ramhi]<7:0> := mb[ramlow:ramhi]<7:0>, ! RAM
19 rom[romlow:romhi]<7:0> := mb[romlow:romhi]<7:0> ! ROM
20
21 **PC.STATE**
22
23 Pc<15:0>, ! Program counter
24
25 Y<7:0>, ! Index register
26 X<7:0>, ! Index register
27 S<7:0>, ! Stack pointer
28 Dl<7:0>, ! Input data latch
29 A<7:0>, ! Accumulator
30 Ir<7:0>, ! Instruction register
31 P<7:0>, ! Processor status
32 n<> := P<7>, ! Negative result
33 v<> := P<6>, ! Overflow
34 b<> := P<4>, ! Break command
35 d<> := P<3>, ! Decimal mode
36 i<> := P<2>, ! Interrupt disable
37 z<> := P<1>, ! Zero
38 c<> := P<0>, ! Carry
39
40 Irq<>, ! Interrupt request
41 Nmi<>, ! Non-maskable interrupt
42 IFSync<>, ! High when instruction fetch
43 Rw<>, ! Read/Write control pin
44 So<>, ! Set overflow pin
45 Reset<>, ! Power up bit
46 Ready<> ! 1 means run, 0 means stop
47
48 **ADDRESS.CALCULATION**
49
50 immed()<15:0> := ! Immediate
51 BEGIN
52 immed = ab = Pc NEXT
53 Pc = Pc + 1
54 END,
55
56 zp()<15:0> := ! Zero page
57 BEGIN
58 zp = ab = read(Pc) NEXT
59 Pc = Pc + 1
60 END,
61
62 abs()<15:0> := ! Absolute
63 BEGIN
64 abs = ab(Pc + 1, Pc) NEXT
65 Pc = Pc + 2
66 END,
67
68 indx()<15:0> := ! Indexed indirect - (IND, X)
69 BEGIN
70 indx = ab((read(Pc) + X + 1)<7:0>, (read(Pc) + X)<7:0>) NEXT
71 Pc = Pc + 1
72 END,
73
74 indy()<15:0> := ! Indirect indexed - (IND), Y
75 BEGIN
76 indy = ab = ab(read(Pc) + 1, read(Pc)) + Y NEXT
77 Pc = Pc + 1
78 END,
79
80 zpx()<15:0> := ! Zero page indexed by X
81 BEGIN
82 zpx = ab = (read(Pc) + X)<7:0> NEXT
83 Pc = Pc + 1
84 END,
85
86 zpy()<15:0> := ! Zero page indexed by Y
87 BEGIN
88 zpy = ab = (read(Pc) + Y)<7:0> NEXT
89 Pc = Pc + 1
90 END,
91
92
93 absy()<15:0> := ! Absolute modified by Y
94 BEGIN
95 absy = ab = ab(Pc + 1, Pc) + Y NEXT
96 Pc = Pc + 2
97 END,
98
99 absx()<15:0> := ! Ablolute modified by X
100 BEGIN
101 absx = ab = ab(Pc + 1, Pc) + X NEXT
102 Pc = Pc + 2
103 END
104
105 **SERVICE.FACILITIES**
106
107 push(dbb.<7:0>) := ! Push a byte on the stack
108 BEGIN
109 write(1@S, dbb.) NEXT
110 S = S - 1
111 END,
112
113 pull<7:0> := ! Pull a byte off the stack
114 BEGIN
115 S = S + 1 NEXT
116 pull = read(1@S)
117 END,
118
119 opex := ! Operation exception
120 BEGIN
121 Ready = 0 NEXT
122 RESTART run
123 END,
124
125 setnz(ta.<7:0>) := ! Set neg and zero condition code
126 BEGIN
127 z = ta. EQL 0; n = ta.<7>
128 END,
129
130 branch(cond<>) :=
131 BEGIN
132 DECODE cond =>
133 BEGIN
134 0 := Pc = Pc + 1,
135 1 := Pc = (Pc + 1) + read(PC) ! Relative addressing
136 END
137 END,
138
139 decimal.adjust(tac.<8:0>) := ! Used by sbc and adc
140 BEGIN
141 IF A<7> EQV read<7> => v = tac.<7> XOR A<7>; c = tac.<8> NEXT
142 IF d =>
143 BEGIN
144 tac.<8> = 0 NEXT
145 IF tac.<3:0> GTR{US} "9 => tac. = tac.<7:0> + "6 NEXT
146 IF NOT c => c = tac.<8> NEXT
147 IF tac.<7:4> GTR{US} "9 => tac. = tac.<7:0> + "60 NEXT
148 IF NOT c => c = tac.<8>
149 END NEXT
150 A = tac.<7:0> NEXT
151 setnz(A)
152 END,
153
154 ab(adh.<15:0>, adl.<15:0>)<15:0> := ! Address buffer
155 BEGIN
156 ab<15:8> = read(adh.) NEXT
157 ab<7:0> = read(adl.)
158 END,
159
160 ! Read and write memory access routines
161
162 read(ab.<15:0>)<7:0> := ! Read from valid memory
163 BEGIN
164 Rw = 1 NEXT
165 IF NOT Ready => RESTART run NEXT
166 read = "FF NEXT ! Fake a nonexistant memory access
167 IF (ab. GEQ{US} ramlow) AND (ab. LEQ{US} ramhi) => read = ram[ab.];
168 IF (ab. GEQ{US} romlow) AND (ab. LEQ{US} romhi) => read = rom[ab.]
169 END,
170
171 write(ab.<15:0>, dbb.<7:0>) := ! Write to valid memory
172 BEGIN
173 IF (ab. GEQ{US} ramlow) AND (ab. LEQ{US} ramhi) => ram[ab.] = dbb.;
174 Rw = 0
175 END,
176
177 ! Interrupt routines
178
179 intstk := ! Interrupt stack operations
180 BEGIN
181 push(Pc<15:8>) NEXT
182 push(Pc<7:0>) NEXT
183 push(P) NEXT
184 i = 1
185 END,
186
187 int := ! Interrupt processing
188 BEGIN
189 IF NOT Reset =>
190 BEGIN
191 Reset = Irq = Nmi = Ready = 1 NEXT
192 Pc = ab("FFFD, "FFFC) NEXT
193 i = 1 NEXT
194 LEAVE int
195 END NEXT
196
197 IF NOT Nmi =>
198 BEGIN
199 Nmi = 1 NEXT
200 intstk() NEXT
201 Pc = ab("FFFB, "FFFA) NEXT
202 LEAVE int
203 END NEXT
204
205 IF b OR (NOT Irq AND NOT i) =>
206 BEGIN
207 intstk() NEXT
208 b = 0 NEXT
209 Pc = ab("FFFF, "FFFE)
210 END
211 END
212
213 **INSTRUCTION.INTERPRETATION**
214
215 run :=
216 BEGIN
217 IF NOT Reset => int() NEXT ! Initial startup
218 IF NOT ready => stop() NEXT
219 IFSync = 1 NEXT ! Instruction fetch
220 Ir = read(Pc) NEXT
221 Pc = Pc + 1 NEXT
222 IFSync = 0 NEXT ! Execute
223 DECODE IR<1:0> =>
224 BEGIN
225 '01 := group1(),
226 '10 := group2(),
227 '00 := group3(),
228 '11 := opex()
229 END NEXT
230 int() NEXT
231 IF So => v = 1 NEXT
232 RESTART RUN
233 END,
234
235 ! Group 1 instruction decode
236
237 group1 :=
238 BEGIN
239 DECODE Ir<7:5> =>
240 BEGIN
241 #0 := ora(),
242 #1 := and.(),
243 #2 := eor(),
244 #3 := adc(),
245 #4 := sta(),
246 #5 := lda(),
247 #6 := cmp(),
248 #7 := sbc()
249 END
250 END,
251
252 ! Group 2 instruction decode
253
254 group2 :=
255 BEGIN
256 DECODE Ir<7:5> =>
257 BEGIN
258 #0 := asl(),
259 #1 := rol(),
260 #2 := lsr(),
261 #3 := ror(),
262 #4 := stx(), ! Includes txa, txs
263 #5 := ldx(), ! Includes tax, tsx
264 #6 := dec(), ! Includes dex
265 #7 := inc() ! Includes no.op
266 END
267 END,
268
269 ! Group 3 instruction decode
270
271 group3 :=
272 BEGIN
273 DECODE Ir =>
274 BEGIN
275 "00 := brk(), ! Break
276 "08 := php(), ! Push status on stack
277 "28 := plp(), ! Pull status from stack
278 "48 := pha(), ! Push accumulator
279 "68 := pla(), ! Pull accumulator
280 "10 := bpl(), ! Branch on plus
281 "30 := bmi(), ! Branch on minus
282 "50 := bvc(), ! Branch if overflow clear
283 "70 := bvs(), ! Branch if overflow set
284 "90 := bcc(), ! Branch on carry clear
285 "D0 := bne(), ! Branch on not equal
286 "F0 := beq(), ! Branch if equal
287 "B0 := bcs(), ! Branch if carry set
288 "18 := clc(), ! Clear carry
289 "38 := sec(), ! Set carry
290 "58 := cli(), ! Clear interrupt enable
291 "78 := sei(), ! Set interrupt enable
292 "B8 := clv(), ! Clear overflow
293 "D8 := cld(), ! Clear decimal mode
294 "F8 := sed(), ! Set decimal mode
295 "20 := jsr(), ! Jump to subroutine
296 "24 := bit(read(zp())), ! Bit test - zero page
297 "2C := bit(read(abs())), ! Bit test - absolute
298 "40 := rti(), ! Return from interrupt
299 "4C := jmp(), ! Jump - absolute
300 "6C := jmp(), ! Jump - indirect
301 "60 := rts(), ! Return from subroutine
302 "84 := sty(zp()), ! Store Y - zero page
303 "8C := sty(abs()), ! Store Y - absolute
304 "94 := sty(zpx()), ! Store Y - zero page, X
305 "88 := dey(), ! Decrement Y
306 "C8 := iny(), ! Increment Y
307 "E8 := inx(), ! Increment X
308 "98 := tya(), ! Transfer Y to A
309 "A8 := tay(), ! Transfer A to Y
310 "A0 := ldy(immed()), ! Load Y - immediate
311 "A4 := ldy(zp()), ! Load Y - zero page
312 "AC := ldy(abs()), ! Load Y - absolute
313 "B4 := ldy(zpx()), ! Load Y - zero page, X
314 "BC := ldy(absx()), ! Load Y - absolute, X
315 "C0 := cpy(immed()), ! Compare immediate to Y
316 "C4 := cpy(zp()), ! Compare zero page to Y
317 "CC := cpy(abs()), ! Compare absolute to Y
318 "E0 := cpx(immed()), ! Compare immediate to X
319 "E4 := cpx(zp()), ! Compare zero page to X
320 "EC := cpx(abs()), ! Compare absolute to X
321 OTHERWISE := opex()
322 END
323 END
324
325 **INSTRUCTION.EXECUTION**
326
327 ! Group 1 instruction execution
328
329 addrs1()<15:0> := ! Group 1 address generation
330 BEGIN
331 DECODE Ir<4:2> =>
332 BEGIN
333 #0 := addrs1 = indx(),
334 #1 := addrs1 = zp(),
335 #2 := addrs1 = immed(),
336 #3 := addrs1 = abs(),
337 #4 := addrs1 = indy(),
338 #5 := addrs1 = zpx(),
339 #6 := addrs1 = absy(),
340 #7 := addrs1 = absx()
341 END
342 END,
343
344 ora := ! Or
345 BEGIN
346 A = A OR read(addrs1()) NEXT
347 setnz(A)
348 END,
349
350 and. := ! And
351 BEGIN
352 A = A AND read(addrs1()) NEXT
353 setnz(A)
354 END,
355
356 eor := ! Exclusive or
357 BEGIN
358 A = A XOR read(addrs1()) NEXT
359 setnz(A)
360 END,
361
362 adc := (decimal.adjust(A +{US} c + read(addrs1()))), ! Add with carry
363
364 sta := (IF Ir NEQ{US} "89 => write(addrs1(),A)), ! Store immediate
365
366 lda := ! Load accumulator
367 BEGIN
368 A = read(addrs1()) NEXT
369 setnz(A)
370 END,
371
372 cmp := ! Compare
373 BEGIN
374 setnz(A - read(addrs1())) NEXT
375 c = A GEQ read
376 END,
377
378 sbc := (decimal.adjust(A +{US} c + NOT read(addrs1()))), ! Sub/carry
379
380 ! Group 2 addressing mode selection
381
382 ! Group 2 gets and puts
383
384 get2()<8:0> := ! Get the correct operand and return it in "get2"
385 BEGIN
386 DECODE Ir<4:2> =>
387 BEGIN
388 #1 := get2<7:0> = read(zp()),
389 #2 := get2<7:0> = A,
390 #3 := get2<7:0> = read(abs()),
391 #5 := get2<7:0> = read(zpx()),
392 #7 := get2<7:0> = read(absx()),
393 OTHERWISE := opex()
394 END NEXT
395 get2<8> = c
396 END,
397
398 put2(ta.<7:0>) := ! Put the operand in the proper location
399 BEGIN
400 DECODE Ir<4:2> =>
401 BEGIN
402 [#1,#3,#5,#7] := write(ab, ta.),
403 #2 := A = ta.,
404 OTHERWISE := opex()
405 END NEXT
406 setnz(ta.)
407 END,
408
409 ! Group 2 instruction execution
410
411 asl := ! Arithmetic shift left
412 BEGIN
413 get2 = get2() SL0 1 NEXT
414 c = get2<8>; put2(get2)
415 END,
416
417
418 rol := ! rotate left
419 BEGIN
420 get2 = get2() SLR 1 NEXT
421 c = get2<8>; put2(get2)
422 END,
423
424 lsr := ! Logical shift right
425 BEGIN
426 c = get2<2> NEXT
427 get2 = get2<7:0> SR0 1 NEXT
428 put2(get2)
429 END,
430
431 ror := ! Rotate right
432 BEGIN
433 get2 = get2() SRR 1 NEXT
434 c = get2<8>; put2(get2)
435 END,
436
437 stx := ! Store index register
438 BEGIN
439 DECODE Ir<4:2> =>
440 BEGIN
441 #1 := write(zp(), X),
442 #2 := A = X, ! Txa
443 #3 := write(abs(), X),
444 #5 := write(zpy(), X),
445 #6 := S = X, ! Txs
446 OTHERWISE := opex()
447 END
448 END,
449
450 ldx := ! Load index register
451 BEGIN
452 DECODE Ir<4:2> =>
453 BEGIN
454 #0 := X = read(immed()),
455 #1 := X = read(zp()),
456 #2 := X = A, ! Tax
457 #3 := X = read(abs()),
458 #4 := opex(),
459 #5 := X = read(zpy()),
460 #6 := X = S, ! Tsx
461 #7 := X = read(absy())
462 END NEXT
463 setnz(X)
464 END,
465
466 dec := ! Decrement
467 BEGIN
468 DECODE Ir EQL "CA =>
469 BEGIN
470 0 := put2(get2() - 1),
471 1 := BEGIN ! Dex
472 X = X - 1 NEXT
473 setnz(X)
474 END
475 END
476 END,
477
478 inc := ! Increment
479 BEGIN
480 IF Ir NEQ "EA => put2(get2() + 1) ! Op "EA => no.op
481 END,
482
483 ! Group 3 instruction execution
484
485 brk := (b = 1; Pc = Pc+1), ! Break
486
487 php := (push(P)), ! Push processor status on stack
488 plp := (P = pull()), ! Pull processor status from stack
489 pha := (push(A)), ! Push accumulator on stack
490 pla := ! Pull accumulator from stack
491 BEGIN
492 A = pull() NEXT
493 setnz(A)
494 END,
495
496 bpl := (branch(NOT n)), ! Branch on plus
497 bmi := (branch(n)), ! Branch on minus
498 bvc := (branch(NOT v)), ! Branch on overflow clear
499 bvs := (branch(v)), ! Branch if overflow set
500 bcc := (Branch(NOT c)), ! Branch on carry clear
501 bne := (branch(NOT z)), ! Branch if not equal
502 beq := (branch(z)), ! Branch on equal
503 bcs := (branch(c)), ! Branch on carry set
504
505 clc := (c = 0), ! Clear carry flag
506 sec := (c = 1), ! Set carry
507 cli := (i = 0), ! Clear interrupt disable bit
508 sei := (i = 1), ! Set interrupt disable status
509 clv := (v = 0), ! Clear overflow
510 cld := (d = 0), ! Clear decimal mode
511 sed := (d = 1), ! Set decimal mode
512
513 jsr := ! Jump to subroutine
514 BEGIN
515 push((Pc + 1)<15:8>) NEXT
516 push((Pc + 1)<7:0>) NEXT
517 Pc = abs()
518 END,
519
520 bit(ta.<7:0>) := ! Bit test
521 BEGIN
522 n = ta.<7>; v = ta.<6>; z = (ta. AND A) EQL 0
523 END,
524
525 rti := ! Return from interrupt
526 BEGIN
527 P = pull() NEXT
528 Pc<7:0> = pull() NEXT
529 Pc<15:8> = pull(); b = 0
530 END,
531
532 jmp := ! Jump
533 BEGIN
534 Pc = abs() NEXT
535 IF Ir EQL "6C => Pc = abs() ! Indirect
536 END,
537
538 ! Group 3 instruction execution (page 2)
539
540 rts := ! return from subroutine
541 BEGIN
542 Pc<7:0> = pull() NEXT
543 Pc<15:8> = pull() NEXT
544 Pc = Pc + 1
545 END,
546
547 sty(ab.<15:0>) := (write(ab., Y)), ! Store index Y in memory
548
549 dey := ! Decrement index Y by one
550 BEGIN
551 Y = Y - 1 NEXT
552 setnz(Y)
553 END,
554
555 tya := ! Transfer index Y to accumulator
556 BEGIN
557 A = Y NEXT
558 setnz(A)
559 END,
560
561 ldy(ab.<15:0>) := (Y = read(ab.)), ! Load index Y with memory
562
563 tay := ! Transfer accumulator to index Y
564 BEGIN
565 Y = A NEXT
566 setnz(Y)
567 END,
568
569 cpy(ab.<15:0>) := ! Compare memory and index Y
570 BEGIN
571 setnz(Y - read(ab.)) NEXT
572 c = Y GEQ read
573 END,
574
575 iny := ! Increment index Y by one
576 BEGIN
577 Y = Y + 1 NEXT
578 setnz(Y)
579 END,
580
581 cpx(ab.<15:0>) := ! Compare memory and index X
582 BEGIN
583 setnz(X - read(ab.)) NEXT
584 c = X GEQ read
585 END,
586
587 inx := ! Increment index X by one
588 BEGIN
589 X = X + 1 NEXT
590 setnz(X)
591 END
592
593
594 END ! End of MC6502
595
596