home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD1.iso / Emulatoren / FRODO24.LZX / Frodo / Src / 6526SC.asm < prev    next >
Encoding:
Assembly Source File  |  1997-01-03  |  29.8 KB  |  1,600 lines

  1. *
  2. * 6526SC.asm - Einzelzyklus-CIA-Emulation
  3. *
  4. * Copyright (C) 1994-1996 by Christian Bauer
  5. *
  6.  
  7. *
  8. * Anmerkungen:
  9. * ------------
  10. *
  11. * Funktionsweise/Periodic:
  12. *  - Für jeden Zyklus wird vom 6510-Task die Routine Periodic6526
  13. *    aufgerufen, die die Timer herunterzählt und ggf. Interrupts auslöst
  14. *
  15. * Timer/Latches:
  16. *  - Die Bytefolge im Register-File ist gegenüber dem echten 6526 umgekehrt,
  17. *    das wird aber bei den WriteTo6526- und ReadFrom6526-Routinen wieder
  18. *    ausgeglichen
  19. *  - TA/TBCNTPHI2-Zustände:
  20. *     <-1 Timer stoppt
  21. *      -1 Timer gestoppt
  22. *       0 Timer läuft
  23. *      >0 Timer startet
  24. *
  25. * TOD-Clocks:
  26. *  - Die TODs werden synchron mit dem VBlank gezählt. Es wird also ein
  27. *    50Hz-Eingangssignal simuliert.
  28. *
  29. * Zyklenzähler:
  30. *  - Periodic6526 erhöht auch einen Langwort-Zyklenzähler, der von der
  31. *    6510- und 6569-Emulation benutzt wird
  32. *
  33. * Tastaturabfrage:
  34. *  - Das Feld KeyMatrix enthält für jede Taste entsprechend der C64-
  35. *    Tastaturmatrix ein Bit (0: Taste gedrückt, 1: Taste nicht gedrückt).
  36. *    InvKeyMatrix ist dieselbe Matrix mit vertauschten Zeilen und Spalten
  37. *    (für "inverse" Tastaturabfragen).
  38. *  - Bei Lesezugriffen aus CIA-A, Port A/B werden entsprechend der aktiven
  39. *    (ausgewählten) Zeilen der Tastatur die entsprechenden Bits aus der
  40. *    Tastaturmatrix zusammengestellt
  41. *  - F9 löst einen NMI aus (Restore), F10 einen RESET
  42. *
  43. * Joystickabfrage:
  44. *  - Die Joysticks werden im VBlank abgefragt, wenn auch die TODs
  45. *    gezählt werden
  46. *
  47. * Lightpen:
  48. *  - Bei jedem Schreibzugriff auf PRB/DDRB von CIA-A wird geprüft, ob die
  49. *    Lightpen-Leitung (Bit 4) einen Übergang 1->0 macht. In diesem Fall
  50. *    wird der VIC informiert.
  51. *
  52. * Inkompatibilitäten:
  53. *  - Die TOD-Clock sollte bei einem Lesezugriff nicht angehalten,
  54. *    sondern gelatcht werden
  55. *  - Der SDR-Interrupt ist nicht echt
  56. *  - Kleinere Inkompatibilitäten mit den Timern
  57. *
  58.  
  59.         MACHINE    68020
  60.  
  61.         XREF    ShowPrefs    ;Main.asm
  62.  
  63.         XREF    _ciaaprb
  64.         XREF    _ciaaddrb
  65.  
  66.         XREF    IntIsNMI    ;6510SC.asm
  67.         NREF    IntIsIRQ
  68.         NREF    IntIsCIAIRQ
  69.         NREF    FirstIRQCycle
  70.         XREF    FirstNMICycle
  71.         XREF    NMIState
  72.  
  73.         XREF    ChangedVA    ;6569SC.asm
  74.         XREF    TriggerLightpen
  75.         XREF    CycleCounter
  76.  
  77.         XREF    IECIsOpen    ;IEC.asm
  78.  
  79.         XDEF    Reset6526
  80.         XDEF    _GetCIA1Dump
  81.         XDEF    _GetCIA2Dump
  82.         XDEF    ReadFrom6526A
  83.         XDEF    ReadFrom6526B
  84.         XDEF    WriteTo6526A
  85.         XDEF    WriteTo6526B
  86.         XDEF    Periodic6526
  87.         XDEF    ChangedKeys
  88.         XDEF    CountTODs
  89.         XDEF    _KeyPressed
  90.  
  91.         XDEF    CIACycles    ;Prefs
  92.         XDEF    Joystick1On
  93.         XDEF    Joystick2On
  94.         XDEF    JoystickSwap
  95.         XDEF    KeyboardYZ
  96.  
  97.         NEAR    a4,-2
  98.  
  99.         SECTION    "text",CODE
  100.  
  101.         FAR
  102.  
  103.  
  104. **
  105. ** Definitionen
  106. **
  107.  
  108. ; CIA-Register
  109. PRA        = 0
  110. PRB        = 1
  111. DDRA        = 2
  112. DDRB        = 3
  113. TAHI        = 4    ;Timer-Wert A
  114. TALO        = 5    ;Achtung: Umgekehrte Bytefolge!
  115. TBHI        = 6    ;Timer-Wert B
  116. TBLO        = 7
  117. TOD10THS    = 8
  118. TODSEC        = 9
  119. TODMIN        = 10
  120. TODHR        = 11
  121. SDR        = 12
  122. ICR        = 13    ;Interrupt-Data
  123. CRA        = 14
  124. CRB        = 15
  125.  
  126. ; Zusätzliche Register
  127. LTCHA        = 16    ;Timer-Latch A
  128. LTCHB        = 18    ;Timer-Latch B
  129. INTMASK        = 20    ;Interrupt-Enable
  130. TODHALT        = 21    ;TOD zwecks Beschreiben/Auslesen gestoppt
  131. ALM10THS    = 22    ;Alarmzeit
  132. ALMSEC        = 23
  133. ALMMIN        = 24
  134. ALMHR        = 25
  135. TODDIV        = 26    ;TOD-Frequenzteiler
  136. TACNTPHI2    = 27    ;Timer A läuft und zählt Phi2 (-1: Stop, 0: Läuft, >0: Verzögerung beim Starten, <0: Verzögerung beim Stoppen)
  137. TBCNTPHI2    = 28    ;Timer B läuft und zählt Phi2 (-1: Stop, 0: Läuft, >0: Verzögerung beim Starten, <0: Verzögerung beim Stoppen)
  138. TBCNTTA        = 29    ;Timer B läuft und zählt Unterläufe von Timer A (0: Stop, #0: Läuft)
  139. PREVLP        = 30    ;Voriger Zustand der Lightpen-Leitung (nur CIA-A)
  140.  
  141.  
  142. **
  143. ** CIAs zurücksetzen
  144. **
  145.  
  146.         FAR
  147.  
  148. ; CIA-A
  149. Reset6526    lea    Registers1,a0
  150.         clr.l    (a0)
  151.         clr.l    4(a0)
  152.         clr.l    8(a0)
  153.         clr.l    12(a0)
  154.         move.w    #-1,TAHI(a0)        ;Timer auf -1
  155.         move.w    #-1,TBHI(a0)
  156.  
  157.         move.w    #$0001,LTCHA(a0)    ;Latches auf 1
  158.         move.w    #$0001,LTCHB(a0)
  159.         clr.b    INTMASK(a0)        ;Interrupts abschalten
  160.         clr.b    TODHALT(a0)        ;TOD läuft
  161.         clr.l    ALM10THS(a0)        ;Alarmzeit auf 00:00:00.0
  162.         st.b    TACNTPHI2(a0)        ;Beide Timer anhalten
  163.         st.b    TBCNTPHI2(a0)
  164.         clr.b    TBCNTTA(a0)
  165.         move.b    #$10,PREVLP(a0)        ;Lightpen-Leitung ist High
  166.  
  167.         move.b    #$ff,Joystick1        ;Joystick inaktiv
  168.         move.b    #$ff,Joystick2
  169.         move.b    #$ff,Joystick2Key
  170.  
  171. ; CIA-B
  172.         lea    Registers2,a0
  173.         clr.l    (a0)
  174.         clr.l    4(a0)
  175.         clr.l    8(a0)
  176.         clr.l    12(a0)
  177.         move.w    #-1,TAHI(a0)        ;Timer auf -1
  178.         move.w    #-1,TBHI(a0)
  179.  
  180.         move.w    #$0001,LTCHA(a0)    ;Latches auf 1
  181.         move.w    #$0001,LTCHB(a0)
  182.         clr.b    INTMASK(a0)        ;Interrupts abschalten
  183.         clr.b    TODHALT(a0)        ;TOD läuft
  184.         clr.l    ALM10THS(a0)        ;Alarmzeit auf 00:00:00.0
  185.         st.b    TACNTPHI2(a0)        ;Beide Timer anhalten
  186.         st.b    TBCNTPHI2(a0)
  187.         clr.b    TBCNTTA(a0)
  188.  
  189. ; Zyklenzähler zurücksetzen
  190.         clr.l    CycleCounter
  191.  
  192. ; Tastaturmatrix löschen
  193.         moveq    #-1,d0
  194.         move.l    d0,KeyMatrix
  195.         move.l    d0,KeyMatrix+4
  196.         move.l    d0,InvKeyMatrix
  197.         move.l    d0,InvKeyMatrix+4
  198.  
  199. ; VIC-Bank 0 einstellen
  200.         moveq    #0,d0
  201.         bra    ChangedVA
  202.  
  203.  
  204. **
  205. ** CIA-Status in Datenstruktur schreiben
  206. **
  207.  
  208. _GetCIA1Dump    lea    Registers1,a0
  209.         bra    GetCIADump
  210.  
  211. _GetCIA2Dump    lea    Registers2,a0
  212.  
  213. GetCIADump    move.l    4(sp),a1
  214.         move.l    (a0),(a1)+
  215.         move.b    TALO(a0),(a1)+    ;Wegen umgekehrter Bytefolge
  216.         move.b    TAHI(a0),(a1)+
  217.         move.b    TBLO(a0),(a1)+
  218.         move.b    TBHI(a0),(a1)+
  219.         move.l    TOD10THS(a0),(a1)+
  220.         move.l    SDR(a0),(a1)+
  221.  
  222.         move.b    LTCHA+1(a0),(a1)+
  223.         move.b    LTCHA(a0),(a1)+
  224.         move.b    LTCHB+1(a0),(a1)+
  225.         move.b    LTCHB(a0),(a1)+
  226.         move.l    ALM10THS(a0),(a1)+
  227.         move.b    INTMASK(a0),(a1)
  228.         rts
  229.  
  230.  
  231. **
  232. ** Tastaturbelegung geändert, Y und Z sortieren
  233. **
  234.  
  235. ChangedKeys    tst.w    KeyboardYZ
  236.         bne    1$
  237.         move.l    #$00010004,KeyPatch1
  238.         move.l    #$00030001,KeyPatch2
  239.         rts
  240. 1$        move.l    #$00030001,KeyPatch1
  241.         move.l    #$00010004,KeyPatch2
  242.         rts
  243.  
  244.  
  245. **
  246. ** In ein CIA-A-Register schreiben
  247. ** d0.w: Registernummer ($00-$0f)
  248. ** d1.b: Byte
  249. **
  250.  
  251.         NEAR
  252.  
  253. WriteTo6526A    lea    Registers1,a0
  254.         move.l    WriteTabA(pc,d0.w*4),a1
  255.         jmp    (a1)
  256.  
  257.         CNOP    0,4
  258. WriteTabA    dc.l    WrNormal
  259.         dc.l    WrAPRB
  260.         dc.l    WrNormal
  261.         dc.l    WrADDRB
  262.         dc.l    WrTALO
  263.         dc.l    WrTAHI
  264.         dc.l    WrTBLO
  265.         dc.l    WrTBHI
  266.         dc.l    WrTOD10THS
  267.         dc.l    WrTODSEC
  268.         dc.l    WrTODMIN
  269.         dc.l    WrTODHR
  270.         dc.l    WrASDR
  271.         dc.l    WrAICR
  272.         dc.l    WrCRA
  273.         dc.l    WrCRB
  274.  
  275. WrNormal    move.b    d1,(a0,d0.w)
  276.         rts
  277.  
  278. WrAPRB        move.b    d1,PRB(a0)
  279.         bra    CheckLP
  280.  
  281. WrADDRB        move.b    d1,DDRB(a0)
  282.  
  283. CheckLP        move.b    DDRB(a0),d0    ;Lightpen-Leitung
  284.         not.b    d0
  285.         or.b    PRB(a0),d0
  286.         and.b    #$10,d0
  287.         cmp.b    PREVLP(a0),d0    ;Änderung?
  288.         beq    1$
  289.         move.b    d0,PREVLP(a0)    ;Ja, negative Flanke?
  290.         bne    1$
  291.         bra    TriggerLightpen    ;Ja, LP triggern
  292. 1$        rts
  293.  
  294. WrTALO        move.b    d1,LTCHA+1(a0)
  295.         rts
  296.  
  297. WrTAHI        move.b    d1,LTCHA(a0)
  298.         btst    #0,CRA(a0)        ;Timer A gestoppt?
  299.         bne    1$
  300.         move.w    LTCHA(a0),TAHI(a0)    ;Ja, Timer laden
  301. 1$        rts
  302.  
  303. WrTBLO        move.b    d1,LTCHB+1(a0)
  304.         rts
  305.  
  306. WrTBHI        move.b    d1,LTCHB(a0)
  307.         btst    #0,CRB(a0)        ;Timer B gestoppt?
  308.         bne    1$
  309.         move.w    LTCHB(a0),TBHI(a0)    ;Ja, Timer laden
  310. 1$        rts
  311.  
  312. WrTOD10THS    and.b    #$0f,d1
  313.         clr.b    TODHALT(a0)    ;TOD weiterlaufen lassen
  314.         btst    #7,CRB(a0)    ;Alarm-Zeit schreiben?
  315.         bne    1$
  316.         move.b    d1,TOD10THS(a0)
  317.         rts
  318. 1$        move.b    d1,ALM10THS(a0)
  319.         rts
  320.  
  321. WrTODSEC    and.b    #$7f,d1
  322.         btst    #7,CRB(a0)    ;Alarm-Zeit schreiben?
  323.         bne    1$
  324.         move.b    d1,TODSEC(a0)
  325.         rts
  326. 1$        move.b    d1,ALMSEC(a0)
  327.         rts
  328.  
  329. WrTODMIN    and.b    #$7f,d1
  330.         btst    #7,CRB(a0)    ;Alarm-Zeit schreiben?
  331.         bne    1$
  332.         move.b    d1,TODMIN(a0)
  333.         rts
  334. 1$        move.b    d1,ALMMIN(a0)
  335.         rts
  336.  
  337. WrTODHR        and.b    #$9f,d1
  338.         st.b    TODHALT(a0)    ;TOD anhalten
  339.         btst    #7,CRB(a0)    ;Alarm-Zeit schreiben?
  340.         bne    1$
  341.         move.b    d1,TODHR(a0)
  342.         rts
  343. 1$        move.b    d1,ALMHR(a0)
  344.         rts
  345.  
  346. WrASDR        move.b    d1,SDR(a0)
  347.         or.b    #$08,ICR(a0)        ;SDR-Interrupt auslösen
  348.         btst    #3,INTMASK(a0)
  349.         beq    1$
  350.         or.b    #$80,ICR(a0)
  351.         tst.w    IntIsIRQ
  352.         bne    2$
  353.         move.l    CycleCounter,FirstIRQCycle
  354. 2$        st.b    IntIsCIAIRQ
  355. 1$        rts
  356.  
  357. WrAICR        bclr    #7,d1            ;S/C-Bit löschen
  358.         bne    1$            ;War es gesetzt?
  359.         not.b    d1            ;Nein, Bits zum Löschen negieren
  360.         and.b    d1,INTMASK(a0)        ;Und Bits löschen
  361.         bra    2$
  362. 1$        or.b    d1,INTMASK(a0)        ;Bits setzen
  363. 2$
  364.         move.b    ICR(a0),d0        ;Anstehende Interrupts erlaubt?
  365.         and.b    INTMASK(a0),d0
  366.         and.b    #$1f,d0
  367.         beq    3$
  368.         or.b    #$80,ICR(a0)        ;Ja, IRQ auslösen
  369.         tst.w    IntIsIRQ
  370.         bne    4$
  371.         move.l    CycleCounter,FirstIRQCycle
  372. 4$        st.b    IntIsCIAIRQ
  373. 3$        rts                ;Nein
  374.  
  375. WrCRA        move.b    d1,d0
  376.         bclr    #4,d0            ;Force load?
  377.         beq    1$
  378.         move.w    LTCHA(a0),TAHI(a0)    ;Ja, Timer laden
  379. 1$        move.b    d0,CRA(a0)
  380.  
  381.         and.b    #$21,d0            ;Läuft der Timer und zählt er Phi2?
  382.         cmp.b    #$01,d0
  383.         bne    2$
  384.         btst    #4,d1
  385.         beq    31$
  386.         move.b    #3,TACNTPHI2(a0)    ;3 Zyklen Verzögerung für Force load
  387.         rts
  388. 31$        tst.b    TACNTPHI2(a0)
  389.         bpl    3$
  390.         move.b    #2,TACNTPHI2(a0)    ;2 Zyklen Verzögerung beim Starten
  391. 3$        rts
  392. 2$        tst.b    TACNTPHI2(a0)
  393.         bmi    21$
  394.         move.b    #-3,TACNTPHI2(a0)    ;2 Zyklen Verzögerung beim Stoppen
  395.         rts
  396. 21$        st.b    TACNTPHI2(a0)
  397.         rts
  398.  
  399. WrCRB        move.b    d1,d0
  400.         bclr    #4,d0            ;Force load?
  401.         beq    1$
  402.         move.w    LTCHB(a0),TBHI(a0)    ;Ja, Timer laden
  403. 1$        move.b    d0,CRB(a0)
  404.  
  405.         and.b    #$61,d0
  406.         cmp.b    #$41,d0
  407.         seq    TBCNTTA(a0)
  408.         cmp.b    #$01,d0            ;Läuft der Timer und zählt er Phi2?
  409.         bne    2$
  410.         btst    #4,d1
  411.         beq    31$
  412.         move.b    #3,TBCNTPHI2(a0)    ;3 Zyklen Verzögerung für Force load
  413.         rts
  414. 31$        tst.b    TBCNTPHI2(a0)
  415.         bpl    3$
  416.         move.b    #2,TBCNTPHI2(a0)    ;2 Zyklen Verzögerung beim Starten
  417. 3$        rts
  418. 2$        tst.b    TBCNTPHI2(a0)
  419.         bmi    21$
  420.         move.b    #-3,TBCNTPHI2(a0)    ;2 Zyklen Verzögerung beim Stoppen
  421.         rts
  422. 21$        st.b    TBCNTPHI2(a0)
  423.         rts
  424.  
  425.  
  426. **
  427. ** In ein CIA-B-Register schreiben
  428. ** d0.w: Registernummer ($00-$0f)
  429. ** d1.b: Byte
  430. **
  431.  
  432. WriteTo6526B    lea    Registers2,a0
  433.         move.l    WriteTabB(pc,d0.w*4),a1
  434.         jmp    (a1)
  435.  
  436.         CNOP    0,4
  437. WriteTabB    dc.l    WrBPRA
  438.         dc.l    WrNormal
  439.         dc.l    WrBDDRA
  440.         dc.l    WrNormal
  441.         dc.l    WrTALO
  442.         dc.l    WrTAHI
  443.         dc.l    WrTBLO
  444.         dc.l    WrTBHI
  445.         dc.l    WrTOD10THS
  446.         dc.l    WrTODSEC
  447.         dc.l    WrTODMIN
  448.         dc.l    WrTODHR
  449.         dc.l    WrBSDR
  450.         dc.l    WrBICR
  451.         dc.l    WrCRA
  452.         dc.l    WrCRB
  453.  
  454. WrBPRA        move.b    d1,PRA(a0)        ;Floppy/VA
  455.         tst.b    IECIsOpen        ;Wenn IEC aktiv ist, Port setzen
  456.         beq    WrBNewVA
  457.         move.b    d1,_ciaaprb
  458.         bra    WrBNewVA
  459.  
  460. WrBDDRA        move.b    d1,DDRA(a0)        ;Floppy/VA
  461.         tst.b    IECIsOpen        ;Wenn IEC aktiv ist, DDR setzen
  462.         beq    WrBNewVA
  463.         move.b    d1,_ciaaddrb
  464. WrBNewVA    move.b    DDRA(a0),d0        ;VA extrahieren
  465.         not.b    d0
  466.         or.b    PRA(a0),d0
  467.         not.b    d0
  468.         and.b    #$03,d0
  469.         bra    ChangedVA        ;Und dem VIC mitteilen
  470.  
  471. WrBSDR        move.b    d1,SDR(a0)
  472.         or.b    #$08,ICR(a0)        ;SDR-Interrupt auslösen
  473.         btst    #3,INTMASK(a0)
  474.         beq    1$
  475.         or.b    #$80,ICR(a0)
  476.         tst.b    NMIState
  477.         bne    1$
  478.         move.l    CycleCounter,FirstNMICycle
  479.         st.b    NMIState
  480.         st.b    IntIsNMI
  481. 1$        rts
  482.  
  483. WrBICR        bclr    #7,d1            ;S/C-Bit löschen
  484.         bne    1$            ;War es gesetzt?
  485.         not.b    d1            ;Nein, Bits zum Löschen negieren
  486.         and.b    d1,INTMASK(a0)        ;Und Bits löschen
  487.         bra    2$
  488. 1$        or.b    d1,INTMASK(a0)        ;Bits setzen
  489. 2$
  490.         move.b    ICR(a0),d0        ;Anstehende Interrupts erlaubt?
  491.         and.b    INTMASK(a0),d0
  492.         and.b    #$1f,d0
  493.         beq    3$
  494.         or.b    #$80,ICR(a0)        ;Ja, NMI auslösen
  495.         tst.b    NMIState
  496.         bne    3$
  497.         move.l    CycleCounter,FirstNMICycle
  498.         st.b    NMIState
  499.         st.b    IntIsNMI
  500. 3$        rts                ;Nein
  501.  
  502.  
  503. **
  504. ** Aus einem CIA-A-Register lesen
  505. ** d0.w: Registernummer ($00-$0f)
  506. ** Rückgabe: d0.b: Byte
  507. **
  508.  
  509. ReadFrom6526A    lea    Registers1,a0
  510.         move.l    ReadTabA(pc,d0.w*4),a1
  511.         jmp    (a1)
  512.  
  513.         CNOP    0,4
  514. ReadTabA    dc.l    RdAPRA
  515.         dc.l    RdAPRB
  516.         dc.l    RdNormal
  517.         dc.l    RdNormal
  518.         dc.l    RdTALO
  519.         dc.l    RdTAHI
  520.         dc.l    RdTBLO
  521.         dc.l    RdTBHI
  522.         dc.l    RdTOD10THS
  523.         dc.l    RdNormal
  524.         dc.l    RdNormal
  525.         dc.l    RdTODHR
  526.         dc.l    RdNormal
  527.         dc.l    RdAICR
  528.         dc.l    RdNormal
  529.         dc.l    RdNormal
  530.  
  531. RdNormal    move.b    (a0,d0.w),d0
  532.         rts
  533.  
  534. RdAPRA        lea    InvKeyMatrix,a1
  535.         move.b    DDRB(a0),d1    ;Tastaturabfrage
  536.         not.b    d1
  537.         or.b    PRB(a0),d1
  538.         and.b    Joystick1,d1
  539.         move.b    DDRA(a0),d0
  540.         not.b    d0
  541.         or.b    PRA(a0),d0
  542.         lsr.b    #1,d1        ;Alle aktiven Spalten dazuANDen
  543.         bcs    1$
  544.         and.b    (a1),d0
  545. 1$        lsr.b    #1,d1
  546.         bcs    2$
  547.         and.b    1(a1),d0
  548. 2$        lsr.b    #1,d1
  549.         bcs    3$
  550.         and.b    2(a1),d0
  551. 3$        lsr.b    #1,d1
  552.         bcs    4$
  553.         and.b    3(a1),d0
  554. 4$        lsr.b    #1,d1
  555.         bcs    5$
  556.         and.b    4(a1),d0
  557. 5$        lsr.b    #1,d1
  558.         bcs    6$
  559.         and.b    5(a1),d0
  560. 6$        lsr.b    #1,d1
  561.         bcs    7$
  562.         and.b    6(a1),d0
  563. 7$        lsr.b    #1,d1
  564.         bcs    8$
  565.         and.b    7(a1),d0
  566. 8$        and.b    Joystick2,d0
  567.         rts
  568.  
  569. RdAPRB        lea    KeyMatrix,a1
  570.         move.b    DDRA(a0),d1    ;Tastaturabfrage
  571.         not.b    d1
  572.         or.b    PRA(a0),d1
  573.         and.b    Joystick2,d1
  574.         move.b    DDRB(a0),d0
  575.         not.b    d0
  576.  
  577.         lsr.b    #1,d1        ;Alle aktiven Reihen dazuANDen
  578.         bcs    1$
  579.         and.b    (a1),d0
  580. 1$        lsr.b    #1,d1
  581.         bcs    2$
  582.         and.b    1(a1),d0
  583. 2$        lsr.b    #1,d1
  584.         bcs    3$
  585.         and.b    2(a1),d0
  586. 3$        lsr.b    #1,d1
  587.         bcs    4$
  588.         and.b    3(a1),d0
  589. 4$        lsr.b    #1,d1
  590.         bcs    5$
  591.         and.b    4(a1),d0
  592. 5$        lsr.b    #1,d1
  593.         bcs    6$
  594.         and.b    5(a1),d0
  595. 6$        lsr.b    #1,d1
  596.         bcs    7$
  597.         and.b    6(a1),d0
  598. 7$        lsr.b    #1,d1
  599.         bcs    8$
  600.         and.b    7(a1),d0
  601. 8$
  602.         move.b    PRB(a0),d1
  603.         and.b    DDRB(a0),d1
  604.         or.b    d1,d0
  605.         and.b    Joystick1,d0
  606.         rts
  607.  
  608. RdTALO        move.b    TALO(a0),d0    ;Weil die Timer im Registerfile
  609.         rts            ;als big-endian gespeichert sind
  610.  
  611. RdTAHI        move.b    TAHI(a0),d0
  612.         rts
  613.  
  614. RdTBLO        move.b    TBLO(a0),d0
  615.         rts
  616.  
  617. RdTBHI        move.b    TBHI(a0),d0
  618.         rts
  619.  
  620. RdTOD10THS    move.b    TOD10THS(a0),d0
  621.         clr.b    TODHALT(a0)    ;TOD weiterlaufen lassen
  622.         rts
  623.  
  624. RdTODHR        st.b    TODHALT(a0)    ;TOD anhalten
  625.         move.b    TODHR(a0),d0
  626.         rts
  627.  
  628. RdAICR        move.b    ICR(a0),d0    ;ICR beim Lesen löschen
  629.         clr.b    ICR(a0)
  630.         clr.b    IntIsCIAIRQ    ;IRQ zurücknehmen
  631.         rts
  632.  
  633.  
  634. **
  635. ** Aus einem CIA-B-Register lesen
  636. ** d0.w: Registernummer ($00-$0f)
  637. ** Rückgabe: d0.b: Byte
  638. **
  639.  
  640. ReadFrom6526B    lea    Registers2,a0
  641.         move.l    ReadTabB(pc,d0.w*4),a1
  642.         jmp    (a1)
  643.  
  644.         CNOP    0,4
  645. ReadTabB    dc.l    RdBPRA
  646.         dc.l    RdBPRB
  647.         dc.l    RdNormal
  648.         dc.l    RdNormal
  649.         dc.l    RdTALO
  650.         dc.l    RdTAHI
  651.         dc.l    RdTBLO
  652.         dc.l    RdTBHI
  653.         dc.l    RdTOD10THS
  654.         dc.l    RdNormal
  655.         dc.l    RdNormal
  656.         dc.l    RdTODHR
  657.         dc.l    RdNormal
  658.         dc.l    RdBICR
  659.         dc.l    RdNormal
  660.         dc.l    RdNormal
  661.  
  662. RdBPRA        move.b    DDRA(a0),d0    ;Floppy/VA
  663.         not.b    d0
  664.         or.b    PRA(a0),d0
  665.  
  666.         tst.b    IECIsOpen    ;Wenn IEC aktiv ist, davon lesen
  667.         beq    1$
  668.         and.b    #$03,d0
  669.         move.b    _ciaaprb,d1
  670.         and.b    #$fc,d1
  671.         or.b    d1,d0
  672. 1$        rts
  673.  
  674. RdBPRB        move.b    DDRB(a0),d0    ;Userport
  675.         not.b    d0        ;Eingabebits immer 1
  676.         or.b    PRB(a0),d0
  677.         rts
  678.  
  679. RdBICR        move.b    ICR(a0),d0    ;ICR beim Lesen löschen
  680.         clr.b    ICR(a0)
  681.         clr.b    NMIState    ;NMI zurücknehmen
  682.         rts
  683.  
  684.  
  685. **
  686. ** Wird jede Rasterzeile einmal aufgerufen
  687. **
  688.  
  689. *
  690. * CIA-A
  691. * d1: ICR
  692. * d2: INTMASK
  693. *
  694.  
  695. Periodic6526    lea    Registers1,a0
  696.         move.b    ICR(a0),d1
  697.         move.b    INTMASK(a0),d2
  698.  
  699. *
  700. * Timer A
  701. *
  702.  
  703.         tst.b    TACNTPHI2(a0)    ;Wird Phi2 gezählt?
  704.         bmi    CiaATAStop    ;Nein
  705.         bne    CiaATADelay    ;Ja, aber noch warten
  706.  
  707. CiaATACount    subq.w    #1,TAHI(a0) ;Ja, herabzählen
  708.         bcc    CiaATADone    ;Unterlauf?
  709.  
  710.         or.b    #$01,d1        ;Ja, IRQ-Bit setzen
  711.         btst    #0,d2        ;IRQ freigegeben?
  712.         beq    CiaATANoIRQ
  713.         or.b    #$80,d1        ;Ja, IR-Bit setzen
  714.         tst.w    IntIsIRQ    ;IRQ schon ausgelöst?
  715.         bne    1$
  716.         move.l    CycleCounter,FirstIRQCycle ;Nein, Zyklus merken
  717. 1$        st.b    IntIsCIAIRQ    ; und IRQ auslösen
  718.  
  719. CiaATANoIRQ    move.w    LTCHA(a0),TAHI(a0) ;Zähler neu laden
  720.         btst    #3,CRA(a0)    ;One-Shot?
  721.         beq    1$
  722.         and.b    #$fe,CRA(a0)    ;Ja, Zähler stoppen
  723.         st.b    TACNTPHI2(a0)
  724.  
  725. 1$        tst.b    TBCNTTA(a0)    ;Läuft Timer B und zählt er
  726.         beq    CiaATADone    ; Unterläufe von Timer A?
  727.  
  728.         subq.w    #1,TBHI(a0)    ;Ja, Timer B runterzählen
  729.         bcs    CiaATBUnderflow    ;Untergelaufen?
  730.         bra    CiaATADone
  731.  
  732. CiaATADelay    subq.b    #1,TACNTPHI2(a0) ;Verzögerung beim Starten des Timers
  733.         bra    CiaATADone
  734.  
  735. CiaATAStop    cmp.b    #-1,TACNTPHI2(a0)
  736.         beq    CiaATADone
  737.         addq.b    #1,TACNTPHI2(a0) ;Verzögerung beim Stoppen des Timers
  738.         bra    CiaATACount
  739. CiaATADone
  740.  
  741. *
  742. * Timer B
  743. *
  744.  
  745.         tst.b    TBCNTPHI2(a0)    ;Wird Phi2 gezählt?
  746.         bmi    CiaATBStop    ;Nein
  747.         bne    CiaATBDelay    ;Ja, aber noch warten
  748.  
  749. CiaATBCount    subq.w    #1,TBHI(a0)    ;Ja, herabzählen
  750.         bcc    CiaATBDone    ;Unterlauf?
  751.  
  752. CiaATBUnderflow    or.b    #$02,d1        ;Ja, IRQ-Bit setzen
  753.         btst    #1,d2        ;IRQ freigegeben?
  754.         beq    CiaATBNoIRQ
  755.         or.b    #$80,d1        ;Ja, IR-Bit setzen
  756.         tst.w    IntIsIRQ    ;IRQ schon ausgelöst?
  757.         bne    1$
  758.         move.l    CycleCounter,FirstIRQCycle ;Nein, Zyklus merken
  759. 1$        st.b    IntIsCIAIRQ    ; und IRQ auslösen
  760.  
  761. CiaATBNoIRQ    move.w    LTCHB(a0),TBHI(a0) ;Zähler neu laden
  762.         btst    #3,CRB(a0)    ;One-Shot?
  763.         beq    CiaATBDone
  764.         and.b    #$fe,CRB(a0)    ;Ja, Zähler stoppen
  765.         st.b    TBCNTPHI2(a0)
  766.         clr.b    TBCNTTA(a0)
  767.         bra    CiaATBDone
  768.  
  769. CiaATBDelay    subq.b    #1,TBCNTPHI2(a0) ;Verzögerung beim Starten des Timers
  770.         bra    CiaATBDone
  771.  
  772. CiaATBStop    cmp.b    #-1,TBCNTPHI2(a0)
  773.         beq    CiaATBDone
  774.         addq.b    #1,TBCNTPHI2(a0) ;Verzögerung beim Stoppen des Timers
  775.         bra    CiaATBCount
  776. CiaATBDone
  777.  
  778. *
  779. * ICR zurückschreiben
  780. *
  781.  
  782.         move.b    d1,ICR(a0)
  783.  
  784. *
  785. * CIA-B
  786. * d1: ICR
  787. * d2: INTMASK
  788. *
  789.  
  790.         lea    Registers2,a0
  791.         move.b    ICR(a0),d1
  792.         move.b    INTMASK(a0),d2
  793.  
  794. *
  795. * Timer A
  796. *
  797.  
  798.         tst.b    TACNTPHI2(a0)    ;Wird Phi2 gezählt?
  799.         bmi    CiaBTAStop    ;Nein
  800.         bne    CiaBTADelay    ;Ja, aber noch warten
  801.  
  802. CiaBTACount    subq.w    #1,TAHI(a0) ;Ja, herabzählen
  803.         bcc    CiaBTADone    ;Unterlauf?
  804.  
  805.         or.b    #$01,d1        ;Ja, IRQ-Bit setzen
  806.         btst    #0,d2        ;IRQ freigegeben?
  807.         beq    CiaBTANoIRQ
  808.         or.b    #$80,d1        ;Ja, IR-Bit setzen
  809.         tst.b    NMIState    ;NMI schon ausgelöst?
  810.         bne    1$
  811.         move.l    CycleCounter,FirstNMICycle ;Nein, Zyklus merken
  812.         st.b    NMIState    ;und NMI auslösen
  813.         st.b    IntIsNMI
  814. 1$
  815.  
  816. CiaBTANoIRQ    move.w    LTCHA(a0),TAHI(a0) ;Zähler neu laden
  817.         btst    #3,CRA(a0)    ;One-Shot?
  818.         beq    1$
  819.         and.b    #$fe,CRA(a0)    ;Ja, Zähler stoppen
  820.         st.b    TACNTPHI2(a0)
  821.  
  822. 1$        tst.b    TBCNTTA(a0)    ;Läuft Timer B und zählt er
  823.         beq    CiaBTADone    ; Unterläufe von Timer A?
  824.  
  825.         subq.w    #1,TBHI(a0)    ;Ja, Timer B runterzählen
  826.         bcs    CiaBTBUnderflow    ;Untergelaufen?
  827.         bra    CiaBTADone
  828.  
  829. CiaBTADelay    subq.b    #1,TACNTPHI2(a0) ;Verzögerung beim Starten des Timers
  830.         bra    CiaBTADone
  831.  
  832. CiaBTAStop    cmp.b    #-1,TACNTPHI2(a0)
  833.         beq    CiaBTADone
  834.         addq.b    #1,TACNTPHI2(a0) ;Verzögerung beim Stoppen des Timers
  835.         bra    CiaBTACount
  836. CiaBTADone
  837.  
  838. *
  839. * Timer B
  840. *
  841.  
  842.         tst.b    TBCNTPHI2(a0)    ;Wird Phi2 gezählt?
  843.         bmi    CiaBTBStop    ;Nein
  844.         bne    CiaBTBDelay    ;Ja, aber noch warten
  845.  
  846. CiaBTBCount    subq.w    #1,TBHI(a0)    ;Ja, herabzählen
  847.         bcc    CiaBTBDone    ;Unterlauf?
  848.  
  849. CiaBTBUnderflow    or.b    #$02,d1        ;Ja, IRQ-Bit setzen
  850.         btst    #1,d2        ;IRQ freigegeben?
  851.         beq    CiaBTBNoIRQ
  852.         or.b    #$80,d1        ;Ja, IR-Bit setzen
  853.         tst.b    NMIState    ;NMI schon ausgelöst?
  854.         bne    1$
  855.         move.l    CycleCounter,FirstNMICycle
  856.         st.b    NMIState    ;und NMI auslösen
  857.         st.b    IntIsNMI
  858. 1$
  859.  
  860. CiaBTBNoIRQ    move.w    LTCHB(a0),TBHI(a0) ;Zähler neu laden
  861.         btst    #3,CRB(a0)    ;One-Shot?
  862.         beq    CiaBTBDone
  863.         and.b    #$fe,CRB(a0)    ;Ja, Zähler stoppen
  864.         st.b    TBCNTPHI2(a0)
  865.         clr.b    TBCNTTA(a0)
  866.         bra    CiaBTBDone
  867.  
  868. CiaBTBDelay    subq.b    #1,TBCNTPHI2(a0) ;Verzögerung beim Starten des Timers
  869.         bra    CiaBTBDone
  870.  
  871. CiaBTBStop    cmp.b    #-1,TBCNTPHI2(a0)
  872.         beq    CiaBTBDone
  873.         addq.b    #1,TBCNTPHI2(a0) ;Verzögerung beim Stoppen des Timers
  874.         bra    CiaBTBCount
  875. CiaBTBDone
  876.  
  877. *
  878. * ICR zurückschreiben
  879. *
  880.  
  881.         move.b    d1,ICR(a0)
  882.  
  883. *
  884. * 6510-Zyklus ausführen und Zyklenzähler erhöhen
  885. *
  886.  
  887.         jsr    (a6)
  888.         addq.l    #1,CycleCounter
  889.         rts
  890.  
  891.  
  892. **
  893. ** TODs zählen
  894. **
  895.  
  896. *
  897. * CIA-A
  898. *
  899.  
  900. CountTODs    lea    Registers1,a0
  901.         subq.b    #1,TODDIV(a0)    ;Frequenzteiler herabzählen
  902.         bpl    CiaATODNop
  903.  
  904.         btst    #7,CRA(a0)    ;Untergelaufen,
  905.         beq    CiaATOD60Hz    ; je nach 50/60Hz-Flag neu laden
  906.         move.b    #4,TODDIV(a0)
  907.         bra    CiaATODLoaded
  908. CiaATOD60Hz    move.b    #5,TODDIV(a0)
  909.  
  910. CiaATODLoaded    move    #0,ccr        ;X löschen
  911.         move.b    #1,d0        ;1/10 Sekunden erhöhen
  912.         move.b    TOD10THS(a0),d1
  913.         abcd    d0,d1
  914.         move.b    d1,TOD10THS(a0)
  915.         cmp.b    #$10,d1        ;Über 10?
  916.         blo    CiaATODDone
  917.  
  918.         clr.b    TOD10THS(a0)    ;Ja, 1/10 Sekunden auf Null setzen
  919.         move    #0,ccr        ;und Sekunden erhöhen
  920.         move.b    #1,d0
  921.         move.b    TODSEC(a0),d1
  922.         abcd    d0,d1
  923.         move.b    d1,TODSEC(a0)
  924.         cmp.b    #$60,d1        ;Über 60?
  925.         blo    CiaATODDone
  926.  
  927.         clr.b    TODSEC(a0)    ;Ja, Sekunden auf Null setzen
  928.         move    #0,ccr        ;und Minuten erhöhen
  929.         move.b    #1,d0
  930.         move.b    TODMIN(a0),d1
  931.         abcd    d0,d1
  932.         move.b    d1,TODMIN(a0)
  933.         cmp.b    #$60,d1        ;Über 60?
  934.         blo    CiaATODDone
  935.  
  936.         clr.b    TODMIN(a0)    ;Ja, Minuten auf Null setzen
  937.         move    #0,ccr        ;und Stunden erhöhen
  938.         move.b    #1,d0
  939.         move.b    TODHR(a0),d1
  940.         and.b    #$1f,d1        ;AM/PM ausmaskieren
  941.         abcd    d0,d1
  942.         and.b    #$80,TODHR(a0)    ;Stunden schreiben, AM/PM lassen
  943.         or.b    d1,TODHR(a0)
  944.  
  945.         cmp.b    #$12,d1        ;Über 12?
  946.         blo    CiaATODDone
  947.  
  948.         and.b    #$80,TODHR(a0)    ;Ja, Stunden auf Null setzen
  949.         eor.b    #$80,TODHR(a0)    ;und AM/PM umdrehen
  950.  
  951. CiaATODDone    move.l    TOD10THS(a0),d0    ;Alarmzeit erreicht?
  952.         cmp.l    ALM10THS(a0),d0
  953.         bne    CiaATODNop
  954.         move.b    ICR(a0),d0    ;Ja, IRQ-Bit setzen
  955.         or.b    #$04,d0
  956.         btst    #2,INTMASK(a0)    ;IRQ freigegeben?
  957.         beq    CiaATODNoIRQ
  958.         or.b    #$80,d0        ;Ja, IR-Bit setzen
  959.         tst.w    IntIsIRQ    ;IRQ schon ausgelöst?
  960.         bne    1$
  961.         move.l    CycleCounter,FirstIRQCycle ;Nein, Zyklus merken
  962. 1$        st.b    IntIsCIAIRQ    ;und IRQ auslösen
  963. CiaATODNoIRQ    move.b    d0,ICR(a0)
  964. CiaATODNop
  965.  
  966. *
  967. * CIA-B
  968. *
  969.  
  970.         lea    Registers2,a0
  971.         subq.b    #1,TODDIV(a0)    ;Frequenzteiler herabzählen
  972.         bpl    CiaBTODNop
  973.  
  974.         btst    #7,CRA(a0)    ;Untergelaufen,
  975.         beq    CiaBTOD60Hz    ; je nach 50/60Hz-Flag neu laden
  976.         move.b    #4,TODDIV(a0)
  977.         bra    CiaBTODLoaded
  978. CiaBTOD60Hz    move.b    #5,TODDIV(a0)
  979.  
  980. CiaBTODLoaded    move    #0,ccr        ;X löschen
  981.         move.b    #1,d0        ;1/10 Sekunden erhöhen
  982.         move.b    TOD10THS(a0),d1
  983.         abcd    d0,d1
  984.         move.b    d1,TOD10THS(a0)
  985.         cmp.b    #$10,d1        ;Über 10?
  986.         blo    CiaBTODDone
  987.  
  988.         clr.b    TOD10THS(a0)    ;Ja, 1/10 Sekunden auf Null setzen
  989.         move    #0,ccr        ;und Sekunden erhöhen
  990.         move.b    #1,d0
  991.         move.b    TODSEC(a0),d1
  992.         abcd    d0,d1
  993.         move.b    d1,TODSEC(a0)
  994.         cmp.b    #$60,d1        ;Über 60?
  995.         blo    CiaBTODDone
  996.  
  997.         clr.b    TODSEC(a0)    ;Ja, Sekunden auf Null setzen
  998.         move    #0,ccr        ;und Minuten erhöhen
  999.         move.b    #1,d0
  1000.         move.b    TODMIN(a0),d1
  1001.         abcd    d0,d1
  1002.         move.b    d1,TODMIN(a0)
  1003.         cmp.b    #$60,d1        ;Über 60?
  1004.         blo    CiaBTODDone
  1005.  
  1006.         clr.b    TODMIN(a0)    ;Ja, Minuten auf Null setzen
  1007.         move    #0,ccr        ;und Stunden erhöhen
  1008.         move.b    #1,d0
  1009.         move.b    TODHR(a0),d1
  1010.         and.b    #$1f,d1        ;AM/PM ausmaskieren
  1011.         abcd    d0,d1
  1012.         and.b    #$80,TODHR(a0)    ;Stunden schreiben, AM/PM lassen
  1013.         or.b    d1,TODHR(a0)
  1014.  
  1015.         cmp.b    #$12,d1        ;Über 12?
  1016.         blo    CiaBTODDone
  1017.  
  1018.         and.b    #$80,TODHR(a0)    ;Ja, Stunden auf Null setzen
  1019.         eor.b    #$80,TODHR(a0)    ;und AM/PM umdrehen
  1020.  
  1021. CiaBTODDone    move.l    TOD10THS(a0),d0    ;Alarmzeit erreicht?
  1022.         cmp.l    ALM10THS(a0),d0
  1023.         bne    CiaBTODNop
  1024.         move.b    ICR(a0),d0    ;Ja, IRQ-Bit setzen
  1025.         or.b    #$04,d0
  1026.         btst    #2,INTMASK(a0)    ;IRQ freigegeben?
  1027.         beq    CiaBTODNoIRQ
  1028.         or.b    #$80,d0        ;Ja, IR-Bit setzen
  1029.         tst.b    NMIState    ;NMI schon ausgelöst?
  1030.         bne    1$
  1031.         move.l    CycleCounter,FirstNMICycle ;Nein, Zyklus merken
  1032.         st.b    NMIState    ;und NMI auslösen
  1033.         st.b    IntIsNMI
  1034. 1$
  1035. CiaBTODNoIRQ    move.b    d0,ICR(a0)
  1036. CiaBTODNop
  1037.  
  1038. *
  1039. * Joystickabfrage
  1040. *
  1041.  
  1042.         lea    Registers1,a0
  1043.  
  1044. ; Port 1
  1045.         move.b    #$ff,d2        ;Vorgabe: Joystick inaktiv
  1046.         tst.w    Joystick1On(pc)
  1047.         beq    15$
  1048.  
  1049.         btst    #6,$bfe001    ;Feuerknopf
  1050.         bne    11$
  1051.         bclr    #4,d2
  1052.  
  1053. 11$        move.w    $dff00a,d0
  1054.         btst    #1,d0        ;Rechts
  1055.         beq    12$
  1056.         bclr    #3,d2
  1057.  
  1058. 12$        btst    #9,d0        ;Links
  1059.         beq    13$
  1060.         bclr    #2,d2
  1061.  
  1062. 13$        move.w    d0,d1
  1063.         add.w    d0,d0
  1064.         eor.w    d1,d0
  1065.         btst    #1,d0        ;Runter
  1066.         beq    14$
  1067.         bclr    #1,d2
  1068.  
  1069. 14$        btst    #9,d0        ;Hoch
  1070.         beq    15$
  1071.         bclr    #0,d2
  1072.  
  1073. 15$        move.b    d2,Joystick1
  1074.  
  1075. ; Port 2
  1076.         move.b    Joystick2Key,d2    ;Vorgabe: Zehnerblock-Emulation
  1077.         tst.w    Joystick2On(pc)
  1078.         beq    25$
  1079.  
  1080.         btst    #7,$bfe001    ;Feuerknopf
  1081.         bne    21$
  1082.         bclr    #4,d2
  1083.  
  1084. 21$        move.w    $dff00c,d0
  1085.         btst    #1,d0        ;Rechts
  1086.         beq    22$
  1087.         bclr    #3,d2
  1088.  
  1089. 22$        btst    #9,d0        ;Links
  1090.         beq    23$
  1091.         bclr    #2,d2
  1092.  
  1093. 23$        move.w    d0,d1
  1094.         add.w    d0,d0
  1095.         eor.w    d1,d0
  1096.         btst    #1,d0        ;Runter
  1097.         beq    24$
  1098.         bclr    #1,d2
  1099.  
  1100. 24$        btst    #9,d0        ;Hoch
  1101.         beq    25$
  1102.         bclr    #0,d2
  1103.  
  1104. 25$        move.b    d2,Joystick2
  1105.  
  1106. ; Joysticks vertauschen?
  1107.         tst.w    JoystickSwap(pc)
  1108.         beq    30$
  1109.         move.b    Joystick1,d0
  1110.         move.b    Joystick2,Joystick1
  1111.         move.b    d0,Joystick2
  1112. 30$        rts
  1113.  
  1114.  
  1115. **
  1116. ** Taste wurde gedrückt
  1117. **
  1118.  
  1119.         FAR
  1120.  
  1121. KeyDown        MACRO
  1122.         bclr    #\1,\2(a0)
  1123.         bclr    #\2,\1(a1)
  1124.         ENDM
  1125.  
  1126. KeyUp        MACRO
  1127.         bset    #\1,\2(a0)
  1128.         bset    #\2,\1(a1)
  1129.         ENDM
  1130.  
  1131. _KeyPressed    move.l    4(sp),d0
  1132.         lea    KeyMatrix,a0
  1133.         lea    InvKeyMatrix,a1
  1134.  
  1135.         bclr    #7,d0                ;KeyUp/KeyDown
  1136.         bne    KeyUp
  1137.  
  1138.         cmp.b    #$40,d0
  1139.         bhs    KeyDownSpecial
  1140.         and.w    #$003f,d0            ;$00..$3f
  1141.  
  1142.         cmp.b    #$0f,d0                ;Joystick-Emulation
  1143.         beq    KeyDownJoyFire
  1144.         cmp.b    #$1d,d0
  1145.         beq    KeyDownJoyDL
  1146.         cmp.b    #$1e,d0
  1147.         beq    KeyDownJoyDown
  1148.         cmp.b    #$1f,d0
  1149.         beq    KeyDownJoyDR
  1150.         cmp.b    #$2d,d0
  1151.         beq    KeyDownJoyLeft
  1152.         cmp.b    #$2e,d0
  1153.         beq    KeyDownJoyFire
  1154.         cmp.b    #$2f,d0
  1155.         beq    KeyDownJoyRight
  1156.         cmp.b    #$3d,d0
  1157.         beq    KeyDownJoyUL
  1158.         cmp.b    #$3e,d0
  1159.         beq    KeyDownJoyUp
  1160.         cmp.b    #$3f,d0
  1161.         beq    KeyDownJoyUR
  1162.  
  1163.         movem.w    KeyTable(pc,d0.w*4),d0/d1
  1164.         bclr    d1,(a0,d0.w)
  1165.         bclr    d0,(a1,d1.w)
  1166.         rts
  1167.  
  1168. KeyUp        cmp.b    #$40,d0
  1169.         bhs    KeyUpSpecial
  1170.         and.w    #$003f,d0            ;$00..$3f
  1171.  
  1172.         cmp.b    #$0f,d0                ;Joystick-Emulation
  1173.         beq    KeyUpJoyFire
  1174.         cmp.b    #$1d,d0
  1175.         beq    KeyUpJoyDL
  1176.         cmp.b    #$1e,d0
  1177.         beq    KeyUpJoyDown
  1178.         cmp.b    #$1f,d0
  1179.         beq    KeyUpJoyDR
  1180.         cmp.b    #$2d,d0
  1181.         beq    KeyUpJoyLeft
  1182.         cmp.b    #$2e,d0
  1183.         beq    KeyUpJoyFire
  1184.         cmp.b    #$2f,d0
  1185.         beq    KeyUpJoyRight
  1186.         cmp.b    #$3d,d0
  1187.         beq    KeyUpJoyUL
  1188.         cmp.b    #$3e,d0
  1189.         beq    KeyUpJoyUp
  1190.         cmp.b    #$3f,d0
  1191.         beq    KeyUpJoyUR
  1192.  
  1193.         movem.w    KeyTable(pc,d0.w*4),d0/d1
  1194.         bset    d1,(a0,d0.w)
  1195.         bset    d0,(a1,d1.w)
  1196. KeyNOP        rts
  1197.  
  1198. KeyDownSpecial    sub.b    #$40,d0
  1199.         cmp.b    #$20,d0
  1200.         bhs    KeyDownMod
  1201.         and.w    #$1f,d0                ;$40..$5f
  1202.         jmp    ([KeyDownSpecTab,pc,d0.w*4])
  1203.  
  1204. KeyDownMod    sub.b    #$20,d0
  1205.         cmp.b    #$08,d0
  1206.         bhs    KeyNOP
  1207.         and.w    #$07,d0                ;$60..$67
  1208.         cmp.w    #$07,d0                ;Amiga rechts ignorieren
  1209.         beq    1$
  1210.         movem.w    KeyModTable(pc,d0.w*4),d0/d1
  1211.         bclr    d1,(a0,d0.w)
  1212.         bclr    d0,(a1,d1.w)
  1213. 1$        rts
  1214.  
  1215. KeyUpSpecial    sub.b    #$40,d0
  1216.         cmp.b    #$20,d0
  1217.         bhs    KeyUpMod
  1218.         and.w    #$1f,d0                ;$40..$5f
  1219.         jmp    ([KeyUpSpecTab,pc,d0.w*4])
  1220.  
  1221. KeyUpMod    sub.b    #$20,d0
  1222.         cmp.b    #$08,d0
  1223.         bhs    KeyNOP
  1224.         and.w    #$07,d0                ;$60..$67
  1225.         cmp.w    #$07,d0                ;Amiga rechts ignorieren
  1226.         beq    1$
  1227.         movem.w    KeyModTable(pc,d0.w*4),d0/d1
  1228.         bset    d1,(a0,d0.w)
  1229.         bset    d0,(a1,d1.w)
  1230. 1$        rts
  1231.  
  1232. KeySpaceD    KeyDown    4,7
  1233.         rts
  1234. KeySpaceU    KeyUp    4,7
  1235.         rts
  1236. KeyBackD    KeyDown    0,0
  1237.         rts
  1238. KeyBackU    KeyUp    0,0
  1239.         rts
  1240. KeyTabD        KeyDown    7,7
  1241.         tst.b    NMIState    ;NMI schon ausgelöst?
  1242.         bne    1$
  1243.         move.l    CycleCounter,FirstNMICycle ;Nein, Zyklus merken
  1244.         st.b    IntIsNMI    ; und NMI auslösen
  1245. 1$        rts
  1246. KeyTabU        KeyUp    7,7
  1247.         rts
  1248. KeyEnterD
  1249. KeyReturnD    KeyDown    1,0
  1250.         rts
  1251. KeyEnterU
  1252. KeyReturnU    KeyUp    1,0
  1253.         rts
  1254. KeyEscD        KeyDown    7,7
  1255.         rts
  1256. KeyEscU        KeyUp    7,7
  1257.         rts
  1258. KeyDeleteD    KeyDown    3,6
  1259.         rts
  1260. KeyDeleteU    KeyUp    3,6
  1261.         rts
  1262. KeyUpD        KeyDown    4,6
  1263.         KeyDown    7,0
  1264.         rts
  1265. KeyUpU        KeyUp    4,6
  1266.         KeyUp    7,0
  1267.         rts
  1268. KeyDownD    KeyDown    7,0
  1269.         rts
  1270. KeyDownU    KeyUp    7,0
  1271.         rts
  1272. KeyRightD    KeyDown    2,0
  1273.         rts
  1274. KeyRightU    KeyUp    2,0
  1275.         rts
  1276. KeyLeftD    KeyDown    4,6
  1277.         KeyDown    2,0
  1278.         rts
  1279. KeyLeftU    KeyUp    4,6
  1280.         KeyUp    2,0
  1281.         rts
  1282. KeyF1D        KeyDown    4,0
  1283.         rts
  1284. KeyF1U        KeyUp    4,0
  1285.         rts
  1286. KeyF3D        KeyDown    5,0
  1287.         rts
  1288. KeyF3U        KeyUp    5,0
  1289.         rts
  1290. KeyF5D        KeyDown    6,0
  1291.         rts
  1292. KeyF5U        KeyUp    6,0
  1293.         rts
  1294. KeyF7D        KeyDown    3,0
  1295.         rts
  1296. KeyF7U        KeyUp    3,0
  1297.         rts
  1298. KeyF2D        KeyDown    4,6
  1299.         KeyDown    4,0
  1300.         rts
  1301. KeyF2U        KeyUp    4,6
  1302.         KeyUp    4,0
  1303.         rts
  1304. KeyF4D        KeyDown    4,6
  1305.         KeyDOwn    5,0
  1306.         rts
  1307. KeyF4U        KeyUp    4,6
  1308.         KeyUp    5,0
  1309.         rts
  1310. KeyF6D        KeyDown    4,6
  1311.         KeyDown    6,0
  1312.         rts
  1313. KeyF6U        KeyUp    4,6
  1314.         KeyUp    6,0
  1315.         rts
  1316. KeyF8D        KeyDown    4,6
  1317.         KeyDown    3,0
  1318.         rts
  1319. KeyF8U        KeyUp    4,6
  1320.         KeyUp    3,0
  1321.         rts
  1322. KeyF9D        tst.b    NMIState    ;NMI schon ausgelöst?
  1323.         bne    1$
  1324.         move.l    CycleCounter,FirstNMICycle ;Nein, Zyklus merken
  1325.         st.b    IntIsNMI    ; und NMI auslösen
  1326. 1$        rts
  1327. KeyNKAsterD    tst.w    KeyboardYZ
  1328.         bne    1$
  1329.         KeyDown    1,6    ;*
  1330.         rts
  1331. 1$        KeyDown    5,6    ;=
  1332.         rts
  1333. KeyNKAsterU    tst.w    KeyboardYZ
  1334.         bne    1$
  1335.         KeyUp    1,6
  1336.         rts
  1337. 1$        KeyUp    5,6
  1338.         rts
  1339. KeyNKSlashD    tst.w    KeyboardYZ
  1340.         bne    1$
  1341.         KeyDown    7,6    ;/
  1342.         rts
  1343. 1$        KeyDown    6,6    ;^
  1344.         rts
  1345. KeyNKSlashU    tst.w    KeyboardYZ
  1346.         bne    1$
  1347.         KeyUp    7,6
  1348.         rts
  1349. 1$        KeyUp    6,6
  1350.         rts
  1351. KeyNKLeftParD    KeyDown    4,6    ;[
  1352.         KeyDown    5,5
  1353.         rts
  1354. KeyNKLeftParU    KeyUp    4,6
  1355.         KeyUp    5,5
  1356.         rts
  1357. KeyNKRightParD    KeyDown    4,6    ;]
  1358.         KeyDown    2,6
  1359.         rts
  1360. KeyNKRightParU    KeyUp    4,6
  1361.         KeyUp    2,6
  1362.         rts
  1363.  
  1364. ; Joystick-Emulation
  1365. KeyDownJoyUp    bclr    #0,Joystick2Key
  1366.         rts
  1367. KeyDownJoyDown    bclr    #1,Joystick2Key
  1368.         rts
  1369. KeyDownJoyLeft    bclr    #2,Joystick2Key
  1370.         rts
  1371. KeyDownJoyRight    bclr    #3,Joystick2Key
  1372.         rts
  1373. KeyDownJoyUL    bclr    #0,Joystick2Key
  1374.         bclr    #2,Joystick2Key
  1375.         rts
  1376. KeyDownJoyUR    bclr    #0,Joystick2Key
  1377.         bclr    #3,Joystick2Key
  1378.         rts
  1379. KeyDownJoyDL    bclr    #1,Joystick2Key
  1380.         bclr    #2,Joystick2Key
  1381.         rts
  1382. KeyDownJoyDR    bclr    #1,Joystick2Key
  1383.         bclr    #3,Joystick2Key
  1384.         rts
  1385. KeyDownJoyFire    bclr    #4,Joystick2Key
  1386.         rts
  1387.  
  1388. KeyUpJoyUp    bset    #0,Joystick2Key
  1389.         rts
  1390. KeyUpJoyDown    bset    #1,Joystick2Key
  1391.         rts
  1392. KeyUpJoyLeft    bset    #2,Joystick2Key
  1393.         rts
  1394. KeyUpJoyRight    bset    #3,Joystick2Key
  1395.         rts
  1396. KeyUpJoyUL    bset    #0,Joystick2Key
  1397.         bset    #2,Joystick2Key
  1398.         rts
  1399. KeyUpJoyUR    bset    #0,Joystick2Key
  1400.         bset    #3,Joystick2Key
  1401.         rts
  1402. KeyUpJoyDL    bset    #1,Joystick2Key
  1403.         bset    #2,Joystick2Key
  1404.         rts
  1405. KeyUpJoyDR    bset    #1,Joystick2Key
  1406.         bset    #3,Joystick2Key
  1407.         rts
  1408. KeyUpJoyFire    bset    #4,Joystick2Key
  1409.         rts
  1410.  
  1411.  
  1412. **
  1413. ** Datenbereich
  1414. **
  1415.  
  1416.         CNOP    0,4
  1417. Registers1    ds.b    32    ;CIA-A-Register
  1418. Registers2    ds.b    32    ;CIA-B-Register
  1419.  
  1420. ; Prefs
  1421. CIACycles    dc.w    0    ;Unbenutzt
  1422. Joystick1On    dc.w    0    ;Joystick an Port 1 wird abgefragt
  1423. Joystick2On    dc.w    0    ;Joystick an Port 2 wird abgefragt
  1424.         XDEF    _JoystickSwap
  1425. _JoystickSwap
  1426. JoystickSwap    dc.w    0    ;Joysticks vertauschen
  1427. KeyboardYZ    dc.w    0    ;Amerikanische Tastaturbelegung
  1428.  
  1429. Joystick1    dc.b    0    ;Joystick 1 AND-Wert
  1430. Joystick2    dc.b    0    ;Joystick 2 AND-Wert
  1431. Joystick2Key    dc.b    0    ;Joystick 2 AND-Wert für Emulation über Zehnerblock
  1432.  
  1433. ; Tastaturübersetzungstabelle:
  1434. ; Für jeden Amiga-RawKey Spalte und Zeile in der KeyMatrix
  1435.         CNOP    0,4
  1436. KeyTable    dc.w    7,1    ;` -> <-
  1437.         dc.w    7,0    ;1
  1438.         dc.w    7,3    ;2
  1439.         dc.w    1,0    ;3
  1440.         dc.w    1,3    ;4
  1441.         dc.w    2,0    ;5
  1442.         dc.w    2,3    ;6
  1443.         dc.w    3,0    ;7
  1444.         dc.w    3,3    ;8
  1445.         dc.w    4,0    ;9
  1446.         dc.w    4,3    ;0
  1447.         dc.w    5,0    ;ß -> +
  1448.         dc.w    5,3    ;´ -> -
  1449.         dc.w    6,0    ;\ -> £
  1450.         dc.w    0,0
  1451.         dc.w    4,3    ;NP 0
  1452.  
  1453.         dc.w    7,6    ;Q
  1454.         dc.w    1,1    ;W
  1455.         dc.w    1,6    ;E
  1456.         dc.w    2,1    ;R
  1457.         dc.w    2,6    ;T
  1458. KeyPatch1    dc.w    1,4    ;Y -> Z
  1459.         dc.w    3,6    ;U
  1460.         dc.w    4,1    ;I
  1461.         dc.w    4,6    ;O
  1462.         dc.w    5,1    ;P
  1463.         dc.w    5,6    ;ü -> @
  1464.         dc.w    6,1    ;+ -> *
  1465.         dc.w    0,0
  1466.         dc.w    7,0    ;NP 1
  1467.         dc.w    7,3    ;NP 2
  1468.         dc.w    1,0    ;NP 3
  1469.  
  1470.         dc.w    1,2    ;A
  1471.         dc.w    1,5    ;S
  1472.         dc.w    2,2    ;D
  1473.         dc.w    2,5    ;F
  1474.         dc.w    3,2    ;G
  1475.         dc.w    3,5    ;H
  1476.         dc.w    4,2    ;J
  1477.         dc.w    4,5    ;K
  1478.         dc.w    5,2    ;L
  1479.         dc.w    5,5    ;ö -> :
  1480.         dc.w    6,2    ;ä -> ;
  1481.         dc.w    6,5    ;# -> =
  1482.         dc.w    0,0
  1483.         dc.w    1,3    ;NP 4
  1484.         dc.w    2,0    ;NP 5
  1485.         dc.w    2,3    ;NP 6
  1486.  
  1487.         dc.w    6,6    ;< -> ^
  1488. KeyPatch2    dc.w    3,1    ;Z -> Y
  1489.         dc.w    2,7    ;X
  1490.         dc.w    2,4    ;C
  1491.         dc.w    3,7    ;V
  1492.         dc.w    3,4    ;B
  1493.         dc.w    4,7    ;N
  1494.         dc.w    4,4    ;M
  1495.         dc.w    5,7    ;,
  1496.         dc.w    5,4    ;.
  1497.         dc.w    6,7    ;- -> /
  1498.         dc.w    0,0
  1499.         dc.w    5,4    ;NP .
  1500.         dc.w    3,0    ;NP 7
  1501.         dc.w    3,3    ;NP 8
  1502.         dc.w    4,0    ;NP 9
  1503.  
  1504. KeyDownSpecTab    dc.l    KeySpaceD
  1505.         dc.l    KeyBackD
  1506.         dc.l    KeyTabD
  1507.         dc.l    KeyEnterD
  1508.         dc.l    KeyReturnD
  1509.         dc.l    KeyEscD
  1510.         dc.l    KeyDeleteD
  1511.         dc.l    KeyNOP
  1512.  
  1513.         dc.l    KeyNOP
  1514.         dc.l    KeyNOP
  1515.         dc.l    KeyNOP
  1516.         dc.l    KeyNOP
  1517.         dc.l    KeyUpD
  1518.         dc.l    KeyDownD
  1519.         dc.l    KeyRightD
  1520.         dc.l    KeyLeftD
  1521.  
  1522.         dc.l    KeyF1D
  1523.         dc.l    KeyF2D
  1524.         dc.l    KeyF3D
  1525.         dc.l    KeyF4D
  1526.         dc.l    KeyF5D
  1527.         dc.l    KeyF6D
  1528.         dc.l    KeyF7D
  1529.         dc.l    KeyF8D
  1530.  
  1531.         dc.l    KeyF9D
  1532.         dc.l    KeyNOP
  1533.         dc.l    KeyNKLeftParD
  1534.         dc.l    KeyNKRightParD
  1535.         dc.l    KeyNKSlashD
  1536.         dc.l    KeyNKAsterD
  1537.         dc.l    KeyNOP
  1538.         dc.l    KeyNOP
  1539.  
  1540. KeyUpSpecTab    dc.l    KeySpaceU
  1541.         dc.l    KeyBackU
  1542.         dc.l    KeyTabU
  1543.         dc.l    KeyEnterU
  1544.         dc.l    KeyReturnU
  1545.         dc.l    KeyEscU
  1546.         dc.l    KeyDeleteU
  1547.         dc.l    KeyNOP
  1548.  
  1549.         dc.l    KeyNOP
  1550.         dc.l    KeyNOP
  1551.         dc.l    KeyNOP
  1552.         dc.l    KeyNOP
  1553.         dc.l    KeyUpU
  1554.         dc.l    KeyDownU
  1555.         dc.l    KeyRightU
  1556.         dc.l    KeyLeftU
  1557.  
  1558.         dc.l    KeyF1U
  1559.         dc.l    KeyF2U
  1560.         dc.l    KeyF3U
  1561.         dc.l    KeyF4U
  1562.         dc.l    KeyF5U
  1563.         dc.l    KeyF6U
  1564.         dc.l    KeyF7U
  1565.         dc.l    KeyF8U
  1566.  
  1567.         dc.l    KeyNOP
  1568.         dc.l    KeyNOP
  1569.         dc.l    KeyNKLeftParU
  1570.         dc.l    KeyNKRightParU
  1571.         dc.l    KeyNKSlashU
  1572.         dc.l    KeyNKAsterU
  1573.         dc.l    KeyNOP
  1574.         dc.l    KeyNOP
  1575.  
  1576. KeyModTable    dc.w    1,7        ;Shift left
  1577.         dc.w    6,4        ;Shift right
  1578.         dc.w    1,7        ;Caps lock -> Shift left
  1579.         dc.w    7,2        ;Control
  1580.         dc.w    7,5        ;Alt left -> C=
  1581.         dc.w    7,5        ;Alt right -> C=
  1582.         dc.w    7,5        ;Amiga left -> C=
  1583.         dc.w    0,0        ;Amiga right
  1584.  
  1585. ; Bit  7   6   5   4   3   2   1   0
  1586. ; 0   CUD  F5  F3  F1  F7 CLR RET DEL
  1587. ; 1   SHL  E   S   Z   4   A   W   3
  1588. ; 2    X   T   F   C   6   D   R   5
  1589. ; 3    V   U   H   B   8   G   Y   7
  1590. ; 4    N   O   K   M   0   J   I   9
  1591. ; 5    ,   @   :   .   -   L   P   +
  1592. ; 6    /   ^   =  SHR HOM  ;   *   £
  1593. ; 7   R/S  Q   C= SPC  2  CTL  <-  1
  1594.  
  1595. KeyMatrix    ds.b    8    ;C64-Tastaturmatrix pro Taste ein Bit
  1596.                 ;0: Taste gedrückt
  1597. InvKeyMatrix    ds.b    8    ;Gespiegelte Tastaturmatrix
  1598.  
  1599.         END
  1600.