home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The AGA Experience 2
/
agavol2.iso
/
software
/
utilities
/
emulation
/
frodo
/
src
/
6569mono.i
< prev
next >
Wrap
Text File
|
1996-02-03
|
9KB
|
423 lines
*
* 6569mono.i - Schnellere VIC-Emulation (Amiga monochrom)
*
* Copyright (C) 1994-1996 by Christian Bauer
*
*
* Anmerkungen:
* ------------
*
* Funktionsweise:
* - Die monochrome Emulation arbeitet nicht mit einer Chunky-Bitmap,
* sondern schreibt die rohen Grafikdaten direkt in eine Amiga-Bitplane
* - Farbwerte werden ignoriert, der Hintergrund ist immer schwarz, die
* Grafik immer weiß, ebenso bei den Sprites. Eine Ausnahme bildet die
* Rahmenfarbe: Sie ist immer weiß, außer wenn der Rahmen schwarz ist
*
*
* Definitionen
*
BytesPerLine = DisplayX/8 ;Anzahl Bytes pro Zeile in einer Bitplane
*
* Makros
*
; Sprite darstellen
FDoSprite MACRO ;Nummer
moveq #\1,d6 ;d6: Spritenummer
btst d6,SPRITEON(a4) ;Wird das Sprite dargestellt?
beq \@1$
move.l MATRIXBASE(a4),a0
moveq #0,d0
move.b $03f8+\1(a0),d0 ;d0: Datenzeiger
move.w MC\1(a4),d1 ;d1: MC
move.w SPRX\1(a4),d5 ;d5: X-Koordinate
bsr FDrawSprite
\@1$
ENDM
**
** Eine Rasterzeile ausführen (monochrom)
**
** d7: Rasterzeilenzähler
** a4: Zeiger auf VIC-Register
** a5: Zeiger auf das Ziel im Bildschirmspeicher
**
AmigaMono6569
*
* "Bad Lines"-Videomatrixzugriff:
* 40 Bytes aus Videomatrix und Farb-RAM lesen und zwischenspeichern
*
tst.b BADLINEENABLE(a4) ;War das DEN-Bit in Rasterzeile $30 gesetzt?
beq FNoBadLine
cmp.w #FirstDMALine,d7 ;Innerhalb des DMA-Bereiches?
blo FNoBadLine
cmp.w #LastDMALine,d7
bhi FNoBadLine
move.b d7,d0 ;Ja, stimmen die unteren Bits
and.b #7,d0 ;der Rasterzeile mit dem Y-Scroll
cmp.b YSCROLL+1(a4),d0 ;überein?
bne FNoBadLine
FIsBadLine st.b BADLINE(a4) ;Ja, Bad Line
move.w VCCOUNT(a4),d2 ;d2: VC Videomatrix-Zähler
move.l MATRIXBASE(a4),a0 ;Videomatrixbasis holen
add.w d2,a0 ;Videomatrixzähler dazunehmen
lea MatrixLine,a1 ;Nur Videomatrix-Zeile lesen
movem.l (a0)+,d0-d6 ;40 Bytes kopieren
movem.l d0-d6,(a1)
movem.l (a0)+,d0-d2
movem.l d0-d2,28(a1)
clr.w RC(a4) ;RC zurücksetzen
clr.b DISPLAYOFF(a4) ;Darstellung anschalten
move.w BadLineCycles,CyclesLeft ;Andere Anzahl Zyklen
FNoBadLine
*
* Oberen und unteren Rahmen handhaben
*
cmp.w DYSTOP(a4),d7 ;Unteres Ende des Fensters erreicht
bne 1$ ; -> Rahmen einschalten
st.b BORDERON(a4)
bra FTBBorderDraw
1$ btst #4,CTRL1(a4) ;Rahmen nur abschalten, wenn DEN-Bit gesetzt
beq FTBBorderDone
cmp.w DYSTART(a4),d7 ;Oberes Ende des Fensters erreicht
bne FTBBorderDone ; -> Rahmen abschalten
clr.b BORDERON(a4)
bra FTBNoBorder
FTBBorderDone tst.b BORDERON(a4) ;Rahmen an?
beq FTBNoBorder
FTBBorderDraw move.l CURRENTA5(a4),a0 ;Ja, Rahmen malen
tst.b $20(a4) ;Jede Farbe außer schwarz wird als weiß dargestellt
beq FTBBorderBlack
moveq #-1,d0 ;Rahmen weiß
move.w #BytesPerLine/4-1,d1
FTBBorderLoop move.l d0,(a0)+
dbra d1,FTBBorderLoop
bra FVICIncA5 ;Sonst nix
FTBBorderBlack move.w #BytesPerLine/4-1,d1 ;Rahmen schwarz
FTBBlackLoop clr.l (a0)+
dbra d1,FTBBlackLoop
bra FVICIncA5 ;Sonst nix
FTBNoBorder
*
* Inhalt des Fensters: Darstellung eingeschaltet?
*
lea 4(a5),a1 ;a1: Ziel in Bildschirmspeicher
lea MatrixLine,a2 ;a2: Zeichencodes
tst.b DISPLAYOFF(a4) ;$3FFF darstellen?
bne FShow3FFF
move.l DisplayProc,a0 ;Nein, Routine entsprechend
jmp (a0) ;dem Darstellungsmodus anspringen
*
* Standard-Text: Zeichendaten holen und darstellen
*
FTextStd add.w #40,VCCOUNT(a4) ;VC erhöhen (wird nicht verwendet)
move.l CHARBASE(a4),a0 ;a0: Zeichengeneratorbasis
add.w RC(a4),a0 ;RC dazunehmen
clr.b 4(a5) ;Hintergrund, wenn XScroll>0
moveq #0,d3 ;XScroll holen
move.w XSCROLL(a4),d3
beq FTextNoScroll
; Schleife für 40 Zeichen
moveq #9,d1 ;d1: 4-Zeichen-Zähler
moveq #0,d0
FCharLoop move.b (a2)+,d0 ;Grafikdaten von 4 Zeichen lesen
move.w (a0,d0.w*8),d2
move.b (a2)+,d0
move.b (a0,d0.w*8),d2
swap d2
move.b (a2)+,d0
move.w (a0,d0.w*8),d2
move.b (a2)+,d0
move.b (a0,d0.w*8),d2
bfins d2,(a1){d3:32} ;und in den Bildschirm schreiben
addq.w #4,a1 ;Zielzeiger erhöhen
dbra d1,FCharLoop
bra FDoSprites
; Schleife für 40 Zeichen, kein XScroll
FTextNoScroll moveq #9,d1 ;d1: 4-Zeichen-Zähler
moveq #0,d0
FNCharLoop move.b (a2)+,d0 ;Grafikdaten von 4 Zeichen lesen
move.w (a0,d0.w*8),d2
move.b (a2)+,d0
move.b (a0,d0.w*8),d2
swap d2
move.b (a2)+,d0
move.w (a0,d0.w*8),d2
move.b (a2)+,d0
move.b (a0,d0.w*8),d2
move.l d2,(a1)+ ;und in den Bildschirm schreiben
dbra d1,FNCharLoop
bra FDoSprites
*
* Standard-BitMap: Grafikdaten holen und darstellen
*
FBitMapStd move.l BITMAPBASE(a4),a0 ;a0: Bitmap-Basis
move.w VCCOUNT(a4),d0 ;VC holen
lsl.w #3,d0 ;*8
add.w RC(a4),d0 ;RC dazunehmen
add.w d0,a0 ;und zur Bitmap-Basis dazunehmen
add.w #40,VCCOUNT(a4) ;VC erhöhen
clr.b 4(a5) ;Hintergrund, wenn XScroll>0
moveq #0,d3 ;XScroll holen
move.w XSCROLL(a4),d3
beq FBitMapNoScroll
; Schleife für 40 Bytes
moveq #9,d1 ;d1: 4-Zeichen-Zähler
FBitMapLoop move.w (a0),d2 ;4 Bytes Grafikdaten lesen
move.b 8(a0),d2
swap d2
move.w 16(a0),d2
move.b 24(a0),d2
bfins d2,(a1){d3:32} ;und in den Bildschirm schreiben
addq.w #4,a1 ;Zielzeiger erhöhen
lea 32(a0),a0 ;Quellzeiger erhöhen
dbra d1,FBitMapLoop
bra FDoSprites
; Schleife für 40 Bytes, kein XScroll
FBitMapNoScroll moveq #9,d1 ;d1: 4-Zeichen-Zähler
FNBitMapLoop move.w (a0),d2 ;4 Bytes Grafikdaten lesen
move.b 8(a0),d2
swap d2
move.w 16(a0),d2
move.b 24(a0),d2
move.l d2,(a1)+ ;und in den Bildschirm schreiben
lea 32(a0),a0 ;Quellzeiger erhöhen
dbra d1,FNBitMapLoop
bra FDoSprites
*
* Ungültiger Darstellungsmodus: Schwarzen Bildschirm anzeigen
*
FBlackScreen add.w #40,VCCOUNT(a4) ;VC erhöhen
moveq #9,d0 ;40 Zeichen schwarz
1$ clr.l (a1)+
dbra d0,1$
bra FDoSprites
*
* $3FFF darstellen
*
FShow3FFF tst.b $21(a4) ;Wenn der Hintergrund schwarz ist, sieht man nichts
beq FInvis3FFF
moveq #0,d3 ;XScroll holen
move.w XSCROLL(a4),d3
clr.b 4(a5) ;Hintergrund, wenn X-Scroll>0
btst #6,CTRL1(a4)
bne 11$
move.w #$3fff,d0 ;Byte bei $3FFF lesen
bra 12$
11$ move.w #$39ff,d0 ;ECM: Byte bei $39FF lesen
12$ bsr GetPhysical
move.w (a0),d0 ;Byte als Langwort lesen
move.b (a0),d0
swap d0
move.w (a0),d0
move.b (a0),d0
not.l d0 ;und invertieren
; Zeile schreiben
moveq #9,d1 ;d0: 4-Zeichen-Zähler
FLoop3FFF bfins d0,(a1){d3:32} ;In den Bildschirm schreiben
addq.w #4,a1 ;Zielzeiger erhöhen
dbra d1,FLoop3FFF
bra FDoSprites
; Hintergrund schwarz: 3FFF unsichtbar
FInvis3FFF moveq #9,d1 ;d0: 4-Zeichen-Zähler
FLoop3FFFInvis clr.l (a1)+ ;In den Bildschirm schreiben
dbra d1,FLoop3FFFInvis
*
* Sprites
*
FDoSprites tst.b SPRITEON(a4) ;Ist überhaupt ein Sprite z.Z. sichtbar?
beq FDrawLRBorder ;Ja, dann Sprites malen
tst.w SpritesOn ;Sprite-Darstellung angeschaltet?
beq FDrawLRBorder
*
* Mindestens ein Sprite ist sichtbar, Sprites malen
*
move.l d7,-(sp)
FDoSprite 7
FDoSprite 6
FDoSprite 5
FDoSprite 4
FDoSprite 3
FDoSprite 2
FDoSprite 1
FDoSprite 0
move.l (sp)+,d7
*
* Linken und rechten Rahmen zeichnen
*
; 40-Spalten-Rahmen
FDrawLRBorder move.l CURRENTA5(a4),a0
tst.b $20(a4)
beq FLRBorderBlack
moveq #-1,d0
move.l d0,(a0) ;Links: $00..$17
move.l d0,44(a0) ;Rechts: $158..$16f
; 38-Spalten-Rahmen
tst.b IS38COL(a4)
beq 1$
move.b d0,4(a0) ;Links: $18..$1e
move.b d0,43(a0) ;Rechts: $14f..$157
1$ bra FVICNext
; Schwarzer Rahmen
FLRBorderBlack clr.l (a0) ;40-Spalten
clr.l 44(a0)
tst.b IS38COL(a4) ;38-Spalten
beq 1$
clr.b 4(a0)
clr.b 43(a0)
1$
*
* Ende einer sichtbaren Zeile: Zeiger in Bitmap erhöhen
*
FVICNext
FVICIncA5 lea BytesPerLine(a5),a5
move.l a5,CURRENTA5(a4)
*
* Zurück zur Haupt-Routine
*
bra VICIncRC
**
** Ein Sprite zeichnen (monochrom)
** d0.l: Spritedatenzeiger
** d1.w: MC
** d5.w: X-Koordinate
** d6.l: Spritenummer (0..7)
**
CNOP 0,4
FDrawSprite lsl.w #6,d0 ;Datenzeiger*64
add.w d1,d0 ;MC dazunehmen
bsr GetPhysical ;a0: Spritedaten
move.w d5,d0 ;X-Koordinate
lsr.w #3,d0 ;Pixel in Bytes umrechnen
lea 1(a5,d0.w),a1 ;a1: Ziel im Bildschirmspeicher
btst d6,MXE(a4) ;X-expandiert?
bne FSprExp
cmp.w #$180-24,d5 ;Sprite horizontal sichtbar?
bhs FSpriteDone
; Standard-Sprite
and.w #7,d5 ;d5: Bit-Shift
move.l (a0),d0 ;Sprite-Daten lesen,
clr.b d0 ; auf 24 Bit beschränken
lsr.l d5,d0 ; verschieben
or.l d0,(a1) ; und in den Bildschirm schreiben
FSpriteDone rts
; X-expandiertes Sprite
FSprExp cmp.w #$180-48,d5 ;Sprite horizontal sichtbar?
bhs FSpriteDone
move.l (a0),d0 ;Sprite-Daten lesen
lea ExpTable,a0 ; und expandieren (3 Bytes -> 3 Worte)
moveq #0,d1
rol.l #8,d0
move.b d0,d1
move.w (a0,d1.w*2),d2
swap d2
rol.l #8,d0
move.b d0,d1
move.w (a0,d1.w*2),d2
moveq #0,d3
rol.l #8,d0
move.b d0,d1
move.w (a0,d1.w*2),d3
swap d3
and.w #7,d5 ;d5: Bit-Shift
bne 1$
or.l d2,(a1)+ ;Kein Shift, in den Bildschirm schreiben
or.l d3,(a1)
rts
1$ subq.w #1,d5 ;Daten verschieben
2$ lsr.l #1,d2
roxr.l #1,d3
dbra d5,2$
or.l d2,(a1)+ ;und in den Bildschirm schreiben
or.l d3,(a1)
rts
*
* Tabelle zum X-expandieren von Sprites
*
CNOP 0,4
ExpTable INCBIN "ExpTable.bin"