Game Duenix for Amiga computers/RecordAndReplay.s
Jump to navigation
Jump to search
;------------------------------------------------------------------------------
; Record and replay assembly procedures for Duenix for the Amiga
;------------------------------------------------------------------------------
; Player decisions (one of three options 0, 1, and 2, requiring two bits)
; are being stored/saved, to be loaded later.
; The single round/frame requires 6 * 2 bits of storage,
; two bits per player; they are stored in a single 16-bit word.
; One would think this would have been fast enough in
; in AMOS using peeks, pokes and similar.
; The comments have been expanded in 2024 to be excessively detailed,
; which is fine for educational purposes.
; This is Motorola 68000 assembly.
;------------------------------------------------------------------------------
MaxSize = 8000
;-------------------------
; Interface variables
;-------------------------
PMove dc.l 0 ;The beginning of an array of player moves/decisions for the current round.
;Each move is stored in an AMOS integer, so the array takes 4 * 6 bytes.
Record dc.l 0 ;The address of record space, containing recorded decisions of players for all rounds.
;In this space, the decision for all players for a given round takes 16 bits
;(12 bits, plus 4 bits free).
TopPtr dc.l 0 ;The pointer in the record space
;-------------------------
; Procedure entry points
;-------------------------
Bra SavePos
Bra LoadPos
;----------------------
; Procedure SavePos
;----------------------
SavePos
Moveq #0,d1 ;d1 := 0
Moveq #5,d0 ;PlayerNumber := 5
Move.l PMove(pc),a0 ;a0 := PMove address
Lea TopPtr(pc),a2 ;a2 := TopPtr address
SavePos_Loop
Move.l d0,d2
Asl.l #2,d2 ;d2 := PlayerNumber * 4
Move.l (a0,d2),d3 ;d3 := PMove[PlayerNumber], which is one of 0, 1, and 2
Asl.w d0,d3
Asl.w d0,d3 ;d3 := d3 << (2 * PlayerNumber)
Or.w d3,d1 ;d1 := d1 bitor d3
DBra d0,SavePos_Loop ;Go to next PlayerNumber
Move.l Record(pc),a1
Move.l (a2),d2
Move.w d1,(a1,d2) ;Record[TopPtr] := word containing the decisions of all players
Cmp.w #MaxSize,a2
Beq SavePos_Skip
Addq.l #2,(a2) ;TopPtr += 2
SavePos_Skip
Rts
;----------------------
; Procedure LoadPos
;----------------------
LoadPos
Move.l PMove(pc),a0 ;a0 := PMove address
Lea TopPtr(pc),a2 ;a2 := TopPtr address
Move.l Record(pc),a1
Move.l (a2),d2
Move.w (a1,d2),d1 ;d1 := Record[TopPtr]
Cmp.w #MaxSize,d2
Beq LoadPos_Skip
Addq.l #2,(a2) ;TopPtr += 2
LoadPos_Skip
Moveq #5,d0 ;PlayerNumber := 5
LoadPos_Loop
Move.w d1,d2 ;d2 := Record[TopPtr]
Asr.w d0,d2
Asr.w d0,d2
And.w #3,d2 ;d2 := (Record[TopPtr] >> (2 * PlayerNumber)) bitand 0b11
Ext.l d2
Move.l d0,d3
Asl.l #2,d3
Move.l d2,(a0,d3) ;PMove[PlayerNumber] := (Record[TopPtr] >> (2 * PlayerNumber)) bitand 0b11
DBra d0,LoadPos_Loop ;Go to next PlayerNumber
Rts