<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="sv">
	<id>http://wiki.sikvall.se/index.php?action=history&amp;feed=atom&amp;title=Racket%2F6502-emu</id>
	<title>Racket/6502-emu - Versionshistorik</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.sikvall.se/index.php?action=history&amp;feed=atom&amp;title=Racket%2F6502-emu"/>
	<link rel="alternate" type="text/html" href="http://wiki.sikvall.se/index.php?title=Racket/6502-emu&amp;action=history"/>
	<updated>2026-04-06T19:12:56Z</updated>
	<subtitle>Versionshistorik för denna sida på wikin</subtitle>
	<generator>MediaWiki 1.43.0</generator>
	<entry>
		<id>http://wiki.sikvall.se/index.php?title=Racket/6502-emu&amp;diff=1817&amp;oldid=prev</id>
		<title>Anders: Skapade sidan med &#039;&lt;pre&gt; #lang racket  ;; ================================================ ;; Enkel 6502-emulator skriven i Racket ;; ================================================ ;; Detta är en grundläggande men fullt fungerande emulator för 6502-processorn. ;; Den hanterar minne (64 KB), register, stack, flaggor och ett grundläggande ;; set av instruktioner. Du kan lätt utöka den med fler opkoder. ;; ;; Instruktioner som stöds i denna version (kan utökas i cpu-step): ;;   - $0...&#039;</title>
		<link rel="alternate" type="text/html" href="http://wiki.sikvall.se/index.php?title=Racket/6502-emu&amp;diff=1817&amp;oldid=prev"/>
		<updated>2026-04-05T02:52:01Z</updated>

		<summary type="html">&lt;p&gt;Skapade sidan med &amp;#039;&amp;lt;pre&amp;gt; #lang racket  ;; ================================================ ;; Enkel 6502-emulator skriven i Racket ;; ================================================ ;; Detta är en grundläggande men fullt fungerande emulator för 6502-processorn. ;; Den hanterar minne (64 KB), register, stack, flaggor och ett grundläggande ;; set av instruktioner. Du kan lätt utöka den med fler opkoder. ;; ;; Instruktioner som stöds i denna version (kan utökas i cpu-step): ;;   - $0...&amp;#039;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Ny sida&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
#lang racket&lt;br /&gt;
&lt;br /&gt;
;; ================================================&lt;br /&gt;
;; Enkel 6502-emulator skriven i Racket&lt;br /&gt;
;; ================================================&lt;br /&gt;
;; Detta är en grundläggande men fullt fungerande emulator för 6502-processorn.&lt;br /&gt;
;; Den hanterar minne (64 KB), register, stack, flaggor och ett grundläggande&lt;br /&gt;
;; set av instruktioner. Du kan lätt utöka den med fler opkoder.&lt;br /&gt;
;;&lt;br /&gt;
;; Instruktioner som stöds i denna version (kan utökas i cpu-step):&lt;br /&gt;
;;   - $00 BRK          (stoppar exekveringen)&lt;br /&gt;
;;   - $A9 LDA #imm&lt;br /&gt;
;;   - $8D STA abs&lt;br /&gt;
;;   - $A2 LDX #imm&lt;br /&gt;
;;   - $E8 INX&lt;br /&gt;
;;   - $4C JMP abs&lt;br /&gt;
;;   - $D0 BNE rel      (enkel branch)&lt;br /&gt;
;;&lt;br /&gt;
;; NYTT: Funktioner för att skriva ut minne och flaggor har lagts till!&lt;br /&gt;
&lt;br /&gt;
(struct cpu (a x y pc sp p mem) #:mutable #:transparent)&lt;br /&gt;
&lt;br /&gt;
;; Flaggor (statusregister P)&lt;br /&gt;
(define CARRY      #b00000001)&lt;br /&gt;
(define ZERO       #b00000010)&lt;br /&gt;
(define INTERRUPT  #b00000100)&lt;br /&gt;
(define DECIMAL    #b00001000)&lt;br /&gt;
(define BREAK      #b00010000)&lt;br /&gt;
(define OVERFLOW   #b01000000)&lt;br /&gt;
(define NEGATIVE   #b10000000)&lt;br /&gt;
&lt;br /&gt;
;; Skapa en ny CPU (PC startar godtyckligt, SP pekar mot stack-sidan)&lt;br /&gt;
(define (make-cpu)&lt;br /&gt;
  (cpu 0 0 0 #x8000 #xFF #b00100100 (make-vector 65536 0)))&lt;br /&gt;
&lt;br /&gt;
;; Minnesåtkomst&lt;br /&gt;
(define (mem-read cpu addr)&lt;br /&gt;
  (vector-ref (cpu-mem cpu) (bitwise-and addr #xFFFF)))&lt;br /&gt;
&lt;br /&gt;
(define (mem-write cpu addr val)&lt;br /&gt;
  (vector-set! (cpu-mem cpu) (bitwise-and addr #xFFFF) (bitwise-and val #xFF)))&lt;br /&gt;
&lt;br /&gt;
;; Stack (6502-stack ligger på sidan 0x01)&lt;br /&gt;
(define (stack-push cpu val)&lt;br /&gt;
  (mem-write cpu (cpu-sp cpu) val)&lt;br /&gt;
  (set-cpu-sp! cpu (bitwise-and #xFF (- (cpu-sp cpu) 1))))&lt;br /&gt;
&lt;br /&gt;
(define (stack-pop cpu)&lt;br /&gt;
  (set-cpu-sp! cpu (bitwise-and #xFF (+ (cpu-sp cpu) 1)))&lt;br /&gt;
  (mem-read cpu (cpu-sp cpu)))&lt;br /&gt;
&lt;br /&gt;
;; Uppdatera N- och Z-flaggor (används av de flesta instruktioner)&lt;br /&gt;
(define (update-nz cpu val)&lt;br /&gt;
  (set-flag cpu NEGATIVE (not (zero? (bitwise-and val #x80))))&lt;br /&gt;
  (set-flag cpu ZERO      (zero? (bitwise-and val #xFF))))&lt;br /&gt;
&lt;br /&gt;
(define (set-flag cpu mask val)&lt;br /&gt;
  (if val&lt;br /&gt;
      (set-cpu-p! cpu (bitwise-ior (cpu-p cpu) mask))&lt;br /&gt;
      (set-cpu-p! cpu (bitwise-and (cpu-p cpu) (bitwise-not mask)))))&lt;br /&gt;
&lt;br /&gt;
(define (get-flag cpu mask)&lt;br /&gt;
  (not (zero? (bitwise-and (cpu-p cpu) mask))))&lt;br /&gt;
&lt;br /&gt;
;; Hjälpfunktioner för att hämta data och öka PC&lt;br /&gt;
(define (fetch-byte cpu)&lt;br /&gt;
  (define addr (cpu-pc cpu))&lt;br /&gt;
  (set-cpu-pc! cpu (add1 addr))&lt;br /&gt;
  (mem-read cpu addr))&lt;br /&gt;
&lt;br /&gt;
(define (fetch-word cpu)&lt;br /&gt;
  (define lo (fetch-byte cpu))&lt;br /&gt;
  (define hi (fetch-byte cpu))&lt;br /&gt;
  (bitwise-ior lo (arithmetic-shift hi 8)))&lt;br /&gt;
&lt;br /&gt;
;; Huvudfunktion: exekvera en instruktion&lt;br /&gt;
(define (cpu-step cpu)&lt;br /&gt;
  (define opcode (fetch-byte cpu))&lt;br /&gt;
  (case opcode&lt;br /&gt;
    ;; BRK – stoppar emulatorn&lt;br /&gt;
    [(#x00)&lt;br /&gt;
     (set-flag cpu BREAK #t)&lt;br /&gt;
     &amp;#039;brk]&lt;br /&gt;
&lt;br /&gt;
    ;; LDA #imm&lt;br /&gt;
    [(#xA9)&lt;br /&gt;
     (define val (fetch-byte cpu))&lt;br /&gt;
     (set-cpu-a! cpu val)&lt;br /&gt;
     (update-nz cpu val)]&lt;br /&gt;
&lt;br /&gt;
    ;; STA abs&lt;br /&gt;
    [(#x8D)&lt;br /&gt;
     (define addr (fetch-word cpu))&lt;br /&gt;
     (mem-write cpu addr (cpu-a cpu))]&lt;br /&gt;
&lt;br /&gt;
    ;; LDX #imm&lt;br /&gt;
    [(#xA2)&lt;br /&gt;
     (define val (fetch-byte cpu))&lt;br /&gt;
     (set-cpu-x! cpu val)&lt;br /&gt;
     (update-nz cpu val)]&lt;br /&gt;
&lt;br /&gt;
    ;; INX&lt;br /&gt;
    [(#xE8)&lt;br /&gt;
     (define new-x (bitwise-and #xFF (add1 (cpu-x cpu))))&lt;br /&gt;
     (set-cpu-x! cpu new-x)&lt;br /&gt;
     (update-nz cpu new-x)]&lt;br /&gt;
&lt;br /&gt;
    ;; JMP abs&lt;br /&gt;
    [(#x4C)&lt;br /&gt;
     (define addr (fetch-word cpu))&lt;br /&gt;
     (set-cpu-pc! cpu addr)]&lt;br /&gt;
&lt;br /&gt;
    ;; BNE rel (branch if not equal / Z=0)&lt;br /&gt;
    [(#xD0)&lt;br /&gt;
     (define offset (fetch-byte cpu))&lt;br /&gt;
     (when (not (get-flag cpu ZERO))&lt;br /&gt;
       (set-cpu-pc! cpu (+ (cpu-pc cpu)&lt;br /&gt;
                           (if (&amp;gt; offset #x7F) (- offset #x100) offset))))]&lt;br /&gt;
&lt;br /&gt;
    [else&lt;br /&gt;
     (error &amp;quot;Okänt opcode:&amp;quot; (format &amp;quot;~x&amp;quot; opcode))]))&lt;br /&gt;
&lt;br /&gt;
;; Ladda ett program (lista av bytes) till minnet&lt;br /&gt;
(define (load-program cpu start-addr program-bytes)&lt;br /&gt;
  (for ([b program-bytes]&lt;br /&gt;
        [i (in-naturals)])&lt;br /&gt;
    (mem-write cpu (+ start-addr i) b)))&lt;br /&gt;
&lt;br /&gt;
;; Kör emulatorn tills BRK eller max-steg nås&lt;br /&gt;
(define (run-cpu cpu [max-steps 100000])&lt;br /&gt;
  (let loop ([steps 0])&lt;br /&gt;
    (cond&lt;br /&gt;
      [(&amp;gt;= steps max-steps) &amp;#039;timeout]&lt;br /&gt;
      [else&lt;br /&gt;
       (define result (cpu-step cpu))&lt;br /&gt;
       (if (eq? result &amp;#039;brk)&lt;br /&gt;
           &amp;#039;halted-by-brk&lt;br /&gt;
           (loop (add1 steps)))])))&lt;br /&gt;
&lt;br /&gt;
;; ================================================&lt;br /&gt;
;; NYA HJÄLPFUNKTIONER: Skriv ut minne och flaggor&lt;br /&gt;
;; ================================================&lt;br /&gt;
&lt;br /&gt;
;; Skriver ut aktuellt CPU-tillstånd (alla register + flaggor i läsbart format)&lt;br /&gt;
(define (print-cpu-state cpu)&lt;br /&gt;
  (printf &amp;quot;=== CPU STATUS ===~n&amp;quot;)&lt;br /&gt;
  (printf &amp;quot;PC: $~x   A: $~x   X: $~x   Y: $~x   SP: $~x~n&amp;quot;&lt;br /&gt;
          (cpu-pc cpu)&lt;br /&gt;
          (cpu-a cpu)&lt;br /&gt;
          (cpu-x cpu)&lt;br /&gt;
          (cpu-y cpu)&lt;br /&gt;
          (cpu-sp cpu))&lt;br /&gt;
  (printf &amp;quot;P:  $~x   &amp;quot; (cpu-p cpu))&lt;br /&gt;
  (printf &amp;quot;Flags: [N:~a V:~a - B:~a D:~a I:~a Z:~a C:~a]~n&amp;quot;&lt;br /&gt;
          (if (get-flag cpu NEGATIVE) &amp;quot;1&amp;quot; &amp;quot;0&amp;quot;)&lt;br /&gt;
          (if (get-flag cpu OVERFLOW) &amp;quot;1&amp;quot; &amp;quot;0&amp;quot;)&lt;br /&gt;
          (if (get-flag cpu BREAK)    &amp;quot;1&amp;quot; &amp;quot;0&amp;quot;)&lt;br /&gt;
          (if (get-flag cpu DECIMAL)  &amp;quot;1&amp;quot; &amp;quot;0&amp;quot;)&lt;br /&gt;
          (if (get-flag cpu INTERRUPT)&amp;quot;1&amp;quot; &amp;quot;0&amp;quot;)&lt;br /&gt;
          (if (get-flag cpu ZERO)     &amp;quot;1&amp;quot; &amp;quot;0&amp;quot;)&lt;br /&gt;
          (if (get-flag cpu CARRY)    &amp;quot;1&amp;quot; &amp;quot;0&amp;quot;))&lt;br /&gt;
  (newline))&lt;br /&gt;
&lt;br /&gt;
;; Hex-dump av ett minnesområde (16 bytes per rad + ASCII-del)&lt;br /&gt;
;; Användning: (print-memory my-cpu #x0000 #x00FF) eller bara (print-memory my-cpu #x0600)&lt;br /&gt;
(define (print-memory cpu start [end #f])&lt;br /&gt;
  (when (not end)&lt;br /&gt;
    (set! end (+ start 255)))                 ; default: 256 bytes om inget slut anges&lt;br /&gt;
  (set! start (bitwise-and start #xFFFF))&lt;br /&gt;
  (set! end   (bitwise-and end   #xFFFF))&lt;br /&gt;
  (printf &amp;quot;=== MEMORY DUMP $~4x – $~4x ===~n&amp;quot; start end)&lt;br /&gt;
  (for ([addr (in-range start (add1 end) 16)])&lt;br /&gt;
    (when (&amp;lt;= addr end)&lt;br /&gt;
      (printf &amp;quot;$~4x: &amp;quot; addr)&lt;br /&gt;
      ;; Hex-delen&lt;br /&gt;
      (for ([i (in-range 16)])&lt;br /&gt;
        (define a (+ addr i))&lt;br /&gt;
        (if (&amp;lt;= a end)&lt;br /&gt;
            (printf &amp;quot;~2x &amp;quot; (mem-read cpu a))&lt;br /&gt;
            (printf &amp;quot;   &amp;quot;)))&lt;br /&gt;
      ;; ASCII-del&lt;br /&gt;
      (printf &amp;quot; | &amp;quot;)&lt;br /&gt;
      (for ([i (in-range 16)])&lt;br /&gt;
        (define a (+ addr i))&lt;br /&gt;
        (if (&amp;lt;= a end)&lt;br /&gt;
            (let ([b (mem-read cpu a)])&lt;br /&gt;
              (printf &amp;quot;~a&amp;quot; (if (and (&amp;gt;= b #x20) (&amp;lt;= b #x7E))&lt;br /&gt;
                               (integer-&amp;gt;char b)&lt;br /&gt;
                               &amp;quot;.&amp;quot;)))&lt;br /&gt;
            (printf &amp;quot; &amp;quot;)))&lt;br /&gt;
      (newline)))&lt;br /&gt;
  (newline))&lt;br /&gt;
&lt;br /&gt;
;; ================================================&lt;br /&gt;
;; EXEMPEL: Ett litet program som demonstrerar emulatorn&lt;br /&gt;
;; ================================================&lt;br /&gt;
;; Programmet gör följande:&lt;br /&gt;
;;   LDA #$05      ; A = 5&lt;br /&gt;
;;   STA $0010     ; minne[0x0010] = 5&lt;br /&gt;
;;   LDX #$0A      ; X = 10&lt;br /&gt;
;;   INX           ; X = 11&lt;br /&gt;
;;   JMP $0610     ; hoppa till en BRK&lt;br /&gt;
;;   BRK&lt;br /&gt;
&lt;br /&gt;
(define example-program&lt;br /&gt;
  (list #xA9 #x05          ; LDA #5&lt;br /&gt;
        #x8D #x10 #x00     ; STA $0010&lt;br /&gt;
        #xA2 #x0A          ; LDX #10&lt;br /&gt;
        #xE8               ; INX&lt;br /&gt;
        #x4C #x10 #x06     ; JMP $0610&lt;br /&gt;
        #x00))             ; BRK (vid 0x0610)&lt;br /&gt;
&lt;br /&gt;
;; Hur du kör exemplet (med de nya utskriftsfunktionerna):&lt;br /&gt;
&lt;br /&gt;
(define my-cpu (make-cpu))&lt;br /&gt;
(load-program my-cpu #x0600 example-program)&lt;br /&gt;
(print-cpu-state my-cpu)&lt;br /&gt;
(set-cpu-pc! my-cpu #x0600)&lt;br /&gt;
(print-cpu-state my-cpu)&lt;br /&gt;
(run-cpu my-cpu)&lt;br /&gt;
(print-cpu-state my-cpu)&lt;br /&gt;
&lt;br /&gt;
;; Flera opkoder kan läggas till för bättre emulering!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Anders</name></author>
	</entry>
</feed>