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:
- The calculation of “Rows Cleared” needs to be corrected
- Once the goal for rows-cleared is completed, play should advance to the next round
- 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.
- Add scoring
- General cleanup
- Stretch 1: Add German/Czech/Polish versions of the instructions)
- 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