657 lines
14 KiB
NASM
657 lines
14 KiB
NASM
SEG zeropageSegment
|
|
introDestPtr WORD
|
|
|
|
SEG programSegment
|
|
introreset SUBROUTINE
|
|
jsr multicolorOff
|
|
|
|
jsr clearScreen
|
|
|
|
; Set screen colors
|
|
lda #0
|
|
sta $d020 ; overscan
|
|
sta $d021 ; center
|
|
|
|
lda #14
|
|
sta introYscroll
|
|
|
|
; for "GLGPROGRAMS" at the beginning
|
|
ldx #$78
|
|
stx introDestPtr
|
|
ldy #$04
|
|
sty introDestPtr + 1
|
|
|
|
; GLGPROGRAMS color
|
|
ldy #$00
|
|
lda #$02
|
|
.colorLoop:
|
|
sta $d800,y
|
|
sta $d900,y
|
|
sta $da00,y
|
|
sta $db00,y
|
|
dey
|
|
bne .colorLoop
|
|
|
|
; first raster interrupt line, for moustaches
|
|
lda #68+18
|
|
sta moustacheLine
|
|
|
|
rts
|
|
|
|
statusIntro0 SUBROUTINE
|
|
; arrives raster interrupt, move moustache one line below
|
|
inc moustacheLine
|
|
|
|
lda $d011 ; load current vertical offset from VIC-II
|
|
and #$07
|
|
cmp #$07
|
|
beq .nextline ; if 7, then it is next text line
|
|
inc $d011 ; else setup moustache interrupt to trigger next raster line...
|
|
jsr setupMoustacheInterrupt
|
|
rts ; ...and return: my job here is done
|
|
|
|
.nextline:
|
|
lda $d011 ; reset raster offset to 0...
|
|
and #$f8
|
|
sta $d011
|
|
|
|
MOV_WORD_MEM dstPointer, introDestPtr
|
|
MEMSET "D", #$80, #40
|
|
|
|
clc ; ... move introDestPtr to next text line ...
|
|
lda introDestPtr
|
|
adc #40
|
|
sta introDestPtr
|
|
lda introDestPtr + 1
|
|
adc #0
|
|
sta introDestPtr + 1
|
|
|
|
MOV_WORD_MEM dstPointer, introDestPtr
|
|
MEMCPY "D", #GLGProgramsText, #200 ; ... and copy "GLG Programs" text to next text line
|
|
|
|
dec introYscroll ; remember that we are one line below
|
|
beq .next ; if we reached the end of the vertical scroll, advance status
|
|
|
|
jsr setupMoustacheInterrupt ; else just continue with the moustache
|
|
rts
|
|
|
|
.next:
|
|
lda #ST_INTRO1
|
|
sta status
|
|
rts
|
|
|
|
setupMoustacheInterrupt SUBROUTINE
|
|
; Store in $314 address of our custom interrupt handler
|
|
ldx #<.moustacheInterruptH
|
|
ldy #>.moustacheInterruptH
|
|
stx $314
|
|
sty $315
|
|
|
|
; Set raster beam to trigger interrupt at row
|
|
lda moustacheLine
|
|
sta $d012
|
|
|
|
rts
|
|
|
|
.moustacheInterruptH:
|
|
; "higher" moustache interrupt (on the right of the screen)
|
|
; +36
|
|
dec $d019 ; +42, EOI
|
|
lda #$02 ; +44, color
|
|
sta $d020 ; +48, color
|
|
nop ; +50, timing
|
|
nop ; +52, timing
|
|
nop ; +54, timing
|
|
bit $02 ; +57, timing
|
|
lda #$00 ; +59, color
|
|
sta $d020 ; +63, color
|
|
|
|
; second line, +0
|
|
inc $0800 ; + 6, timing
|
|
inc $0800 ; +12, timing
|
|
inc $0800 ; +18, timing
|
|
inc $0800 ; +24, timing
|
|
inc $0800 ; +30, timing
|
|
inc $0800 ; +36, timing
|
|
inc $0800 ; +42, timing
|
|
lda #$02 ; +44, color
|
|
sta $d020 ; +48, color
|
|
inc $0800 ; +54, timing
|
|
bit $02 ; +57, timing
|
|
lda #$00 ; +59, color
|
|
sta $d020 ; +63, color
|
|
|
|
; set raster beam low
|
|
ldx #<.moustacheInterruptL
|
|
ldy #>.moustacheInterruptL
|
|
stx $314
|
|
sty $315
|
|
clc
|
|
lda moustacheLine
|
|
adc #23 ; "lower" moustache is 23 raster lines below higher one
|
|
sta $d012
|
|
|
|
jmp $ea31
|
|
|
|
.moustacheInterruptL:
|
|
; "lower" moustache interrupt (on the left of the screen)
|
|
; +36
|
|
dec $d019 ; +42, EOI
|
|
inc $0800 ; +48, timing
|
|
inc $0800 ; +54, timing
|
|
lda #$02 ; +56, color
|
|
bit $0800 ; +60, timing
|
|
bit $02 ; +63, timing
|
|
|
|
; newline
|
|
sta $d020 ; + 4, color
|
|
lda #$00 ; + 6, timing
|
|
inc $0800 ; +12, timing
|
|
inc $0800 ; +18, timing
|
|
nop ; +20, timing
|
|
sta $d020 ; +24, color
|
|
lda #$02 ; +26, color
|
|
bit $0800 ; +30, timing
|
|
inc $0800 ; +36, timing
|
|
inc $0800 ; +42, timing
|
|
inc $0800 ; +48, timing
|
|
inc $0800 ; +54, timing
|
|
inc $0800 ; +60, timing
|
|
bit $02 ; +63, timing
|
|
|
|
; newline
|
|
sta $d020 ; + 4, color
|
|
lda #$00 ; + 6, color
|
|
inc $0800 ; +12, timing
|
|
inc $0800 ; +18, timing
|
|
sta $d020 ; +22, color
|
|
|
|
ldx #<irq ; restore main raster interrupt handler
|
|
ldy #>irq
|
|
stx $314
|
|
sty $315
|
|
lda #$00
|
|
sta $d012
|
|
|
|
jmp $ea31
|
|
|
|
GLGProgramsText: ; fancy PETSCII-looking brand name
|
|
BYTE #$80,#$80,#$80,#$80,#$80,#$80,#$80,#$f0,#$f4,#$80,#$80,#$80,#$f0,#$f4,#$80,#$80,#$f0,#$f4,#$f1,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80
|
|
BYTE #$80,#$80,#$80,#$80,#$80,#$80,#$80,#$f5,#$80,#$80,#$f5,#$80,#$f5,#$80,#$80,#$80,#$f5,#$80,#$f5,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$f1,#$80,#$80,#$80,#$f0,#$f4,#$f4,#$f4,#$f4,#$f4,#$f4,#$f4,#$f4,#$f4
|
|
BYTE #$80,#$80,#$80,#$80,#$80,#$80,#$80,#$f5,#$80,#$f5,#$f5,#$80,#$f5,#$80,#$f5,#$80,#$fd,#$f4,#$f3,#$f0,#$f0,#$f1,#$f0,#$f1,#$f0,#$f0,#$fc,#$f0,#$fb,#$f1,#$f2,#$f1,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80
|
|
BYTE #$80,#$80,#$80,#$80,#$80,#$80,#$80,#$f2,#$f4,#$fc,#$f2,#$f4,#$f2,#$f4,#$fc,#$80,#$f5,#$80,#$80,#$f5,#$f2,#$f3,#$f2,#$fc,#$f5,#$f2,#$f3,#$f5,#$f5,#$f5,#$f4,#$f3,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80
|
|
BYTE #$f4,#$f4,#$f4,#$f4,#$f4,#$f4,#$f4,#$f4,#$f4,#$fa,#$f4,#$f4,#$f4,#$f4,#$f3,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$f3,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80
|
|
|
|
statusIntro1 SUBROUTINE
|
|
; continue moving moustaches down, up to 4 raster lines (middle of text)
|
|
lda $d011
|
|
and #$07
|
|
cmp #$04
|
|
beq .next ; if interrupt is in the middle, don't move it anymore, and...
|
|
inc $d011
|
|
inc moustacheLine
|
|
|
|
jsr setupMoustacheInterrupt
|
|
|
|
rts
|
|
|
|
.next:
|
|
jsr setupMoustacheInterrupt ; ... always remember to display moustache, anyhow ...
|
|
|
|
lda counter ; wait for song synchronization up to interrupt $0080
|
|
cmp #$80
|
|
bne .end
|
|
lda counter + 1
|
|
cmp #$00
|
|
bne .end
|
|
|
|
ldy #$0
|
|
lda #$07
|
|
.colorLoop:
|
|
sta $d940,y
|
|
iny
|
|
cpy #200
|
|
bne .colorLoop
|
|
|
|
lda #ST_INTRO2
|
|
sta status
|
|
|
|
.end:
|
|
rts
|
|
|
|
statusIntro2 SUBROUTINE
|
|
jsr setupMoustacheInterrupt
|
|
|
|
; "RETROFFICINA"
|
|
lda #<introStringA1
|
|
sta srcStringPointer
|
|
lda #>introStringA1
|
|
sta srcStringPointer + 1
|
|
lda #$48
|
|
sta dstScreenPointer
|
|
lda #$05
|
|
sta dstScreenPointer + 1
|
|
jsr printString
|
|
|
|
lda counter
|
|
cmp #$08
|
|
bne .end
|
|
lda counter + 1
|
|
cmp #$01
|
|
bne .end
|
|
lda #ST_INTRO3
|
|
sta status
|
|
|
|
.end:
|
|
rts
|
|
|
|
statusIntro3 SUBROUTINE
|
|
jsr setupMoustacheInterrupt
|
|
|
|
; "AND"
|
|
lda #<introStringA2
|
|
sta srcStringPointer
|
|
lda #>introStringA2
|
|
sta srcStringPointer + 1
|
|
lda #$a5
|
|
sta dstScreenPointer
|
|
lda #$05
|
|
sta dstScreenPointer + 1
|
|
jsr printString
|
|
|
|
lda counter
|
|
cmp #$86
|
|
bne .end
|
|
lda counter + 1
|
|
cmp #$01
|
|
bne .end
|
|
lda #ST_INTRO4
|
|
sta status
|
|
|
|
.end:
|
|
rts
|
|
|
|
statusIntro4 SUBROUTINE
|
|
jsr setupMoustacheInterrupt
|
|
|
|
; "GIOMBA"
|
|
lda #<introStringA3
|
|
sta srcStringPointer
|
|
lda #>introStringA3
|
|
sta srcStringPointer + 1
|
|
lda #$f9
|
|
sta dstScreenPointer
|
|
lda #$05
|
|
sta dstScreenPointer + 1
|
|
jsr printString
|
|
|
|
lda counter
|
|
cmp #$08
|
|
bne .end
|
|
lda counter + 1
|
|
cmp #$02
|
|
bne .end
|
|
|
|
MEMSET #$540, #$80, #200
|
|
|
|
lda #ST_INTRO5
|
|
sta status
|
|
|
|
.end:
|
|
rts
|
|
|
|
statusIntro5 SUBROUTINE
|
|
jsr setupMoustacheInterrupt
|
|
|
|
; "PRESENT"
|
|
lda #<introStringA4
|
|
sta srcStringPointer
|
|
lda #>introStringA4
|
|
sta srcStringPointer + 1
|
|
lda #$50
|
|
sta dstScreenPointer
|
|
lda #$05
|
|
sta dstScreenPointer + 1
|
|
jsr printString
|
|
|
|
lda counter
|
|
cmp #$80
|
|
bne .end
|
|
lda counter + 1
|
|
cmp #$02
|
|
bne .end
|
|
|
|
lda #ST_INTRO6
|
|
sta status
|
|
|
|
.end:
|
|
rts
|
|
|
|
statusIntro6 SUBROUTINE
|
|
jsr setupMoustacheInterrupt
|
|
|
|
; "A COMMODORE 64"
|
|
lda #<introStringA5
|
|
sta srcStringPointer
|
|
lda #>introStringA5
|
|
sta srcStringPointer + 1
|
|
lda #$9d
|
|
sta dstScreenPointer
|
|
lda #$05
|
|
sta dstScreenPointer + 1
|
|
jsr printString
|
|
|
|
lda counter
|
|
cmp #$08
|
|
bne .end
|
|
lda counter + 1
|
|
cmp #$03
|
|
bne .end
|
|
|
|
lda #ST_INTRO7
|
|
sta status
|
|
|
|
.end:
|
|
rts
|
|
|
|
statusIntro7 SUBROUTINE
|
|
jsr setupMoustacheInterrupt
|
|
|
|
; "VIDEOGAME"
|
|
lda #<introStringA6
|
|
sta srcStringPointer
|
|
lda #>introStringA6
|
|
sta srcStringPointer + 1
|
|
lda #$ef
|
|
sta dstScreenPointer
|
|
lda #$05
|
|
sta dstScreenPointer + 1
|
|
jsr printString
|
|
|
|
lda counter
|
|
cmp #$80
|
|
bne .end
|
|
lda counter + 1
|
|
cmp #$03
|
|
bne .end
|
|
|
|
lda #ST_INTRO8
|
|
sta status
|
|
|
|
.end:
|
|
rts
|
|
|
|
statusIntro8 SUBROUTINE
|
|
jsr setupMoustacheInterrupt
|
|
|
|
; blank wait
|
|
lda counter
|
|
cmp #$16
|
|
bne .end
|
|
lda counter + 1
|
|
cmp #$04
|
|
bne .end
|
|
|
|
lda #ST_MENURESET
|
|
sta status
|
|
|
|
.end:
|
|
rts
|
|
|
|
statusMenuReset SUBROUTINE
|
|
lda #$05
|
|
ldy #$0
|
|
.lastlineColorLoop:
|
|
sta $db98,y
|
|
iny
|
|
cpy #80
|
|
bne .lastlineColorLoop
|
|
|
|
; Print Game Title: big "SNAKE"
|
|
MEMSET #$d800, #$02, #280 ; color
|
|
MEMCPY #$400, #SnakeText, #280 ; text
|
|
|
|
; Print PETSCII GLG Programs
|
|
MEMSET #($6a8 + $d800 - $400), #$02, #200 ; color
|
|
MEMCPY #$6a8, #GLGProgramsText, #200 ; text
|
|
|
|
; Print website
|
|
lda #<intro2string ; lsb of string address
|
|
sta srcStringPointer ; put into lsb of source pointer
|
|
lda #>intro2string ; do the same for msb of string address
|
|
sta srcStringPointer + 1 ; put into msb of source pointer
|
|
lda #$9e ; this is lsb of address of 23th line
|
|
sta dstScreenPointer ; put into lsb of dest pointer
|
|
lda #$07 ; do the same for msb of adress of 20th line
|
|
sta dstScreenPointer + 1 ; put into msb of dest pointer
|
|
jsr printString ; print
|
|
|
|
; Print Copyright
|
|
lda #<intro3string ; the assembly is the same as above,
|
|
sta srcStringPointer ; just change string to be printed
|
|
lda #>intro3string ; and line (24th line)
|
|
sta srcStringPointer + 1
|
|
lda #$ce
|
|
sta dstScreenPointer
|
|
lda #$07
|
|
sta dstScreenPointer + 1
|
|
jsr printString
|
|
|
|
; boat-shaped horizontal line (rounded edges toward the top)
|
|
; this overwrites the "present" word from the intro
|
|
lda #$f2 ; 3rd quadrant
|
|
sta $540
|
|
lda #$f3 ; 4th quadrant
|
|
sta $567
|
|
lda #$07 ; color for edges
|
|
sta $540+$d800-$400
|
|
sta $567+$d800-$400
|
|
ldy #$1
|
|
.boatLineLoop:
|
|
lda #$f4 ; horizontal line
|
|
sta $540,y
|
|
lda #$07
|
|
sta $540+$d800-$400,y
|
|
iny
|
|
cpy #39
|
|
bne .boatLineLoop
|
|
|
|
lda #$05
|
|
sta XCharOffset
|
|
|
|
jsr setupMoustacheInterrupt ; never forget the magic moustaches
|
|
|
|
lda #ST_MENU
|
|
sta status
|
|
rts
|
|
|
|
SnakeText:
|
|
HEX 80 80 80 80 80 80 80 80 f6 a0 a0 f9 80 f7 80 80 f6 80 f6 a0 a0 f7 80 f7 80 80 80 f6 a0 a0 f9 80 80 80 80 80 80 80 80 80
|
|
HEX 80 80 80 80 80 80 80 80 a0 80 80 80 80 a0 f7 80 a0 80 a0 80 80 a0 80 a0 f6 f7 80 a0 80 80 80 80 80 80 80 80 80 80 80 80
|
|
HEX 80 80 80 80 80 80 80 80 a0 80 80 80 80 a0 a0 f7 a0 80 a0 80 80 a0 80 a0 a0 f9 80 a0 80 80 80 80 80 80 80 80 80 80 80 80
|
|
HEX 80 80 80 80 80 80 80 80 f8 a0 a0 f7 80 a0 f8 a0 a0 80 a0 a0 a0 a0 80 a0 f9 80 80 a0 a0 80 80 80 80 80 80 80 80 80 80 80
|
|
HEX 80 80 80 80 80 80 80 80 80 80 80 a0 80 a0 80 f8 a0 80 a0 80 80 a0 80 a0 f7 80 80 a0 80 80 80 80 80 80 80 80 80 80 80 80
|
|
HEX 80 80 80 80 80 80 80 80 80 80 80 a0 80 a0 80 80 a0 80 a0 80 80 a0 80 a0 a0 f7 80 a0 80 80 80 80 80 80 80 80 80 80 80 80
|
|
HEX 80 80 80 80 80 80 80 80 f6 a0 a0 f9 80 f8 80 80 f8 80 f9 80 80 f8 80 a0 f8 f9 80 f8 a0 a0 f7 80 80 80 80 80 80 80 80 80
|
|
|
|
;ParabolicSpaceChars:
|
|
; HEX 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 01 00 00 00 00 00 01 00 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 00 00 00 00 00 01 00 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
|
;ParabolicSpaceScroll:
|
|
; HEX 00 01 01 01 01 01 01 01 02 02 02 03 03 04 04 05 06 06 07 00 00 01 02 03 04 05 06 07 00 01 02 04 05 06 00 01 02 04 05 07 00 02 04 05 07 00 01 03 04 06 00 01 03 04 06 07 00 02 03 04 06 07 00 01 02 03 04 05 06 07 00 01 02 02 03 04 04 05 05 06 06 06 07 06 07 07 07 07 07 07 07
|
|
|
|
setupXScrollInterrupt SUBROUTINE
|
|
ldx #<XScrollInterruptH
|
|
ldy #>XScrollInterruptH
|
|
stx $314
|
|
sty $315
|
|
|
|
; Set raster beam to trigger interrupt at row
|
|
lda #42
|
|
sta $d012
|
|
|
|
rts
|
|
|
|
XScrollInterruptH SUBROUTINE
|
|
|
|
lda $d016
|
|
and #$f8
|
|
ora XScrollOffset
|
|
sta $d016
|
|
|
|
dec $d019
|
|
|
|
ldx #<XScrollInterruptL
|
|
ldy #>XScrollInterruptL
|
|
stx $314
|
|
sty $315
|
|
lda #110
|
|
sta $d012
|
|
|
|
jmp $ea31
|
|
|
|
XScrollInterruptL SUBROUTINE
|
|
lda $d016
|
|
and #$f8
|
|
sta $d016
|
|
|
|
dec $d019
|
|
|
|
ldx #<XScrollInterruptMoveAll
|
|
ldy #>XScrollInterruptMoveAll
|
|
stx $314
|
|
sty $315
|
|
lda #120
|
|
sta $d012
|
|
|
|
jmp $ea31
|
|
|
|
XScrollInterruptMoveAll SUBROUTINE
|
|
dec $d019 ; EOI
|
|
|
|
tsx
|
|
dex
|
|
|
|
lda XCharOffset
|
|
asl
|
|
asl
|
|
asl
|
|
sta $100,x
|
|
lda $d016
|
|
and #$07
|
|
ora $100,x
|
|
|
|
inx
|
|
txs
|
|
|
|
cmp #78
|
|
bcs .isEdge
|
|
cmp #3
|
|
bcc .isEdge
|
|
cmp #70
|
|
bcs .isMiddle
|
|
cmp #10
|
|
bcc .isMiddle
|
|
jmp .enter
|
|
|
|
.isMiddle:
|
|
lda counter
|
|
and #$01
|
|
beq .enter
|
|
jmp .next
|
|
|
|
.isEdge:
|
|
lda counter
|
|
and #$03
|
|
beq .enter ; ah, some good spaghetti code to accomodate for far branch
|
|
jmp .next ; bounce slower
|
|
|
|
.isCenter:
|
|
.enter:
|
|
lda XScrollDirection
|
|
and #$01
|
|
bne .goRight
|
|
.goLeft:
|
|
dec XScrollOffset
|
|
lda XScrollOffset
|
|
and #$07
|
|
cmp #$07
|
|
beq .continue1
|
|
jmp .next
|
|
.continue1:
|
|
lda #$07
|
|
sta XScrollOffset
|
|
.moveEverythingLeft:
|
|
dec XCharOffset
|
|
ldy #0
|
|
.loop1:
|
|
lda $401,y
|
|
sta $400,y
|
|
lda $429,y
|
|
sta $428,y
|
|
lda $451,y
|
|
sta $450,y
|
|
lda $479,y
|
|
sta $478,y
|
|
lda $4a1,y
|
|
sta $4a0,y
|
|
lda $4c9,y
|
|
sta $4c8,y
|
|
lda $4f1,y
|
|
sta $4f0,y
|
|
iny
|
|
cpy #38
|
|
bne .loop1
|
|
|
|
lda XCharOffset
|
|
cmp #0
|
|
bne .next
|
|
lda #$01
|
|
sta XScrollDirection
|
|
jmp .next
|
|
|
|
.goRight:
|
|
inc XScrollOffset
|
|
lda XScrollOffset
|
|
and #$07
|
|
cmp #$00
|
|
bne .next
|
|
lda #$00
|
|
sta XScrollOffset
|
|
.moveEverythingRight:
|
|
inc XCharOffset
|
|
ldy #38
|
|
.loop2:
|
|
lda $400,y
|
|
sta $401,y
|
|
lda $428,y
|
|
sta $429,y
|
|
lda $450,y
|
|
sta $451,y
|
|
lda $478,y
|
|
sta $479,y
|
|
lda $4a0,y
|
|
sta $4a1,y
|
|
lda $4c8,y
|
|
sta $4c9,y
|
|
lda $4f0,y
|
|
sta $4f1,y
|
|
dey
|
|
bne .loop2
|
|
|
|
lda XCharOffset
|
|
cmp #10
|
|
bne .next
|
|
lda #$00
|
|
sta XScrollOffset
|
|
lda #$00
|
|
sta XScrollDirection
|
|
|
|
.next:
|
|
jsr setupMoustacheInterrupt
|
|
|
|
jmp $ea31
|
|
|
|
statusMenu SUBROUTINE
|
|
jsr setupXScrollInterrupt
|
|
rts
|