home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Brotikasten
/
BROTCD01.iso
/
amiga
/
frodov13.lha
/
src
/
6526.asm
< prev
next >
Wrap
Assembly Source File
|
1995-02-06
|
23KB
|
1,229 lines
*
* 6526.asm - CIA-Emulation
*
* Copyright (C) 1994-1995 by Christian Bauer
*
*
* Anmerkungen:
* ------------
*
* Funktionsweise/Periodic:
* - Fⁿr jede (simulierte) C64-Rasterzeile wird vom 6510-Task die Routine
* Periodic6526 aufgerufen, die die Timer herunterzΣhlt, ggf. Interrupts
* ausl÷st und die Joysticks abfragt
*
* Timer/Latches:
* - Die Bytefolge im Register-File ist gegenⁿber dem echten 6526 umgekehrt,
* das wird aber bei den WriteTo6526- und ReadFrom6526-Routinen wieder
* ausgeglichen
*
* TOD-Clocks:
* - Die TODs werden synchron mit dem VBlank gezΣhlt. Es wird also ein
* 50Hz-Eingangssignal simuliert.
*
* Tastaturabfrage:
* - Das Feld KeyMatrix enthΣlt fⁿr jede Taste entsprechend der C64-
* Tastaturmatrix ein Bit (0: Taste gedrⁿckt, 1: Taste nicht gedrⁿckt)
* - Bei Lesezugriffen aus CIA-A, Port B werden entsprechend der aktiven
* (ausgewΣhlten) Zeilen der Tastatur die entsprechenden Bits aus der
* Tastaturmatrix zusammengestellt
* - Die Help-Taste l÷st einen NMI aus (Restore), F10 einen RESET,
* ⁿber F9 wird das Einstellungs-Fenster aufgerufen
*
* InkompatibilitΣten:
* - Die TOD-Clock sollte bei einem Lesezugriff nicht angehalten,
* sondern gelatcht werden
*
MACHINE 68020
XREF ShowPrefs ;Main.asm
XREF _ciaaprb
XREF _ciaaddrb
XREF IntIsRESET ;6510.asm
XREF IntIsNMI
XREF IntIsCIAIRQ
XREF Peri6526Cont
XREF ChangedVA ;6569.asm
XREF Reset6581 ;6581.asm
XREF IECIsOpen ;1541.asm
XDEF Reset6526
XDEF ReadFrom6526A
XDEF ReadFrom6526B
XDEF WriteTo6526A
XDEF WriteTo6526B
XDEF Periodic6526
XDEF ChangedKeys
XDEF CountTODs
XDEF KeyPressed
XDEF CIACycles ;Prefs
XDEF Joystick1On
XDEF Joystick2On
XDEF JoystickSwap
XDEF KeyboardYZ
SECTION "CODE",CODE
**
** Definitionen
**
; CIA-Register
PRA = 0
PRB = 1
DDRA = 2
DDRB = 3
TAHI = 4 ;Timer-Wert A
TALO = 5 ;Achtung: Umgekehrte Bytefolge!
TBHI = 6 ;Timer-Wert B
TBLO = 7
TOD10THS = 8
TODSEC = 9
TODMIN = 10
TODHR = 11
SDR = 12
ICR = 13 ;Interrupt-Data
CRA = 14
CRB = 15
; ZusΣtzliche Register
LTCHA = 16 ;Timer-Latch A
LTCHB = 18 ;Timer-Latch B
INTMASK = 20 ;Interrupt-Enable
TODHALT = 21 ;TOD zwecks Beschreiben/Auslesen gestoppt
ALM10THS = 22 ;Alarmzeit
ALMSEC = 23
ALMMIN = 24
ALMHR = 25
TODDIV = 26 ;TOD-Frequenzteiler
TACNTPHI2 = 27 ;Timer A lΣuft und zΣhlt Phi2
TBCNTPHI2 = 28 ;Timer B lΣuft und zΣhlt Phi2
TBCNTTA = 29 ;Timer B lΣuft und zΣhlt UnterlΣufe von Timer A
JOY1 = 30 ;Joystick 1 AND-Wert (nur CIA-A)
JOY2 = 31 ;Joystick 2 AND-Wert (nur CIA-A)
**
** CIAs zurⁿcksetzen
**
; CIA-A
Reset6526 lea Registers1,a0
clr.l (a0)
clr.l 4(a0)
clr.l 8(a0)
clr.l 12(a0)
move.w #-1,TAHI(a0) ;Timer auf -1
move.w #-1,TBHI(a0)
move.w #$0001,LTCHA(a0) ;Latches auf 1
move.w #$0001,LTCHB(a0)
clr.b INTMASK(a0) ;Interrupts abschalten
clr.b TODHALT(a0) ;TOD lΣuft
clr.l ALM10THS(a0) ;Alarmzeit auf 00:00:00.0
clr.w TACNTPHI2(a0) ;Beide Timer anhalten
move.b #$ff,JOY1(a0) ;Joystick inaktiv
move.b #$ff,JOY2(a0)
; CIA-B
lea Registers2,a0
clr.l (a0)
clr.l 4(a0)
clr.l 8(a0)
clr.l 12(a0)
move.w #-1,TAHI(a0) ;Timer auf -1
move.w #-1,TBHI(a0)
move.w #$0001,LTCHA(a0) ;Latches auf 1
move.w #$0001,LTCHB(a0)
clr.b INTMASK(a0) ;Interrupts abschalten
clr.b TODHALT(a0) ;TOD lΣuft
clr.l ALM10THS(a0) ;Alarmzeit auf 00:00:00.0
clr.w TACNTPHI2(a0) ;Beide Timer anhalten
; Tastaturmatrix l÷schen
moveq #-1,d0
move.l d0,KeyMatrix
move.l d0,KeyMatrix+4
; VIC-Bank 0 einstellen
moveq #0,d0
bra ChangedVA
**
** Tastaturbelegung geΣndert, Y und Z sortieren
**
ChangedKeys tst.w KeyboardYZ
bne 1$
move.l #$00010004,KeyPatch1
move.l #$00030001,KeyPatch2
rts
1$ move.l #$00030001,KeyPatch1
move.l #$00010004,KeyPatch2
rts
**
** In ein CIA-A-Register schreiben
** d0.w: Registernummer ($00-$0f)
** d1.b: Byte
**
** Darf das obere Wort von d0 und d1 nicht verΣndern!
**
WriteTo6526A lea Registers1,a0
move.l WriteTabA(pc,d0.w*4),a1
jmp (a1)
CNOP 0,4
WriteTabA dc.l WrNormal
dc.l WrNormal
dc.l WrNormal
dc.l WrNormal
dc.l WrTALO
dc.l WrTAHI
dc.l WrTBLO
dc.l WrTBHI
dc.l WrTOD10THS
dc.l WrTODSEC
dc.l WrTODMIN
dc.l WrTODHR
dc.l WrNormal
dc.l WrICR
dc.l WrCRA
dc.l WrCRB
WrNormal move.b d1,(a0,d0.w)
rts
WrTALO move.b d1,LTCHA+1(a0)
rts
WrTAHI move.b d1,LTCHA(a0)
btst #0,CRA(a0) ;Timer A gestoppt?
bne 1$
move.w LTCHA(a0),TAHI(a0) ;Ja, Timer laden
1$ rts
WrTBLO move.b d1,LTCHB+1(a0)
rts
WrTBHI move.b d1,LTCHB(a0)
btst #0,CRB(a0) ;Timer B gestoppt?
bne 1$
move.w LTCHB(a0),TBHI(a0) ;Ja, Timer laden
1$ rts
WrTOD10THS and.b #$0f,d1
clr.b TODHALT(a0) ;TOD weiterlaufen lassen
btst #7,CRB(a0) ;Alarm-Zeit schreiben?
bne 1$
move.b d1,TOD10THS(a0)
rts
1$ move.b d1,ALM10THS(a0)
rts
WrTODSEC and.b #$7f,d1
btst #7,CRB(a0) ;Alarm-Zeit schreiben?
bne 1$
move.b d1,TODSEC(a0)
rts
1$ move.b d1,ALMSEC(a0)
rts
WrTODMIN and.b #$7f,d1
btst #7,CRB(a0) ;Alarm-Zeit schreiben?
bne 1$
move.b d1,TODMIN(a0)
rts
1$ move.b d1,ALMMIN(a0)
rts
WrTODHR and.b #$9f,d1
st.b TODHALT(a0) ;TOD anhalten
btst #7,CRB(a0) ;Alarm-Zeit schreiben?
bne 1$
move.b d1,TODHR(a0)
rts
1$ move.b d1,ALMHR(a0)
rts
WrICR bclr #7,d1 ;S/C-Bit l÷schen
bne 1$ ;War es gesetzt?
not.b d1 ;Nein, Bits zum L÷schen negieren
and.b d1,INTMASK(a0) ;Und Bits l÷schen
bra 2$
1$ or.b d1,INTMASK(a0) ;Bits setzen
2$ rts
WrCRA btst #4,d1 ;Force load?
beq 1$
and.b #$ef,d1
move.w LTCHA(a0),TAHI(a0) ;Ja, Timer laden
1$ move.b d1,CRA(a0)
and.b #$21,d1 ;LΣuft der Timer und zΣhlt er Phi2?
cmp.b #$01,d1
seq.b TACNTPHI2(a0) ;Ja, Flag setzen
rts
WrCRB btst #4,d1 ;Force load?
beq 1$
and.b #$ef,d1
move.w LTCHB(a0),TBHI(a0) ;Ja, Timer laden
1$ move.b d1,CRB(a0)
and.b #$61,d1 ;LΣuft der Timer und zΣhlt er Phi2?
cmp.b #$01,d1
seq.b TBCNTPHI2(a0) ;Ja, Flag setzen
cmp.b #$41,d1 ;LΣuft er und zΣhlt UnterlΣuft von Timer A?
seq.b TBCNTTA(a0) ;Ja, Flag setzen
rts
**
** In ein CIA-B-Register schreiben
** d0.w: Registernummer ($00-$0f)
** d1.b: Byte
**
** Darf das obere Wort von d0 und d1 nicht verΣndern!
**
WriteTo6526B lea Registers2,a0
move.l WriteTabB(pc,d0.w*4),a1
jmp (a1)
CNOP 0,4
WriteTabB dc.l WrBPRA
dc.l WrNormal
dc.l WrBDDRA
dc.l WrNormal
dc.l WrTALO
dc.l WrTAHI
dc.l WrTBLO
dc.l WrTBHI
dc.l WrTOD10THS
dc.l WrTODSEC
dc.l WrTODMIN
dc.l WrTODHR
dc.l WrNormal
dc.l WrICR
dc.l WrCRA
dc.l WrCRB
WrBPRA move.b d1,PRA(a0) ;Floppy/VA
tst.b IECIsOpen ;Wenn IEC aktiv ist, Port setzen
beq WrBNewVA
move.b d1,_ciaaprb
bra WrBNewVA
WrBDDRA move.b d1,DDRA(a0) ;Floppy/VA
tst.b IECIsOpen ;Wenn IEC aktiv ist, DDR setzen
beq WrBNewVA
move.b d1,_ciaaddrb
WrBNewVA move.b DDRA(a0),d0 ;VA extrahieren
not.b d0
or.b PRA(a0),d0
not.b d0
and.b #$03,d0
bra ChangedVA ;Und dem VIC mitteilen
**
** Aus einem CIA-A-Register lesen
** d0.w: Registernummer ($00-$0f)
** Rⁿckgabe: d0.b: Byte
**
** Darf das obere Wort von d0 und d1 nicht verΣndern!
** Darf a1 nicht verΣndern!
**
ReadFrom6526A move.l ReadTabA(pc,d0.w*4),a0
jmp (a0)
CNOP 0,4
ReadTabA dc.l RdAPRA
dc.l RdAPRB
dc.l RdANormal
dc.l RdANormal
dc.l RdATALO
dc.l RdATAHI
dc.l RdATBLO
dc.l RdATBHI
dc.l RdATOD10THS
dc.l RdANormal
dc.l RdANormal
dc.l RdATODHR
dc.l RdANormal
dc.l RdAICR
dc.l RdANormal
dc.l RdANormal
RdANormal lea Registers1,a0
move.b (a0,d0.w),d0
rts
RdAPRA lea Registers1,a0
move.b DDRA(a0),d0
not.b d0
or.b PRA(a0),d0
and.b JOY2(a0),d0
rts
RdAPRB move.l a1,-(sp)
lea Registers1,a0
lea KeyMatrix,a1
move.b PRA(a0),d1 ;Tastaturabfrage
move.b #$ff,d0 ;Alle aktiven Reihen dazuANDen
lsr.b #1,d1
bcs 1$
and.b (a1),d0
1$ lsr.b #1,d1
bcs 2$
and.b 1(a1),d0
2$ lsr.b #1,d1
bcs 3$
and.b 2(a1),d0
3$ lsr.b #1,d1
bcs 4$
and.b 3(a1),d0
4$ lsr.b #1,d1
bcs 5$
and.b 4(a1),d0
5$ lsr.b #1,d1
bcs 6$
and.b 5(a1),d0
6$ lsr.b #1,d1
bcs 7$
and.b 6(a1),d0
7$ lsr.b #1,d1
bcs 8$
and.b 7(a1),d0
8$ and.b JOY1(a0),d0
move.b DDRB(a0),d1
not.b d1
or.b PRB(a0),d1
and.b d1,d