home *** CD-ROM | disk | FTP | other *** search
/ Brotikasten / BROTCD01.iso / amiga / frodov13.lha / src / 6526.asm < prev    next >
Assembly Source File  |  1995-02-06  |  23KB  |  1,229 lines

  1. *
  2. * 6526.asm - CIA-Emulation
  3. *
  4. * Copyright (C) 1994-1995 by Christian Bauer
  5. *
  6.  
  7. *
  8. * Anmerkungen:
  9. * ------------
  10. *
  11. * Funktionsweise/Periodic:
  12. *  - Fⁿr jede (simulierte) C64-Rasterzeile wird vom 6510-Task die Routine
  13. *    Periodic6526 aufgerufen, die die Timer herunterzΣhlt, ggf. Interrupts
  14. *    ausl÷st und die Joysticks abfragt
  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. * Tastaturabfrage:
  26. *  - Das Feld KeyMatrix enthΣlt fⁿr jede Taste entsprechend der C64-
  27. *    Tastaturmatrix ein Bit (0: Taste gedrⁿckt, 1: Taste nicht gedrⁿckt)
  28. *  - Bei Lesezugriffen aus CIA-A, Port B werden entsprechend der aktiven
  29. *    (ausgewΣhlten) Zeilen der Tastatur die entsprechenden Bits aus der
  30. *    Tastaturmatrix zusammengestellt
  31. *  - Die Help-Taste l÷st einen NMI aus (Restore), F10 einen RESET,
  32. *    ⁿber F9 wird das Einstellungs-Fenster aufgerufen
  33. *
  34. * InkompatibilitΣten:
  35. *  - Die TOD-Clock sollte bei einem Lesezugriff nicht angehalten,
  36. *    sondern gelatcht werden
  37. *
  38.  
  39.         MACHINE    68020
  40.  
  41.         XREF    ShowPrefs    ;Main.asm
  42.  
  43.         XREF    _ciaaprb
  44.         XREF    _ciaaddrb
  45.  
  46.         XREF    IntIsRESET    ;6510.asm
  47.         XREF    IntIsNMI
  48.         XREF    IntIsCIAIRQ
  49.         XREF    Peri6526Cont
  50.  
  51.         XREF    ChangedVA    ;6569.asm
  52.  
  53.         XREF    Reset6581    ;6581.asm
  54.  
  55.         XREF    IECIsOpen    ;1541.asm
  56.  
  57.         XDEF    Reset6526
  58.         XDEF    ReadFrom6526A
  59.         XDEF    ReadFrom6526B
  60.         XDEF    WriteTo6526A
  61.         XDEF    WriteTo6526B
  62.         XDEF    Periodic6526
  63.         XDEF    ChangedKeys
  64.         XDEF    CountTODs
  65.         XDEF    KeyPressed
  66.  
  67.         XDEF    CIACycles    ;Prefs
  68.         XDEF    Joystick1On
  69.         XDEF    Joystick2On
  70.         XDEF    JoystickSwap
  71.         XDEF    KeyboardYZ
  72.  
  73.         SECTION    "CODE",CODE
  74.  
  75. **
  76. ** Definitionen
  77. **
  78.  
  79. ; CIA-Register
  80. PRA        = 0
  81. PRB        = 1
  82. DDRA        = 2
  83. DDRB        = 3
  84. TAHI        = 4    ;Timer-Wert A
  85. TALO        = 5    ;Achtung: Umgekehrte Bytefolge!
  86. TBHI        = 6    ;Timer-Wert B
  87. TBLO        = 7
  88. TOD10THS    = 8
  89. TODSEC        = 9
  90. TODMIN        = 10
  91. TODHR        = 11
  92. SDR        = 12
  93. ICR        = 13    ;Interrupt-Data
  94. CRA        = 14
  95. CRB        = 15
  96.  
  97. ; ZusΣtzliche Register
  98. LTCHA        = 16    ;Timer-Latch A
  99. LTCHB        = 18    ;Timer-Latch B
  100. INTMASK        = 20    ;Interrupt-Enable
  101. TODHALT        = 21    ;TOD zwecks Beschreiben/Auslesen gestoppt
  102. ALM10THS    = 22    ;Alarmzeit
  103. ALMSEC        = 23
  104. ALMMIN        = 24
  105. ALMHR        = 25
  106. TODDIV        = 26    ;TOD-Frequenzteiler
  107. TACNTPHI2    = 27    ;Timer A lΣuft und zΣhlt Phi2
  108. TBCNTPHI2    = 28    ;Timer B lΣuft und zΣhlt Phi2
  109. TBCNTTA        = 29    ;Timer B lΣuft und zΣhlt UnterlΣufe von Timer A
  110. JOY1        = 30    ;Joystick 1 AND-Wert (nur CIA-A)
  111. JOY2        = 31    ;Joystick 2 AND-Wert (nur CIA-A)
  112.  
  113.  
  114. **
  115. ** CIAs zurⁿcksetzen
  116. **
  117.  
  118. ; CIA-A
  119. Reset6526    lea    Registers1,a0
  120.         clr.l    (a0)
  121.         clr.l    4(a0)
  122.         clr.l    8(a0)
  123.         clr.l    12(a0)
  124.         move.w    #-1,TAHI(a0)        ;Timer auf -1
  125.         move.w    #-1,TBHI(a0)
  126.  
  127.         move.w    #$0001,LTCHA(a0)    ;Latches auf 1
  128.         move.w    #$0001,LTCHB(a0)
  129.         clr.b    INTMASK(a0)        ;Interrupts abschalten
  130.         clr.b    TODHALT(a0)        ;TOD lΣuft
  131.         clr.l    ALM10THS(a0)        ;Alarmzeit auf 00:00:00.0
  132.         clr.w    TACNTPHI2(a0)        ;Beide Timer anhalten
  133.         move.b    #$ff,JOY1(a0)        ;Joystick inaktiv
  134.         move.b    #$ff,JOY2(a0)
  135.  
  136. ; CIA-B
  137.         lea    Registers2,a0
  138.         clr.l    (a0)
  139.         clr.l    4(a0)
  140.         clr.l    8(a0)
  141.         clr.l    12(a0)
  142.         move.w    #-1,TAHI(a0)        ;Timer auf -1
  143.         move.w    #-1,TBHI(a0)
  144.  
  145.         move.w    #$0001,LTCHA(a0)    ;Latches auf 1
  146.         move.w    #$0001,LTCHB(a0)
  147.         clr.b    INTMASK(a0)        ;Interrupts abschalten
  148.         clr.b    TODHALT(a0)        ;TOD lΣuft
  149.         clr.l    ALM10THS(a0)        ;Alarmzeit auf 00:00:00.0
  150.         clr.w    TACNTPHI2(a0)        ;Beide Timer anhalten
  151.  
  152. ; Tastaturmatrix l÷schen
  153.         moveq    #-1,d0
  154.         move.l    d0,KeyMatrix
  155.         move.l    d0,KeyMatrix+4
  156.  
  157. ; VIC-Bank 0 einstellen
  158.         moveq    #0,d0
  159.         bra    ChangedVA
  160.  
  161.  
  162. **
  163. ** Tastaturbelegung geΣndert, Y und Z sortieren
  164. **
  165.  
  166. ChangedKeys    tst.w    KeyboardYZ
  167.         bne    1$
  168.         move.l    #$00010004,KeyPatch1
  169.         move.l    #$00030001,KeyPatch2
  170.         rts
  171. 1$        move.l    #$00030001,KeyPatch1
  172.         move.l    #$00010004,KeyPatch2
  173.         rts
  174.  
  175.  
  176. **
  177. ** In ein CIA-A-Register schreiben
  178. ** d0.w: Registernummer ($00-$0f)
  179. ** d1.b: Byte
  180. **
  181. ** Darf das obere Wort von d0 und d1 nicht verΣndern!
  182. **
  183.  
  184. WriteTo6526A    lea    Registers1,a0
  185.         move.l    WriteTabA(pc,d0.w*4),a1
  186.         jmp    (a1)
  187.  
  188.         CNOP    0,4
  189. WriteTabA    dc.l    WrNormal
  190.         dc.l    WrNormal
  191.         dc.l    WrNormal
  192.         dc.l    WrNormal
  193.         dc.l    WrTALO
  194.         dc.l    WrTAHI
  195.         dc.l    WrTBLO
  196.         dc.l    WrTBHI
  197.         dc.l    WrTOD10THS
  198.         dc.l    WrTODSEC
  199.         dc.l    WrTODMIN
  200.         dc.l    WrTODHR
  201.         dc.l    WrNormal
  202.         dc.l    WrICR
  203.         dc.l    WrCRA
  204.         dc.l    WrCRB
  205.  
  206. WrNormal    move.b    d1,(a0,d0.w)
  207.         rts
  208.  
  209. WrTALO        move.b    d1,LTCHA+1(a0)
  210.         rts
  211.  
  212. WrTAHI        move.b    d1,LTCHA(a0)
  213.         btst    #0,CRA(a0)        ;Timer A gestoppt?
  214.         bne    1$
  215.         move.w    LTCHA(a0),TAHI(a0)    ;Ja, Timer laden
  216. 1$        rts
  217.  
  218. WrTBLO        move.b    d1,LTCHB+1(a0)
  219.         rts
  220.  
  221. WrTBHI        move.b    d1,LTCHB(a0)
  222.         btst    #0,CRB(a0)        ;Timer B gestoppt?
  223.         bne    1$
  224.         move.w    LTCHB(a0),TBHI(a0)    ;Ja, Timer laden
  225. 1$        rts
  226.  
  227. WrTOD10THS    and.b    #$0f,d1
  228.         clr.b    TODHALT(a0)    ;TOD weiterlaufen lassen
  229.         btst    #7,CRB(a0)    ;Alarm-Zeit schreiben?
  230.         bne    1$
  231.         move.b    d1,TOD10THS(a0)
  232.         rts
  233. 1$        move.b    d1,ALM10THS(a0)
  234.         rts
  235.  
  236. WrTODSEC    and.b    #$7f,d1
  237.         btst    #7,CRB(a0)    ;Alarm-Zeit schreiben?
  238.         bne    1$
  239.         move.b    d1,TODSEC(a0)
  240.         rts
  241. 1$        move.b    d1,ALMSEC(a0)
  242.         rts
  243.  
  244. WrTODMIN    and.b    #$7f,d1
  245.         btst    #7,CRB(a0)    ;Alarm-Zeit schreiben?
  246.         bne    1$
  247.         move.b    d1,TODMIN(a0)
  248.         rts
  249. 1$        move.b    d1,ALMMIN(a0)
  250.         rts
  251.  
  252. WrTODHR        and.b    #$9f,d1
  253.         st.b    TODHALT(a0)    ;TOD anhalten
  254.         btst    #7,CRB(a0)    ;Alarm-Zeit schreiben?
  255.         bne    1$
  256.         move.b    d1,TODHR(a0)
  257.         rts
  258. 1$        move.b    d1,ALMHR(a0)
  259.         rts
  260.  
  261. WrICR        bclr    #7,d1            ;S/C-Bit l÷schen
  262.         bne    1$            ;War es gesetzt?
  263.         not.b    d1            ;Nein, Bits zum L÷schen negieren
  264.         and.b    d1,INTMASK(a0)        ;Und Bits l÷schen
  265.         bra    2$
  266. 1$        or.b    d1,INTMASK(a0)        ;Bits setzen
  267. 2$        rts
  268.  
  269. WrCRA        btst    #4,d1            ;Force load?
  270.         beq    1$
  271.         and.b    #$ef,d1
  272.         move.w    LTCHA(a0),TAHI(a0)    ;Ja, Timer laden
  273. 1$        move.b    d1,CRA(a0)
  274.  
  275.         and.b    #$21,d1            ;LΣuft der Timer und zΣhlt er Phi2?
  276.         cmp.b    #$01,d1
  277.         seq.b    TACNTPHI2(a0)        ;Ja, Flag setzen
  278.         rts
  279.  
  280. WrCRB        btst    #4,d1            ;Force load?
  281.         beq    1$
  282.         and.b    #$ef,d1
  283.         move.w    LTCHB(a0),TBHI(a0)    ;Ja, Timer laden
  284. 1$        move.b    d1,CRB(a0)
  285.  
  286.         and.b    #$61,d1            ;LΣuft der Timer und zΣhlt er Phi2?
  287.         cmp.b    #$01,d1
  288.         seq.b    TBCNTPHI2(a0)        ;Ja, Flag setzen
  289.         cmp.b    #$41,d1            ;LΣuft er und zΣhlt UnterlΣuft von Timer A?
  290.         seq.b    TBCNTTA(a0)        ;Ja, Flag setzen
  291.         rts
  292.  
  293.  
  294. **
  295. ** In ein CIA-B-Register schreiben
  296. ** d0.w: Registernummer ($00-$0f)
  297. ** d1.b: Byte
  298. **
  299. ** Darf das obere Wort von d0 und d1 nicht verΣndern!
  300. **
  301.  
  302. WriteTo6526B    lea    Registers2,a0
  303.         move.l    WriteTabB(pc,d0.w*4),a1
  304.         jmp    (a1)
  305.  
  306.         CNOP    0,4
  307. WriteTabB    dc.l    WrBPRA
  308.         dc.l    WrNormal
  309.         dc.l    WrBDDRA
  310.         dc.l    WrNormal
  311.         dc.l    WrTALO
  312.         dc.l    WrTAHI
  313.         dc.l    WrTBLO
  314.         dc.l    WrTBHI
  315.         dc.l    WrTOD10THS
  316.         dc.l    WrTODSEC
  317.         dc.l    WrTODMIN
  318.         dc.l    WrTODHR
  319.         dc.l    WrNormal
  320.         dc.l    WrICR
  321.         dc.l    WrCRA
  322.         dc.l    WrCRB
  323.  
  324. WrBPRA        move.b    d1,PRA(a0)        ;Floppy/VA
  325.         tst.b    IECIsOpen        ;Wenn IEC aktiv ist, Port setzen
  326.         beq    WrBNewVA
  327.         move.b    d1,_ciaaprb
  328.         bra    WrBNewVA
  329.  
  330. WrBDDRA        move.b    d1,DDRA(a0)        ;Floppy/VA
  331.         tst.b    IECIsOpen        ;Wenn IEC aktiv ist, DDR setzen
  332.         beq    WrBNewVA
  333.         move.b    d1,_ciaaddrb
  334. WrBNewVA    move.b    DDRA(a0),d0        ;VA extrahieren
  335.         not.b    d0
  336.         or.b    PRA(a0),d0
  337.         not.b    d0
  338.         and.b    #$03,d0
  339.         bra    ChangedVA        ;Und dem VIC mitteilen
  340.  
  341.  
  342. **
  343. ** Aus einem CIA-A-Register lesen
  344. ** d0.w: Registernummer ($00-$0f)
  345. ** Rⁿckgabe: d0.b: Byte
  346. **
  347. ** Darf das obere Wort von d0 und d1 nicht verΣndern!
  348. ** Darf a1 nicht verΣndern!
  349. **
  350.  
  351. ReadFrom6526A    move.l    ReadTabA(pc,d0.w*4),a0
  352.         jmp    (a0)
  353.  
  354.         CNOP    0,4
  355. ReadTabA    dc.l    RdAPRA
  356.         dc.l    RdAPRB
  357.         dc.l    RdANormal
  358.         dc.l    RdANormal
  359.         dc.l    RdATALO
  360.         dc.l    RdATAHI
  361.         dc.l    RdATBLO
  362.         dc.l    RdATBHI
  363.         dc.l    RdATOD10THS
  364.         dc.l    RdANormal
  365.         dc.l    RdANormal
  366.         dc.l    RdATODHR
  367.         dc.l    RdANormal
  368.         dc.l    RdAICR
  369.         dc.l    RdANormal
  370.         dc.l    RdANormal
  371.  
  372. RdANormal    lea    Registers1,a0
  373.         move.b    (a0,d0.w),d0
  374.         rts
  375.  
  376. RdAPRA        lea    Registers1,a0
  377.         move.b    DDRA(a0),d0
  378.         not.b    d0
  379.         or.b    PRA(a0),d0
  380.         and.b    JOY2(a0),d0
  381.         rts
  382.  
  383. RdAPRB        move.l    a1,-(sp)
  384.         lea    Registers1,a0
  385.         lea    KeyMatrix,a1
  386.         move.b    PRA(a0),d1    ;Tastaturabfrage
  387.         move.b    #$ff,d0        ;Alle aktiven Reihen dazuANDen
  388.         lsr.b    #1,d1
  389.         bcs    1$
  390.         and.b    (a1),d0
  391. 1$        lsr.b    #1,d1
  392.         bcs    2$
  393.         and.b    1(a1),d0
  394. 2$        lsr.b    #1,d1
  395.         bcs    3$
  396.         and.b    2(a1),d0
  397. 3$        lsr.b    #1,d1
  398.         bcs    4$
  399.         and.b    3(a1),d0
  400. 4$        lsr.b    #1,d1
  401.         bcs    5$
  402.         and.b    4(a1),d0
  403. 5$        lsr.b    #1,d1
  404.         bcs    6$
  405.         and.b    5(a1),d0
  406. 6$        lsr.b    #1,d1
  407.         bcs    7$
  408.         and.b    6(a1),d0
  409. 7$        lsr.b    #1,d1
  410.         bcs    8$
  411.         and.b    7(a1),d0
  412.  
  413. 8$        and.b    JOY1(a0),d0
  414.         move.b    DDRB(a0),d1
  415.         not.b    d1
  416.         or.b    PRB(a0),d1
  417.         and.b    d1,d