2015 Retrochallenge Winter Warmup, Retrochallenge

Retrochallenge 2015/01 – Post 06

Assembly Time

(This is part six of the chronicle of my Retrochallenge 2015/01 submission, which is to port the modern-day Apple II game, Structris, to the Atari 8-bit home computer using an obscure language called PL65. The mediocrity starts here.)

I was able to convert the scroll routine that moves the Tetris pieces down the screen from straight PL65 to 6502 Assembly. Recall that one of the brilliant virtues of Noahsoft’s PL65 is its ability to treat 6502 mnemonics as first-class commands. There are limitations and PL65’s documentation warns against intermingling PL65 and 6502 statements unless you have a fetish for devious bugs.

Though you can’t help but use INC MYVAR instead of MYVAR = MYVAR + 1.

Earlier this month, I was dismayed that PL65, by itself, couldn’t render quickly enough to match speed of the Apple version. The Apple does use a machine language routine to perform the scrolling. It was implemented using Ivan X’s Applesoft extension called Slammer, which embeds monitor or assembly instructions as REM statements. I’m still relatively new to 6502 Assembly, so I wasn’t planning on having to spend time trying to figure that one out.

Holy Crap! I May Finish This Yet.

The performance difference using the 6502 routine is astounding.

This will give me plenty of cycles to spare to help finishing up any lingering features. In fact, if I don’t run out of time, my plan is to throttle the Atari version to animate the pieces to match the speed of the Apple version. In Martin Haye’s Apple II game, as the player advances to the next level, the Tetris well reduces in size. A happy side effect is the computer has fewer pixels to move and therefore the pieces fall faster as the level increases.

But there’s still several features needed before calling this one done:

  1. The calculation of “Rows Cleared” needs to be corrected
  2. Once the goal for rows-cleared is completed, play should advance to the next round
  3. Match the game’s speed exactly to the Apple II version (may vary by level) – this should aid in the player’s blip being more visible.
  4. Add scoring
  5. General cleanup
  6. Stretch 1: Add German/Czech/Polish versions of the instructions)
  7. Stretch 2: Add other instructions to the BeweDOS batch file to better mimic the Apple II version

Code Dump

Here’s the logic for the scroll routine first in PL65 and then re-implemented as 6502 instructions:

!---------------------------------------
! SCROLL
!---------------------------------------
PROC SCROLL()
INT A1, A2
BYTE R, S, CL
BEGIN
  ! CHECK TO SEE IF BOTTOM ROW IS CLEAR
  CL = 0 R = 0 S = 0 A1 = ORIGIN P1 = ORIGIN
  WHILE V1 <> $88 DO
    IF V1 = $00 THEN 
      INC R 
    ELSE  
      INC S 
    ENDIF
    A1 = A1 + 2  P1 = A1
  ENDWHILE

  ! IF CLEARED
  IF R = 0 AND S > 0 THEN
    INC RC INC CL
  ENDIF

  R = CL
  S = HEIGHT2
  A1 = ORIGIN
  A2 = A1 - 32
  P1 = A1 P2 = A2 P3 = A1 + 1 P4 = A2 + 1
  WHILE V1 <> $88 DO
    WHILE S > 0 DO
      IF R = 0 AND V1 = $00 THEN R = 1 ENDIF
      IF R = 1 THEN 
        V1 = V2 V3 = V4
        IF S = 1 THEN V2 = $00 V4 = $00 ENDIF
      ENDIF 
      P1 = A2 P3 = A2 + 1 A2 = A2 - 32 
      P2 = A2 P4 = A2 + 1
      DEC S
    ENDWHILE
    A1 = A1 + 2 A2 = A1 - 32
    P1 = A1 P2 = A2 P3 = A1 + 1 P4 = A2 + 1
    S = 37 - LV
    R = CL
  ENDWHILE
END

CONST DUMMY4 = @
@ = $8800
!-----------------------------
! SCROLL2
!-----------------------------
PROC SCROLL2()
INT A1, A2
BYTE FILL_FL, HGT, CL
BEGIN
  ! CHECK TO SEE IF BOTTOM ROW IS CLEAR
  ! SCAN BOTTOM ROW
  !CL = 0 R = 0 S = 0
  LDA #$00
  STA CL
  STA FILL_FL
  STA HGT

  !A1 = ORIGIN
  LDA ORIGIN+1
  LDY ORIGIN
  STY A1
  STA A1+1

  !P1 = ORIGIN
  STY P1
  STA P1+1

  !WHILE V1 <> $88 DO
  LDY #$00
:wh01
  LDA (P1),Y
  CMP #$88
  BEQ endw01
  CMP #$00
  BNE inc_s
  INC FILL_FL
  GOTO endif01
:inc_s
  INC HGT
:endif01
  INY 
  INY 
  JMP wh01
:endw01

  !IF R = 0 AND S > 0 THEN
  LDA FILL_FL
  BNE endif04
  LDA HGT
  BEQ endif04
  INC RC
  JSR PRINT_ROWS_CLEARED
  INC CL
:endif04

  ! FILL_FL = CL
  LDA CL
  STA FILL_FL

  !HGT = HEIGHT2
  LDA HEIGHT2
  STA HGT

  ! A1 = ORIGIN
  LDA ORIGIN+1
  LDY ORIGIN
  STY A1
  STA A1+1

  !A2 = A1 - 32
  SEC
  LDA A1
  SBC #$20
  STA A2
  LDA A1+1
  SBC #$00
  STA A2+1

  !P1 = A1
  LDA A1+1
  LDY A1
  STA P1+1
  STY P1

  !P2 = A2
  LDA A2+1
  LDY A2
  STA P2+1
  STY P2

  !P3 = A1 + 1
  LDA A1
  LDY A1+1
  STY P3+1
  CLC
  ADC #$01
  STA P3
  BCC add02
  INC P3+1
:add02

  !P4 = A2 + 1
  LDA A2
  LDY A2+1
  STY P4+1
  CLC
  ADC #$01
  STA P4
  BCC add03
  INC P4+1
:add03

  !WHILE V1 <> $88 DO
:wh02
  LDY #$00
  LDA (P1),Y
  CMP #$88
  BNE wh03
  GOTO endw02

    !WHILE HGT > 0 DO
:wh03
  LDA HGT
  BEQ endw03

      !IF FILL_FL = 0 AND V1 = $00 THEN FILL_FL = 1 ENDIF
  LDA FILL_FL
  BNE endif02
  LDY #$00
  LDA (P1),Y
  BNE endif02
  LDA #$01
  STA FILL_FL
:endif02

      !IF FILL_FL = 1 THEN 
  LDA FILL_FL
  BEQ endif03

        !V1 = V2 V3 = V4
  LDY #$00
  LDA (P2),Y
  STA (P1),Y
  LDA (P4),Y
  STA (P3),Y

        !IF HGT = 1 THEN V2 = $00 V4 = $00 ENDIF
  LDA HGT
  CMP #$01
  BNE endif03
  LDA #$00
  STA (P2),Y
  STA (P4),Y
      !ENDIF 
:endif03

      !P1 = A2
  LDA A2+1
  LDY A2
  STA P1+1
  STY P1  

      !P3 = A2 + 1
  LDA A2
  LDY A2+1
  STY P3+1
  CLC
  ADC #$01
  STA P3
  BCC add04
  INC P3+1
:add04

      !A2 = A2 - 32 
  SEC
  LDA A2
  SBC #$20
  STA A2
  LDA A2+1
  SBC #$00
  STA A2+1

      !P2 = A2
  LDA A2+1
  LDY A2
  STA P2+1
  STY P2

      !P4 = A2 + 1
  LDA A2
  LDY A2+1
  STY P4+1
  CLC
  ADC #$01
  STA P4
  BCC add05
  INC P4+1
:add05

  DEC HGT
    !ENDWHILE
  JMP wh03
:endw03

    !A1 = A1 + 2
    CLC
    LDA A1
    ADC #$02
    STA A1
    BCC add01
    INC A1+1
:add01

!    A2 = A1 - 32
    SEC
    LDA A1
    SBC #$20
    STA A2
    LDA A1+1
    SBC #$00
    STA A2+1

    !P1 = A1
    LDA A1+1
    LDY A1
    STA P1+1
    STY P1

    !P2 = A2
    LDA A2+1
    LDY A2
    STA P2+1
    STY P2

   ! P3 = A1 + 1
    LDA A1
    LDY A1+1
    STY P3+1
    CLC
    ADC #$01
    STA P3
    BCC add06
    INC P3+1
:add06

    !P4 = A2 + 1
    LDA A2
    LDY A2+1
    STY P4+1
    CLC
    ADC #$01
    STA P4
    BCC add07
    INC P4+1
:add07

    !S = HEIGHT2
    LDA HEIGHT2
    STA HGT

    !R = CL
    LDA CL
    STA FILL_FL

    JMP wh02

  !ENDWHILE
:endw02
END
@ = DUMMY4