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