#if VERBOSE = 1 LASTINIT SET . #endif 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 dstPointer ldy #$04 sty dstPointer + 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+19 sta moustacheLine rts statusIntro0 SUBROUTINE lda introYscroll .enter: inc moustacheLine lda $d011 and #$07 cmp #$07 beq .nextline inc $d011 jsr setupMoustacheInterrupt rts .nextline: lda $d011 and #$f8 sta $d011 ldy #0 lda #$80 .clearLineLoop: sta (dstPointer),y iny cpy #40 bne .clearLineLoop clc lda dstPointer adc #40 sta dstPointer lda dstPointer + 1 adc #0 sta dstPointer + 1 ldy #$00 .glgLoop: lda GLGProgramsText,y sta (dstPointer),y iny cpy #200 bne .glgLoop dec introYscroll beq .next jsr setupMoustacheInterrupt 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: ; +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 sta $d012 jmp $ea31 .moustacheInterruptL: ; +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 stx $314 sty $315 lda #$00 sta $d012 jmp $ea31 GLGProgramsText: 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 lda $d011 and #$07 cmp #$04 beq .next inc $d011 inc moustacheLine jsr setupMoustacheInterrupt rts .next: jsr setupMoustacheInterrupt lda counter 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 + 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 + 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 + 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 lda #$80 ldy #$0 .loop: sta $540,y iny cpy #200 bne .loop lda #ST_INTRO5 sta status .end: rts statusIntro5 SUBROUTINE jsr setupMoustacheInterrupt ; "PRESENT" 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 + 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 + 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 lda #$00 sta dstPointer lda #$04 sta dstPointer + 1 ; Print big "SNAKE" ldx #SnakeText stx srcPointer sty srcPointer + 1 ldy #$00 .SnakeTitleLoop: lda (srcPointer),y sta (dstPointer),y inc srcPointer bne .noinc1 inc srcPointer + 1 .noinc1: inc dstPointer bne .noinc2 inc dstPointer + 1 .noinc2: lda dstPointer cmp #$18 bne .SnakeTitleLoop lda dstPointer + 1 cmp #$05 bne .SnakeTitleLoop ; Print website 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 ; and line (24th line) sta srcStringPointer + 1 lda #$ce sta dstScreenPointer lda #$07 sta dstScreenPointer + 1 jsr printString lda #$f2 sta $540 lda #$f3 sta $567 ldy #$1 lda #$f4 .cancelPresent: sta $540,y iny cpy #39 bne .cancelPresent 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 setupXScrollInterrupt SUBROUTINE ldx #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 stx $314 sty $315 lda #110 sta $d012 jmp $ea31 XScrollInterruptL SUBROUTINE lda $d016 and #$f8 sta $d016 dec $d019 ldx #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 #if VERBOSE = 1 ECHO "intro1.asm @ ",LASTINIT,"len:",(. - LASTINIT) #endif