Close
0%
0%

W6502SBC

a 6502 sbc with the option to be used with a backplane as a module.

Similar projects worth following
Willies 6502 single board computer
a 6502 sbc with the option to be used with a backplane as a module.

An old topic has been bothering me for a long time. Assembler and 6502. My C64 has been mothballed for a long time, the VC20 is selling. Nevertheless, I find the 6502 very interesting in terms of assembly language. What you could do with 1MHz and 64kb RAM. This year (2022) the time had come. I decided to build a 6502 SBC. There are many, many posts and suggestions on the Internet about this. Unfortunately, there is no version that you could easily rebuild and that meets my expectations of a 6502 workbench computer. Here are my requirements in brief:

- WDC65C02 CPU with 4MHz (clock can be switched by program)
- WDC65C22 VIA with 4MHz, possibly 2 of them
- 6551 ASIC for the serial port (R65C51)
- 32Kb or 64KB SRAM (both were available)
- EEPROM or Flash as Kernal/Basic ROM
- NMI and IRQ assignable
- Variable memory allocation, possibly also modifiable from the outside
- Plug-in card system or system bus, preferably with corner edge connectors, as in the C64, VC20, a suitable backplane would be nice
- no video, audio or anything
- SPI over 6522, so you can connect a display/keyboard
- CPLD for something
- opt. LC display

I started on July 22. Initially with orders from Mouser and Reichelt.

Follow the steps to learn:

- CLPD: I needed a programming adapter for this (my choice was a TL866II+)
- build a simple system on breadboard with 1MHz
- Implement Wozmon
- ...

At the end of the first section there should be a CPU plug-in card with a working 6502 system. Incl. BASIC via terminal. VTL-2 and Basl (my own small language) would be considered as further languages.

More information and project logs are here:
https://github.com/willie68/w6502sbc

  • 1 × Quarzoszillator 1MHz (Oder auch mehr)
  • 1 × Maxim DS1813 EconoReset
  • 1 × PushSwitch
  • 1 × WDC W65C02N
  • 7 × 100nF ceramic capacitors

View all 25 components

  • W65C51 die 2.

    Wilfried Klaas11/02/2022 at 06:37 0 comments

    Nachdem das Projekt aus privaten Gründen etwas geruht hat, habe ich in den letzten paar Tagen weiter gemacht.

    Senden

    Zunächst ging es darum den W65C51 dazu zu bewegen, Daten aus die Schnittstelle auszuspucken. Als Terminal Programm verwende ich HTerm. Ich hab mit einem einfachen Sendeprogramm angefangen. Einfach nur einen String senden. Übernpmmen habe ich dabei die Routine von dem LCD. Aber irgendwie wollte es nicht so richtig funktionieren. Ich habe 2 verschiedene Adapter ausprobiert. Mit HTerm keine Reaktion. Mit meinem anderen Programm, CoolTerm, und der Einstellung HArdwareflow ging es auf anhieb. Also muss da was mit den Einstellungen vom HTerm nicht stimmen. Nach langer Suche bin ich auf die Lösung gestossen (worden) In HTerm muss ich DTR einschalten (das sind die Buttons im Sendebereich). Erst wenn DTR aktiv ist, sendet auch der 6551. Und schon funktionierte es. Der WDC65C51 hat einen unschönen Bug: das Sende Flag wird nicht mehr zurück gesetzt, d.h. der 6551 meldet immer, daß er etwas senden kann, auch wenn er gerade noch beschäftigt ist. Um den 6551 nicht zu überfahren muss man also nach dem Senden eine gewisse Zeit warten, bis man das nächste Zeichen senden kann. Unschön aber nicht weiter tragisch. Ich habe in der seriell.asm auch gleich eine automatische Berechnung der Delayzeit auf Basis der Taktfrequenz eingebaut. Gilt aber nur für feste Clock Frequenzen. Die automatische Umschaltung ist noch nicht implementiert.

    Empfangen

    Ich habe dann das Bios etwas um organisiert. Das LCD ist für System- und Debugmeldungen zuständig, während der serielle Schnittstelle als Nabelschur für die weiteren Funktionen dienen soll. Aber der Empfang wollte auch nicht. Keine Kombination. Im 6502.org Forum kam als Hinweis mal die DCDB Leitung zu kontrollieren, evtl. empfänge der 6551 nur wenn diese aktiv (also 0) ist. Laut Datenblatt sollte das zwar nicht so sein, aber ein zusätzliches Kabel schadet ja auch nicht. Also am Full Serial Anschluss (K6) die DCB Leitung nach GND gejumpert. Nanu, der SBC bleibt stumm. Kurzschluss. Platine kontrolliert und siehe da, Leitung 15 und 16 am 6551 sind vertauscht. DCDB und VCC. Also musste ich sowohl die Platine, wie auch im PCB Layout und auch gleich in der Bibliothek den Fehler korrigieren. Danach ging es auf Anhieb.

    Main Menu

    Nachdem auch das Problem aus dem Weg geräumt war, habe ich nun die 1. Version des Bios Menüs gebaut.

    Nach dem Start kommt nun folgende Meldungen im Terminal:

    W6502SBC Welcome
    W6502SBC ready
    1: Mon 2: Basic

    Hier kann man nun zwischen dem Monitor und dem (noch nicht implementierten Basic) wählen.

    Der Monitor ist eine angepasste Version vom WOZMON in der Version von fsafstrom (http://www.brielcomputers.com/phpBB3/viewtopic.php?f=9&t=197) mit Intel Hex Unterstützung.

  • WDC65C51 PLCC28

    Wilfried Klaas10/01/2022 at 13:22 0 comments

    Ich habe mit einigen verschiedenen R65C51 Varianten aus China experimentiert. Alle 5 Chips unterscheiden sich etwas in ihrem Aussehen. 3 PlasticDip einmal Keramik, 3 mit Rockwell-Logo einmal ohne… Und in meiner Platine verhält sich jeder Chip anders. Der Keramikchip startet den Oszillator nicht, einer gibt immer einen Interrupt (Bit 7) auch wenn kein anderes Bit gesetzt ist. Einer will immer 5 Bit seriell verwenden, egal was ich in das Steuerregister eintrage, einer gibt immer %00000000 aus und der letzte hat eine andere Baudrate. Ich gebe auf, den R6551 für meinen SBC verwenden zu wollen und habe ein Paar max3100 bestellt… Diese werden allerdings mit SPI angesprochen. In der Zwischenzeit konnte ich auch einen WDC W65C51 ergattern, allerdings nur in PLCC28. Und dafür einen vollständigen Adapter zu besorgen ist auch nicht einfach. Also habe ich mir einen selber designed und gebaut.

    Ein SBC sieht also jetzt so aus

  • 4-Bit LC Display

    Wilfried Klaas08/28/2022 at 17:12 0 comments

    Bei dem bisherigen Versuchen habe ich das LCD immer mit 8-Bit angesprochen. D.h. der komplette Port B vom VIA und noch 3 Steuerleitungen vom Port A wurden für das LCD belegt. Nun haben die LCDs aber auch einen 4-Bit Modus. Dieser wird auch im Arduino Umfeld gerne benutzt, da man so Leitungen sparen kann. Der Geschwindigkeitsnachteil durch die Verwendung des 4-Bit Interfaces ist vernachlässigbar. Also habe ich das LCD auch bei meinen SBC auf 4-Bit umgestellt. Hardwaretechnisch war das ganz einfach. Die Datenleitungen D0..3 vom Display werden fest mit Masse verbunden, währen die Leitung D4..7 auf die Port Pins PB0..3 kommen. PB 4 bleibt leer. PB5..7 sind jetzt die Steuerleitungen RS, R/W und E. (In dieser Reihenfolge)

    Nun geht's an die Software und das ist gar nicht mal so einfach. Zwar gibt es viele Beispiele auch für den 6502 mit 6522, aber von den Beispielen habe ich keines zum Laufen bekommen. Also musste ich selbst forschen. Zum Umschalten des Displays in den 4-Bit Modus muss ein gewisse Muster eingehalten werden. Und nebenbei machte dann auch das Display bei erneutem Reset Druck plötzlich mucken. Also muss das Display auch per Software einen Reset ausführen. Ließt man dazu das Kapitel im Datenblatt, erhält man eine genaue Reihenfolge wie welche Befehle mit welchen Zeitabständen erfolgen müssen. Dazu braucht man dann auch eine zuverlässige Delay Routine. Gleichzeitig habe ich nun auch ein paar zusätzliche Methoden zur Ausgabe ins ROM integriert.

    Nebenbei habe ich auch den ROM Sockel mit einem ZIF Aufsatz versehen. Das macht das Programmieren erheblich einfacher und schont die Beine der ICs und den Sockel. Evtl. muss ich auch mal über eine In-Circut-Programmiermöglichkeit nachdenken. Achja, die zusätzlichen Kabel, die vom Display nach recht weggehen, hängen an meinem Logic Analyser. Der hat mir dismal bei der Analyse und Programmierung sehr gute Dienste geleistet.

    Hier die LCD-Routinen aus meinem BIOS.

    Read more »

  • Breadboard, die 2.

    Wilfried Klaas08/20/2022 at 19:01 0 comments

    Und schon wieder will das Breadboard nicht. Diesmal der Pin D7 an der CPU. Da mittlerweile aber die Platinen der V1 gekommen sind, habe ich die mal schnell bestückt.

    Ich musste allerdings noch 2 Probleme in der Platine beseitigen. Einmal fehlte in der Stromversorgung ein Kontakt, da hat das Layoutprogramm einfach eine Verbindung nicht erstellt. Optisch da, aber tatsächlich nicht verbunden. Aber keine echtes Problem. Einfach mit einem kleinen Drahtstück an der LED überbrückt. Und einmal fehlte dem Flashsockel noch eine +5V Verbindung, damit man auch eine 8KB EEPROM einsetzen kann. Auch hier ein kleines Stückchen Draht, fertig.

    Schnell noch meinen Arduino Mega Monitor/Clock verbunden (die Flachbandkabel am Bus) und das LCD angeschlossen und siehe da, es läuft. Als nächstes kommt der ZIF Sockel Bus Adapter für das EEPROM. Dann braucht man nicht immer das EEPROM aus dem Sockel puhlen.

    Ich habe auch schon etwas weiter gemacht mit dem Kernel. Angelehnt an den C64 Kernal (Ja der schreibt sich so) habe ich einige Konzepte, die wohl noch aus der PET Zeit stammen gerne übernommen. Zum einen gibt es im letzten Bereich des ROM sowas ähnliches wie Sprungtabellen, um die Kernel Funktionen anzusprechen. Ist keine echte Sprungtabelle, sondern ein Block mit einem JMP auf die jeweilige Routine. Und dann habe ich schon die Jiffy Clock implementiert. Und natürlich auch die Routinen für das LCD sind schon enthalten. Wenn das soweit läuft, werde ich mal versuchen das LCD im 4 Bit Modus zu betreiben. Der 8 Bit Modus verbraucht mir zu viele Portpins. Aber eines nach dem anderen. Jetzt erstmal freuen.

  • Hello World!

    Wilfried Klaas08/14/2022 at 15:36 0 comments

    Heute wollte ich dem SBC mal etwas mehr Leben einhauchen. Eigentlich wollte ich ja das RAM einbauen, aber da hätte man ja auch nichts gesehen, ausser im Monitor. Also hab ich mich kurzerhand dazu entschlossen, dass LC-Display anzuschließen. Die direkte Methode fand ich jetzt nich so überzeugend, also hab ich das Display an den 6522 angeschlossen. (evtl. mach ich das später mal über 4 bit oder I2C) Ich hab es wie Ben Eater in seinem Video mit vollenb 8 Bit auf Port B und 3 Leitungen auf Port A angeschlossen. Und tatsächlich es lebt. Ein paar kleine Änderungen wegen der anderen Adressaufteilung und dem RetroAssembler und schon konnte ich das Hello World Programm auf dem Display sehen. Hier der Beweis:


    Und natürlich hier auch gleich das Programm:

    .format "bin"
    
    	.memory "fill", $E000, $2000, $ea
    	.org $E000
    	IO .equ $B000
    	VIA .equ IO
    	VIA_ORB .equ VIA
    	VIA_ORA .equ VIA+1
    	VIA_DDRB .equ VIA+2
    	VIA_DDRA .equ VIA+3
    	VIA_T1Cl .equ VIA+4
    	VIA_T1CH .equ VIA+5
    	VIA_T1LL .equ VIA+6
    	VIA_T1LH .equ VIA+7
    	VIA_T2CL .equ VIA+8
    	VIA_T2CH .equ VIA+9
    	VIA_SR .equ VIA+$A
    	VIA_ACR .equ VIA+$B
    	VIA_PCR .equ VIA+$C
    	VIA_IFR .equ VIA+$D
    	VIA_IER .equ VIA+$E
    	VIA_IRA .equ VIA+$F
    	ACIA .equ IO + $0100
     
      E  = %10000000
      RW = %01000000
      RS = %00100000
    
    do_reset:
      lda #%11111111 ; Set all pins on port B to output
      sta VIA_DDRB
    
      lda #%11100000 ; Set top 3 pins on port A to output
      sta VIA_DDRA
    
      lda #%00111000 ; Set 8-bit mode; 2-line display; 5x8 font
      sta VIA_ORB
      lda #0         ; Clear RS/RW/E bits
      sta VIA_ORA
      lda #E         ; Set E bit to send instruction
      sta VIA_ORA
      lda #0         ; Clear RS/RW/E bits
      sta VIA_ORA
    
      lda #%00001110 ; Display on; cursor on; blink off
      sta VIA_ORB
      lda #0         ; Clear RS/RW/E bits
      sta VIA_ORA
      lda #E         ; Set E bit to send instruction
      sta VIA_ORA
      lda #0         ; Clear RS/RW/E bits
      sta VIA_ORA
    
      lda #%00000110 ; Increment and shift cursor; don't shift display
      sta VIA_ORB
      lda #0         ; Clear RS/RW/E bits
      sta VIA_ORA
      lda #E         ; Set E bit to send instruction
      sta VIA_ORA
      lda #0         ; Clear RS/RW/E bits
      sta VIA_ORA
    
      lda #"H"
      sta VIA_ORB
      lda #RS         ; Set RS; Clear RW/E bits
      sta VIA_ORA
      lda #(RS | E)   ; Set E bit to send instruction
      sta VIA_ORA
      lda #RS         ; Clear E bits
      sta VIA_ORA
    
      lda #"e"
      sta VIA_ORB
      lda #RS         ; Set RS; Clear RW/E bits
      sta VIA_ORA
      lda #(RS | E)   ; Set E bit to send instruction
      sta VIA_ORA
      lda #RS         ; Clear E bits
      sta VIA_ORA
    
      lda #"l"
      sta VIA_ORB
      lda #RS         ; Set RS; Clear RW/E bits
      sta VIA_ORA
      lda #(RS | E)   ; Set E bit to send instruction
      sta VIA_ORA
      lda #RS         ; Clear E bits
      sta VIA_ORA
    
      lda #"l"
      sta VIA_ORB
      lda #RS         ; Set RS; Clear RW/E bits
      sta VIA_ORA
      lda #(RS | E)   ; Set E bit to send instruction
      sta VIA_ORA
      lda #RS         ; Clear E bits
      sta VIA_ORA
    
      lda #"o"
      sta VIA_ORB
      lda #RS         ; Set RS; Clear RW/E bits
      sta VIA_ORA
      lda #(RS | E)   ; Set E bit to send instruction
      sta VIA_ORA
      lda #RS         ; Clear E bits
      sta VIA_ORA
    
      lda #","
      sta VIA_ORB
      lda #RS         ; Set RS; Clear RW/E bits
      sta VIA_ORA
      lda #(RS | E)   ; Set E bit to send instruction
      sta VIA_ORA
      lda #RS         ; Clear E bits
      sta VIA_ORA
    
      lda #" "
      sta VIA_ORB
      lda #RS         ; Set RS; Clear RW/E bits
      sta VIA_ORA
      lda #(RS | E)   ; Set E bit to send instruction
      sta VIA_ORA
      lda #RS         ; Clear E bits
      sta VIA_ORA
    
      lda #"w"
      sta VIA_ORB
      lda #RS         ; Set RS; Clear RW/E bits
      sta VIA_ORA
      lda #(RS | E)   ; Set E bit to send instruction
      sta VIA_ORA
      lda #RS         ; Clear E bits
      sta VIA_ORA
    
      lda #"o"
      sta VIA_ORB
      lda #RS         ; Set RS; Clear RW/E bits
      sta VIA_ORA
      lda #(RS | E)   ; Set E bit to send instruction
      sta VIA_ORA
      lda #RS         ; Clear E bits
      sta VIA_ORA
    
      lda #"r"
      sta VIA_ORB
      lda #RS         ; Set RS; Clear RW/E bits
      sta VIA_ORA
      lda #(RS | E)   ; Set E bit to send instruction
      sta VIA_ORA
      lda #RS         ; Clear E bits
      sta VIA_ORA
    
      lda #"l"
      sta VIA_ORB
      lda #RS         ; Set RS; Clear RW/E bits
      sta VIA_ORA
      lda #(RS | E)   ; Set E bit to send instruction
      sta VIA_ORA
      lda #RS         ; Clear E bits
      sta VIA_ORA
    
      lda #"d"
      sta VIA_ORB
      lda #RS         ; Set RS; Clear RW/E bits
      sta VIA_ORA
     lda #(RS |...
    Read more »

  • Neuaufbau

    Wilfried Klaas08/13/2022 at 14:41 0 comments

    Wie schon im letzten Blog geschrieben, war ein Breadboardaufbau buggy. Tatsächlich war nur eine Adressleitung (A14) nicht richtig verbunden, direkt am CPU Pin. Also hab ich das Breadboard hinten aufgemacht, die entsprechende Kontaktleiste raus genommen und mit der Zange wieder etwas mehr zusammen gebogen. Und siehe da, es funktioniert. Also habe ich den Aufbau nochmal neu machen müssen.

    Gleichzeitig hab ich auch mal einen Arduino Mega als Logicanalyser mit angeschlossen, ähnlich wie bei Ben Eater. Von ihm hab ich mir dann auch den Logic Code geklaut. Allerdings habe ich seine Clock nachgebaut. Ich verwende hier einen eigenen Pin vom Arduino, den ich als Clock dann in den SBC einspeise. So läuft alles schön syncron. Die Sourcen zum 6502 Monitor liegen im github unter software/arduino/6502-clock für die reine Clock und der Monitor mit Clock ist unter software/arduino/6502-monitor zu finden. Hier sieht man auch, das ich dsa RAM noch nicht eingebaut habe.

    Nachdem ist einen Test mit einem $EA ROM, also ein ROM voller $EA, also quasi der NOP Generator im ROM, gemacht habe, habe ich ein kleines Programm geschrieben, was den Port A vom VIA benutzt um LEDs blinken zulassen. Geschrieben ist das in VS Code mit dem RetroAssembler und dem passenden VS Plugin. Gebrannt mit meinem TL866 pro II.

    .format "bin"
    
        .memory "fill", $E000, $2000, $ea
        .org $E000
        IO .equ $B000
        VIA .equ IO
        VIA_ORB .equ VIA
        VIA_ORA .equ VIA+1
        VIA_DDRB .equ VIA+2
        VIA_DDRA .equ VIA+3
        VIA_T1Cl .equ VIA+4
        VIA_T1CH .equ VIA+5
        VIA_T1LL .equ VIA+6
        VIA_T1LH .equ VIA+7
        VIA_T2CL .equ VIA+8
        VIA_T2CH .equ VIA+9
        VIA_SR .equ VIA+$A
        VIA_ACR .equ VIA+$B
        VIA_PCR .equ VIA+$C
        VIA_IFR .equ VIA+$D
        VIA_IER .equ VIA+$E
        VIA_IRA .equ VIA+$F
        ACIA .equ IO + $0100
    
    do_reset:    
    // setting up the 65C22 VIA
        LDA #$FF
        STA VIA_DDRA
        LDA #$AA
        STA VIA_ORA
    blinkloop:
        ROR
        STA VIA_ORA
        jmp blinkloop
    
    do_nmi: NOP
            RTI
         do_irq: NOP
            RTI
    
        .org  $FFFA
        .word  

    Es funktioniert.


    Im Terminal, das auf den Arduino eingestellt ist, sieht man dann schön wie der Prozessor die Befehle abarbeitet. Mission completet für Heute.

  • Sch#### Breadboards

    Wilfried Klaas08/04/2022 at 13:21 0 comments

    Leider ist mir beim Testen aufgefallen, dass es einige Adressverbindungen gibt, die nicht richtig kontakt haben. Also musste ich die gesamte Adressverkabellung neu machen. Das macht leider keinen Spaß. Deswegen geht's hier derzeit nicht weiter.

    Dafür habe ich den ersten PCB Entwurf abgeschickt.

    pcb_v1


    Es gibt jetzt auch eine neue Adressverteilung.

    simple Variante

    BereichHi Adress NibbleBeschreibung
    0xFFFF ... 0xC00011xx xxxx16KB Kernel ROM, HiROM
    0xBFFF 0xB0001011 xxxxIO Bereich aufgeteilt in 16 Bereiche für die Peripherie. 0xD300: CS3 #0011 0xD200: CS2 #0010 0xD100: ASIC 1 #0001 0xD000: VIA 1 #0000 CS2 und 3 gehen nur auf den "Bus"
    0xAFFF ... 0x80001010 xxxx 1001 xxxx 1000 xxxx12k ext ROM, BASIC oder anderes ROM
    0x7FFF ... 0x02000xxx xxxx31469 Bytes RAM (BaseRAM)
    0x01FF ... 0x01000xxx xxxx256 Bytes Stack
    0x00FF ... 0x00000xxx xxxx256 Bytes ZP RAM

    Für den Adressdecoder wird ein ATF16V8B, also ein CPLD, verwendet. Dadurch habe ich die Möglichkeit die Adressdekodierung variabel gestalten zu können. Da noch genügend Pins im CPLD vorhanden sind kann ich die unteren 4 IO Leitungen auch direkt dekodieren. Falls mehr gewünscht sind, kann man per CSIO einen weitern Dekodierer kaskadieren. (74HC138 o.ä.)

    Die Verknüpfung von PHI2 und RAM ist bereits enthalten. Hier der Entwurf des PLDs:

    header:
    Name     adr_simple ;
    PartNo   01 ;
    Date     24.07.2022 ;
    Revision 03 ;
    Designer wkla ;
    Company  nn ;
    Assembly None ;
    Location  ;
    Device   G16V8 ;
    
    pld:
    /* *************** INPUT PINS *********************/
    PIN [1..8]   =  [A15..A8]; PIN 9   =  PHI2;
    
    /* *************** OUTPUT PINS *********************/
    PIN 12   =  CSRAM;
    PIN 13   =  CSHIROM;
    PIN 14   =  CSEXTROM;
    PIN 15   =  CSIO;
    PIN 16   =  CSIO3;
    PIN 17   =  CSIO2;
    PIN 18   =  CSIO1;
    PIN 19   =  CSIO0;
    /* *************** LOGIC *********************/
    
    FIELD Addr = [A15..A8];
    CSRAM_EQU = Addr:[0000..7FFF]; // 32KB
    IOPORT_EQU = Addr:[B000..BFFF]; // 4KB
    VIAPORT_EQU = Addr:[B000..B0FF];
    ACIAPORT_EQU = Addr:[B100..B1FF];
    CSIO2PORT_EQU = Addr:[B200..B2FF];
    CSIO3PORT_EQU = Addr:[B300..B3FF];
    CSEXTROM_EQU = Addr:[8000..AFFF]; // 12KB
    CSROM_EQU = Addr:[C000..FFFF];  // 16KB
    
    /* ZP */
    CSEXTROM = !CSEXTROM_EQU;
    
    /* RAM */
    CSRAM = !CSRAM_EQU # !PHI2;
    
    /* 8kb of ROM */
    CSHIROM = !CSROM_EQU;
    
    /* IO */
    CSIO= !IOPORT_EQU;
    CSIO0 = !VIAPORT_EQU;
    CSIO1 = !ACIAPORT_EQU;
    CSIO2 = !CSIO2PORT_EQU;
    CSIO3 = !CSIO3PORT_EQU;
    
    simulator:
    ORDER: A15, A14, A13, A12, A11, A10, A9, A8, PHI2, CSEXTROM, CSRAM, CSHIROM, CSIO, CSIO0, CSIO1, CSIO2, CSIO3; 
    VECTORS:
    /* internal RAM */
    0 X X X X X X X 0 H H H H H H H H 0 X X X X X X X 1 H L H H H H H H 
    /* 8000-AFFF external Rom */ 1 0 0 0 X X X X X L H H H H H H H 1 0 0 1 X X X X X L H H H H H H H 1 0 1 0 X X X X X L H H H H H H H 
    /* IO */ /* CSIO0 */
    1 0 1 1 0 0 0 0 X H H H L L H H H /* CSIO1 */
    1 0 1 1 0 0 0 1 X H H H L H L H H /* CSIO2 */
    1 0 1 1 0 0 1 0 X H H H L H H L H /* CSIO3 */
    1 0 1 1 0 0 1 1 X H H H L H H H L /* nicht direkt benutzt */
    1 0 1 1 0 1 X X X H H H L H H H H 1 0 1 1 1 X X X X H H H L H H H H /* ROM */
    1 1 X X X X X X X H H L H H H H H 

    Das Format ist wpld. Eine Erweiterung von pld von mir. Mit diesem kleinen Tool kann ich PLD und SI File in einer Datei bearbeiten. Das Tool generiert automatisch die erforderlichen Dateien (pld und si) aus dieser Quelle in einem eigenen Unterverzeichnis und startet dort dann CUPL.

  • Die Logik

    Wilfried Klaas07/25/2022 at 17:27 0 comments

    Um RAM und ROM und später auch die Interfacebausteine unter den richtigen Adressen ansprechen zu können, ist etwas Logik nötig. Die großen Speicherblöcke für RAM und ROM will ich über den CPLD ansprechen. Das ist schnell und man kann die Logik später modifizieren ohne die Schaltung zu ändern. Den für den IO Bereich hab ich den Bereich von $D000 bis $DFFF also 4Kb vorgesehen. Diese will ich in 16 Bereiche aufteilen. Jeder Bereich hat dann Platz für 256 Register (A0-A7). Auf dem SBC verwende ich dazu einen 74HC138. Dieser wird einerseits mit dem CSIO Signal aus dem CPLD selektiert. Als zweite Selektion kommt A11 zum Einsatz. Dekodiert werden dann A10..A8. Somit habe ich die untere Hälfte der 16 Bereiche bereits hier dekodiert. Der CPLD bekommt zur Dekodierung zunächst die Leitungen A12..A15. Damit kann man die jeweiligen 4K Blöcke aufteilen. Für das RAM muss man zusätzlich auch noch die CLK (PHI2) Leitung verwenden, damit die Schreibvorgänge richtig synchronisiert werden. (https://wilsonminesco.com/6502primer/addr_decoding.html) Im Projekt habe ich ja bereits die große Adress-CLPD Logik geschrieben. Für das Steckbrett verwende ich eine kleinere Variante. Hier wird erst einmal nur der der CPLD zur Adressdekodierung verwendet. Da sich die eigentliche Adressaufteilung nicht ändern soll muss ich auf den CPLD die Adressen A15..A8 legen. Für das RAM brauche ich zusätzlich noch das CLK 8PHI2) Signal. Hier mal die PLD Datei im meinem eigenen WPLD Format. Dazu später mehr.

    adr_simple.wpld

    header:
    Name     adr_simple ;
    PartNo   01 ;
    Date     24.07.2022 ;
    Revision 03 ;
    Designer wkla ;
    Company  nn ;
    Assembly None ;
    Location  ;
    Device   G16V8 ;
    
    pld:
    /* *************** INPUT PINS *********************/
    PIN [1..8]   =  [A15..A8]; PIN 9   =  PHI2;
    
    /* *************** OUTPUT PINS *********************/
    PIN 12   =  CSRAM;
    PIN 13   =  CSHIROM;
    PIN 15   =  CSIO;
    PIN 16   =  CSIO3;
    PIN 17   =  CSIO2;
    PIN 18   =  CSIO1;
    PIN 19   =  CSIO0;
    /* *************** LOGIC *********************/
    
    FIELD Addr = [A15..A8];
    IOPORT_EQU = Addr:[D000..DFFF];
    VIAPORT_EQU = Addr:[D000..D0FF];
    ACIAPORT_EQU = Addr:[D100..D1FF];
    CSIO2PORT_EQU = Addr:[D200..D2FF];
    CSIO3PORT_EQU = Addr:[D300..D3FF];
    CSRAM_EQU = Addr:[0000..7FFF];
    CSROM_EQU = Addr:[E000..FFFF];
    
    /* RAM */
    CSRAM = !CSRAM_EQU # !PHI2;
    
    /* 8kb of ROM */
    CSHIROM = !CSROM_EQU;
    
    /* IO */
    CSIO= !IOPORT_EQU;
    CSIO0 = !VIAPORT_EQU;
    CSIO1 = !ACIAPORT_EQU;
    CSIO2 = !CSIO2PORT_EQU;
    CSIO3 = !CSIO3PORT_EQU;
    
    simulator:
    ORDER: A15, A14, A13, A12, A11, A10, A9, A8, PHI2, CSRAM, CSHIROM, CSIO, CSIO0, CSIO1, CSIO2, CSIO3; 
    VECTORS:
    /* RAM */
    0 X X X X X X X 0 H H H H H H H 0 X X X X X X X 1 L H H H H H H /* 8000-CFFF nothing */ 1 0 X X X X X X X H H H H H H H 1 1 0 0 X X X X X H H H H H H H 1 1 0 0 X X X X X H H H H H H H /* IO */ /* CSIO0 */
    1 1 0 1 0 0 0 0 X H H L L H H H /* CSIO1 */
    1 1 0 1 0 0 0 1 X H H L H L H H /* CSIO2 */
    1 1 0 1 0 0 1 0 X H H L H H L H /* CSIO3 */
    1 1 0 1 0 0 1 1 X H H L H H H L /* nicht direkt benutzt */
    1 1 0 1 0 1 X X X H H L H H H H 1 1 0 1 1 X X X X H H L H H H H /* ROM */
    1 1 1 X X X X X X H L H H H H H 
    

    Und hier mal gleich der Schaltplan dazu

    WPLD Format und das Tool WCUPL

    Da WinCUPL auf keinem meiner Rechner mehr läuft, habe ich mir eine Batch geschrieben, mit denen ich sowohl das JED File erzeuge, wie auch gleich einen Test durchführen kann. Ich persönlich mag es allerdings, wenn ich die Quellen an einer Stelle habe. Die Dopplung der Header von der PLD und SI-Datei  und damit die manuelle syncronisation zwischen den beiden finde ich persönlich unschön. Deswegen hab ich mir das einfache WPLD Format ausgedacht und dazu das WCUPL Tool geschrieben. Das Tool WCUPL gibt's in meinem Repo (https://github.com/willie68/w6502sbc/releases). Dadurch entfällt das leidige Header abgleichen...

    Read more »

  • EEPROM und mehr?

    Wilfried Klaas07/25/2022 at 06:33 0 comments

    Nun geht's richtig los. Jetzt wird ein EEPROM (AT28C64 8Kx8) angeschlossen. Und da das RAM ja eh auch bald dran ist, hab ich das gleich schon mal mit verkabelt. Zunächst aber nur Adress- und Datenleitung. Die Steuerleitungen vom RAM sind alle auf +5V, sodass das eigentlich nicht aktiv sein sollte. Beim EEPROM sind die Steuerleitung so gesetzt, daß es immer mit einem READ reagiert. Allerdings so richtig tun kann der SBC ja noch nix. Keine Ausgabe, keine Eingabe, da muss ich mir noch was überlegen.

    Vorher:

    Nachher:

    Hmm, derzeit wird also alles aus dem ROM geladen. Egal wo der Prozessor hin greift, es antwortet immer das ROM. Die 8KB werden im kompletten Speicher dupliziert. Also 8x. Wenn ich nun das ROM mit $EA (NOP) fülle, sollte sich eigentlich der gleiche Effekt wie beim NOP Generator ergeben. Also hab ich das WWPROM in den PRommer gepackt, mit $EA gefüllt und wieder eingebaut.

    Klar das hat nicht auf Anhieb funktioniert. Wer findet den Fehler? Der Adresszähler machte komische Dinge. Erst als ich das RAM heraus genommen hatte, gings. Also das RAM mit dem Progger getestet. Der sagt: "alles OK". Noch mal auf die Schaltung geschaut, da sah ich es... Ich hab den GND auf die falsche Rail (+5V) gesteckt. Also RAM wieder eingebaut, GND richtig verbunden und schon gings.

  • NOP Generator

    Wilfried Klaas07/23/2022 at 08:55 0 comments

    Der erste Schritt mit der CPU für mich ist ein sog. NOP Generator. Wenn der 6502 startet, ließt er zunächst aus den Adressen 0xFFFC/0xFFFD die Adresse, wo er seine Startroutine finden soll. Dort springt der Prozessor dann hin und führt den Code aus. Wenn man nun den Datenbus auf das NOP (no operation) Kommando $EA fest verdrahtet, passiert folgendes: Zunächst ließt die CPU nach dem Einschalten (oder auch nach einem Reset) den Reset Vektor $EAEA. Damit wird nun der Adresszeiger geladen. Als nächstes ließt die CPU den ersten Befehl, auch wieder ein $EA und führt diesen aus. dabei wird der Adresszeiger inkrementiert. Da nichts zu tun ist, NOP, liesst er von der neuen Adresse den nächsten, erhöht wieder den Adresszeiger und führt diesen aus. Und so weiter... Wie man sieht erhöht sich die Adresse bis zum Überlauf des Adresszeiger. Dort wird dann einfach bei $0000 weiter gemacht und das ganze wiederholt sich. Wenn man nun an den Adressbus (vor allen an den höheren Bits) LED anschließt, sollte man einen typischen Zähler sehen. Wenn das funktioniert, funktioniert sowohl der Takt wie auch die CPU selber.

    Hier mal ein Plan dazu:

    Hier mal ein Blick auf das Steckbrett.

    Die Widerstände bilden das Wort $EA ab. D0 befindet sich links, D7 rechts. Der kleine schwarze Kasten ist mein 8 Kanal Logik Analyser. Angeschlossen habe ich R/W, A0, A10-A15. Hier mal ein Bild von dem "Programm"

    Man sieht hier sehr schön wie die Adressleitungen hoch gezählt werden. Wir können auch mal hineinzoomen um die Frequenz zu messen. Am besten der A0 Leitung. Jeder Wechsel ist eine neue Instruktion. (Kanalbelegung geändert R/W, Clk, A0, A11-A15)

    Die Adressleitung wird mit 250KHz umgeschaltet, d.h. die NOP Kommandos werden mit 500KHz verarbeitet, das bedeutet ein NOP braucht 2 Takte.

    Also funktioniert mein Aufbau erst einmal.

View all 15 project logs

Enjoy this project?

Share

Discussions

Rob Ward wrote 04/02/2023 at 06:35 point

Did you have a look at my Sym-1? The 8kb Assembler is quite comprehensive for the memory allocated to it. The real revelations come from Hans Otten's Retro Site. http://retro.hansotten.nl/6502-sbc/synertek-sym-ktm/sym-1/

And all the manuals he has documented. The 6502 Assembler is in there.  The Sym-1 RAE is there along with the ROM images too http://retro.hansotten.nl/6502-sbc/synertek-sym-ktm/sym-1/

I hope your project is going well, best wishes, Rob

  Are you sure? yes | no

Rob Ward wrote 08/07/2022 at 09:27 point

What did you think Wilfried?

  Are you sure? yes | no

Rob Ward wrote 07/31/2022 at 01:26 point

Hi  Wilfried Klaas,

I like your project. I am only fluent in English so I can't follow all of it. The introduction sounds really good though.

I have been working on a SBC from the olden days of c:1978. I also want to explore Assembler in 6502. The Sym-1 is the board I am using and it has a pretty good 8kb Assembler in ROM that I have implemented. The SYM-1 had  very good 4kb Monitor, and it has its operation and vectors very well documented. The overall design is very high quality for its time. It was based on the KIM-1 and was unfortunately released very shortly before the PET and the Apple II were released, so it was soon eclipsed and largely forgotten.

As I was resurrecting it for my curiosity's sake, I realised without a filing system it would quickly become very frustrating, so I developed a disc style filing system where the Resident Assembler and Editor (RAE) could save and load files through an 8bit port with handshaking, to and from an Arduino Mega with an SD card on it. The interface is very general, extremely simple (just hookup wire) and could be adapted to other 6502 SBC's or any other processor really.

I am wondering if you would take a look and see if there is any interest for you in the project. You might find the 8kb RAE an interesting goal. 

Here is the link:  https://hackaday.io/project/181733-sym-1-a-6502-phoenix

  Are you sure? yes | no

Wilfried Klaas wrote 08/04/2022 at 09:39 point

Thanks for your comment. I'll will take a look at it.

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates