Amiga Asm: Combining Score, Time-Keeping & Ending the Game

The final listing for this section is combining the timer code with the score code and adding a simple check to see if we have reached the end of time for the match. We also incorporate a score comparison to announce a winner or draw a match.

 ExecBase = 4
OpenLib = -552
OpenLibVersion = 34
CloseLib = -414
PutString = -948
MOVE.L #OpenLibVersion,D0
LEA DosName,A1
MOVE.L ExecBase,A6
JSR OpenLib(A6)
MOVE.L D0,A6
MOVE.L #TitleString,D1
JSR PutString(A6)
MOVE.L #InstructionString,D1
JSR PutString(A6)
MOVE.B #0,SideOneScoreValue ;init side one score
MOVE.B #0,SideTwoScoreValue ;init side two score
title_page:
MOVE.B $bfec01,D0 ; Keypress
NOT.B D0
ROR.B #1,D0 ; D0 now contains the raw key
CMP.B #$45,D0 ;Check for esc
BEQ quit
CMP.B #$21,D0 ;Check for 'S'
BEQ game_loop
BNE title_page
BSR gettime ;put the current time into D7
MOVE.L D7,D6 ;save to D6
MOVE.B #0000,Seconds
MOVE.B #0000,Minutes
game_loop:
BSR gettime ;put the current time into D7
SUB.B D6,D7 ;elapse time in 1 50th of a sec in d7
CMP.B #$32,d7 ;elapse time > hex 32 (50) so 50 50ths = 1 sec
BGE.B add_second
BLT.B display
add_second:
BSR gettime ;put the current time into d7
MOVE.L d7,D6 ;save to D6
ADD.B #0001,Seconds
CMP.B #0010,Seconds
BGE.B add_minute
BLT.B display
add_minute
MOVE.B #0000,Seconds
ADD.B #0001,Minutes
display:
MOVE.B Seconds,D1
LEA buffer,a0 ;pointer to the buffer
JSR deci_4
MOVE.L #SecondsText,D1
JSR PutString(A6)
MOVE.L #buffer,D1
JSR PutString(A6)
MOVE.L #newline,D1
JSR PutString(A6)
CLR.L buffer
MOVE.B Minutes,D1
LEA buffer,a0 ;pointer to the buffer
JSR deci_4
MOVE.L #MinutesText,D1
JSR PutString(A6)
MOVE.L #buffer,D1
JSR PutString(A6)
MOVE.L #newline,D1
JSR PutString(A6)
CLR.L buffer
LEA buffer,a0 ;pointer to the buffer
MOVE.L d7,D1
JSR byte ;test subroutine
MOVE.L #buffer,D1
JSR PutString(A6)
MOVE.L #newline,D1
JSR PutString(A6)
JSR scoring
JSR scoreboard ;get scoreboard text

As you can see we have merged our timer and scoring code together along with code to to check to see if we have reach the desired time for the match. This is placed towards the end of our game loop as follows;

    CMP.B    #0001,Minutes
BGE.B end_match
BTST #6,$bfe001
BNE game_loop

As you can see a check on the minutes reach a defined time is executed and if the desired time has been reached then the end_match code is branched to

end_match:
MOVE.B SideOneScoreValue,D1
MOVE.B SideTwoScoreValue,D2
CMP.B D1,D2
BEQ.B draw
JSR quit
CMP.B D1,D2
BGT.B winner_one
JSR quit
CMP.B D1,D2
BLT.B winner_two

The code executes a number of checks on the scores which are first moved into the data register. We compare to see if the scores are the same, a draw. If not then we check to see which side score is the greatest. A branch is made to the appropriate section of code to announce a winner.

draw:
MOVE.L #DrawNoWinnerText,D1
JSR PutString(A6)
JSR quit
RTS
winner_one:
MOVE.L #SideOneWinnerText,D1
JSR PutString(A6)
JSR quit
RTS
winner_two:
MOVE.L #SideTwoWinnerText,D1
JSR PutString(A6)
JSR quit
RTS

And that’s the end of these checks. We branch to the quit code to finish. To finish the rest of the listing is the rest of the merge between score and time keeping.

gettime:             
MOVE.B $bfea01,D7 ;hi-byte in D0
LSL.L #4,D7 ;shift twice by 4 bits
LSL.L #4,D7 ;(8 bits shifted)
MOVE.B $bfe901,D7 ;get mid-byte
LSL.L #4,D7
LSL.L #4,D7 ;shift again
MOVE.B $bfe801,D7 ;get the lo-byte
RTS ;done

deci_4: ;subroutine-four digit numbers
DIVU #1000,D1 ;divide by 1000
BSR digit ;evaluate result-move remainder
DIVU #100,D1 ;divide by 100
BSR digit ;evaluate result and move
DIVU #10,D1 ;divide by 10
BSR digit ;evaluate result-move remainder
;evaluate the remainder directly
digit:
ADD #$30,D1 ;convert result into ASCII
MOVE.B D1,(a0)+ ;move it into buffer
CLR D1 ;erase lower word
SWAP D1 ;move the remainder down
RTS ;return
byte:
MOVE D1,D2 ;move value into D2
LSR #4,D2 ;move upper nibble into lower nibble
BSR nibble ;convert D2
MOVE.B D2,(A0)+ ;put character into buffer
MOVE D1,D2 ;value in D2
BSR nibble ;convert lower nibble
MOVE.B D2,(A0)+ ;and put it in buffer
RTS ;done
nibble:
AND #$0f,D2 ;just keep low byte
ADD #$30,D2 ;add $30
CMP #$3a,D2 ;was it a digit?
BCS ok ;yes:done
ADD #7,D2 ;else add 7
ok:
RTS ;done
scoreboard:
BSR check_for_keypress
MOVE.L #ScoreboardString,D1
JSR PutString(A6) ;output text
LEA buffer,a0 ;pointer to the buffer
MOVE.B SideOneScoreValue,D1 ;number to convert
JSR deci_4 ;test subroutine
MOVE.L #buffer,D1
JSR PutString(A6)
MOVE.L #newline,D1
JSR PutString(A6)
MOVE.L #ScoreboardStringThree,D1
JSR PutString(A6)
LEA buffer,a0 ;pointer to the buffer
MOVE.B SideTwoScoreValue,D1 ;number to convert
jsr deci_4 ;test subroutine
MOVE.L #buffer,D1
JSR PutString(A6)
MOVE.L #newline,D1
JSR PutString(A6)
MOVE.L #newline,D1
JSR PutString(A6)
MOVE.L #newline,D1
JSR PutString(A6)
RTS
scoring:
BSR check_for_keypress
CMP.B #$01,d0 ;check for '1' key to increase side 1 score
BEQ increase_side_one_score
CMP.B #$02,d0 ;check for '2' key to increase side 2 acore
BEQ increase_side_two_score
RTS
increase_side_one_score:
MOVE.B SideOneScoreValue,D1
ADD.B #1,D1
MOVE.B D1,SideOneScoreValue
RTS
increase_side_two_score
MOVE.B SideTwoScoreValue,D1
ADD.B #1,D1
MOVE.B D1,SideTwoScoreValue
RTS
check_for_keypress:
MOVE.B $bfec01,d0 ;move key press (if any) to d0
NOT.B d0
ROR.B #1,d0
RTS
quit:
MOVE.L #QuitString,D1
JSR PutString(A6)
MOVE.L A6,A1
MOVE.L ExecBase,A6
JSR CloseLib(A6)
RTS
buffer:
blk.b 9,0 ;space for long word data
DosName: DC.B "dos.library",0
TitleString: DC.B "Stop Watch",10,0
InstructionString: DC.B "Press 's' to Start or 'Esc' to quit.",10,0
QuitString: DC.B "Quit",10,0
newline: DC.B 10+'',0
SecondsText: DC.B "SECONDS: " ,10,0
Seconds: DS.B 1
Minutes: DS.B 1
MinutesText: DC.B "MINUTES: ",10,0
ScoreboardStringThree: DC.B 'Side 2 ',10,0
SideOneScoreValue: DS.B 1
SideTwoScoreValue: DS.B 1
ScoreboardString: DC.B 'Scoreboard: Side 1 ',10,0
DrawNoWinnerText: DC.B 'Result is a draw',10,0
SideOneWinnerText: DC.B 'Side one wins',10,0
SideTwoWinnerText: DC.B 'Side two wins',10,0

And that completes our merger of the time-keeping and scoring code. We now have a very, very basic program flow for our game. In the next phase we move away from the CLI and move into the area of graphics.

Be the first to comment

Leave a Reply

Your email address will not be published.


*