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

; 68k
; flags: CCR 
; MOVE #$00,CCR

; signed values
; https://stackoverflow.com/questions/13615568/ccr-on-the-68000
; unsigned values
; 
; scc
; https://stackoverflow.com/questions/25035030/understanding-the-scc-instructions-of-68000-assembly
;

;For unsigned arithmetic use the following branches:

;>   BHI
;<=  BLS
;>=  BCC/BHS
;<   BCS/BLO
;For signed arithmetic use the following branches:

;>=  BGE
;<   BLT
;>   BGT
;<=  BLE


; 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


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

xxxx:
  	    BTST   #6,$BFE001      ; Test left mouse button
   		BEQ.S   xxxx


		;--------------------------------------------------------------------------------------------------------------
		; GAMELOOP
		;--------------------------------------------------------------------------------------------------------------
ingame:

		; 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
		lea		sprite0,a2		; Source Address
		lea		Spr0_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData
		lea		sprite0,a2		; Source Address
		lea		Spr1_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData
		lea		sprite0,a2		; Source Address
		lea		Spr2_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData
		lea		sprite0,a2		; Source Address
		lea		Spr3_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData
		lea		sprite0,a2		; Source Address
		lea		Spr4_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData
		lea		sprite0,a2		; Source Address
		lea		Spr5_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData
		lea		sprite0,a2		; Source Address
		lea		Spr6_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData
		lea		sprite0,a2		; Source Address
		lea		Spr7_Data,a1		; DESTINATION Address
		bsr.w   copyVisualSpriteData

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

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

		; draw actual level
		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)

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

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



		; ---------------------------
		; 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

		bsr.w	RndB						; Get a Random Number in D0
		and.w	#$0000000ff,d0				; We are only interested in the first 8 (0 - 7)
		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)
			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)
			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)
			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)
			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		
		add.w  #1,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
		
		sub.w  #1,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		
		add.w  #1,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
		
		sub.w  #1,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

		move.l #8,d7 ; gameobjects_no
		lea.l gameobjects,a7
collision:		
		
		clr d5
		; innerCollision
		move.l #8,d6 ; gameobjects_no
		lea.l gameobjects,a6
innerCollision:		
		clr d4
		clr d3

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

		; box collision
		; with box colliders
		;   ______ 
		;  | a7  _|___
		;  |_____|a6 |
		;        |___|
		;

		clr.l d5
		clr.l d4
		clr.l d3
		move.w gameobject_y(a7),d5
		move.w gameobject_y(a6),d4
		move.w gameobject_height(a6),d3
		move.w #0,CCR
		add.w d3,d4
		cmp.w d4,d5
		bhi.w yhigher
		;  a7.y > a6.y+a6.height

		clr.l d5
		clr.l d4
		clr.l d3
		move.w gameobject_y(a7),d5
		move.w gameobject_y(a6),d4
		move.w gameobject_height(a7),d3
		move.w #0,CCR
		sub.w d3,d4
		cmp.w d4,d5
		bcs.w ylower	
		;  a7.y < a6.y-a7.height

		clr.l d5
		clr.l d4
		clr.l d3
		move.w gameobject_x(a7),d5
		move.w gameobject_x(a6),d4
		move.w gameobject_width(a6),d3
		add.w d3,d4
		move.w #0,CCR
		cmp.w d4,d5
		bhi.w xhigher
		;  a7.x > a6.x+a6.width

		clr.l d5
		clr.l d4
		clr.l d3
		move.w gameobject_x(a7),d5
		move.w gameobject_x(a6),d4
		move.w gameobject_width(a7),d3
		sub.w d3,d4
		move.w #0,CCR
		cmp.w d4,d5
		bcs.w xlower
		;  a7.x < a6.x-a7.width

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

		; bonus consume
		; move.w    $DFF006,$DFF180 ; background
		cmp.w #type_bonus,gameobject_type(a6)
		bne  nobonus
		move.w #behavior_4dir_random,gameobject_behaviour(a6)
		add.l #10,score
		jmp noavatar
nobonus:
		; rainbow
		move.w    $DFF006,$DFF180 ; background


noavatar:

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

xlower:
xhigher:

ylower: 
yhigher:		

thesame:

		add.l  #gameobject_size_bytes,a6 ; gameobject_size
		dbra d6,innerCollision
		; / innerCollision

		; collision
		add.l  #gameobject_size_bytes,a7 ; gameobject_size
		dbra d7,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
		; very dark > todo: shift and shift or mulu

		; block version
		; version use blocks
	 	;lea.l blocks,a2 ; Source Address
		;lea.l blocks,a3 ; Source Address
		;add.l #32,a3

		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
counter:
		add.l #spritevisualdata_object_bytes,a2
		;block version
		;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
		jmp vdoit
vnot0:
		cmp.w #1,d5
		bne.w vnot1
		lea		Spr1_Data,a1		; DESTINATION Address
		jmp vdoit
vnot1:
		cmp.w #2,d5
		bne.w vnot2
		lea		Spr2_Data,a1		; DESTINATION Address
		jmp vdoit
vnot2:
		cmp.w #3,d5
		bne.w vnot3
		lea		Spr3_Data,a1		; DESTINATION Address
		jmp vdoit
vnot3:
		cmp.w #4,d5
		bne.w vnot4
		lea		Spr4_Data,a1		; DESTINATION Address
		jmp vdoit
vnot4:
		cmp.w #5,d5
		bne.w vnot5
		lea		Spr5_Data,a1		; DESTINATION Address
		jmp vdoit
vnot5:
		cmp.w #6,d5
		bne.w vnot6
		lea		Spr6_Data,a1		; DESTINATION Address
		jmp vdoit
vnot6:
		cmp.w #7,d5
		bne.w vnot7
		lea		Spr7_Data,a1		; DESTINATION Address
		jmp vdoit
vnot7:
		jmp vedoit
vdoit:
		; bsr.w   copyVisualSpriteData

		; direct version with sprite data plane_0, plane_1
		; copy correct data
		; jmp no_directdata
		add.l   #2,a1
		moveq.l	#16-1,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
no_directdata:

		; block data (bitplanes)
		; copy block data
		jmp no_blockdata
		add.l   #2,a1
		moveq.l	#16-1,d2					; Sprite Image Data Lenght in Long Words
blockDataX:
		move.w	(a2)+,(a1)+					; Copy from Source to destination in Long Words
		move.w	(a3)+,(a1)+					; Copy from Source to destination in Long Words
		dbra	d2,blockDataX			; Loop Till we Copy
no_blockdata:


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

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

		; --------------------------
		; behavior service
		; --------------------------
		; --------------------------
		; mouse control
		; --------------------------
	    jsr ReadMouse

		; exit
  	    btst   #6,$BFE001      ; Test left mouse button
   		beq.s  exit

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


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

		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_avatar equ 1
type_avatar_animind equ 0 ; anim

type_bonus equ 2
type_bonus_animind equ 1  ; anim

type_enemy equ 3
type_enemy_animind equ 2 ; 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
state_menu equ 1
state_ingame equ 2
state_gameover equ 3

timer dc.l   0
timestep dc.l 4

level: 	dc.l 	0

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 0   ; 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 0   ; 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 0   ; 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 0   ; 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 0   ; 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 0   ; 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 0   ; 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 0   ; 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
;======================================================================================================================

act_level: dc.w 0


; load into the actual level
loadLevel:

	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 setBlockXY
	add.l #1,d4
	dbra d6,lx

	add.l #1,d5	
	dbra d7,ly

	rts

	even


	even



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

setBlockXY:
	; 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

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

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

	; image data
	; sprx_data

copyVisualSpriteData:
		add.l   #2,a1
		moveq.l	#16-1,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


 ; -----------------------------
 ; 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 ****
 
OldDeltaY:      dc.w    0
OldDeltaX:      dc.w    0
MouseY:         dc.w    0
MouseX:         dc.w    0


; -----------------------------
; COLORS
; -----------------------------
		even
colors: 
	include	"colors.s"

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

actualLevel:

	include	"level0.s"


             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	"level1.s"

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

		include	"blocksall.s"
 
		even 


;======================================================================================================================
;  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	


 


