Seite 4 von 8

Re: Emulator in Python...

Verfasst: Freitag 11. Oktober 2013, 09:19
von hemmerling
6502 und 6800 hatten verschiedene Hersteller,
6502 war ein Erfolg bei Hobbyisten, 6800 keiner, 6809 auch nicht.
6502 ist ausgestorben.
6800 Nachfolger ( 68HC08 ) gibts trotzdem bis heute - weil es auf Cent-Preise kalkulierte Automotive-Steuergeräte gibt die damit bestückt sind - , von Freescale :-), also auch preiswerte Eval-Boards ( die von Freescale in den frühen 2000er Jahren auf Veranstaltungen zuerst noch verlost, dann aber auch schon mal verschenkt wurden, zuletzt eher als Verramsche und Ausverschenke :-) ), siehe
http://www.hemmerling.com/doku.php/en/6800.html

.. es gibt also eine komplette IDE, CodeWarrior, für lau :-).

Grüße
Rolf

Re: Emulator in Python...

Verfasst: Freitag 11. Oktober 2013, 09:49
von BlackJack
@hemmerling: Na schönen Dank auch, jetzt hast Du die Prozessoren in meinen Commodore-Diskettenlaufwerken zum weinen gebracht. :mrgreen: Die 6510er und 8500er in den Rechnern gucken eher böse. Allesamt fühlen sich noch sehr lebendig. ;-)

Re: Emulator in Python...

Verfasst: Samstag 12. Oktober 2013, 23:50
von jens
So, bin nun bei Simple6809 soweit, das "Daten" zur virtuellen RS232 Schnittstelle gesendet werden.
Im ROM code hier:

Code: Alles auswählen

0285                         * INITIALISE ACIA                      
0286 dbb0 86 95                        LDA  #RTS_LOW       DIV16 CLOCK -> 7372800 / 4 / 16 = 115200 
0287 dbb2 b7 a0 00                     STA  UCTRL           
0288 dbb5 8e dc 03                     LDX  #LA147-1       POINT X TO COLOR BASIC COPYRIGHT MESSAGE 
0289 dbb8 bd eb e5                     JSR  LB99C          PRINT ‘COLOR BASIC’ 
0290 dbbb 8e db c6                     LDX  #BAWMST        WARM START ADDRESS 
0291 dbbe 9f 6f                        STX  RSTVEC         SAVE IT 
0292 dbc0 86 55                        LDA  #$55           WARM START FLAG 
0293 dbc2 97 6e                        STA  RSTFLG         SAVE IT 
0294 dbc4 20 04                        BRA  LA0F3          GO TO BASIC’S MAIN LOOP 
In meinen eigenen Log Ausgaben sehe ich zum Thema RS232 das:
read from RS232 address: $a000 send $0 back
write to RS232 address: $a000 value: $95 ASCII: '\x95'
Ich hab allerdings keine Plan, wie ich eine Virtuelle RS232 implementieren kann. Denke da muß ich erst mir genau das Protokoll ansehen...

Re: Emulator in Python...

Verfasst: Mittwoch 16. Oktober 2013, 14:17
von jens
Einen ersten Erfolg... Endlich!

Mit dem letzten bugfix in PUS/PUL ( https://github.com/jedie/DragonPy/tree/ ... b816a0e376 ) kommt nun eine Ausgabe beim Simple6809:
db3c| (15218) read from RS232 address: $a000
db1c| (15269) write to RS232 address: $a001 value: $36 (dez.: 54) ASCII: '6'
db3c| (15380) read from RS232 address: $a000
db1c| (15431) write to RS232 address: $a001 value: $38 (dez.: 56) ASCII: '8'
db3c| (15542) read from RS232 address: $a000
db1c| (15593) write to RS232 address: $a001 value: $30 (dez.: 48) ASCII: '0'
db3c| (15704) read from RS232 address: $a000
db1c| (15755) write to RS232 address: $a001 value: $39 (dez.: 57) ASCII: '9'
db3c| (15866) read from RS232 address: $a000
db1c| (15917) write to RS232 address: $a001 value: $20 (dez.: 32) ASCII: ' '
db3c| (16028) read from RS232 address: $a000
db1c| (16079) write to RS232 address: $a001 value: $45 (dez.: 69) ASCII: 'E'
db3c| (16190) read from RS232 address: $a000
db1c| (16241) write to RS232 address: $a001 value: $58 (dez.: 88) ASCII: 'X'
db3c| (16352) read from RS232 address: $a000
db1c| (16403) write to RS232 address: $a001 value: $54 (dez.: 84) ASCII: 'T'
db3c| (16514) read from RS232 address: $a000
db1c| (16565) write to RS232 address: $a001 value: $45 (dez.: 69) ASCII: 'E'
db3c| (16676) read from RS232 address: $a000
db1c| (16727) write to RS232 address: $a001 value: $4e (dez.: 78) ASCII: 'N'
db3c| (16838) read from RS232 address: $a000
db1c| (16889) write to RS232 address: $a001 value: $44 (dez.: 68) ASCII: 'D'
db3c| (17000) read from RS232 address: $a000
db1c| (17051) write to RS232 address: $a001 value: $45 (dez.: 69) ASCII: 'E'
db3c| (17162) read from RS232 address: $a000
db1c| (17213) write to RS232 address: $a001 value: $44 (dez.: 68) ASCII: 'D'
db3c| (17324) read from RS232 address: $a000
db1c| (17375) write to RS232 address: $a001 value: $20 (dez.: 32) ASCII: ' '
db3c| (17486) read from RS232 address: $a000
db1c| (17537) write to RS232 address: $a001 value: $42 (dez.: 66) ASCII: 'B'
db3c| (17648) read from RS232 address: $a000
db1c| (17699) write to RS232 address: $a001 value: $41 (dez.: 65) ASCII: 'A'
db3c| (17810) read from RS232 address: $a000
db1c| (17861) write to RS232 address: $a001 value: $53 (dez.: 83) ASCII: 'S'
db3c| (17972) read from RS232 address: $a000
db1c| (18023) write to RS232 address: $a001 value: $49 (dez.: 73) ASCII: 'I'
db3c| (18134) read from RS232 address: $a000
db1c| (18185) write to RS232 address: $a001 value: $43 (dez.: 67) ASCII: 'C'
db3c| (18296) read from RS232 address: $a000
17236.76 cycles/sec.
db3c| (18375) read from RS232 address: $a000
db2d| (18413) write to RS232 address: $a001 value: $d (dez.: 13) ASCII: '\r'
db3c| (18441) read from RS232 address: $a000
db34| (18479) write to RS232 address: $a001 value: $a (dez.: 10) ASCII: '\n'
db3c| (18561) read from RS232 address: $a000
db1c| (18612) write to RS232 address: $a001 value: $28 (dez.: 40) ASCII: '('
db3c| (18723) read from RS232 address: $a000
db1c| (18774) write to RS232 address: $a001 value: $43 (dez.: 67) ASCII: 'C'
db3c| (18885) read from RS232 address: $a000
db1c| (18936) write to RS232 address: $a001 value: $29 (dez.: 41) ASCII: ')'
db3c| (19047) read from RS232 address: $a000
db1c| (19098) write to RS232 address: $a001 value: $20 (dez.: 32) ASCII: ' '
db3c| (19209) read from RS232 address: $a000
db1c| (19260) write to RS232 address: $a001 value: $31 (dez.: 49) ASCII: '1'
db3c| (19371) read from RS232 address: $a000
db1c| (19422) write to RS232 address: $a001 value: $39 (dez.: 57) ASCII: '9'
db3c| (19533) read from RS232 address: $a000
db1c| (19584) write to RS232 address: $a001 value: $38 (dez.: 56) ASCII: '8'
db3c| (19695) read from RS232 address: $a000
db1c| (19746) write to RS232 address: $a001 value: $32 (dez.: 50) ASCII: '2'
db3c| (19857) read from RS232 address: $a000
db1c| (19908) write to RS232 address: $a001 value: $20 (dez.: 32) ASCII: ' '
db3c| (20019) read from RS232 address: $a000
db1c| (20070) write to RS232 address: $a001 value: $42 (dez.: 66) ASCII: 'B'
db3c| (20181) read from RS232 address: $a000
db1c| (20232) write to RS232 address: $a001 value: $59 (dez.: 89) ASCII: 'Y'
db3c| (20343) read from RS232 address: $a000
db1c| (20394) write to RS232 address: $a001 value: $20 (dez.: 32) ASCII: ' '
db3c| (20505) read from RS232 address: $a000
db1c| (20556) write to RS232 address: $a001 value: $4d (dez.: 77) ASCII: 'M'
db3c| (20667) read from RS232 address: $a000
db1c| (20718) write to RS232 address: $a001 value: $49 (dez.: 73) ASCII: 'I'
db3c| (20829) read from RS232 address: $a000
db1c| (20880) write to RS232 address: $a001 value: $43 (dez.: 67) ASCII: 'C'
db3c| (20991) read from RS232 address: $a000
db1c| (21042) write to RS232 address: $a001 value: $52 (dez.: 82) ASCII: 'R'
db3c| (21153) read from RS232 address: $a000
db1c| (21204) write to RS232 address: $a001 value: $4f (dez.: 79) ASCII: 'O'
db3c| (21315) read from RS232 address: $a000
db1c| (21366) write to RS232 address: $a001 value: $53 (dez.: 83) ASCII: 'S'
db3c| (21477) read from RS232 address: $a000
db1c| (21528) write to RS232 address: $a001 value: $4f (dez.: 79) ASCII: 'O'
db3c| (21639) read from RS232 address: $a000
db1c| (21690) write to RS232 address: $a001 value: $46 (dez.: 70) ASCII: 'F'
db3c| (21801) read from RS232 address: $a000
db1c| (21852) write to RS232 address: $a001 value: $54 (dez.: 84) ASCII: 'T'
3505.40 cycles/sec.
db3c| (21963) read from RS232 address: $a000
db3c| (22042) read from RS232 address: $a000
db2d| (22080) write to RS232 address: $a001 value: $d (dez.: 13) ASCII: '\r'
db3c| (22108) read from RS232 address: $a000
db34| (22146) write to RS232 address: $a001 value: $a (dez.: 10) ASCII: '\n'
db3c| (22228) read from RS232 address: $a000
db3c| (22307) read from RS232 address: $a000
db2d| (22345) write to RS232 address: $a001 value: $d (dez.: 13) ASCII: '\r'
db3c| (22373) read from RS232 address: $a000
db34| (22411) write to RS232 address: $a001 value: $a (dez.: 10) ASCII: '\n'
db3c| (23170) read from RS232 address: $a000
db1c| (23221) write to RS232 address: $a001 value: $4f (dez.: 79) ASCII: 'O'
db3c| (23332) read from RS232 address: $a000
db1c| (23383) write to RS232 address: $a001 value: $4b (dez.: 75) ASCII: 'K'
db3c| (23494) read from RS232 address: $a000
db3c| (23573) read from RS232 address: $a000
db2d| (23611) write to RS232 address: $a001 value: $d (dez.: 13) ASCII: '\r'
db3c| (23639) read from RS232 address: $a000
db34| (23677) write to RS232 address: $a001 value: $a (dez.: 10) ASCII: '\n'

Na, was steht da??? ;)

Nun muß ich mit pyserial mal besser ansehen um das auch wirklich an einer Seriellen Schnittstelle anbieten zu können.
Ich hab zwar damit angefangen, das es funktioniert leider noch nicht: https://github.com/jedie/DragonPy/blob/ ... 809.py#L29

Re: Emulator in Python...

Verfasst: Mittwoch 16. Oktober 2013, 17:21
von jens
Es lebt... Zumindest ein wenig...

Ich hab eine Tkinter Konsole gebastelt. Als RS232 Interface.
Senden um empfangen von Text, geht grundsätzlich...

Allerdings werden gesendete Texte einfach wie ein Echo zurück geschrieben.

So sieht es aus:

Bild

Re: Emulator in Python...

Verfasst: Mittwoch 16. Oktober 2013, 22:19
von jens
Hab noch mal einige änderungen vorgenommen. Mit https://github.com/jedie/DragonPy/commi ... fa2400b2d0 wird nun Zeichen für Zeichen übertragen.
Nun macht das "Echo" auch sinn, weil ich es so gemacht habe, das nicht direkt in Tkinter.Text() geschrieben wird.

Allerdings ist das IMHO unschön gelöst, siehe: http://www.python-forum.de/viewtopic.php?f=18&t=32508

Re: Emulator in Python...

Verfasst: Donnerstag 17. Oktober 2013, 11:02
von jens
So, ich hab noch eine Fehler behoben und einige Op implementiert: https://github.com/jedie/DragonPy/commi ... 094543f706

Nun kann ich z.B. ein "PRINT 123" abschicken. Ich sehe dann auch, das er in die Commando Tabelle zu de38 also zu PRINT springt:

Code: Alles auswählen

                        *
                        * DISPATCH TABLE FOR COMMANDS TOKEN #
                        CMD_TAB
...
0085                    TOK_IF    EQU  *-CMD_TAB/2+$7F
de36 e1 8d                        FDB  DATA                        86
0086                    TOK_DATA  EQU  *-CMD_TAB/2+$7F
de38 eb 6a                        FDB  PRINT                       87
0087                    TOK_PRINT EQU  *-CMD_TAB/2+$7F
de3a e1 ef                        FDB  ON                          88
siehe: https://github.com/jedie/DragonPy/blob/ ... M.LST#L708

Somit muß er schonmal das PRINT richtig erkannt haben.
Der Sprung erfolgt damit:

Code: Alles auswählen

                        * HERE IS WHERE WE BRANCH TO DO A 'COMMAND'
e08f 6e 94                        JMP  [,X]                       GO DO A COMMAND
siehe: https://github.com/jedie/DragonPy/blob/ ... .LST#L1060

Allerdings scheint er die DISPATCH TABLE FOR COMMANDS dann als code zu interpretieren, was IMHO nicht so richtig ist. Sieht dann so aus:

Code: Alles auswählen

e08f| 6e   JMP    ea:de38                     cc=57 a=00 b=0e dp=00 x=de38 y=dd35 u=00f7 s=7f32 | .F.I.ZVC
de38| eb   ADDB   B=0e ea:7f3c m:0            cc=50 a=00 b=0e dp=00 x=de38 y=dd35 u=00f7 s=7f32 | .F.I....
de3a| e1   CMPB   B=0e ea:e29c m:c6           cc=53 a=00 b=0e dp=00 x=de38 y=dd35 u=00f7 s=7f32 | .F.I..VC
de3e| e0   SUBB   B=0e ea:deff m:25           cc=53 a=00 b=e9 dp=00 x=de38 y=dd35 u=00f7 s=7f32 | .F.I..VC
...
Das kann ja nicht richtig sein, denke ich mal.

Re: Emulator in Python...

Verfasst: Freitag 18. Oktober 2013, 19:18
von jens
Nun läuft es weiter.

Fehler war quasi:

Code: Alles auswählen

-indirect = postbyte & 0x10 == 1 # bit 4 is 1 -> Indirect
+indirect = postbyte & 0x10 != 0 # bit 4 is 1 -> Indirect
siehe: https://github.com/jedie/DragonPy/commi ... 973c259816

Nun läuft die CPU noch weiter. Mann kann BASIC Zeilen eingeben, allerdings ein LIST geht nicht.
Anscheinend sind noch einige Bugs vorhaden.

Das Grundproblem, ist IMHO, das mein "Daten Python Skript" über die Ops noch nicht vollständig und richtig ist. Also diese Datei: https://github.com/jedie/DragonPy/blob/ ... L699-L3026

Ich weiß allerdings nicht, ob man noch mehr Informationen alleine aus dem Op-Code-Hex-Wert ziehen kann. z.B. Speichert der Op-code in's RAM? Und wenn ja Byte oder Word?
Eine Übersicht über die MC6809_data_raw.py habe ich öffentlich bei https://docs.google.com/spreadsheet/ccc ... URnUTNtSFE hinterlegt.

Re: Emulator in Python...

Verfasst: Samstag 19. Oktober 2013, 11:26
von jens
Ich denke ich komme nicht weiter, wenn meine Grundannahmen falsch sind. Sprich, mein "6809 Daten Skript"...

Deswegen hab ich nochmal ein neuen Generator dafür angefangen: https://github.com/jedie/DragonPy/blob/ ... 9_data2.py

Ich hab mal das vorläufige Ergebnis in einer neuen Tabelle "NEW" eingefügt: https://docs.google.com/spreadsheet/ccc ... URnUTNtSFE

Ziel ist halt sowas zu haben:

Code: Alles auswählen

{'ABX': {'ABX': {'desc': 'X = B+X (Unsigned)',
              'operand': '',
              'ops': {0x3a: 'INHERENT'},
              'read_from_memory': '-',
              'write_to_memory': '-'}},
'ADC': {'ADCA': {'desc': 'A = A+M+C',
               'operand': 'A',
               'ops': {0x89: 'IMMEDIATE',
                      0x99: 'DIRECT',
                      0xa9: 'INDEXED',
                      0xb9: 'EXTENDED'},
               'read_from_memory': 'BYTE',
               'write_to_memory': '-'},
       'ADCB': {'desc': 'B = B+M+C',
               'operand': 'B',
               'ops': {0xc9: 'IMMEDIATE',
                      0xd9: 'DIRECT',
                      0xe9: 'INDEXED',
                      0xf9: 'EXTENDED'},
               'read_from_memory': 'BYTE',
               'write_to_memory': '-'}},
'ADD': {'ADDA': {'desc': 'A = A+M',
               'operand': 'A',
               'ops': {0x8b: 'IMMEDIATE',
                      0x9b: 'DIRECT',
                      0xab: 'INDEXED',
                      0xbb: 'EXTENDED'},
               'read_from_memory': 'BYTE',
               'write_to_memory': '-'},
       'ADDB': {'desc': 'B = B+M',
               'operand': 'B',
               'ops': {0xcb: 'IMMEDIATE',
                      0xdb: 'DIRECT',
                      0xeb: 'INDEXED',
                      0xfb: 'EXTENDED'},
               'read_from_memory': 'BYTE',
               'write_to_memory': '-'},
       'ADDD': {'desc': 'D = D+M:M+1',
               'operand': 'D',
               'ops': {0xc3: 'IMMEDIATE_WORD',
                      0xd3: 'DIRECT',
                      0xe3: 'INDEXED',
                      0xf3: 'EXTENDED'},
               'read_from_memory': 'WORD',
               'write_to_memory': '-'}},
...
Vollstängige Ausgabe: https://gist.github.com/jedie/7054130

Das Problem ist, wie komme ich an die Information "read from memory" und "write to memory" zum jeweiligen Op-Code ???

Meine aktuelle Lösung ist recht simple. Ich schaue nach "M" (für Memory) in der Beschreibung zu jedem Op-Code hier: https://github.com/jedie/DragonPy/blob/ ... #L385-L490

Also damit:

Code: Alles auswählen

    read_from_memory = "-"
    if "=" in desc:
        right = desc.split("=")[1]
        if "M:M" in right:
            read_from_memory = "WORD"
        elif "M" in right:
            read_from_memory = "BYTE"

    write_to_memory = "-"
    if desc.startswith("M:M"):
        write_to_memory = "WORD"
    elif desc.startswith("M ="):
        write_to_memory = "BYTE"
Aber ich denke mal so bekomme ich nicht wirklich alles richtig hin...

Re: Emulator in Python...

Verfasst: Sonntag 20. Oktober 2013, 13:29
von jens
Bisher habe ich keine bessere Referenz gefunden. Deswegen habe ich die Information die ich habe mit einem Skript zusammen gefasst: https://github.com/jedie/DragonPy/blob/ ... 9_data2.py

Das Resultat ist dann: https://github.com/jedie/DragonPy/blob/ ... ta_raw2.py

Und so sieht es aus:

Code: Alles auswählen

OP_DATA = {ABX: {'HNZVC': '-----',
     'condition code': 'Not affected.',
     'description': 'Add the 8-bit unsigned value in accumulator B into index register X.',
     'instr_desc': 'Add B accumulator to X (unsigned)',
     'mnemonic': {ABX: {'desc': 'X = B+X (Unsigned)',
                      'operand': None,
                      'ops': {0x3a: {'addr_mode': INHERENT,
                                   'bytes': 1,
                                   'cycles': 3}},
                      'read_from_memory': None,
                      'write_to_memory': None}},
     'operation': "IX' = IX + ACCB",
     'source form': ABX},
ADC: {'HNZVC': 'aaaaa',
     'condition code': 'H - Set if a half-carry is generated; cleared otherwise.\nN - Set if the result is negative; cleared otherwise.\nZ - Set if the result is zero; cleared otherwise.\nV - Set if an overflow is generated; cleared otherwise.\nC - Set if a carry is generated; cleared otherwise.',
     'description': 'Adds the contents of the C (carry) bit and the memory byte into an 8-bit accumulator.',
     'instr_desc': 'Add memory to accumulator with carry',
     'mnemonic': {'ADCA': {'desc': 'A = A+M+C',
                         'operand': REG_A,
                         'ops': {0x89: {'addr_mode': IMMEDIATE,
                                      'bytes': 2,
                                      'cycles': 2},
                                0x99: {'addr_mode': DIRECT,
                                      'bytes': 2,
                                      'cycles': 4},
                                0xa9: {'addr_mode': INDEXED,
                                      'bytes': 2,
                                      'cycles': 4},
                                0xb9: {'addr_mode': EXTENDED,
                                      'bytes': 3,
                                      'cycles': 5}},
                         'read_from_memory': BYTE,
                         'write_to_memory': None},
                 'ADCB': {'desc': 'B = B+M+C',
                         'operand': REG_B,
                         'ops': {0xc9: {'addr_mode': IMMEDIATE,
                                      'bytes': 2,
                                      'cycles': 2},
                                0xd9: {'addr_mode': DIRECT,
                                      'bytes': 2,
                                      'cycles': 4},
                                0xe9: {'addr_mode': INDEXED,
                                      'bytes': 2,
                                      'cycles': 4},
                                0xf9: {'addr_mode': EXTENDED,
                                      'bytes': 3,
                                      'cycles': 5}},
                         'read_from_memory': BYTE,
                         'write_to_memory': None}},
     'operation': "R' = R + M + C",
     'source form': 'ADCA P; ADCB P'},
ADD: {'HNZVC': 'aaaaa',
...

Re: Emulator in Python...

Verfasst: Montag 21. Oktober 2013, 16:14
von jens
Wieder eine ganze Ecke weiter.

Mit den neuen 6809 Opcode Datensatz läuft es nun weiter.
Mit dem Simple6809 ROM kann ich nun ein paar Befehle eingeben. Diese Enden allerdings fast immer mit einem "OM ERROR" (out of memory).

Hier der Code der Prüfung:

Code: Alles auswählen

                        * CHECK TO SEE IF THERE IS ROOM TO STORE 2*ACCB
                        * BYTES IN FREE RAM - OM ERROR IF NOT
def0 4f                 LAC33     CLRA                            * ACCD CONTAINS NUMBER OF EXTRA
def1 58                           ASLB                            * BYTES TO PUT ON STACK
def2 d3 1f                        ADDD 001f(ARYEND)               END OF PROGRAM AND VARIABLES
def4 c3 00 3a           LAC37     ADDD #003a(STKBUF)              ADD STACK BUFFER - ROOM FOR STACK?
def7 25 08                        BCS  LAC44                      BRANCH IF GREATER THAN $FFFF
def9 10 df 17                     STS  0017(BOTSTK)               CURRENT NEW BOTTOM OF STACK STACK POINTER
defc 10 93 17                     CMPD 0017(BOTSTK)               ARE WE GOING TO BE BELOW STACK?
deff 25 ee                        BCS  deef(LAC32)                YES - NO ERROR
df01 c6 0c              LAC44     LDB  #6*2                       OUT OF MEMORY ERROR
Meine Debug Aushaben:

Code: Alles auswählen

def2| (30188) read byte $c3 from $def4
read pc byte: $c3 from $def4
	get m with get_m_immediate_word
def4| (30189) read byte $3a from $def6
def4| (30190) read byte $0 from $def5
	read pc word: $003a from $def5
	get_m_immediate_word(): $3a from $def5
def4| instruction_ADD16(m=$3a opcode=$c3 register=D=021c)
$def7 c3 3a ADD16 D: 540 + 58 = 598 (signed: 598)
def4| c3   ADDD   D=021c m:3a                 cc=50 a=02 b=56 dp=00 x=00f4 y=dd35 u=00ff s=0147 | .F.I....
-------------------------------------------------------------------------------
def4| (30195) read byte $25 from $def7
read pc byte: $25 from $def7
	get ea with get_ea_relative
def7| (30196) read byte $8 from $def8
read pc byte: $08 from $def8
	get_ea_relative(): ea = $def9 + 8 = $df01 	| $df01: $df01 - OUT OF MEMORY ERROR
def7| instruction_BLO(ea=$df01 opcode=$25)
$def9 BLO/BCS/LBLO/LBCS: don't branch to $df01, because C==0 	| $df01: $df01 - OUT OF MEMORY ERROR
def7| 25   BLO    ea:df01                     cc=50 a=02 b=56 dp=00 x=00f4 y=dd35 u=00ff s=0147 | .F.I....
	 new PC: def7 -> $def9	| $def9: $def9 - CURRENT NEW BOTTOM OF STACK STACK POINTER
Denke es liegt an falschen CC Werten.

Mit dem Dragon 32 ROM und dem XRoar trace vergleich, läuft es nun run 33.400 CPU Zyklen gleich. Dann kommt der Unterschied:

Code: Alles auswählen

b3d3| 30   LEAX   X=0601 ea:0602              cc=50 a=00 b=60 dp=00 x=0602 y=b39b u=0000 s=03d7 | .F.I....
b3d3| 3001        LEAX    1,X                 cc=50 a=00 b=60 dp=00 x=0602 y=b39b u=0000 s=03d7 | .F.I....
b3d5| 63   COM    ea:0603 m:10                cc=59 a=00 b=60 dp=00 x=0602 y=b39b u=0000 s=03d7 | .F.IN..C
b3d5| 6301        COM     1,X                 cc=59 a=00 b=60 dp=00 x=0602 y=b39b u=0000 s=03d7 | .F.IN..C
b3d8| f1   CMPB   B=60 m:dd                   cc=53 a=00 b=60 dp=00 x=0602 y=b39b u=0000 s=03d7 | .F.I..VC
b3d7| 20f1        BRA     $b3ca               cc=59 a=00 b=60 dp=00 x=0602 y=b39b u=0000 s=03d7 | .F.IN..C
trace: b3d7| 20f1        BRA     $b3ca               cc=59 a=00 b=60 dp=00 x=0602 y=b39b u=0000 s=03d7 | .F.IN..C
own..: b3d8| f1   CMPB   B=60 m:dd                   cc=53 a=00 b=60 dp=00 x=0602 y=b39b u=0000 s=03d7 | .F.I..VC
b3d8|Error in CPU cycles: 33439
address ('b3d8' != 'b3d7') not the same as trace reference!

trace: b3d7| 20f1        BRA     $b3ca               cc=59 a=00 b=60 dp=00 x=0602 y=b39b u=0000 s=03d7 | .F.IN..C
own..: b3d8| f1   CMPB   B=60 m:dd                   cc=53 a=00 b=60 dp=00 x=0602 y=b39b u=0000 s=03d7 | .F.I..VC
b3d8|Error in CPU cycles: 33439
mnemonic ('CMPB' != 'BRA') not the same as trace reference!
Auch hier denke ich, das falsche CC Werte die Ursache sind.

Und so sieht Simple6809 nun aus:
Bild

Re: Emulator in Python...

Verfasst: Dienstag 22. Oktober 2013, 17:26
von jens
OM ERROR is weg. Benutztbar aber immer noch nicht.

Schaut nun so aus:
Bild

Re: Emulator in Python...

Verfasst: Freitag 25. Oktober 2013, 17:23
von jens
So, nachdem nun die CC register flags nun richtig funktionieren sollten (s. http://www.python-forum.de/viewtopic.ph ... 24#p247624 ) hatte ich gehofft, das es nun endlich ein wenig benutzbar wird. Is aber nüscht.

Nun habe ich mir gedacht, schnappe ich mir ein wenig original ROM Assembler code und packe es in einen unittests, um Fehler zu finden:

Hab ein kleines skript gehackt, welches mir aus dem ROM Listing code für einen Unittest generiert: https://github.com/jedie/DragonPy/blob/ ... nittest.py
Also aus:

Code: Alles auswählen

db16 34 02 PSHS A
db18 81 0d CMPA #000d(CR) IS IT CARRIAGE RETURN?
db1a 27 0b BEQ NEWLINE YES
wird dann:

Code: Alles auswählen

        self.cpu_test_run2(start=0x4000, count=3, mem=[
            # origin start address in ROM: $db16
            0x34, 0x02, # PSHS A
            0x81, 0x0d, # CMPA #000d(CR)       ; IS IT CARRIAGE RETURN?
            0x27, 0x0b, # BEQ  NEWLINE         ; YES
        ])
Alles per copy&paste... Und zu einem richtigen unittest per Hand geformt:
https://github.com/jedie/DragonPy/blob/ ... #L583-L601


Denke damit werde ich nach und nach Routinen aus dem ROM nehmen und weitere unittests schreiben. In der Hoffnung so alle Fehler zu finden.

Re: Emulator in Python...

Verfasst: Sonntag 27. Oktober 2013, 00:04
von jens
Es ist garnicht so einfach brauchbaren "Test Code" überhaupt zu finden...

Deswegen bin ich nochmal im Netz herrum geschweift um Thema 6809 Assembler.
Ich bin auf einer Unscheinbaren Seite gelandet: http://lennartb.home.xs4all.nl/m6809.html
Dort gibt es u.a. den Download: http://lennartb.home.xs4all.nl/sbc09.tar.gz (unter GPL)

Ich hab mir das angesehen und finde es so interessant, das ich das in DragonPy einbaue. Mit https://github.com/jedie/DragonPy/commi ... 042b8151c7 hab ich das einkopiert. d.h. den kompletten Inhalt von sbc09.tar.gz + compilierte Versionen liegen nun hier: https://github.com/jedie/DragonPy/tree/ ... bc09/sbc09

Darin ist eine ganze Menge (in C geschrieben) u.a.:
* 6809 Assembler: https://github.com/jedie/DragonPy/blob/ ... bc09/a09.c
* 6809 Simulator: https://github.com/jedie/DragonPy/blob/ ... bc09/v09.c
* ein ROM mit ASM Quellentext. Beinhaltet u.a. ein Monitor Programm: https://github.com/jedie/DragonPy/blob/ ... onitor.asm

Informationen sind in der README.doc (die ich in .txt umbenannt habe) und in LaTeX dateien:
https://github.com/jedie/DragonPy/blob/ ... README.txt
https://github.com/jedie/DragonPy/blob/ ... /sbc09.tex

Das nette ist, das man dem "6809 Simulator" auch einen trace entlocken kann. Der sieht ähnlich dem von XRoar aus.
Bsp:

Code: Alles auswählen

pc=e400 i=1a    x=0000 y=0000 u=0000 s=0000 a=00 b=00 cc=00
pc=e402 i=4f    x=0000 y=0000 u=0000 s=0000 a=00 b=00 cc=ff
pc=e403 i=1f    x=0000 y=0000 u=0000 s=0000 a=00 b=00 cc=f4
pc=e405 i=10 ce x=0000 y=0000 u=0000 s=0000 a=00 b=00 cc=f4
pc=e409 i=8e    x=0000 y=0000 u=0000 s=0400 a=00 b=00 cc=f0
pc=e40c i=ce    x=e520 y=0000 u=0000 s=0400 a=00 b=00 cc=f8
pc=e40f i=c6    x=e520 y=0000 u=0280 s=0400 a=00 b=00 cc=f0
...
So habe ich ein neues ROM, plus einen trace zum vergleichen...

Re: Emulator in Python...

Verfasst: Sonntag 27. Oktober 2013, 11:17
von jens
So, beim Simple6809 komme ich noch nicht weiter. Doch das ROM vom sbc09 läuft schon ganz gut.

Sieht dann so aus:
Bild

Hab Informationen in den READMEs dazu rein geschrieben
https://github.com/jedie/DragonPy#current-status
https://github.com/jedie/DragonPy/tree/ ... c09#readme

Was ich gerade komisch finde: Manche Zeichen die per ACIA zur Anzeige gesendet werden, sind "verschoben". Also kein 1:1 ASCII Zeichensatz.
Dadurch das ich mit dem Simulator die Ausgaben die kommen sollen sehen kann, habe ich mir zwei "Übersetzungen" eingefügt, damit ich in DragonPy das selbe sehe:

Code: Alles auswählen

        if value >= 0x90: # FIXME: Why?
            value -= 0x60
            char = chr(value)
            log.error("convert value -= 0x30 to %s ($%x)" , repr(char), value)

        if value <= 9: # FIXME: Why?
            value += 0x41
            char = chr(value)
            log.error("convert value += 0x41 to %s ($%x)" , repr(char), value)
Siehe: https://github.com/jedie/DragonPy/blob/ ... #L238-L246

Weiß jemand zufällig, was dahinter steckt?

Re: Emulator in Python...

Verfasst: Montag 28. Oktober 2013, 15:01
von jens
Hab die sbc09.tex mal in moderner Form gebracht, mit einem hacked skript: https://github.com/jedie/DragonPy/blob/ ... 2creole.py

So kann man sie ganz gut auf github lesen: https://github.com/jedie/DragonPy/blob/ ... c09.creole

Hab noch ein wenig mit dem Single Board Compuer ROM rumgespielt. Funktioniert wirklich schon sehr gut. Bis darauf das DragonPy halt noch recht langsam ist.
Sollte es mal so wie es ist, einfach mit PyPy laufen lassen, als Vergleich...

In einer VM (In der eh alles ein wenig langsamer läuft) kommt ich mir PyPy auf Werte um die 140.000 cycles/sec. mit dem aktuellen unoptimierten und voller log-statements...
Aber immer hin. Mit dem normalen CPython kommen nur rund 37.000 raus!

Eine realer Dragon 32 kommt allerdings auf rund 880.000 ... Ist also auch mit PyPy noch ein wenig weit weg ;)

Re: Emulator in Python...

Verfasst: Dienstag 29. Oktober 2013, 09:41
von jens
Hat mich dann doch mal interessiert. Deswegen hab ich mal alle logging Aktivitäten in der cpu auskommentiert (per skript):
https://github.com/jedie/DragonPy/commi ... a37f8fce6b

* In der VM mit PyPy kommt man dann auf ca. 315.000 cycles/sec (vorher 140.000 cycles/sec)
* In der VM mit CPython: 165.000 cycles/sec (vorher 37.000 cycles/sec)
* CPython native unter Windows: 235.000 cycles/sec (vorher 55.000 cycles/sec)

Macht schon einiges aus. Gut ist noch immer noch was weg von den rund 880.000 cycles/sec einer echten Maschine. Aber vollkommen ok zum testen...

Leider bekomme ich z.Z. kein TKinter mit PyPy unter Windows zum laufen (s. http://www.python-forum.de/viewtopic.ph ... 12#p247912 ) Denke dann wird es nochmal eine Schüppe drauflegen.

Dazu kommt noch, das ich ja nur die logging Ausgaben auskommentiert habe. Aber ich denke man kann noch eine ganze Menge mehr Optimieren... Aber das steht hinten an...

Re: Emulator in Python...

Verfasst: Dienstag 29. Oktober 2013, 11:36
von jens
Ha! Optimieren muß man nicht unbedingt.

Ich hab eine einfache Console implementiert: https://github.com/jedie/DragonPy/commi ... debcf13f5d

Damit kann sbc09 auch ohne TKinter laufen. Somit kann ich PyPy nativ unter Windows nutzten... und siehe da, nun ist es mit 1.370.000 CPU cycles/sec schneller als "Echtzeit" :mrgreen:

Re: Emulator in Python...

Verfasst: Dienstag 1. Juli 2014, 11:18
von jens
Mal ein Update, nach den letzten Bugfixes...

Sieht dann so aus:

Code: Alles auswählen

6809 EXTENDED BASIC
(C) 1982 BY MICROSOFT

OK
10 FOR I=1 TO 3
20 PRINT STR$(I)+" DRAGONPY"
30 NEXT I
RUN
 .0/////909 DRAGONPY
 .0/////909 DRAGONPY
OK

A="B"
?TM ERROR
OK

LIST
0./////909 FOR I=1 TO 3
0./////909 PRINT STR$(I)+" DRAGONPY"
0.///90909 NEXT I
OK
Offensichtlich werden Zahlen nicht richtig evaluiert. Sieht aber Lustig aus, oder? :P

Re: Emulator in Python...

Verfasst: Donnerstag 3. Juli 2014, 08:50
von darktrym
Wollte mal fragen, nutzt dein Emulator eigentlich auch fortschrittliche Technologien wie Recompiling?