;======================================================================================================================
;
; cryAEngine - a small gameengine for the Amiga
; 
; CHLUDENS.ch project
;
; Some Code from  Massimo Bonnucchi
;======================================================================================================================

; ATTENTION: DONT USE D7,D6,A7,A& 
; IS SOMEHOW NEEDED BY MUSIC AND MOUSE

; ------------------------------
; 68000 KNOWHOW
; ------------------------------

; 68k online ausprobieren
; https://asm-editor.specy.app/projects/GuILvBB

; CLR.[B/W/L]
; ADD.[B/W/L]
; SUB.[B/W/L]
; MOVE.[B/W/L]
; SWAP.[B/W/L]

; WITHOUT .B/W/L > WORD
; MOVE #4,d0 MEANS MOVE.W #4,d0!!!

; MULTIPLY:
; ROL ETC 
; DIV[U|S] / (int)   W1: RESULT  W2: REST %
; MUL[U|S] * (int)
;
; Data-Register: d0-d7
; Adress-Register: a0-a7
; 
; CMP.[B/W/L]
; BNE/BEQ etc.

;         even
; label:  must be even for 68k!

; DBRA: FOR-NEXT
;    move.l #10
; lab:
;    dbra d0,lab


;
; COPPER - graphic processor binded to crt-raster
;
; If you install a copper list, this will be executed forever! 
; but you can put labels and write direct there !
;
; commands WAIT,MOVE,SKIP
;  
;
; water ... 
;		; data, command
;		; will be always executed
;		DC.W    $9601,$FF00 	; wait for line 150
;		dc.w	$0180,$0fff   ; set color

; ---------------------
; GAMEENGINE
; ---------------------

; simple version without bobs: experiment
;
; double-buffering-version:
; idea: change playfield > update playfield-change-map or two! 
;       repaint then before next
;       perhaps a version behind always up to date - render to frontend   
;       1 change     playfield
;       2 change bob remove again           
;


; demoscene - blk - default value for 

	section	GameCode,CODE_P

;======================================================================================================================
; Startup File
; Makes sure we take control of the OS the proper way
;======================================================================================================================

	include	"lib/startup.s"

;======================================================================================================================
; Which DMAs we will enable
;
; 15	SET/CLR	Set/Clear control bit.
;				Determines if bits written with a 1 get set or cleared
;			    Bits written with a zero are unchanged
; 14	BBUSY	Blitter busy status bit (read only)
; 13	BZERO	Blitter logic zero status bit (read only)
; 12	X	
; 11	X	
; 10	BLTPRI	Blitter DMA priority (also called "blitter nasty" for stealing from CPU)
; 09	DMAEN	Enable all DMA below (also UHRES DMA)
; 08	BPLEN	Bit plane DMA enable
; 07	COPEN	Coprocessor DMA enable
; 06	BLTEN	Blitter DMA enable
; 05	SPREN	Sprite DMA enable
; 04	DSKEN	Disk DMA enable
; 03	AUD3EN	Audio channel 3 DMA enable
; 02	AUD2EN	Audio channel 2 DMA enable
; 01	AUD1EN	Audio channel 1 DMA enable
; 00	AUD0EN	Audio channel 0 DMA enable
;======================================================================================================================

								;5432109876543210
DMASET					equ		%1000001110101111	; Enable Copper, Bitplane DMA, Sprite DMA, Sound DMA

WaitDisk				equ		30		; Defined in Startup.s : Time to wait 50-150 to save/load (50 = 1 second in Pal system)

;======================================================================================================================
; Game Source Files + Data Files
;======================================================================================================================

; Game Constants
		include	"Source/HWConstants.s"
		include	"Source/Constants.s"

; Game Core Files
		include	"Source/Utils.s"
		include	"Source/Player.s"
		include	"Source/Enemies.s"
		include	"Source/GameOver.s"
		include	"Source/Intro.s"
		include	"Source/Hud.s"
		include	"Source/GameCore.s"
		include	"Lib/music.s"

; Game Data Files
		include	"Source/VarTables.s"
		include	"Source/Data.s"

;======================================================================================================================
; Main Program Start
;======================================================================================================================

START:
		;--------------------------------------------------------------------------------------------------------------
		; Saving everything for startup file
		;--------------------------------------------------------------------------------------------------------------

		movem.l	d0-d7/a0-a6,-(SP)

		bsr.w	WaitForRaster

		;--------------------------------------------------------------------------------------------------------------
		; The following is more setup to complete the startup file 
		;--------------------------------------------------------------------------------------------------------------

		; Custom Chips HW Base Address
		lea		$dff000,a5

		; DMA Set / Enable
		move.w	#DMASET,$96(a5)		; DMACON - Enable Bitplane, Copper DMA, Sprties

		; Disable AGA for compatibility
		move.w	#0,$1fc(a5)			; Disable AGA
		move.w	#$c00,$106(a5)		; Disable AGA
		move.w	#$11,$10c(a5)		; Disable AGA

		;--------------------------------------------------------------------------------------------------------------
		; Init Music
		;--------------------------------------------------------------------------------------------------------------

	

		move.l	#GameScreenBitplanes,d0		; Source Image Address that is the address of Bitplane 1
		lea		GameBitplanePointers,a0		; Bitplane Pointers in the Copper
		moveq.l	#NoOfBpls-1,d1				; Number of Bitplanes
		move.l	#BitplaneSize,d2			; Add the bitplane size to the source start Image Address
		bsr.w	SetBitPlanes				; Set the Bitplane Pointers

;		bsr.w	CheckForJoystickFire

		bsr.w	mt_init

	
		;--------------------------------------------------------------------------------------------------------------
		; Init Main Game Screen
		; This only need to be initialised once
		;--------------------------------------------------------------------------------------------------------------

		bsr.w	InitBitPlanes
		bsr.w	InitColours

		;--------------------------------------------------------------------------------------------------------------
		; Init the Intro Screen
		;--------------------------------------------------------------------------------------------------------------


	.Intro:
		; Init the Intro Screen Bitplanes and Colours
		bsr.w	InitIntroScr  ; wird nachträglich gemacht!
		; bsr.w	SetIntroCol	

		;--------------------------------------------------------------------------------------------------------------
		; The following is more setup to complete the startup file 
		;--------------------------------------------------------------------------------------------------------------

		; Custom Chips HW Base Address
		lea		$dff000,a5

		; Init Copper
		move.l	#GenericScreen,$80(a5)	; Point to our copper
		move.w	d0,$88(a5)			; Init our copper

		;--------------------------------------------------------------------------------------------------------------
		; Play Music while we wait for the user to press the fire button
		; and also till the player releases the fire button
		;--------------------------------------------------------------------------------------------------------------

		bsr.w	mt_music

	 	; jmp ingame

		;--------------------------------------------------------------------------------------------------------------
		; TITLESCREEN
		;--------------------------------------------------------------------------------------------------------------
xxx:
		bsr.w	WaitForRaster

		bsr.w	mt_music

  	    BTST   #6,$BFE001      ; Test left mouse button
   		BNE.S   xxx

		jsr WaitForMouseUp

		;--------------------------------------------------------------------------------------------------------------
		; MENU & GAMELOOP
		;--------------------------------------------------------------------------------------------------------------
menustart:

		; copy new background

		move.l	#GameOverScreen,d0			; Source Image Address that is the address of Bitplane 1
		lea		GenericBPL,a0				; Bitplane Pointers in the Copper

		moveq.l	#NoOfBpls-1,d1				; Number of Bitplanes
		move.l	#BitplaneSize,d2			; Add the bitplane size to the source start Image Address
		bsr.w	SetBitPlanes


		; Init Copper
		; move.l	#CopperList,$80(a5)	; Point to our copper
		; move.w	d0,$88(a5)			; Init our copper

		; init sprites
		bsr.w	InitSprite ; player
;		bsr.w   InitGameVars
;		bsr.w	ResetEnemies

		; ------------------------------
		; SPRITE INIT VISUAL POINTERS
		; ------------------------------		
		move.l	#Spr0,d0
		lea		SpritePointer0,a1
		move.w	d0,6(a1)
		swap	d0
		move.w	d0,2(a1)

		move.l	#Spr1,d0
		lea		SpritePointer1,a1
		move.w	d0,6(a1)
		swap	d0
		move.w	d0,2(a1)

		move.l	#Spr2,d0
		lea		SpritePointer2,a1
		move.w	d0,6(a1)
		swap	d0
		move.w	d0,2(a1)

		move.l	#Spr3,d0
		lea		SpritePointer3,a1
		move.w	d0,6(a1)
		swap	d0
		move.w	d0,2(a1)

		move.l	#Spr4,d0
		lea		SpritePointer4,a1
		move.w	d0,6(a1)
		swap	d0
		move.w	d0,2(a1)

		move.l	#Spr5,d0
		lea		SpritePointer5,a1
		move.w	d0,6(a1)
		swap	d0
		move.w	d0,2(a1)

		move.l	#Spr6,d0
		lea		SpritePointer6,a1
		move.w	d0,6(a1)
		swap	d0
		move.w	d0,2(a1)

		move.l	#Spr7,d0
		lea		SpritePointer7,a1
		move.w	d0,6(a1)
		swap	d0
		move.w	d0,2(a1)

		; ----------------
		; copy colors
		; ----------------
		; jmp nocopycolors

; colors manual 
		jmp no_manualcolors
		; monochrom
		move.w #$0000,color_0
		move.w #$0111,color_1
		move.w #$0222,color_2
		move.w #$0333,color_3
		move.w #$0444,color_4
		move.w #$0555,color_5
		move.w #$0666,color_6
		move.w #$0777,color_7
		move.w #$0888,color_8
		move.w #$0999,color_9
		move.w #$0aaa,color_10
		move.w #$0bbb,color_11
		move.w #$0ccc,color_12
		move.w #$0ddd,color_13
		move.w #$0eee,color_14
		move.w #$0fff,color_15

		; red
		move.w #$0000,color_0
		move.w #$0100,color_1
		move.w #$0200,color_2
		move.w #$0300,color_3
		move.w #$0400,color_4
		move.w #$0500,color_5
		move.w #$0600,color_6
		move.w #$0700,color_7
		move.w #$0800,color_8
		move.w #$0900,color_9
		move.w #$0a00,color_10
		move.w #$0b00,color_11
		move.w #$0c00,color_12
		move.w #$0d00,color_13
		move.w #$0e00,color_14
		move.w #$0f00,color_15
no_manualcolors:		
		
		
		; a list 
		lea.l colors,a0						; Move to A0 since we will work with Address Register

		lea		InGameColors,a1			; Get the Address of where the colours are in the Copper list
		moveq	#15,d1						; Number of Colours
		addq.l	#2,a1							; Add 4 to the Copper list Address
nextcol:
		; move.w	d1,(a1)						; Copy the Word to teh Copper list Address Word
		move.w	(a0),(a1)						; Copy the Word to teh Copper list Address Word
		add.l	#2,a0							; Add 4 to the Copper list Address
		add.l	#4,a1							; Add 4 to the Copper list Address
		dbra	d1,nextcol					; Loop
nocopycolors:

		


		; move.l	#GenericScreen,$80(a5)	; Point to our copper
		; move.w	d0,$88(a5)			; Init our copper
		bsr.w	WaitForRaster
		move.l	#CopperList,$80(a5)	; Point to our copper
		move.w	d0,$88(a5)			; Init our copper

		; ----------------------------
		; setup
		; ----------------------------
		; behavior
		lea.l gameobjects,a6
		move.l #8,d5
bvx:
		move.w #behavior_4dir_random,gameobject_behaviour(a6)
;		move.w #behavior_standstill,gameobject_behaviour(a6)
		move.w #type_enemy,gameobject_type(a6)
		add.l #gameobject_size_bytes,a6		
		dbra d5,bvx

		; bonus / boni
		lea.l gameobjects,a6
		add.l #1*gameobject_size_bytes,a6
		move.w #type_bonus,gameobject_type(a6)
		add.l #gameobject_size_bytes,a6
		move.w #type_bonus,gameobject_type(a6)
		add.l #gameobject_size_bytes,a6
		move.w #type_bonus,gameobject_type(a6)

		; avatar
		lea.l gameobjects,a6
		; add.l #1*gameobject_size_bytes,a6
		move.w #behavior_mouse_direct,gameobject_behaviour(a6)
		move.w #type_avatar,gameobject_type(a6)
		
		; init types
		lea.l gameobjects,a6
		move.l #8,d7
bvxt:	
		move.l a6,a0	; pointers forever
		jsr initType
		add.l #gameobject_size_bytes,a6
		dbra d7,bvxt

		; ---------------------------
		; VISUALS SPRITE DATA
		; XETUP
		; ---------------------------
		; copy bitplanes

		; setupSpritesMouseMode
		jsr  setupSpritesMouseMode

		; -----------------------------------------------
		; MENU & SUBMENU
		; -----------------------------------------------

menu:   
		move.l #state_menu,game_state
		move.l #statesub_main,game_state_sub
		 
		; display mainmenu and submenus
submenu: 
		move.l game_state_sub,actualLevelIndex
		; move.l #1,actualLevelIndex
		
		cmp #statesub_main,game_state_sub
		beq notmain		
		; move.l game_state_sub,actualLevelIndex
notmain:
		; move.l #8,actualLevelIndex
		jsr loadActualLevel 
		; todo: blendin/out
		jsr drawLevel

		; disable all sprites from 1-7
		; set it to transparent

		; handle menu
menuloop:
		jsr WaitForRaster

		bsr.w	mt_music


		; debug
		jmp no_menudebug 
		clr.l d0
		move.w game_state_sub,d0
		move.w d0,number
		move.w #10,blockx
		move.w #7,blocky
		jsr displayBlockNumber 

		move.l game_state_sub,d0
;		swap   d0
;		move.w d0,number
;		move.w #39,d0
		add.l  #39,d0
		move.w d0,blockno 
		move.w #10,blockx
		move.w #9,blocky
		jsr drawBlockXY
		; jsr displayBlockNumber 
no_menudebug:

		; some block animations? 

		; --------------------------
		; "water simulation"
		; --------------------------
		; manipulate waves ...
		; effect_wave
		jsr WaterEffect

		; --------------------------
		; block animations
		; --------------------------
		jsr BlockAnimation


		; mouse 
		jsr ReadMouse
		lea.l gameobjects,a6
		move.w MouseX,gameobject_x(a6)
		move.w MouseY,gameobject_y(a6)

		; update it ... 
		lea		Spr0,a1
		move.w  gameobject_y(a6),d0
		move.w  gameobject_x(a6),d1
		move.w	#$10,d2
		bsr.w	MoveSprite


		; not main menu 
		; back ... 
		cmp.l #statesub_main,game_state_sub		
		beq   not_main_main		
;txt:
		; move.w    $DFF006,$DFF180 ; background
		btst   #6,$BFE001      ;  left mouse button ?
   		bne.s  not_main_main
		move.l #statesub_main,game_state_sub				
		jmp submenu	
not_main_main:

		; menu
		; check on click

		; ---------------------
		; MOUSE DOWN
		; ---------------------
		btst   #6,$BFE001      ;  left mouse button ?
   		bne.s  no_mouse_button_pressedx
		jmp    no_mouse_button_pressedt
no_mouse_button_pressedx:
		jmp no_mouse_button_pressed
no_mouse_button_pressedt:

		jsr WaitForMouseUp

		; ---------------------
		; MENU MAIN
		; ---------------------
		; mainmenu: select game 
		cmp #statesub_main,game_state_sub
		bne not_mainmenu
		; wait for mouse up
yyyy:
		bsr.w	mt_music
  	    BTST   #6,$BFE001      ; Test left mouse button
   		BEQ.S   yyyy

		; get row
		clr.l d0
		move.w gameobject_y(a6),d0
		divu.w    #16,d0
		; 0-16

		; MENU: STORY
		cmp.w #7,d0
		bne.w notplay_story
		move.l #statesub_story,game_state_sub
		jmp submenu
notplay_story:

		; MENU: HOWTO
		cmp.w #8,d0
		bne.w notplay_howto
		move.l #statesub_howto,game_state_sub
		jmp submenu
notplay_howto:

		; MENU: PLAY
		cmp.w #9,d0
		bne.w notplay
		jmp startgame
notplay:

		; MENU: HOWTO
		cmp.w #10,d0
		bne.w notplay_about
		move.l #statesub_about,game_state_sub
		jmp submenu
notplay_about:


		jmp not_submenu
not_mainmenu:
		; ---------------------
		; SUBMENU BACK
		; ---------------------
		move.l #statesub_main,game_state_sub				
;txt:
		move.w    $DFF006,$DFF180 ; background
;		jmp txt

		jmp submenu
not_submenu:

no_mouse_button_pressed:

		; < MENU LOOP
		jmp menuloop

		; ----------------------------
		; GAME STARTS HERE
		; ----------------------------
startgame:

		move.l #0,level
		; repaint
		move.l #1,level_old

		move.l #0,timer
		move.l #0,timercounter

		; all gameobjects to init! 
		lea.l gameobjects,a6
		move.l #8,d7
bvxtct:	
		move.l a6,a0	; pointers forever
		cmp #7,d7
		bne ghnot
		move.w #behavior_4dir_random,gameobject_behaviour(a6)
ghnot:		
		jsr initType 
		add.l #gameobject_size_bytes,a6
		dbra d7,bvxtct

		; show avatar  
		move.w #type_transparent_animind,gameobject_animind(a3)


		; ----------------------------
		; test
		; ----------------------------

		; move.w    $0,$DFF180 ; background
		; blocks
		move.w #19,blockx
		move.w #15,blocky
		move.w #5,blockno
		; jsr drawBlockXY

		; draw actual level
		; first level
		;move.l #8,actualLevelIndex
		;jsr loadActualLevel
		;jsr drawLevel

		; ----------------------------
		; snippets
		; ----------------------------
		; bsr.w	RndB						; Get a Random Number in D0
		; and.l	#$00000007,d0				; We are only interested in the first 8 (0 - 7)

		jmp nogui_here

		; highscore
		move.l #3,number_x
		move.l #0,number_y
		move.l hscore,number_no
		jsr drawNumbers

		move.l #19,number_x
		move.l #0,number_y
		move.l score,number_no
		; move.l #20,number_no
		jsr drawNumbers

nogui_here:

		lea.l demo_text,a4
		move.w #10,text_x
		move.w #5,text_y
		; jsr drawBlockText

		; ----------------------------
		; ingameloop
		; ----------------------------
ingameloop:


		; wait for the raster ... 
		bsr.w	WaitForRaster


		; ------------------------
		; new level?
		; ------------------------

		; is there an new level?
		move.l level,d0
		cmp.l  level_old,d0
		beq  no_newlevelhere

		move.l level,d0
		add.l #8,d0
		move.l d0,actualLevelIndex
		jsr loadActualLevel 
		; todo: blendin/out
		jsr drawLevel

		; highscore
		move.l #3,number_x
		move.l #0,number_y
		move.l hscore,number_no
		jsr drawNumbers

		move.l #19,number_x
		move.l #0,number_y
		move.l score,number_no
		; move.l #20,number_no
		jsr drawNumbers

		; level 
		move.w #19,blockx
		move.w #1,blocky
		move.l level,d0
		add.l  #1,d0
		move.l d0,number
		jsr displayBlockNumber

		; reset
		lea.l gameobjects,a6
		move.l #8,d5
kbvx:
		move.w #behavior_4dir_random,gameobject_behaviour(a6)
;		move.w #behavior_standstill,gameobject_behaviour(a6)
		move.w #type_enemy,gameobject_type(a6)

		move.l d5,d0
		cmp.l level_maxbonus,d0
		bhi.w nocollectives
		move.w #type_bonus,gameobject_type(a6)
nocollectives:

		add.l #gameobject_size_bytes,a6		
		dbra d5,kbvx

		lea.l gameobjects,a6
		move.w #type_avatar,gameobject_type(a6)
		move.w #behavior_mouse_direct,gameobject_behaviour(a6)

		; init types
		lea.l gameobjects,a6
		move.l #8,d7
abvxt:	
		move.l a6,a0	; pointers forever
		jsr initType
		add.l #gameobject_size_bytes,a6
		dbra d7,abvxt


no_newlevelhere:

	
 
		; ---------------------------
		; level based on time
		; ---------------------------
		; in game mode?
		cmp.l #state_gameover,game_state_sub
		beq gameover_nonewlevel

		move.l level,d0
		move.l d0,level_old

		; primitive counter
		add.l #1,timercounter
		move.l timercounter,d0
		cmp.l timestep,d0
		bcs lowerthantimer 

		move.l #0,timercounter
		add.l  #1,timer

;		; next level 
;		cmp.l #20,timer
;		bcs not_nextlevel
;		move.l #0,timer

		add.l #1,level
not_nextlevel:

lowerthantimer:

gameover_nonewlevel:

		; ---------------------------
		; BEHAVIOUR GAMEOBJECTS
		; ---------------------------

		; ---------------------------
		; MOVE SOMETHING
		; ---------------------------
;		lea		Spr3,a1
;		move.w	d5,d0
;		move.w	#90,d0
;		move.w	#90,d1
;		move.w	#$10,d2
;		bsr.w	MoveSprite


		move.l #8,d6 ; gameobjects_no
		lea.l gameobjects,a6
behave:		
		clr d0

		; jmp nobehavior

		; mouse direct
		move.w #0,CCR 
		cmp.w #behavior_mouse_direct,gameobject_behaviour(a6)
		bne.w notmousedirect

		move.w MouseX,gameobject_x(a6)
		move.w MouseY,gameobject_y(a6)

		jmp notbehav_4dir_random
notmousedirect:


		; jmp nosquarez
		; -----------------------
		; squarez behavior
		; -----------------------
		clr.l d0	
		move.w gameobject_behaviour(a6),d0
		move.w #0,CCR 
		cmp.w #behavior_4dir_random,d0
		bne.w  notbehav_4dir_random

		; generate a random speed here

		; default
		move.l #4,level_maxbonus
		move.w #1,d1
		move.w  d1,d0
		move.w  d0,gameobject_arg(a6)

		; level
		cmp.l #0,level
		bne lev0 
		move.w #1,d1
		move.w  d1,d0
		move.w  d0,gameobject_arg(a6)
		move.l #4,level_maxbonus
lev0:
		cmp.l #1,level
		bne lev1 		
		move.l #3,level_maxbonus
		move.w #1,d1
		move.w  d1,d0
		move.w  d0,gameobject_arg(a6)
lev1:	
		cmp.l #2,level
		bne lev2		
		move.l #3,level_maxbonus
		bsr.w	RndB						; Get a Random Number in D0
		and.w	#$00000001,d0
		move.w  d1,d0
		add.w   #1,d0
		move.w  d0,gameobject_arg(a6)
lev2:	

		cmp.l #1,level
		bne lev3		
		move.l #3,level_maxbonus
		bsr.w	RndB						; Get a Random Number in D0
		and.w	#$00000002,d0
		and.w	d1,d0				; We are only interested in the first 8 (0 - 7)
		add.w   #1,d0
		move.w  d0,gameobject_arg(a6)
lev3:	




		; position
		bsr.w	RndB						; Get a Random Number in D0
		and.w	#$0000000ff,d0				; We are only interested in the first 8 (0 - 7)
		; divu.w  #16,d0
		; mulu.w  #16,d0
		divu.w  #4,d0
		mulu.w  #4,d0
		move.w d0,gameobject_y(a6)
		move.w #120,gameobject_x(a6)

		bsr.w	RndB						; Get a Random Number in D0
		and.w	#$00000003,d0				; We are only interested in the first 8 (0 - 7)

		move.w #0,CCR 
		cmp.w #0,d0
		bne.w ntrandom_left
		move.w #behavior_right,gameobject_behaviour(a6)

			bsr.w	RndB						; Get a Random Number in D0
			and.w	#$0000000ef,d0				; We are only interested in the first 8 (0 - 7)
			divu.w  #4,d0
			mulu.w  #4,d0

			move.w d0,gameobject_y(a6)
			move.w #10,gameobject_x(a6)

		jmp notbehav_4dir_random
ntrandom_left:	

		move.w #0,CCR 
		cmp.w #1,d0
		bne.w ntrandom_right
		move.w #behavior_left,gameobject_behaviour(a6)

			bsr.w	RndB						; Get a Random Number in D0
			and.l	#$0000000ef,d0				; We are only interested in the first 8 (0 - 7)
			divu.w  #4,d0
			mulu.w  #4,d0
			move.w d0,gameobject_y(a6)
			move.w #300,gameobject_x(a6)

		jmp endbehav_4dir_random
ntrandom_right:		

		move.w #0,CCR 
		cmp.w #2,d0
		bne.w ntrandom_down
		move.w #behavior_down,gameobject_behaviour(a6)

			bsr.w	RndB						; Get a Random Number in D0
			and.l	#$0000000ff,d0				; We are only interested in the first 8 (0 - 7)
			divu.w  #4,d0
			mulu.w  #4,d0

			move.w d0,gameobject_x(a6)
			move.w #10,gameobject_y(a6)

		jmp endbehav_4dir_random
ntrandom_down:	

		move.w #0,CCR 
		cmp.w #3,d0
		bne.w ntrandom_up
		move.w #behavior_up,gameobject_behaviour(a6)

			bsr.w	RndB						; Get a Random Number in D0
			and.l	#$0000000ff,d0				; We are only interested in the first 8 (0 - 7)
			divu.w  #4,d0
			mulu.w  #4,d0

			move.w d0,gameobject_x(a6)
			move.w #180,gameobject_y(a6)

		jmp endbehav_4dir_random
ntrandom_up:

		jmp notbehav_4dir_random

endbehav_4dir_random: ; for all with new direction


notbehav_4dir_random:

		
		; -------------------
		; 4 directions
		; -------------------
		; move left		
		move.w gameobject_behaviour(a6),d0
		move.w #0,CCR 
		cmp.w #behavior_right,d0
		bne.w nobehavior_right		
		move.w gameobject_arg(a6),d0
		add.w  d0,gameobject_x(a6)
		move.w gameobject_x(a6),d0
		cmp.w #300,gameobject_x(a6)
		blt.w xhigherend
		move.w #behavior_4dir_random,gameobject_behaviour(a6)
xhigherend:
		jmp end_behavior
nobehavior_right:

		; move right	
		clr.l d0	
		move.w gameobject_behaviour(a6),d0
		move.w #0,CCR 
		cmp.w #behavior_left,d0
		bne.w nobehavior_left
		
		move.w gameobject_arg(a6),d0
		sub.w  d0,gameobject_x(a6)

		move.w gameobject_x(a6),d0
		cmp.w #10,d0
		bgt.w xlowerend
;		move.w #319,gameobject_x(a6)
		move.w #behavior_4dir_random,gameobject_behaviour(a6)
xlowerend:
		jmp end_behavior
nobehavior_left:

		; move down		
		move.w gameobject_behaviour(a6),d0
		move.w #0,CCR 
		cmp.w #behavior_down,d0
		bne.w nobehavior_down		
		move.w gameobject_arg(a6),d0
		add.w  d0,gameobject_y(a6)
		move.w gameobject_y(a6),d0
		cmp.w #300,gameobject_y(a6)
		blt.w yhigherend
		move.w #behavior_4dir_random,gameobject_behaviour(a6)
yhigherend:
		jmp end_behavior
nobehavior_down:


		; move up	
		clr.l d0	
		move.w gameobject_behaviour(a6),d0
		move.w #0,CCR 
		cmp.w #behavior_up,d0
		bne.w nobehavior_up
		
		move.w gameobject_arg(a6),d0
		sub.w  d0,gameobject_y(a6)
		move.w gameobject_y(a6),d0
		cmp.w #10,d0
		bgt.w ylowerend
;		move.w #319,gameobject_x(a6)
		move.w #behavior_4dir_random,gameobject_behaviour(a6)
ylowerend:
		jmp end_behavior
nobehavior_up:

		
nosquarez:

 

end_behavior:

		add.l  #gameobject_size_bytes,a6 ; gameobject_size
		dbra d6,behave

nobehavior:

;	------------------------
;	/END BEHVAVIOUR
;	------------------------

		; ---------------------------
		;  COLLISION
		; ---------------------------
			; jmp nocollision


		; not game over!
		cmp.l #state_gameover,game_state_sub
		beq nocollision


				move.l #8,d5 ; gameobjects_no
				lea.l gameobjects,a3
		collision:		
				
				clr d3
				; innerCollision
				move.l #8,d4 ; gameobjects_no
				lea.l gameobjects,a2
		innerCollision:		
				clr d2
				clr d1

				; no collision against the same object
				move.w #0,ccr
				cmp.l d4,d5
				bne notthesame
				jmp thesame
		notthesame:

				; box collision
				; with box colliders
				;   ______ 
				;  | a3  _|___
				;  |_____|a2 |
				;        |___|
				;

				clr.l d3
				clr.l d2
				clr.l d1
				move.w gameobject_y(a3),d3
				move.w gameobject_y(a2),d2
				move.w gameobject_height(a2),d1
				move.w #0,CCR
				add.w d1,d2
				cmp.w d2,d3
				bhi.w yhigher
				;  a3.y > a2.y+a2.height

				clr.l d3
				clr.l d2
				clr.l d1
				move.w gameobject_y(a3),d3
				move.w gameobject_y(a2),d2
				move.w gameobject_height(a3),d1
				move.w #0,CCR
				sub.w d1,d2
				cmp.w d2,d3
				bcs.w ylower	
				;  a3.y < a2.y-a3.height

				clr.l d3
				clr.l d2
				clr.l d1
				move.w gameobject_x(a3),d3
				move.w gameobject_x(a2),d2
				move.w gameobject_width(a2),d1
				add.w d1,d2
				move.w #0,CCR
				cmp.w d2,d3
				bhi.w xhigher
				;  a3.x > a2.x+a2.width

				clr.l d3
				clr.l d2
				clr.l d1
				move.w gameobject_x(a3),d3
				move.w gameobject_x(a2),d2
				move.w gameobject_width(a3),d1
				sub.w d1,d2
				move.w #0,CCR
				cmp.w d2,d3
				bcs.w xlower
				;  a3.x < a2.x-a3.width

				; ------------------------
				; avatar
				cmp.w #type_avatar,gameobject_type(a3)
				bne.w   noavatar

				; bonus consume
				; move.w    $DFF006,$DFF180 ; background
				cmp.w #type_bonus,gameobject_type(a2)
				bne  nobonus
				move.w #behavior_4dir_random,gameobject_behaviour(a2)
				add.l #10,score
				jmp noavatar
		nobonus:
				; rainbow
				; death 
				; move.w    $DFF006,$DFF180 ; background
				; move.l #0,score
				move.l #state_gameover,game_state_sub
				; disable sprite - use transparent sprite
				move.w #0,gameobject_animind(a3)

				; faehnchen
				move.l #19,d3
faehn:
				bsr.w	RndB						; Get a Random Number in D0
				and.l	#$00000003,d0				; We are only interested in the first 8 (0 - 7)
				move.w  d3,blockx
				move.w  #6,blocky
				move.w  #91,blockno
				cmp.l   #1,d0
				bne   not_alpha
				move.w  #106,blockno
				jmp   drawit
not_alpha:
				cmp.l   #2,d0
				bne	drawit
				move.w  #107,blockno
drawit:
				jsr 	drawBlockXY

				dbra d3,faehn

				; game over .-) 
				; no cursor any more ... 
				lea.l text_gameover,a4
				move.w #5,text_x
				move.w #6,text_y
				jsr drawBlockText

		noavatar:

				
				; rainbow
				; move.w    $DFF006,$DFF180 ; background

		xlower:
		xhigher:

		ylower: 
		yhigher:		

		thesame:

				add.l  #gameobject_size_bytes,a2 ; gameobject_size
				dbra d4,innerCollision
				; / innerCollision

				; collision
				add.l  #gameobject_size_bytes,a3 ; gameobject_size
				dbra d5,collision

		collision_done:

		nocollision:

		; ---------------------------
		; / END COLLISION
		; ---------------------------



		; ---------------------------
		; RENDER GAMEOBJECTS
		; ---------------------------
		; TO SPRITES (if there is a sprite representation)

		; ---------------------------
		; RENDER VISUALS 
		; UPDATE visual sprite data
		; ---------------------------
		; jmp notatall
		
		; ATTENTION
		; BITPLANES OF SPRITES ARE
		; 1 line : BITPLANE 0 + BITPLANE 1

		; following routine has two 
		; possiblities

		move.l #8,d6 ; gameobjects_no
		lea.l gameobjects,a6

rendervisualdata:		

		; dump switch		
		; is there a sprite? 

		; check oldind != actualind
;		clr.l d4
		move.w gameobject_animindold(a6),d4
		cmp.w gameobject_animind(a6),d4
		beq.w nonewanim

		; overwrite old version
		clr.l d3
		move.w gameobject_animind(a6),d3
		move.w d3,gameobject_animindold(a6)
		
		; create ...		
		; lea.l		Cotton,a2		; test

		; normal version ... 
		lea.l SpriteVisualData,a2 ; Source Address
		lea.l SpriteVisualData,a3 ; Source Address
		; very dark > todo: shift and shift or mulu

		lea.l spritecolor_01_0,a4

		clr.l d2
; problem here!
		move.w gameobject_animind(a6),d2
; test 		
;		move.w #1,d2
		; jmp nocounting
		; move.l d6,d2
		cmp.w #80,d2 ; what the hell ... 
		bhi.w nocounting
		cmp.w #0,d2
		beq.w nocounting
		sub.l #1,d2
counter: 
		; spritevisualdata_object_bytes equ 64+4*2
		add.l #spritevisualdata_object_bytes,a2
		add.l #spritevisualdata_object_bytes,a3
		dbra d2,counter
nocounting:

		; testing
		; lea.l SpriteVisualData,a2
		; lea.l Diaper,a2
		; add.l #2*spritevisualdata_object_bytes,a2

		clr.l d5
		move.w gameobject_spr(a6),d5
		cmp.w #0,d5
		bne.w vnot0
		lea		Spr0_Data,a1		; DESTINATION Address
		lea.l spritecolor_01_0,a4
		jmp vdoit
vnot0:
		cmp.w #1,d5
		bne.w vnot1
		lea		Spr1_Data,a1		; DESTINATION Address
		lea.l spritecolor_01_0,a4
		jmp vdoit
vnot1:
		cmp.w #2,d5
		bne.w vnot2
		lea		Spr2_Data,a1		; DESTINATION Address
		lea.l spritecolor_23_0,a4
		jmp vdoit
vnot2:
		cmp.w #3,d5
		bne.w vnot3
		lea		Spr3_Data,a1		; DESTINATION Address
		lea.l spritecolor_23_0,a4
		jmp vdoit
vnot3:
		cmp.w #4,d5
		bne.w vnot4
		lea		Spr4_Data,a1		; DESTINATION Address
		lea.l spritecolor_45_0,a4
		jmp vdoit
vnot4:
		cmp.w #5,d5
		bne.w vnot5
		lea		Spr5_Data,a1		; DESTINATION Address
		lea.l spritecolor_45_0,a4
		jmp vdoit
vnot5:
		cmp.w #6,d5
		bne.w vnot6
		lea		Spr6_Data,a1		; DESTINATION Address
		lea.l spritecolor_67_0,a4
		jmp vdoit
vnot6:
		cmp.w #7,d5
		bne.w vnot7
		lea		Spr7_Data,a1		; DESTINATION Address
		lea.l spritecolor_67_0,a4
		jmp vdoit
vnot7:
		jmp vedoit
vdoit:
		; bsr.w   copyVisualSpriteData

		; direct version with sprite data plane_0, plane_1
		; copy correct data
		; add.l   #2,a1
		moveq.l	#16,d2					; Sprite Image Data Lenght in Long Words
directData:
		move.l	(a2)+,(a1)+					; Copy from Source to destination in Long Words
		dbra	d2,directData			; Loop Till we Copy

		; copy now the color data
		; 2 sprites have 3 colors together 01,23,45,67
		; you could also ! attach them than you have 4 sprites ... dam nothing

		; a2 the end of sprite data
		; move now to 
		

		; manual
		jmp jackmet
		lea.l spritecolor_01_0,a1 
		move.w #$0fff,(a1)+
		lea.l spritecolor_01_1,a1 
		move.w #$0fff,(a1)
		lea.l spritecolor_01_2,a1 
		move.w #$0fff,(a1)
		lea.l spritecolor_01_3,a1 
		move.w #$0fff,(a1)

		lea.l spritecolor_01_0,a1 
		move.w #$0000,(a1)+
		lea.l spritecolor_01_1,a1 
		move.w #$0888,(a1)
		lea.l spritecolor_01_2,a1 
		move.w #$0aaa,(a1)
		lea.l spritecolor_01_3,a1 
		move.w #$0fff,(a1)
jackmet:
		

		; jmp nonono_notanymore
		; get color data
		add.l #spritevisualdata_object_bytes,a3
		sub.l #4*2,a3
		move.l a4,a1 
		move.w (a3)+,(a1)
		add.l #4,a1
		move.w (a3)+,(a1)
		add.l #4,a1
		move.w (a3)+,(a1)
		add.l #4,a1
		move.w (a3)+,(a1)
nonono_notanymore:		

no_directdata:



vedoit:

nonewanim:
		add.l #gameobject_size_bytes,a6
		dbra d6,rendervisualdata



		; ---------------------------
		; RENDER GAMEOBJECTS X/Y
		; ---------------------------
		; xy to hardware sprites
		move.l #8,d6 ; gameobjects_no
		lea.l gameobjects,a6

render:		

		; dump switch		
		; is there a sprite? 
		move.w gameobject_spr(a6),d5

		cmp #0,d5
		bne not0
		lea		Spr0,a1
		jmp rendertospritenow	
not0:

		cmp #1,d5
		bne not1
		lea		Spr1,a1
		jmp rendertospritenow		
not1:
		cmp #2,d5
		bne not2
		lea		Spr2,a1
		jmp rendertospritenow
not2:
		cmp #3,d5
		bne not3
		lea		Spr3,a1
		jmp rendertospritenow
not3:
		cmp #4,d5
		bne not4
		lea		Spr4,a1
		jmp rendertospritenow
not4:
		cmp #5,d5
		bne not5
		lea		Spr5,a1
		jmp rendertospritenow
not5:
		cmp #6,d5
		bne not6
		lea		Spr6,a1
		jmp rendertospritenow
not6:
		cmp #7,d5
		bne not7
		lea		Spr7,a1
		jmp rendertospritenow
not7:
		; not found
		jmp norendertosprite

rendertospritenow:

		; render now to hardware sprites
		move.w  gameobject_y(a6),d0
		move.w  gameobject_x(a6),d1
		move.w	#$10,d2
		bsr.w	MoveSprite

norendertosprite:

		add.l  #gameobject_size_bytes,a6 ; gameobject_size
		dbra d6,render

notatall:


		; ---------------------------
		; GUI
		; ---------------------------
		; jsr DrawText
		move.l old_score,d0
;   jmp no_newhighscore
		cmp.l score,d0
		beq no_newscore
		; write direct in the screen memory
		move.l #19,number_x
		move.l #0,number_y
		move.l score,number_no
		; move.l #20,number_no
		jsr drawNumbers
		move.l score,d0
		move.l d0,old_score
no_newscore:

		; new real highscore
		move.l score,d0
		cmp hscore,d0
		bcc no_newhighscore
		move.l score,hscore
		move.l #3,number_x
		move.l #0,number_y
		move.l hscore,number_no
		jsr drawNumbers
no_newhighscore:

		; test
		;move.w #17,blockx
		;move.w #3,blocky
		;move.w #4+39,blockno
		;jsr drawBlockXY

		; ---------------------------
		; MUSIC
		; ---------------------------
		bsr.w	mt_music

		; --------------------------
		; behavior service
		; --------------------------

		; --------------------------
		; mouse control
		; --------------------------
	    jsr ReadMouse

		; --------------------------
		; block animations
		; --------------------------
		jsr BlockAnimation

		; --------------------------
		; "water simulation"
		; --------------------------
		; manipulate waves ...
		; effect_wave
		jsr WaterEffect

		; press mouse
  	    btst   #6,$BFE001      ; Test left mouse button
   		bne.s  notpressedmouse
		cmp.l #state_gameover,game_state_sub
		bne notpressedmouse

		; back ...

		move.l #state_menu,game_state_sub
		jmp  menustart
notpressedmouse:



		jmp ingameloop ; gameloop
		; ---------------------------
		; INGAME LOOP ^
		; ---------------------------


exit:	
		bsr.w	mt_end
		; ---------------------------
		; BACK TO AMIGADOS
		; ---------------------------

		movem.l	(SP)+,d0-d7/a0-a6

		rts

tryout:

		rts 

;======================================================================================================================
; Prints a Character to the screen
;======================================================================================================================

DrawText:
	MOVE.L	StrCodingPtr(PC),A0			; Text Address in a0
	MOVEQ	#0,D2					; Clear d2
	MOVE.B	(A0)+,D2				; Next Char d2
	CMP.B	#$ff,d2					; End of text? ($FF)
	beq.s	XText_Exit				; Yes - Exit
	TST.B	d2						; End of Line? ($00)
	bne.s	XNotEOL					; No Not End Of Line

	ADD.L	#20*7,XBitplanePtr		; Screen is 40 byte wide and the font is 8 bytes high
	ADDQ.L	#1,StrCodingPtr				; Hold the column on the on the screen or where we are on the current line
									; hence reset it to 1 since we are starting a new line
	move.b	(a0)+,d2				; First character on the line skipping 0

XNotEOL:
	SUB.B	#$20,D2					; Subtract 32 from the char ASCII value 
									; so that we can transform for example
									; if it was a space which is $20 to a $00
									; the asterics $21 to $01 etc etc
	LSL.W	#3,D2					; Multiply the same number by 8,
									; since the font is 8 pixels high
	MOVE.L	D2,A2					; move the multiplication result to A2
	ADD.L	#XFont,A2				; Add the value in A2 to the font Base address

	; Display char on bitplanes
	MOVE.L	XBitplanePtr(PC),A3		; Bitplane Address in a3
	MOVE.B	(A2)+,40*0(A3)			; Print Line 1 of char
	MOVE.B	(A2)+,40*1(A3)			; Print Line 2 of char
	MOVE.B	(A2)+,40*2(A3)			; Print Line 3 of char
	MOVE.B	(A2)+,40*3(A3)			; Print Line 4 of char
	MOVE.B	(A2)+,40*4(A3)			; Print Line 5 of char
	MOVE.B	(A2)+,40*5(A3)			; Print Line 6 of char
	MOVE.B	(A2)+,40*6(A3)			; Print Line 7 of char
	MOVE.B	(A2)+,40*7(A3)			; Print Line 8 of char

	ADDQ.L	#1,XBitplanePtr	 		; We need to move 8 bits or 1 byte for next character
	ADDQ.L	#1,StrCodingPtr				; Next character to print

XBitplanePtr:
	dc.l	GameScreenBitplanes

XText_Exit:
	RTS

StrCodingPtr:
	dc.l	StrCoding
StrCoding:
    dc.b    "sq"
    dc.b    $ff

XFont:
	incbin	"gfx/nice.fnt"

;======================================================================================================================
;  cryAengine
;======================================================================================================================
	even

gameobjects_no equ 3 //  

gameobject_size equ 17 ; members 
gameobject_size_bytes equ 34 ; gameobject_size * 2 ; word

gameobject_state equ 0
gameobject_x equ 1*2 
gameobject_y equ 2*2 
gameobject_width equ 3*2
gameobject_height equ 4*2 
gameobject_colwidth equ 5*2
gameobject_colheight equ 6*2 
gameobject_type equ 7*2
gameobject_typesub equ 8*2 
gameobject_art equ 9*2   ; 
gameobject_animmin equ 10*2  ; -- represented in a sprite
gameobject_animmax equ 11*2  ; 
gameobject_animind equ 12*2 ;
gameobject_animindold equ 13*2 ;
gameobject_arg equ 14*2 ;
gameobject_behaviour equ 15*2 ;
gameobject_spr equ 16*2  ; -- represented in a sprite

; > update also length of a gameobject ^ up 

; behavior
behavior_standstill equ 0 ; stand still
behavior_mouse_direct equ 1 ; 
behavior_mouse_relative equ 2 ; 

; squarez behaviors
behavior_left equ 3 ; 
behavior_right equ 4 ; 
behavior_up equ 5 ; 
behavior_down equ 6 ; 
behavior_4dir_random equ 7 ; generates left>down and creates 

; anim 
anim_indold_default equ 42000

; type
type_neutral equ 0

type_transparent_animind equ 0; transparent

type_avatar equ 1
type_avatar_animind equ 2 ; anim

type_bonus equ 2
type_bonus_animind equ 3  ; anim

type_enemy equ 3
type_enemy_animind equ 4 ; anim


; ------------------------
; types
; ------------------------
; in a0 pointer to the gameobject
initType:

	cmp.w #type_avatar,gameobject_type(a0)
	bne.w init_nottheavatar
	move.w #type_avatar_animind,gameobject_animind(a0)
	move.w #anim_indold_default,gameobject_animindold(a0)
init_nottheavatar:

	cmp.w #type_enemy,gameobject_type(a0)
	bne.w init_nottheenemy
	move.w #type_enemy_animind,gameobject_animind(a0)
	move.w #anim_indold_default,gameobject_animindold(a0)
init_nottheenemy:

	cmp.w #type_bonus,gameobject_type(a0)
	bne.w init_notthebonus
	move.w #type_bonus_animind,gameobject_animind(a0)
	move.w #anim_indold_default,gameobject_animindold(a0)
init_notthebonus:

	rts

; ------------------------
; important vars
; ------------------------
	even
game_state dc.l 0
game_state_sub dc.l 0

state_intro equ 0  ; title too
state_menu equ 1
state_ingame equ 2
state_gameover equ 3

statesub_main equ 0
statesub_story equ 1
statesub_howto equ 2
statesub_play equ 3
statesub_about equ 4 ; or credits
statesub_higscore equ 5

statesub_gameover equ 7
statesub_won equ 8


timer dc.l   0

; for counts timer + 1
timercounter:
	 dc.l 0
timestep:
 dc.l 200


level: 	dc.l 	0
level_old: 	dc.l 	0

level_maxbonus: dc.l 4

score: 	dc.l 	1
old_score: dc.l  0
hscore: dc.l 	100
lifes: 	dc.l 	3
health: dc.l 	100

scoredefault: 	dc.l 	0
hscoredefault: dc.l 	100
lifesdefault: 	dc.l 	3
healthdefault: dc.l 	100

; ------------------------
; gameobjects
; ------------------------
	even
gameobjects:

gameobject0:
	dc.w 1    ; state
	gameobject0_x:
	dc.w 20   ; x
	gameobject0_y:
	dc.w 100   ; y
	dc.w 16   ; width
	dc.w 16   ; height
	dc.w 16   ; col width
	dc.w 16   ; col height
	dc.w 0   ; type
	dc.w 0   ; typesub
	dc.w 0   ; art
	dc.w 0   ; animmin
	dc.w 0   ; animmax
	dc.w 0   ; animind
	dc.w 21000   ; animindold
	dc.w 1   ; arg
	dc.w 0   ; behavior
	dc.w 0   ; spr

gameobject1:
	dc.w 1    ; state
	dc.w 40   ; x
	dc.w 100   ; y
	dc.w 16   ; width
	dc.w 16   ; height
	dc.w 16   ; col width
	dc.w 16   ; col height
	dc.w 0   ; type
	dc.w 0   ; typesub
	dc.w 0   ; art
	dc.w 0   ; animmin
	dc.w 0   ; animmax
	dc.w 1   ; animind
	dc.w 21000   ; animindold
	dc.w 2   ; arg
	dc.w 0   ; behavior
	dc.w 1   ; spr

gameobject2:
	dc.w 1    ; state
	dc.w 60   ; x
	dc.w 100   ; y
	dc.w 16   ; width
	dc.w 16   ; height
	dc.w 16   ; col width
	dc.w 16   ; col height
	dc.w 0   ; type
	dc.w 0   ; typesub
	dc.w 0   ; art
	dc.w 0   ; animmin
	dc.w 0   ; animmax
	dc.w 2   ; animind
	dc.w 21000   ; animindold
	dc.w 1   ; arg
	dc.w 0   ; behavior
	dc.w 2   ; spr

gameobject3:
	dc.w 1    ; state
	dc.w 80   ; x
	dc.w 100   ; y
	dc.w 16   ; width
	dc.w 16   ; height
	dc.w 16   ; col width
	dc.w 16   ; col height
	dc.w 0   ; type
	dc.w 0   ; typesub
	dc.w 0   ; art
	dc.w 0   ; animmin
	dc.w 0   ; animmax
	dc.w 3   ; animind
	dc.w 21000   ; animindold
	dc.w 3   ; arg
	dc.w 0   ; behavior
	dc.w 3   ; spr

gameobject4:
	dc.w 1    ; state
	dc.w 100   ; x
	dc.w 100   ; y
	dc.w 16   ; width
	dc.w 16   ; height
	dc.w 16   ; col width
	dc.w 16   ; col height
	dc.w 0   ; type
	dc.w 0   ; typesub
	dc.w 0   ; art
	dc.w 0   ; animmin
	dc.w 0   ; animmax
	dc.w 4   ; animind
	dc.w 21000   ; animindold
	dc.w 1   ; arg
	dc.w 0   ; behavior
	dc.w 4   ; spr

gameobject5:
	dc.w 1    ; state
	dc.w 120   ; x
	dc.w 100   ; y
	dc.w 16   ; width
	dc.w 16   ; height
	dc.w 16   ; col width
	dc.w 16   ; col height
	dc.w 0   ; type
	dc.w 0   ; typesub
	dc.w 0   ; art
	dc.w 0   ; animmin
	dc.w 0   ; animmax
	dc.w 5   ; animind
	dc.w 21000   ; animindold
	dc.w 2   ; arg
	dc.w 0   ; behavior
	dc.w 5   ; spr

gameobject6:
	dc.w 1    ; state
	dc.w 140   ; x
	dc.w 100   ; y
	dc.w 16   ; width
	dc.w 16   ; height
	dc.w 16   ; col width
	dc.w 16   ; col height
	dc.w 0   ; type
	dc.w 0   ; typesub
	dc.w 0   ; art
	dc.w 0   ; animmin
	dc.w 0   ; animmax
	dc.w 6   ; animind
	dc.w 21000   ; animindold
	dc.w 3   ; arg
	dc.w 0   ; behavior
	dc.w 6   ; spr

gameobject7:
	dc.w 1    ; state
	dc.w 160   ; x
	dc.w 100   ; y
	dc.w 16   ; width
	dc.w 16   ; height
	dc.w 16   ; col width
	dc.w 16   ; col height
	dc.w 0   ; type
	dc.w 0   ; typesub
	dc.w 0   ; art
	dc.w 0   ; animmin
	dc.w 0   ; animmax
	dc.w 7   ; animind
	dc.w 21000   ; animindold
	dc.w 1   ; arg
	dc.w 0   ; behavior
	dc.w 7   ; spr

gameobject8:
	dc.w 1    ; state
	dc.w 180   ; x
	dc.w 100   ; y
	dc.w 16   ; width
	dc.w 16   ; height
	dc.w 16   ; col width
	dc.w 16   ; col height
	dc.w 0   ; type
	dc.w 0   ; typesub
	dc.w 0   ; art
	dc.w 0   ; animmin
	dc.w 0   ; animmax
	dc.w 0   ; animind
	dc.w 21000   ; animindold
	dc.w 0   ; arg
	dc.w 0   ; behavior
	dc.w 42   ; spr

gameobject9:
	dc.w 1    ; state
	dc.w 200   ; x
	dc.w 100   ; y
	dc.w 16   ; width
	dc.w 16   ; height
	dc.w 16   ; col width
	dc.w 16   ; col height
	dc.w 0   ; type
	dc.w 0   ; typesub
	dc.w 0   ; art
	dc.w 0   ; animmin
	dc.w 0   ; animmax
	dc.w 0   ; animind
	dc.w 21000   ; animindold
	dc.w 0   ; arg
	dc.w 0   ; behavior
	dc.w 42   ; spr


	; space for more gameobject

	dcb.w	5*18*2,0

;======================================================================================================================
;  cryAengine: levels
;======================================================================================================================

actualLevelIndex: dc.l 0


; load into the actual level
loadActualLevel:

	lea.l levels,a1
	move.l actualLevelIndex,d0
	cmp.l #0,d0
	beq nocounting_levels
	sub.l #1,d0
adac_counting:
	add.l #20*16+2,a1
	dbra d0,adac_counting 	
nocounting_levels:

;	lea.l levels,a1

	move.l #20*16,d1
	lea.l actualLevel,a2
cp:
	move.b (a1)+,(a2)+
	dbra d1,cp

	rts

; draw the actual level
drawLevel:

	move.l #15,d7
	
	lea.l actualLevel,a4

	move.l #0,d5
ly:
	move.w d5,blocky
	move.l #19,d6
	move.l #0,d4
lx:
	move.w d4,blockx
	clr.l  d0
	move.b (a4)+,d0
	move.w d0,blockno
	jsr drawBlockXY
	add.l #1,d4
	dbra d6,lx

	add.l #1,d5	
	dbra d7,ly

	rts


	even

;======================================================================================================================
;  cryAengine: block animations
;======================================================================================================================
; animate actual level 
; one animation 4 blocks
block_anim_index: dc.l 0
block_anim_speed: dc.l 5

block_anim_startblock: dc.l 119
block_anim_stopblock: dc.l 145

BlockAnimation:

	add.l  #1,block_anim_index
	move.l block_anim_speed,d0
	cmp.l  block_anim_index,d0
	bne no_blockanimation
	move.l #0,block_anim_index	

	move.l #15,d7
	
	lea.l actualLevel,a4

	move.l #0,d5
bly:
	move.w d5,blocky
	move.l #19,d6
	move.l #0,d4
blx:
	move.w d4,blockx
	clr.l  d0
	move.b (a4)+,d0
	
	move.l block_anim_startblock,d1
	cmp.b d0,d1
	bhi.b notimp
	move.l block_anim_stopblock,d1
	cmp.b d0,d1
	bcs.b notimp

	; animate now ...
	add.b #1,d0

	; %4 
	clr.l d1
	move.b d0,d1
	divu #4,d1
	swap d1 ; %
	cmp.w #0,d1
	bne.w not_4
	
	clr.l d0
	move.b -1(a4),d0
	divu #4,d0
	mulu #4,d0
	; move.b #120,d0

not_4: 
	move.b d0,-1(a4)
	move.w d0,blockno
	jsr drawBlockXY



notimp:

	add.l #1,d4
	dbra d6,blx

	add.l #1,d5	
	dbra d7,bly

no_blockanimation:

		rts 

;======================================================================================================================
;  cryAengine: numbers
;======================================================================================================================
number_no: dc.l 0
number_x: dc.l 0
number_y: dc.l 0
number_size: dc.l 3

; tmp
number_tmp_x: dc.l 0
number_tmp: dc.l 0

; print it revers    <-startx
drawNumbers:

		move.l number_size,d4
		move.l number_no,number_tmp 
		; move.l #123,number_tmp
		move.l number_y,d0
		move.w d0,blocky
		move.l number_x,number_tmp_x
dn:		

		move.l number_tmp_x,d0
		move.w d0,blockx
		move.l  number_tmp,d3
		divu #10,d3
		clr d0
		move.w d3,d0
		move.l d0,number_tmp
		clr d0
		swap d3
		move.w d3,d0
		add.l #39,d0
		move.w d0,blockno

		jsr drawBlockXY

		sub.l #1,number_tmp_x
		dbra d4,dn

		rts


;======================================================================================================================
;  cryAengine: blocks
;======================================================================================================================
			even
blockx: 	; * 16
	dc.w	5
blocky: 	; * 16
	dc.w    3
blockno:
	dc.w	1	



; drawBlockXY
drawBlockXY:
	; 2**16

	lea.l  blocks,a0
	; add.l  #(2*16)*12,a0 ; (2*16)*4 = 1line (2byte) * 16 *4  planes
	clr.l d0
	move.w blockno,d0
	cmp.w #0,d0
	beq   ncd
	sub.w #1,d0
cd: 
	add.l  #(2*16)*4,a0
	dbra d0,cd
ncd:
	; screen
	lea.l  GameScreenBitplanes,a1

	; + y*16*40
	clr.l d0
	move.w blocky,d0
	cmp.w #0,d0
	beq   yncd
	sub.w #1,d0
ycd: 
	add.l  #40*16,a1
	dbra d0,ycd
yncd:

	; x
	clr.l d0
	move.w blockx,d0
	cmp.w #0,d0
	beq   xncd
	sub.w #1,d0

xcd: 
	add.l  #2,a1
	dbra d0,xcd
xncd:


	; simpler
	move.l  a1,a2 ; backup

	; plane 0 
	move.l #16-1,d0
for_plane0:
	move.b (a0)+,(a1)+
	move.b (a0)+,(a1)+
	add.l #40-2,a1
;	move.b #255,(a1)+
;	move.b #255,(a1)+
;	add.l #20-2,a1
	dbra d0,for_plane0

	move.l a2,a1
	add.l #40*256,a1 ; a line 40b * 256 = screen	
	move.l #16-1,d0
for_plane1:
	move.b (a0)+,(a1)+
	move.b (a0)+,(a1)+
	add.l #40-2,a1
	dbra d0,for_plane1

	move.l a2,a1
	add.l #2*40*256,a1 ; a line 40b * 256 = screen	
	move.l #16-1,d0
for_plane2:
	move.b (a0)+,(a1)+
	move.b (a0)+,(a1)+
	add.l #40-2,a1
	dbra d0,for_plane2

	move.l a2,a1
	add.l #3*40*256,a1 ; a line 40b * 256 = screen	
	move.l #16-1,d0
for_plane3:
	move.b (a0)+,(a1)+
	move.b (a0)+,(a1)+
	add.l #40-2,a1
	dbra d0,for_plane3



	rts


; displayBlock
	even
number: 
	dc.l    1 

; display Block No > 1,2,4,5, 
displayBlockNumber:

		move.l number,d0
		add.l #39,d0	 
		move.w d0,blockno
		jsr drawBlockXY		

		rts

		even
; -------------------------
; texts
; -------------------------
text_gameover: dc.b "GAME OVER",0
 
		even
; ----------------------
; drawBlockText
; ----------------------
; text in a4
;

demo_text: dc.b "CODE FOREVER",0
	even

text_x: dc.w 0
text_y: dc.w 0
text_x_max: dc.w 20

text_tmp_x: dc.w 0
text_tmp_y: dc.w 0

; usage:
; move.w #5,text_x
; move.w #,text_y
; ; move.lw text_x_max
; lea.l demo_text,a4
; jsr drawBlockText

drawBlockText:
	move.w text_x,text_tmp_x
	move.w text_y,text_tmp_y

;	lea.l demo_text,a4
while_text:

	clr.l d0
	move.b (a4),d0
	add.l  #1,a4

	cmp.b #0,d0
	beq.b drawEnd_def

	cmp.b #32,d0
	bne.b n_space
	move.b #12,d0
	jmp   drawNowDirect
n_space:

	sub.b #65,d0
	add.b #13,d0

drawNowDirect:

	move.w text_tmp_x,blockx
	move.w text_tmp_y,blocky
	move.w d0,blockno
	jsr drawBlockXY

	add.w #1,text_tmp_x
	move.w text_x_max,d1
	cmp.w text_tmp_x,d1
	bne.w text_x_maxtttt
	move.w text_x,text_tmp_x
	add.w  #1,text_tmp_y
text_x_maxtttt:

	jmp while_text

drawEnd_def:	

	rts





;======================================================================================================================
;  cryAengine: sprites mode 
;======================================================================================================================

setupSpritesMouseMode:

		lea		sprite0,a2		; Source Address
		lea		Spr0_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData

		; colors
		lea	sprite0,a3		; Source Address		
		add.l #64,a3 
;		add.l #spritevisualdata_object_bytes,a3
		lea.l spritecolor_01_0,a1 		
		move.w (a3)+,(a1)
		add.l #4,a1
		move.w (a3)+,(a1)
		add.l #4,a1
		move.w (a3)+,(a1)
		add.l #4,a1
		move.w (a3)+,(a1)


		lea		sprite0,a2		; Source Address		
		add.l   #spritevisualdata_object_bytes,a2
		lea		Spr1_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData

		lea		sprite0,a2		; Source Address
		add.l  #spritevisualdata_object_bytes,a2
		lea		Spr2_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData

		lea		sprite0,a2		; Source Address
		add.l #spritevisualdata_object_bytes,a2
		lea		Spr3_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData

		lea		sprite0,a2		; Source Address
		add.l #spritevisualdata_object_bytes,a2
		lea		Spr4_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData

		lea		sprite0,a2		; Source Address
		add.l   #spritevisualdata_object_bytes,a2
		lea		Spr5_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData

		lea		sprite0,a2		; Source Address
		add.l   #spritevisualdata_object_bytes,a2
		lea		Spr6_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData

		lea		sprite0,a2		; Source Address
		add.l   #spritevisualdata_object_bytes,a2
		lea		Spr7_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData



		rts

;======================================================================================================================
;  cryAengine: visual data 
;======================================================================================================================

		lea		sprite0,a2		; Source Address
		lea		Spr0_Data,a1		; DESTINATION Address
		; bsr.w   copyVisualSpriteData

	; image data
	; sprx_data

	copyVisualSpriteData:
		moveq.l	#16,d2					; Sprite Image Data Lenght in Long Words
	XCopyImgSprDatax:
		move.l	(a2)+,(a1)+					; Copy from Source to destination in Long Words
		dbra	d2,XCopyImgSprDatax			; Loop Till we Copy
	rts


;======================================================================================================================
;  cryAengine: WAVE-EFFECT
;======================================================================================================================
	even


WaterEffect:

		; version 1.0 
 	   ; plane 0
  	   lea.l effect_wave,a2
;	   move.l a2,effect_wave_pointer	   
	   lea.l GameScreenBitplanes,a0 ; start screen
	   lea.l GameScreenBitplanes,a1 ; start screen
	   add.l #40*(256-41),a0	   
	   add.l #40*(256-40),a1
	   move.l #38,d1
	   move.l #19,d1
cpy:	
		move.l (a2),d0
		mulu #40,d0
		sub.l d0,a0
	   move.l #19,d2
cpxor: 
		move.w (a0)+,(a1)+
		dbra d2,cpxor
	    sub.l #120,a0
	    add.l #40,a1
		dbra d1,cpy
		; /plane 0

	   ; plane 1
  	   lea.l effect_wave,a2
;	   move.l a2,effect_wave_pointer	   
	   lea.l GameScreenBitplanes,a0 ; start screen
	   lea.l GameScreenBitplanes,a1 ; start screen
	   add.l #40*(256-41),a0	   
	   add.l #40*(256-40),a1
	   add.l #40*256,a0
	   add.l #40*256,a1
	   move.l #38,d1
	   move.l #19,d1
cpy1:	
		move.l (a2),d0
		mulu #40,d0
		sub.l d0,a0
	   move.l #19,d2
cpxor1: 
		move.w (a0)+,(a1)+
		dbra d2,cpxor1
	    sub.l #120,a0
	    add.l #40,a1
		dbra d1,cpy1
		; /plane 1

		; plane 2
  	   lea.l effect_wave,a2
;	   move.l a2,effect_wave_pointer	   
	   lea.l GameScreenBitplanes,a0 ; start screen
	   lea.l GameScreenBitplanes,a1 ; start screen
	   add.l #40*(256-41),a0	   
	   add.l #40*(256-40),a1
	   add.l #80*256,a0
	   add.l #80*256,a1
	   move.l #38,d1
	   move.l #19,d1
cpy2:	
		move.l (a2),d0
		mulu #40,d0
		sub.l d0,a0
	   move.l #19,d2
cpxor2: 
		move.w (a0)+,(a1)+
		dbra d2,cpxor2
	    sub.l #120,a0
	    add.l #40,a1
		dbra d1,cpy2
		; /plane 2
		
	   ; -----------------------
	   ; move waves now
	   ; -----------------------
	   jmp nomore_x
	   add.l #1,effect_water_counter_uber
	   cmp.l #3,effect_water_counter_uber
	   bne effect_water_nolo_ost_tox
	   move.l #0,effect_water_counter_uber	

	   add.l #1,effect_water_counter
	   cmp.l #3,effect_water_counter
	   bne effect_water_nolo_ost
	   move.l #0,effect_water_counter	   
effect_water_nolo_ost:
effect_water_nolo_ost_tox:
nomore_x:


	   lea.l effect_wave,a2
  	   move.l #20,d4
	   move.l #0,d3
wavecontrol:
		move.l  #2,(a2)+
		dbra d4,wavecontrol
effect_water_nolo:

		rts

effect_water_counter: dc.l 0

effect_water_counter_uber: dc.l 0

effect_wave_pointer: dc.l 1

effect_wave: 
	dc.l 1
	dc.l 1
	dc.l 2
	dc.l 3
	dc.l 2
	dc.l 2
	dc.l 1
	dc.l 3
	dc.l 1
	dc.l 2
	dc.l 3
	dc.l 4
	dc.l 5
	dc.l 3
	dc.l 3
	dc.l 2
	dc.l 1
	dc.l 1
	dc.l 2
	dc.l 1
	dc.l 1
	dc.l 1
	dc.l 2
	dc.l 3
	dc.l 2
	dc.l 2
	dc.l 1
	dc.l 3
	dc.l 1
	dc.l 2
	dc.l 3
	dc.l 4
	dc.l 5
	dc.l 3
	dc.l 3
	dc.l 2
	dc.l 1
	dc.l 1
	dc.l 2
	dc.l 1
	dc.l 1
	dc.l 1
	dc.l 2
	dc.l 3
	dc.l 2
	dc.l 2
	dc.l 1
	dc.l 3
	dc.l 1
	dc.l 2
	dc.l 3
	dc.l 4
	dc.l 5
	dc.l 3
	dc.l 3
	dc.l 2
	dc.l 1
	dc.l 1
	dc.l 2
	dc.l 1
	dc.l 1
	dc.l 1
	dc.l 2
	dc.l 3
	dc.l 2
	dc.l 2
	dc.l 1
	dc.l 3
	dc.l 1
	dc.l 2
	dc.l 3
	dc.l 4
	dc.l 5
	dc.l 3
	dc.l 3
	dc.l 2
	dc.l 1
	dc.l 1
	dc.l 2
	dc.l 1
; -----------------------------
; COLORS
; -----------------------------
		even
colors: 
	include	"colors.s"

; -----------------------------
; LEVELS
; -----------------------------
; levels from blockeditor

actualLevel:

	; demo level 
             dc.b 0,1,2,3,4,5,1,1,4,0,0,0,0,0,0,0,0,0,0,0
             dc.b 0,0,2,4,1,4,1,3,4,1,3,3,3,3,0,5,0,0,0,0
             dc.b 3,5,2,4,1,4,1,3,4,1,1,1,1,3,3,5,0,0,0,0
             dc.b 3,5,2,4,4,4,1,3,4,1,3,3,3,3,0,5,0,0,0,0
             dc.b 4,3,2,3,4,4,1,3,4,1,3,0,0,0,0,5,0,0,0,0
             dc.b 4,3,5,3,3,3,1,3,4,0,3,0,0,0,0,0,0,0,0,0
             dc.b 4,3,1,3,1,1,1,3,4,0,0,0,4,4,4,0,0,0,0,0
             dc.b 3,3,3,3,3,4,4,4,4,0,0,0,0,0,4,4,0,0,0,0
             dc.b 0,3,0,0,0,0,0,3,0,4,4,0,0,0,0,4,0,0,0,0
             dc.b 0,3,0,4,0,0,0,3,0,0,4,0,0,0,0,4,0,0,0,0
             dc.b 0,3,0,4,0,0,4,0,0,0,0,0,0,4,4,0,0,0,0,0
             dc.b 0,0,0,4,0,4,4,0,0,0,0,0,4,4,0,0,0,0,0,0
             dc.b 0,0,0,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0
             dc.b 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
             dc.b 1,0,0,0,0,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0
             dc.b 1,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
	even
levels:
	include	"level0.s"
	include	"level1.s"
	include	"level2.s"
	include	"level3.s"
	include	"level4.s"
	include	"level5.s"
	include	"level6.s"
	include	"level7.s"
	include	"level8.s"
	include	"level9.s"
	include	"level10.s"
	include	"level11.s"
	include	"level12.s"
	include	"level13.s"
	include	"level14.s"
	include	"level15.s"
	include	"level16.s"

; -----------------------------
; BLOCKS
; -----------------------------
; blocks from blockeditor

		include	"blocksall.s"

; -----------------------------
; MOUSE HANDLING
; -----------------------------
WaitForMouseUp
xxxx:
		jsr WaitForRaster
		jsr 	mt_music
  	    BTST   #6,$BFE001      ; Test left mouse button
   		BEQ.S   xxxx

		rts

		even 

; -----------------------------
 ; MOUSE CHECK
 ; -----------------------------
 ; https://www.ikod.se/reading-the-mouse/

XScreenWidth             equ     320
XScreenHeight            equ     256
 
        IFND MouseLimit
                ; 0 = Mouse Limit InActive
                ; 1 = Mouse Limit Active (Default)
MouseLimit                      equ     1
        ENDC
 

ReadMouse:
 
                ; **** SOF Read Mouse Routine ****
         
                movem.l d0-d2/a0-a1,-(sp)
                lea.l   OldDeltaY,a0
                lea.l   $dff00a,a1
 
                moveq   #0,d0
                move.b  (a1),d0         ; Get New Y Mouse
                move.w  (a0),d1         ; Get Old Y Mouse
                move.w  d0,(a0)         ; Save New Y Mouse
                sub.w   d1,d0           ; Delta Y
 
                moveq   #0,d1
                move.b  1(a1),d1        ; Get New X Mouse
                move.w  2(a0),d2        ; Get Old X Mouse
                move.w  d1,2(a0)        ; Save New X Mouse
                sub.w   d2,d1           ; Delta X
                 
                ; **** Check Y Delta ****
 
                cmp.w   #-127,d0
                bge     noUnderFlowY
                move.w  #-255,d2
                sub.w   d0,d2           ; Delta Y = -255 - Delta Y
                bpl     noYPos
                moveq   #0,d2
 
noYPos:        move.w  d2,d0
                bra     rmSkipY
 
noUnderFlowY:  cmp.w   #127,d0
                ble     rmSkipY
                move.w  #255,d2
                sub.w   d0,d2           ; Delta X = 255 - Delta Y
                bmi     noYNeg
                moveq   #0,d2
noYNeg:        move.w  d2,d0
 
rmSkipY:
 
                ; **** Check X Delta ****
 
                cmp.w   #-127,d1
                bge     NoUnderFlowX
                move.w  #-255,d2
                sub.w   d1,d2           ; Delta X = -255 - Delta X
                bpl     noXPos
                moveq   #0,d2
 
noXPos:        move.w  d2,d1
                bra     rmSkipX
 
NoUnderFlowX:  cmp.w   #127,d1
                ble     rmSkipX
                move.w  #255,d2
                sub.w   d1,d2           ; Delta X = 255 - Delta X
                bmi     noXNeg
                moveq   #0,d2
noXNeg:        move.w  d2,d1
 
rmSkipX:
 
                lea.l   MouseY,a0
 
                move.w  (a0),d2         ; D2.W = Old Y Mouse 
                add.w   d0,d2           ; Y Mouse = Y Mouse + Y Delta
 
        IF MouseLimit
                bpl     yPositive
 
                moveq   #0,d2
yPositive:     cmp.w   #XScreenHeight-1,d2      ; Y Mouse > Screen Height?
                ble     yBelow
                move.w  #XScreenHeight-1,d2
yBelow:       
        ENDC
                move.w  d2,(a0)+        ; Save Y Mouse
 
                move.w  (a0),d2         ; D2.W = Old X Mouse
                add.w   d1,d2           ; X Mouse = X Mouse + X Delta
        IF MouseLimit
                bpl     xPositive
 
                moveq   #0,d2
xPositive:     cmp.w   #XScreenWidth-1,d2       ; X Mouse > Screen Width?
                ble     xBelow
                move.w  #XScreenWidth-1,d2
xBelow:       
        ENDC
                move.w  d2,(a0)+
 
                movem.l (sp)+,d0-d2/a0-a1
                rts
 
                ; **** EOF Read Mouse Routine ****
				EVEN
OldDeltaY:      dc.w    0
OldDeltaX:      dc.w    0
MouseY:         dc.w    0
MouseX:         dc.w    0


;======================================================================================================================
;  Chip Data Section
;======================================================================================================================

		include	"Source/C_SpriteStructs.s"
		include	"Source/C_Copper.s"
		include	"Source/C_Data.s"






ChkKey:		;read ext. ASCII key code-->d0.0=no key!auto-fixes shift etc.
	moveq #0,d0
	lea Key(PC),a1
	btst #3,$1f-2(a6)
	beq.s .End
	lea $bfed01,a0
	btst #3,(a0)
	beq.s .End			;key pressed down?
	clr.b (a0)			;nec?
	moveq #0,d1
	move.b -$100(a0),d1		;read key
	move.b #$50,$100(a0)		;output+force load (start handshake)
	lea 6-2(a6),a2			;<-for spd/Size only
	move.b (a2),d2			;wait for 75 microsecs=60 or so cycles
	not.b d1
	lsr.b #1,d1
	bcc.s .Pres
	moveq #-1,d0			;neg=released!
.Pres:	move.w Shift(PC),d3
	bpl.s .Shift
	move.w Caps(PC),d3
	bmi.s .NoSh
.Shift:	add.w #KeyTblS-KeyTbl,d1
.NoSh:	move.b KeyTbl-Key(a1,d1.w),d0	;fetch ASCII equivalent
	moveq #0,d1
	move.b d0,d1
	bpl.s .WLup1			;special key is neg!
	addq.b #5,d1			;less than -5?
	bmi.s .WLup1			;then no special key
	add.w d1,d1
	move.w d0,2(a1,d1.w)		;put state in corr. key-slot (-=OFF!)
.WLup1:	cmp.b (a2),d2			;QikFix:wait AT LEAST 1 scanline
	beq.s .WLup1
	move.b (a2),d2			;make this into an int later!
.WLup2:	cmp.b (a2),d2
	beq.s .WLup2

	move.b #$10,$100(a0)		;input+force load (handshake done)
	move.w #8,$9c-2(a6)		;clear lev2-intreq
.End:	move.w d0,(a1)
	RTS				;d0/[key]=Ascii key
Key:	dc.w 0
Caps:	dc.w -1
Amiga:	dc.w -1				;special keys state
Alt:	dc.w -1				;-=OFF(!)
Shift:	dc.w -1
Ctrl:	dc.w -1				;DONT SEP ^5!
KeyTbl:					;clr unused keybytes for final opti.
dc.b "`1234567890-=\",0,"0"
dc.b "qwertyuiop[]",0,"123"
dc.b "asdfghjkl;'",0,0,"456"
dc.b 0,"zxcvbnm,./",0,".789"
dc.b " ",8,9,13,13,27,127,0,0,0,"-",0,31,30,29,28	;28-31=cursor keys
dc.b -7,-8,-9,-10,-11,-12,-13,-14,-15,-16,"()/*+",-6	;F-keys,Help
dc.b -2,-2,-5,-1,-3,-3,-4,-4				;Shift,Ctrl,Alt,<A>
dc.b 128,129,130,131,132,133,134,135
dc.b 136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151
KeyTblS:				;SHIFTED
dc.b "~!@#$%^&*()_+|",0,"0"
dc.b "QWERTYUIOP{}",0,"123"
dc.b "ASDFGHJKL:",34,0,0,"456"
dc.b 0,"ZXCVBNM<>?",0,".789"
dc.b " ",8,9,13,13,27,127,0,0,0,"-",0,31,30,29,28	;28-31=cursor keys
dc.b -7,-8,-9,-10,-11,-12,-13,-14,-15,-16,"()/*+",-6	;F-keys,Help
dc.b -2,-2,-5,-1,-3,-3,-4,-4				;Shift,Ctrl,Alt,<A>
dc.b 128,129,130,131,132,133,134,135
dc.b 136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151	


 


