Created
June 27, 2025 11:05
-
-
Save coolbutuseless/9e5f4127e4e24f49de5ce122a0b04050 to your computer and use it in GitHub Desktop.
6502 ASM code for a text scroller which says "Hello #RStats" (ACME assembler)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
; Tiny bit of basic with a SYS command to jump to main. | |
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
*=$0801 | |
!byte $0c,$08,$b5,$07,$9e,$20,$32,$30,$36,$32,$00,$00,$00 | |
jmp main | |
clrscreen=$e544 | |
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
; Setup code for IRQ and screen setting | |
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
main | |
jsr clrscreen | |
sei ; suspend interupts during init | |
lda #%01111111 ; clear CIA interupts | |
sta $dc0d | |
lda $d01a ; Enable raster interupts | |
ora #$01 | |
sta $d01a | |
lda $d011 ; Clear the 9th-bit for raster line | |
and #$7f ; position | |
sta $d011 | |
lda #200 ; lower 8-bits of raster interupt line | |
sta $d012 | |
lda #<irq ; load the address of the interupt routine | |
sta $0314 ; into the IRQ vector | |
lda #>irq | |
sta $0315 | |
; set screen to 38 columns | |
lda $d016 | |
and #%11110111 ; unset the bit-3 | |
sta $d016 | |
lda #00 | |
sta $d020 | |
lda #00 | |
sta $d021 | |
jsr colorsetup ; set a color gradient | |
cli | |
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
; busy loop waitkng for IRQ | |
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
loop | |
jmp loop | |
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
; IRQ servicing | |
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
irq | |
; turn on character rom access | |
lda $01 // Save original $01 state | |
sta original_01+1 | |
lda #$32 // Set memory configuration to | |
sta $01 // character ROM access. | |
jsr scroller | |
; reset mem configuration | |
original_01 | |
lda #$00 // Retrieve the original memory configuration | |
sta $01 // state before the scroll routine was executed. | |
; sane exit from IRQ | |
irqdone | |
lda #$ff ; Acknowledge IRQ | |
sta $d019 | |
jmp $ea81 ; Minimal sane Return from interupt. Pulls y,x,a from stack and RTI | |
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
; Setup the color ram with a grayscale gradient | |
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
colorsetup | |
ldy #40 | |
- | |
lda colorseq2,y | |
sta $d800+(08 * 40),y ; set colour | |
sta $d800+(09 * 40),y ; set colour | |
sta $d800+(10 * 40),y ; set colour | |
sta $d800+(11 * 40),y ; set colour | |
sta $d800+(12 * 40),y ; set colour | |
sta $d800+(13 * 40),y ; set colour | |
sta $d800+(14 * 40),y ; set colour | |
sta $d800+(15 * 40),y ; set colour | |
dey | |
bne - | |
rts | |
colorseq | |
!byte 11, 11, 11, 11, 11 | |
!byte 12, 12, 12, 12, 12, 12 | |
!byte 15, 15, 15, 15, 15, 15 | |
!byte 1, 1, 1, 1, 1, 1 | |
!byte 15, 15, 15, 15, 15, 15 | |
!byte 12, 12, 12, 12, 12, 12 | |
!byte 11, 11, 11, 11, 11 | |
colorseq2 | |
!byte 11, 11, 11 | |
!byte 12, 12, 12 | |
!byte 15, 15, 15 | |
!byte 1, 1, 1 | |
!byte 3, 3, 3 | |
!byte 14, 14, 14 | |
!byte 2, 2, 2, 2 | |
!byte 14, 14, 14 | |
!byte 3, 3, 3 | |
!byte 1, 1, 1 | |
!byte 15, 15, 15 | |
!byte 12, 12, 12 | |
!byte 11, 11, 11 | |
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
; Scroll 1 character | |
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
scroller | |
ldy #00 | |
scrollerloop | |
; copy all characters from left to right | |
lda $400+(08*40 + 1),y ; get char | |
sta $400+(08*40 + 0),y ; put char | |
lda $400+(09*40 + 1),y ; get char | |
sta $400+(09*40 + 0),y ; put char | |
lda $400+(10*40 + 1),y ; get char | |
sta $400+(10*40 + 0),y ; put char | |
lda $400+(11*40 + 1),y ; get char | |
sta $400+(11*40 + 0),y ; put char | |
lda $400+(12*40 + 1),y ; get char | |
sta $400+(12*40 + 0),y ; put char | |
lda $400+(13*40 + 1),y ; get char | |
sta $400+(13*40 + 0),y ; put char | |
lda $400+(14*40 + 1),y ; get char | |
sta $400+(14*40 + 0),y ; put char | |
lda $400+(15*40 + 1),y ; get char | |
sta $400+(15*40 + 0),y ; put char | |
;sta $d800+(11 * 40)+ofs,y ; set colour | |
iny | |
cpy #40 | |
bne scrollerloop | |
; Load in the base address for the character set in char rom | |
; not strctly needed as address is set for a particular character | |
; later | |
.mychar = $fc | |
lda #$00 | |
sta .mychar | |
lda #$d0 | |
sta .mychar+1 | |
; Pull the next char out of my string. String is limited to 16 chars | |
lda .nextchar | |
and #$0f | |
tay | |
lda .hellotext,y | |
; Multiply character byte value by 8 and store in ".mychar" to | |
; be used as base address for grabbing character bytes | |
asl | |
asl | |
asl | |
sta .mychar | |
lda .hellotext,y | |
;lda #.thischar | |
lsr | |
lsr | |
lsr | |
lsr | |
lsr | |
lsr | |
adc #$d0 | |
sta .mychar+1 | |
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
; Depending on the cycle, pull the character bytes one-by-one, | |
; AND to extract the current bit, and place a "dot" or a "space" at the | |
; y height for this particular byte | |
; Repeat for 8 lines in total - one line for each chracter byte. | |
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
ldx .cycle | |
line0 | |
ldy #0 | |
lda (.mychar),y | |
;lda .mychar3 + 0 | |
and .and,x ; is this pixel set? | |
beq + | |
ldy #81 ; dot | |
sty $400+(09*40 - 2) | |
jmp line1 | |
+ | |
ldy #32 ; space | |
sty $400+(09*40 - 2) | |
line1 | |
ldy #1 | |
lda (.mychar),y | |
;lda .mychar3 + 1 | |
and .and,x | |
beq + | |
ldy #81 ; dot | |
sty $400+(10*40 - 2) | |
jmp line2 | |
+ | |
ldy #32 ; space | |
sty $400+(10*40 - 2) | |
line2 | |
ldy #2 | |
lda (.mychar),y | |
;lda .mychar3 + 2 | |
and .and,x | |
beq + | |
ldy #81 ; dot | |
sty $400+(11*40 - 2) | |
jmp line3 | |
+ | |
ldy #32 ; space | |
sty $400+(11*40 - 2) | |
line3 | |
ldy #3 | |
lda (.mychar),y | |
and .and,x | |
beq + | |
ldy #81 ; dot | |
sty $400+(12*40 - 2) | |
jmp line4 | |
+ | |
ldy #32 ; space | |
sty $400+(12*40 - 2) | |
line4 | |
ldy #4 | |
lda (.mychar),y | |
and .and,x | |
beq + | |
ldy #81 ; dot | |
sty $400+(13*40 - 2) | |
jmp line5 | |
+ | |
ldy #32 ; space | |
sty $400+(13*40 - 2) | |
line5 | |
ldy #5 | |
lda (.mychar),y | |
and .and,x | |
beq + | |
ldy #81 ; dot | |
sty $400+(14*40 - 2) | |
jmp line6 | |
+ | |
ldy #32 ; space | |
sty $400+(14*40 - 2) | |
line6 | |
ldy #6 | |
lda (.mychar),y | |
and .and,x | |
beq + | |
ldy #81 ; dot | |
sty $400+(15*40 - 2) | |
jmp line7 | |
+ | |
ldy #32 ; space | |
sty $400+(15*40 - 2) | |
line7 | |
ldy #7 | |
lda (.mychar),y | |
and .and,x | |
beq + | |
ldy #81 ; dot | |
sty $400+(16*40 - 2) | |
jmp lineend | |
+ | |
ldy #32 ; space | |
sty $400+(16*40 - 2) | |
lineend | |
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
; cycle = cycle + 1. If cycle = 8, then reset to 0, and advance to next char | |
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
inc .cycle | |
lda #08 | |
cmp .cycle | |
beq .advancechar | |
rts | |
.advancechar | |
inc .nextchar | |
lda #0 | |
sta .cycle | |
rts | |
.cycle | |
!byte 0 | |
.nextchar | |
!byte 0 | |
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
; each cycle needs to AND with a different bit-mask to get the | |
; necessary bit in each byte to put on screen | |
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
.and | |
!byte %10000000 | |
!byte %01000000 | |
!byte %00100000 | |
!byte %00010000 | |
!byte %00001000 | |
!byte %00000100 | |
!byte %00000010 | |
!byte %00000001 | |
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
; Scrolly text. Hardcoded at 16chars for now | |
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
.hellotext | |
!scr "hello #rstats. " |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment