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