;**********************
;* ROUTINE TO DISPLAY *
;* A BACKGROUND USING *
;* FASTSPR            *
;**********************

ALIGN

#smile on
#name MainCode
#type &0
#base &40000
#load &40000
#exec &40000

; All registers up to R8 are used and preserved

#set sx=320               ; Max X Position
#set sy=256-16            ; Max Y Position
#set col1=23              ; Player 1 Colour
#set col2=31              ; Player 2 Colour
#set px1=0                ; X Pos 1
#set px2=26               ; X Pos 2 
#set calctime=5           ; Amount to add
#set timedelay=10         ; Time delay

B Background
B DisplayScore
B ClearScore
B AddPoints
B IncreaseTime
B DecreaseTime
B IncreaseLives
B IncreaseBombs
B GetAddress
B DecreaseLives
B DecreaseTimer
B ClearBombs

ALIGN

;***************
;* CLEAR BOMBS *
;***************

.ClearBombs
STMFD R13!,{R0-R12,R14}
MOV R0,#"0"

MOV R5,#2

.loop2
ADR R1,db1
STRB R0,[R1,R5]
ADR R1,db2
STRB R0,[R1,R5]
SUBS R5,R5,#1
BPL loop2
LDMFD R13!,{R0-R12,R15}

ALIGN

;******************
;* DECREASE LIVES *
;******************

.DecreaseLives
CMP R0,#0
ADREQ R1,lives1
ADRNE R1,lives2

MOV R2,#1
LDRB R0,[R1,R2]
SUB R0,R0,#1
STRB R0,[R1,R2]
MOVS R15,R14

ALIGN

;**********************
;* GET DATA ADDRESSES *
;**********************

.GetAddress
MOV R1,R0,LSL#2
ADR R2,data
LDR R0,[R2,R1]
MOV R15,R14

ALIGN
.data
DCD score1,score2,lives1,lives2,db1,db2,dotime,outtime

ALIGN
     
; Out of time

ALIGN
.outtime
DCB 0
 
ALIGN

; Timer

.timedly
DCD timedelay

ALIGN

;******************
;* INCREASE BOMBS *
;******************

.IncreaseBombs
STMFD R13!,{R0-R12,R14}
CMP R0,#0
ADREQ R0,db1
ADRNE R0,db2
MOV R1,#2

LDRB R2,[R0,R1]
ADD R2,R2,#1

._loop
STRB R2,[R0,R1]
CMP R2,#"9"+1
BCC finish4

SUB R2,R2,#"9"+1
ADD R2,R2,#"0"
STRB R2,[R0,R1]
SUBS R1,R1,#1
LDRB R2,[R0,R1]
ADD R2,R2,#1
BPL _loop

.finish4
LDMFD R13!,{R0-R12,R15}

    
ALIGN

;******************
;* INCREASE LIVES *
;******************

.IncreaseLives
STMFD R13!,{R0-R12,R14}
CMP R0,#0
ADREQ R1,lives1
ADRNE R1,lives2

MOV R2,#1
LDRB R3,[R1,R2]
CMP R3,#"9"
BEQ _finish

ADD R3,R3,#1
STRB R3,[R1,R2]

._finish
LDMFD R13!,{R0-R12,R15}

ALIGN

;******************
;* DECREASE TIMER *
;******************

.DecreaseTimer
STMFD R13!,{R0-R12,R14}
LDR R0,timedly
SUBS R0,R0,#1
STR R0,timedly
BNE finish3

MOV R0,#timedelay
STR R0,timedly
MOV R0,#1
BL DecreaseTime
LDMFD R13!,{R0-R12,R15}

ALIGN

;*****************
;* DECREASE TIME *
;*****************

; Registers used :
; R0 - Amount to subtract

.DecreaseTime
STMFD R13!,{R0-R12,R14}
MOV R5,R0

.loop4
LDRB R0,dotime
CMP R0,#"1"
BNE nottimer

LDRB R0,dotime+1
CMP R0,#"0"

MOVEQ R0,#8
MOVEQ R1,#&FFF1
MOVEQ R2,#150
MOVEQ R3,#5
SWIEQ Sound_Control

.nottimer
LDRB R0,dotime
CMP R0,#"0"

LDREQB R0,dotime+1
CMPEQ R0,#"0"
BNE _more

MOV R0,#0
STRB R0,outtime

LDMFD R13!,{R0-R12,R15}

._more
LDRB R0,dotime
CMP R0,#"1"
BLT keep
LDRB R0,dotime+1
CMP R0,#"1"
BLT keep

MOV R0,#8
MOV R1,#0
MOV R2,#0
MOV R3,#0
SWI Sound_Control

.keep
LDRB R0,dotime+1
SUB R0,R0,#1
STRB R0,dotime+1
CMP R0,#"0"-1
BNE next2

MOV R0,#"9"
STRB R0,dotime+1
LDRB R0,dotime
SUB R0,R0,#1
STRB R0,dotime

.next2
SUBS R5,R5,#1
BNE loop4

.finish3
LDMFD R13!,{R0-R12,R15}

ALIGN

;*****************
;* INCREASE TIME *
;*****************

.IncreaseTime
STMFD R13!,{R0-R12,R14}
MOV R5,R0

.loop3
LDRB R0,dotime
CMP R0,#"9"
BNE more

LDRB R0,dotime+1
CMP R0,#"9"
BEQ finish2

.more
LDRB R0,dotime+1
ADD R0,R0,#1
STRB R0,dotime+1
CMP R0,#"9"+1
BNE next

MOV R0,#"0"
STRB R0,dotime+1
LDRB R0,dotime
ADD R0,R0,#1
STRB R0,dotime
.next
SUBS R5,R5,#1
BNE loop3

.finish2
LDMFD R13!,{R0-R12,R15}

ALIGN

;**************
;* ADD POINTS *
;**************

.AddPoints
STMFD R13!,{R0-R12,R14}
   
CMP R0,#0
ADREQ R0,score1
ADRNE R0,score2
MOV R1,#5

LDRB R2,[R0,R1]
ADD R2,R2,#2
._loop
STRB R2,[R0,R1]
CMP R2,#"9"+1
BCC finish

SUB R2,R2,#"9"+1
ADD R2,R2,#"0"
STRB R2,[R0,R1]
SUBS R1,R1,#1
LDRB R2,[R0,R1]
ADD R2,R2,#1
BPL _loop

.finish
LDMFD R13!,{R0-R12,R15}
            

.Background
STMFD R13!,{R0-R12,R14}
STR R0,levelpos

MOV R0,#19
SWI OS_Byte

MOV R0,#112
LDR R1,bank
SWI OS_Byte

MOV R0,#113
LDR R1,bank
SWI OS_Byte         

LDR R1,bank
EOR R1,R1,#3
STR R1,bank

LDR R0,bank
SWI FastSpr_ScreenBank

MOV R0,#113
LDR R1,bank
SWI OS_Byte

MOV R0,#0
SWI FastSpr_SetBackdrop
MOV R0,#12
SWI OS_WriteC

MOV R1,#0
MOV R2,#0
MOV R7,#0
LDR R8,levelpos

.loop1
LDRB R0,[R8,R7]
CMP R0,#0
CMPNE R0,#15
SWINE FastSpr_Plot
._skip
ADD R7,R7,#1
ADD R1,R1,#16
CMP R1,#sx
MOVEQ R1,#0
ADDEQ R2,R2,#16
CMPEQ R2,#sy
BNE loop1
LDMFD R13!,{R0-R12,R15}

ALIGN
.bank
DCD 1

ALIGN
.levelpos
DCD 0

ALIGN
.t
DCB 12,17,21+128

ALIGN

;****************
;* CLEAR SCORES *
;****************

.ClearScore
STMFD R13!,{R0-R12,R14}
MOV R0,#"0"
MOV R5,#5

; Clear score

._loop
ADR R1,score1
STRB R0,[R1,R5]
ADR R1,score2
STRB R0,[R1,R5]
SUBS R5,R5,#1
BPL _loop


; Set lives

STRB R0,lives1
STRB R0,lives2

ADR R1,lives1
MOV R0,#"3"
STRB R0,[R1,#1]
ADR R1,lives2
STRB R0,[R1,#1]

LDMFD R13!,{R0-R12,R15}
 
;*****************************
;* DISPLAY STATUS FOR PLAYER *
;*****************************

;Registers used :
;  R0 - Player (0 or 1)
;  R7 - Used in place of R0

; All registers preserved

ALIGN
.DisplayScore
; Set text colour
STMFD R13!,{R0-R12,R14}
STRB R0,which                ; Save which player

LDRB R7,which
CMP R7,#0
MOVEQ R0,#col1
MOVNE R0,#col2
STRB R0,col

ADR R0,textcolour
MOV R1,#2
SWI OS_WriteN

ADR R0,tintcolour
MOV R1,#10
SWI OS_WriteN

MOVEQ R0,#px1
MOVNE R0,#px2
MOV R1,#30
BL MoveCursor

ADR R0,status
MOV R1,#10
SWI OS_Write0

LDRB R7,which
CMP R7,#0
MOVEQ R0,#px1
MOVNE R0,#px2
MOV R1,#31
BL MoveCursor

CMP R7,#0
ADREQ R0,score1
ADRNE R0,score2
SWI OS_Write0

MOV R0,#" "
SWI OS_WriteC

CMP R7,#0
ADREQ R0,db1
ADRNE R0,db2
SWI OS_Write0

MOV R0,#" "
SWI OS_WriteC

CMP R7,#0
ADREQ R0,lives1
ADRNE R0,lives2
SWI OS_Write0

MOV R0,#63
STRB R0,col

ADR R0,textcolour
MOV R1,#2
SWI OS_WriteN

MOV R0,#17
MOV R1,#30
BL MoveCursor

ADR R0,time
SWI OS_Write0

MOV R0,#18
MOV R1,#31
BL MoveCursor

ADR R0,dotime
SWI OS_Write0

MOV R0,#0
MOV R1,#0
BL MoveCursor

LDMFD R13!,{R0-R12,15}

;***************
;* Move Cursor *
;*************** 

ALIGN
.MoveCursor
STMFD R13!,{R0-R12,R14}
STRB R0,cx
STRB R1,cy

ADR R0,movecursor
MOV R1,#3
SWI OS_WriteN
LDMFD R13!,{R0-R12,R15}

;**************************
;* SET TEXT COLOUR + TINT *
;**************************

ALIGN
.textcolour
DCB 17
.col
DCB 25

ALIGN
.tintcolour
DCB 23,17,0,&C0,0,0,0,0,0,0

;***************
;* MOVE CURSOR *
;***************

ALIGN
.movecursor
DCB 31
.cx
DCB 0
.cy
DCB 28

ALIGN
.which
DCB 0

;***************
;* STATUS TEXT *
;***************

ALIGN
.status
DCB "SCORE: BD: LV:",0

;******************
;* PLAYER 1 STATS *
;******************

ALIGN
.score1
DCB "500000",0

ALIGN
.db1
DCB "111",0   

ALIGN
.lives1
DCB "98",0

;********
;* TIME *
;********

ALIGN
.time
DCB "TIME:",0

ALIGN
.dotime
DCB "00",0

;******************
;* PLAYER 2 STATS *
;******************

ALIGN
.score2
DCB "444444",0

ALIGN
.db2
DCB "555",0

ALIGN   
.lives2
DCB "77",0
