
; Listing 28x.s		Original 'Baycat' modified Rock'n Roll
; https://github.com/LutzGrosshennig/amiga-baycat-command
; Tilemap Grafik mit 16x16px Tiles in 24 Tilereihen untereinander mit 14 Tiles in einer Reihe
; Raw Blit Tiles 

; offsets blitter
bltsize        = $dff058
bltafwm        = $dff044

bltapth        = $dff050
bltbpth        = $dff04c
bltcpth        = $dff048
bltdpth        = $dff054

bltamod        = $dff064
bltbmod        = $dff062
bltcmod        = $dff060
bltdmod        = $dff066

bltcon0        = $dff040
bltcon1        = $dff042

; various hardware registers
dmaconr        = $dff002

; const values
SCREENX        = 224			; Pixel 14 Tiles * 16px=224px
SCREENB        = SCREENX/8		; Bytes 224/8=28 ($1c) 28 Bytes
SCREENY        = 384			; 24 Tilereihen * 16px= 384
								; 256 Zeilen Bildschirm d.h 16 Tilereihen 16*16=256 
PLANES         = 5
PLANESIZE      = (SCREENX*SCREENY)/8	; (224 * 384)/8=10752
playfield      = PLANESIZE*PLANES		; 10752*5=53760

TILE_W         = 16
TILE_H         = 16
TILE_PLANE     = (TILE_W*TILE_H)/8		; (16*16)/8=> 256/8=32 Bytes
TILE_SIZE      = TILE_PLANE*PLANES		; 32*5=160


	SECTION BAYCAT,CODE


Start:
	move.l	4.w,a6				; Execbase
	jsr	-$78(a6)				; Disable
	lea	GfxName(pc),a1			; Libname
	jsr	-$198(a6)				; OpenLibrary
	move.l	d0,GfxBase
	move.l	d0,a6
	move.l	$26(a6),OldCop		; speichern die alte COP
	
	bsr CopyColors				; Farbwerte in Copperliste kopieren
	bsr BuildBackground			; Hintergrundgrafik erstellen oder die Kacheln in das Playfield kopieren	

	move.l	#Copperlist,$dff080	; unsere COP
	;move.w	d0,$dff088			; START COP
	move.w	#0,$dff1fc			; NO AGA!
	move.w	#$c00,$dff106

Mainloop: 
	move.l $dff004,d1
	and.l #$000fff00,d1
	cmp.l #$00013700,d1			; auf Ende des-Rasterdurchlaufs warten
	bne.b	Mainloop

	bsr CheckBorder				; nach oben und unten scrollen
	bsr SetScreen				; setzt Bitplanepointer in Copperliste zur aktuellen y-Position

Mouse:
	btst	#6,$bfe001			; linke Maustaste gedrückt?
	bne Mainloop

	move.l	OldCop(pc),$dff080	; Pointen auf die SystemCOP
	move.w	d0,$dff088			; Starten die alte SystemCOP

	move.l	4.w,a6
	jsr	-$7e(a6)				; Enable
	move.l	GfxBase(pc),a1
	jsr	-$19e(a6)				; Closelibrary
	rts					

;	Daten
GfxName:
	dc.b	"graphics.library",0,0
GfxBase:
	dc.l	0
OldCop:
	dc.l	0
	
YPos:
	dc.w	0	

Yadd:
	dc.w	1

;****************************************************************************
	
CheckBorder:
	moveq	#0,d7			; 
	move.w YPos,d7			; aktuelle Position
	move.w Yadd,d6			; y add
	add.b d6,d7				; 1 oder -1 zu screen_y
	cmp.b #8*16,d7			; 64 bottom check - sind wir unten?
	bne Ok1					; 				
	neg d6					; change direction	1 wird -1
	move.w  d6,Yadd			; y add speichern
Ok1:
	cmp.b #$0,d7			; 0 sind wir oben?
	bne Ok2					; 
	neg d6					; change direction	-1 wird 1
	move.w  d6,Yadd			; y add speichern	
Ok2:
	move.w  d7,YPos			; aktuelle Position zurück
	move.l  d7,screen_y		; Wert für Copperliste
	rts
	
;------------------------------------------------------------------------------
; ermittelt zur aktuellen Zeile (y-Position) die Bitplanepointer
; und setzt sie in die Copperliste 

SetScreen:
	move.l  Screen_Y,d2			; aktuelle Zeile des Playfields
	mulu    #SCREENB,d2			; Anzahl Zeilen * Breite des Playfields (14 Wörter) in Bytes ermitteln 
								; 224/8=28 ($1C) 28*   d2= SCREENB*Screen_Y in Bytes
	move.l	#Bitplane,d0		; Anfangsadresse des playfields
    add.l   d2,d0				; aktuelle Höhe (y-Position) hinzufügen    
    move.l  #PLANESIZE,d1		; Größe der Bitebene
	lea     Bplpointers,a0		; Bitplanepointer in Copperliste

	moveq.l #5-1,d7				; Anzahl der Bitebenen 5
PointerLoop:					; d0-Adresse Bitplane
    move.w  d0,6(a0)			; BPL-Pointer low
    swap    d0					; hi-low tauschen	
    move.w  d0,2(a0)			; BPL-Pointer high
    swap    d0					; hi-low tauschen	
    add.l   d1,d0				; nächste Bitebene
    addq.l  #8,a0				; nächste BPL-Paar in Copperliste
    dbra    d7,PointerLoop

	rts
;------------------------------------------------------------------------------

BuildBackground:
	;move.l  #100,screen_y				; wenn dieser Wert erhöht wird, beginnt das 
										; Bild Screen_Y Zeilen tiefer zu blitten
	moveq   #(SCREENY/TILE_H)-1,d5		; Anzahl Kachelreihen (384/16)=24 Kachelreihen
YLoop:
	bsr		SetRow						; eine Kachelreihe blitten
	add.l   #TILE_H,Ground_Y			; +16 hinzuaddieren für nächste Kachelreihe
    dbra    d5,YLoop					; über alle Kachelreihen
    rts
	
;------------------------------------------------------------------------------
; In dieser Routine wird eine Kachelreihe mit 14 Kacheln geblittet
; dazu wird das Unterprogramm BlitBackground 14x aufgerufen

SetRow:
    moveq   #(SCREENB/2)-1,d6			; 14 Kacheln pro Zeile (Schleifenzähler)
RowLoop:
; Adresse der nächsten Tile-Bitplanedaten ermitteln
	moveq	#0,d0						; d0 - 
	move.l  #TILE_SIZE,d1				; d1 - 160 Bytes Abstand von Kachelreihe zu Kachelreihe
	move.l  MapPointer,a0				; a0 - Zeiger auf aktuelle Kachel
	move.b  (a0),d0						; Bytewert aus der Map holen (welches Tile zu zeichnen?)
    mulu    d0,d1						; und mit der Tilegröße multiplizieren
										; um den richtigen Offset zu bekommen
										; d1 - Zeiger auf Tile-Bitplandaten
    move.l  #GroundData,d0				; Anfangsadresse der Tiles-Grafikdaten
    add.l   d1,d0						; und Offset hinzuaddieren um richtiges Tile zu bekommen
    move.l  d0,DataPointer				; Adresse der Tile-Bitplanedaten, nach DataPointer kopieren
	
; an dieser Stelle haben wir in DataPointer die Anfangsadresse der nächsten Tile-Bitplanedaten

; dieses Tile in den Hintergrund blitten
; BlitBackground benötigt als Eingang:
; in d0 - DataPointer auf Mapdaten
; in d1 - Abstand von tile zu tile, hier 160 Bytes										
    bsr     BlitBackground				; nächste Kachel blitten		
    add.l   #TILE_W,Ground_X			; 16px horizontalen Versatz hinzufügen
    addq.l  #1,MapPointer				; Zeiger erhöhen zum nächsten Tile-Bytewert
    dbra    d6,RowLoop					; wiederholen für ganze Zeile
    clr.l   Ground_X					; horizontalen Versatz zurücksetzen
										; um nächste Kachelreihe wieder links anzufangen
	rts
;------------------------------------------------------------------------------
; In dieser Routine wird eine einzige Kachel in den Hintergrund geblittet

BlitBackground:
	move.l  Ground_X,d0					; d0=ground_x - x Position im Playfield 	
    move.l  Ground_Y,d1					; d1=ground_y - y Position im Playfield 
	moveq   #0,d2						; d2=0

; Kalkulation der Zielposition im Playfield
; Eingang: d0=ground_x, d1=ground_y
    move.w  d1,d2						; d2 - Kopie aktuelle Zeile im Playfield
    mulu    #SCREENB,d2					; d2 - Offset ermitteln, Anzahl Zeilen * Breite Playfield
										; 14 Kacheln pro Zeile sind 28 Bytes 
    
	; horizontaler Versatz - das Byte 
	move.w  d0,d1						; Kopie - x Position im Playfield 	
    lsr.w   #3,d0						; x-Position/8
	
	; horizontaler Versatz - das Bit im Byte    
    ;and.w   #$000f,d1					; nur die unteren 4 Bits von Interesse
    ;lsl.w   #8,d1						; den Wert um 12 Bits nach links verschieben
    ;lsl.w   #4,d1						; um ins obere Byte zu kommen
    ;move.w  d1,control					; Ergebnis in d1
	
	add.l   ScreenBase,d0				; Anfangsadresse des Playfields
	add.l   d2,d0						; genaue Zeile im Playfield
; an dieser Stelle haben wir den Zielpointer in d0

	move.l  DataPointer,d1				; Adresse auf Tile-Bitplanedaten welche kopiert werden soll
	bsr     WaitBlit					; waitblit

    move.w	#0,bltcon1					; bltcon1=0
	moveq   #0,d2						; d2=0
    ;move.w  control,d2					; Verschiebungswert in d2
    add.w   #$09f0,d2					; USE A+D, Kopie
    move.w  d2,bltcon0					; Bltcon0 fertig

    move.l  #$ffffffff,bltafwm			; alles passiert
    move.w  #0,bltamod					; bltamod=0
    move.w  #SCREENB-2,bltdmod			; bltdmod=28-2

	moveq   #PLANES-1,d7				; raw Blitt, daher 5 einzelne Blitts
BackLoop:
    move.l  d1,bltapth					; Zeiger Quelle
    move.l  d0,bltdpth					; Zeiger Ziel
    move.w  #$0401,bltsize				; Blitt ausführen
										; 1 Word und 16 Zeilen
    add.l   #PLANESIZE,d0				; auf Anfang nächste Plane zeigen
    add.l   #TILE_PLANE,d1				; +160 Anfang nächste Plane der Tile

    bsr     WaitBlit
    dbra    d7,BackLoop					; für alle 5 Bitebenen wiederholen

	rts

;------------------------------------------------------------------------------
WaitBlit:
    btst    #14,dmaconr
    bne.b   WaitBlit
    rts

;------------------------------------------------------------------------------
CopyColors:
    lea     ColorTab,a0					; Zeiger auf Tabelle mit Farbwerten
	lea     col,a1						; Zeiger auf Bereich in Copperliste
    moveq.l #31,d7						; Anzahl Farben 32
    move.l  #$180,d0					; Color0
ColorLoop:
    move.w  d0,(a1)+					; dc.w $180,
    move.w  (a0)+,(a1)+					; dc.w $180,$RGB
    addq.l  #2,d0						; dc.w $182, usw.
    dbra    d7,ColorLoop				; für alle Farben wiederholen
    rts
	

;****************************************************************************

	SECTION	GRAPHIC,DATA_C

Copperlist:
	dc.w	$8e,$2cb1			; DIWSTRT
	dc.w	$90,$2c91			; DIWSTOP
	dc.w	$92,$50				; DDFSTRT
	dc.w	$94,$b8				; DDFSTOP
	dc.w	$102,0				; BPLCON1
	dc.w	$104,0				; BPLCON2
	dc.w	$108,0				; BPL1MOD
	dc.w	$10a,0				; BPLsMOD

	dc.w	$100,$5200			; BPLCON0 - 1 Bitplane lowres

Bplpointers:
	dc.w	$e0,$0000,$e2,$0000	; erste Bitplane
	dc.w	$e4,$0000,$e6,$0000	; zweite Bitplane - BPL1PT
	dc.w	$e8,$0000,$ea,$0000	; dritte Bitplane - BPL2PT
	dc.w	$ec,$0000,$ee,$0000	; vierte Bitplane - BPL3PT
	dc.w	$f0,$0000,$f2,$0000	; fünfte Bitplane - BPL4PT

Col:
	blk.b	128,0				; Platz für die Farbtabelle

	dc.w	$ffff,$fffe			; Ende Copperlist

;****************************************************************************

;------------------------------------------------------------------------------
Screen_Y:      dc.l    0		; Zeile mit der das Playfield beginnt
Ground_X:      dc.l    0		; Position X Ground
Ground_Y:      dc.l    0		; Position Y Ground
DataPointer:   dc.l    0			; Pointer auf Tile-Bitplanedaten
MapPointer:    dc.l    Level1	; Pointer auf aktuelle map

ColorTab:
               dc.w    $000,$eca,$222,$446,$668,$99b,$cce,$eef
Blau1:         dc.w    $3ac,$19b,$079,$079,$189,$29b,$3bd,$5ce
               dc.w    $ed0,$ca1,$d82,$c73,$951,$740,$2b0,$1a0
               dc.w    $190,$180,$070,$060,$f20,$d20,$b20,$920
;control:       
;	dc.w    0		; horizontaler Verschiebungswert Blitter

ScreenBase		dc.l Bitplane

	even
	
Level1:		;incbin	"level/level1.map"
	dc.b 27,38,20,0,0,0,0,0,15,15,15,15,16,21	; 1 	
	dc.b 21,6,10,0,0,0,0,0,0,0,0,11,08,21		; 2
	dc.b 32,6,0,0,0,0,0,0,0,12,0,17,37,21		; 3
	dc.b 34,14,15,15,15,15,15,0,0,0,0,8,29,28	; 4
	dc.b 21,6,10,0,0,0,0,0,0,0,22,37,26,27		; 5
	dc.b 21,36,23,0,0,12,0,0,0,17,37,21,21,21	; 6
	dc.b 32,21,36,18,0,0,0,0,17,37,31,32,21,31  ; 7
	dc.b 34,31,32,36,18,0,0,0,24,35,33,34,21,33 ; 8
	dc.b 21,33,34,38,20,0,0,0,0,24,35,21,21,21	; 9
    dc.b 21,21,38,25,0,0,0,0,0,0,8,21,31,32		; 10
	dc.b 32,21,6,11,0,0,0,0,0,0,19,35,33,34     ; 11
	dc.b 34,38,25,0,10,0,0,0,0,10,0,19,35,21	; 12
	dc.b 21,6,0,10,0,0,0,0,0,0,10,0,8,21		; 13
	dc.b 32,6,10,10,0,0,0,0,0,0,0,10,8,21		; 14	
	dc.b 34,36,7,7,18,0,0,0,0,0,0,22,37,21		; 15
	dc.b 21,38,9,9,20,0,0,0,0,0,17,37,21,21		; 16
	; um 8 Reihen verlängern	
	dc.b 21,36,23,0,0,12,0,0,0,17,37,21,21,21	; 6
	dc.b 32,21,36,18,0,0,0,0,17,37,31,32,21,31  ; 7
	dc.b 34,31,32,36,18,0,0,0,24,35,33,34,21,33 ; 8
	dc.b 21,33,34,38,20,0,0,0,0,24,35,21,21,21	; 9
    dc.b 21,21,38,25,0,0,0,0,0,0,8,21,31,32		; 10
	dc.b 32,21,6,11,0,0,0,0,0,0,19,35,33,34     ; 11
	dc.b 34,38,25,0,10,0,0,0,0,10,0,19,35,21	; 12
	dc.b 21,6,0,10,0,0,0,0,0,0,10,0,8,21		; 13
Level1End:	


GroundData:
    incbin "/Sources/bits/wasser1.bit"   ; 1
    incbin "/Sources/bits/wasser2.bit"   ; 2
    incbin "/Sources/bits/wasser3.bit"   ; 3
    incbin "/Sources/bits/wasser4.bit"   ; 4
    incbin "/Sources/bits/wasser5.bit"   ; 5
    incbin "/Sources/bits/wasser6.bit"   ; 6
    incbin "/Sources/bits/ufer1.bit"     ; 7
    incbin "/Sources/bits/ufer2.bit"     ; 8
    incbin "/Sources/bits/ufer3.bit"     ; 9
    incbin "/Sources/bits/ufer4.bit"     ; 10
    incbin "/Sources/bits/rock1.bit"     ; 11
    incbin "/Sources/bits/rock2.bit"     ; 12
    incbin "/Sources/bits/boje1.bit"     ; 13
    incbin "/Sources/bits/boje2.bit"     ; 14
    incbin "/Sources/bits/bruecke1.bit"  ; 15
    incbin "/Sources/bits/bruecke2.bit"  ; 16
    incbin "/Sources/bits/bruecke3.bit"  ; 17
    incbin "/Sources/bits/kurve1.bit"    ; 18
    incbin "/Sources/bits/kurve2.bit"    ; 19
    incbin "/Sources/bits/kurve3.bit"    ; 20
    incbin "/Sources/bits/kurve4.bit"    ; 21
    incbin "/Sources/bits/land1.bit"     ; 22
    incbin "/Sources/bits/bucht1.bit"    ; 23
    incbin "/Sources/bits/bucht2.bit"    ; 24
    incbin "/Sources/bits/bucht3.bit"    ; 25
    incbin "/Sources/bits/bucht4.bit"    ; 26
    incbin "/Sources/bits/gras1.bit"     ; 27
    incbin "/Sources/bits/gras2.bit"     ; 28
    incbin "/Sources/bits/gras3.bit"     ; 29
    incbin "/Sources/bits/gras4.bit"     ; 30
    incbin "/Sources/bits/gras5.bit"     ; 31
    incbin "/Sources/bits/palme1.bit"    ; 32
    incbin "/Sources/bits/palme2.bit"    ; 33
    incbin "/Sources/bits/palme3.bit"    ; 34
    incbin "/Sources/bits/palme4.bit"    ; 35
    incbin "/Sources/bits/sand1.bit"     ; 36
    incbin "/Sources/bits/sand2.bit"     ; 37
    incbin "/Sources/bits/sand3.bit"     ; 38
    incbin "/Sources/bits/sand4.bit"     ; 39


;****************************************************************************

	SECTION	LEEREPLANE,BSS_C
	
Bitplane:
	ds.b 5*((224*384)/8)
	
;****************************************************************************
