Monday, March 6, 2017

Switching to 6502 Assembly for a moment ...

I wanted to handle screen backgrounds via a peek and poke system from BASIC, but it was unbelievably SLOW.  The solution?  Assembly language.  It's taken me a few weeks to get my head wrapped around 6502 assembly again (it's been a few years, after all), and managed to hammer out the following copy and replace routines; one is at 49152, one at 49206.  The first copies screen and color memory  to $C100, and the second copies it back from $C100.

So, the memory at $C100 maps out as follows:
$C100-$C4FF is a copy of screen memory (which starts at $0400 when displayed).
$C500-$C8FF is a copy of color memory (which starts at $D800 when displayed).

So, to make a copy of the screen: SYS49152
To retrieve the copy for display: SYS49206

Here's the code:

1000 *= 49152
1010 .S
1020 .O
1025 .D SP
1030 ; "SCREENPOKER"
1040 ; THIS ASSEMBLY CODE GENERATES THE
1050 ; MACHINE LANGUAGE TO PERFORM A
1060 ; COPY OF SCREEN CODE DATA FROM
1070 ; $0400 TO $C100.
1080 ;
1090 ; IN THE COMING PROGRAMMING, THE
1100 ; ROUTINE, ALLOWING A COPY AND
1110 ; PASTE FUNCTIONALITY FOR THE
1120 ; SCREEN, ALLOWING, FOR EXAMPLE,
1130 ; WINDOWS TO BE DRAWN ON THE SCRN
1140 ; AND THEN THE SCREEN RESTORED.
1150 ;
1160 LDX #$00
1170 START LDA $0400,X
1180 STA $C100,X
1190 LDA $0500,X
1200 STA $C200,X
1210 LDA $0600,X
1220 STA $C300,X
1230 LDA $0700,X
1240 STA $C400,X
1250 LDA $D800,X
1260 STA $C500,X
1270 LDA $D900,X
1280 STA $C600,X
1290 LDA $DA00,X
1300 STA $C700,X
1310 LDA $DB00,X
1320 STA $C800,X
1330 INX
1340 BNE START
1350 RTS
1360 ;
1370 ; THE NEXT SECTION OF CODE WILL
1380 ; PERFORM THE REVERSE OF THE
1390 ; PRIOR. IT WILL COPY THE SCREEN
1400 ; AND COLOR CODES FROM THE COPY
1410 ; BACK TO THE SCREEN
1420 ;
1430 LDX #$00
1440 START2 LDA $C100,X
1450 STA $0400,X
1460 LDA $C200,X
1470 STA $0500,X
1480 LDA $C300,X
1490 STA $0600,X
1500 LDA $C400,X
1510 STA $0700,X
1520 LDA $C500,X
1530 STA $D800,X
1540 LDA $C600,X
1550 STA $D900,X
1560 LDA $C700,X
1570 STA $DA00,X
1580 LDA $C800,X
1590 STA $DB00,X
1600 INX
1610 BNE START2
1620 RTS


There really should be an easier/shorter way to handle this, and I'll be looking into that in the future.  Right now, it just does an LDA/STA to and from memory, basically moving 8 256-byte blocks in pseudo-parallel.

Fun stuff.