Skip to navigation

Revs on the BBC Micro

3D objects: MoveObjectBack

Name: MoveObjectBack [Show more] Type: Subroutine Category: 3D objects Summary: Move a specified object backwards along the track by one segment
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * GetTrackSegment (Part 1 of 3) calls MoveObjectBack * MovePlayer calls MoveObjectBack * PlaceCarsOnTrack calls MoveObjectBack

Moves object X backwards by one segment, updating the section number if we cross into a new section. Also updates the lap number if this is the current player.
Arguments: X Object number (0-23)
Returns: C flag Whether the object has moved into a new section: * Clear if the object is still within the same track section as before * Set if the object has now moved back into the previous track section
.MoveObjectBack LDY objTrackSection,X \ Set Y to the track section number * 8 for object X LDA objSectionSegmt,X \ Set A = objSectionSegmt, which keeps track of the \ object's segment number in the current track section CLC \ If A is non-zero then the object can move backwards by BNE back2 \ one step while staying in the same track section, so \ clear the C flag and jump to back2 to store this \ result on the stack \ Otherwise moving backwards will move the object into \ the previous track section TYA \ Store the current track section number * 8 in A BNE back1 \ If the track section number is non-zero, then skip the \ following instruction \ If we get here then the object is in the first track \ section and is moving backwards into the previous \ track section, so we have to wrap around to the end \ of the track to move into the very last track section LDA trackSectionCount \ Set A = trackSectionCount \ \ So A contains the number * 8 of the last track section \ plus 1 (as the track sections count from zero) .back1 \ By this point, A contains the number * 8 of the \ current track section, updated to cater for wrapping \ round at the end SEC \ Set A = A - 8 SBC #8 \ \ So A is now the number * 8 of the previous track \ section, which is where the driver is moving to STA objTrackSection,X \ Update the object's track section number to the new \ one that they just moved into TAY \ Set A to the size of the new track section, so A LDA trackSectionSize,Y \ contains the track section counter for the end of the \ new track section (so the object moves to the end of \ the new track section) SEC \ Set the C flag to indicate that the object has moved \ into a different track section .back2 PHP \ Store the C flag on the stack, which will be clear if \ the object is still within the same track section, set \ otherwise SEC \ A contains the object's segment number in the current SBC #1 \ track section, so subtract 1 to move the object \ backwards STA objSectionSegmt,X \ Set the track section counter to the new value .back3 \ We now need to decrement the object's segment number \ in (objectSegmentHi objectSegmentLo) LDA objectSegmentLo,X \ If the low byte of objectSegment for object X is BNE back4 \ non-zero, then jump to back4 to decrement the low \ byte, and we are done DEC objectSegmentHi,X \ Otherwise decrement the high byte BPL back4 \ If the high byte is positive, jump to back4 to \ decrement the low byte to &FF, and we are done \ If we get here then we just decremented the 16-bit \ value in (objectSegmentHi objectSegmentLo) into \ negative territory, so the object just moved \ backwards across the starting line, into the previous \ lap LDA trackLength \ Set objectSegment for driver X = trackLength STA objectSegmentLo,X \ LDA trackLength+1 \ So objectSegment wraps around to the segment number STA objectSegmentHi,X \ for the end of the track, as trackLength contains the \ length of the full track (in terms of segments) CPX currentPlayer \ If object X is not the current player, jump to back3 BNE back3 \ to decrement the newly wrapped segment number LDA driverLapNumber,X \ If the current lap number for the current player is BEQ back3 \ zero (i.e. this is the first lap) then jump to back3 \ to decrement the newly wrapped segment number DEC driverLapNumber,X \ Otherwise this is not the current player's first lap, \ and they just moved backwards, across the starting \ line and into the previous lap, so decrement the \ current lap number for the current player JMP back3 \ Jump to back3 to decrement the newly wrapped segment \ number .back4 DEC objectSegmentLo,X \ Decrement the low byte of the object's segment number \ to move it backwards PLP \ Retrieve the C flag from the stack so we can return it \ from the subroutine, so it is clear if the object is \ still within the same track section, set otherwise RTS \ Return from the subroutine