;------------------------------------------------------------------------; ; SPINNER - Pope ; ; This is a quick little program that spins the BASIC character set ; using the interrupt. It is included with CASM Version 1.3, available ; on the World Wide Web at http://www.cs.wm.edu/~pbgonz/progc64.html, ; or via Email to Lucas Pope ;------------------------------------------------------------------------; ;------------------------------------------------------------------------; LAYOUT ;------------------------------------------------------------------------; ; ; The BASIC SYS start runs sSetup at $0810, which hooks the user interrupt ; to jump to sSpinner. Then control is returned to BASIC, and the ; interrupt takes over. $0801: dSysStart ; BASIC start $0810: sSetup ; intialization code sSpinner ; interrupt handler dProgVars ; program variables ENDL ALIASB CharBackColor = $00 ; color of character back ALIASB CharFrontColor = $0e ; color of character front ALIASB TurnPause = 05 ; pause while letters are turning ALIASB FlatPause = 70 ; pause while letters are flat ALIASB CountDown = $fd ; used as a timer ALIASB Temp1 = $fb ; temporary variable 1 ALIASB Temp2 = $fe ; temporary variable 2 ALIASB Next = $fc ; stores the turn sequence of ; the chars ALIASW kReturnFromInt = $ea81 ; some Kernel code that returns from ; an interrupt ;------------------------------------------------------------------------; DATA dProgVars ;------------------------------------------------------------------------; OldInterrupt: 0 0 ENDD ;------------------------------------------------------------------------; DATA dSysStart ;------------------------------------------------------------------------; ; ; The BASIC program looks like this: ; ; 1995 SYS(2064) ; EndOfLine ; This will store the address of the label 1995 ; This is a decimal word storing the line # $9E ; Basic "SYS" instruction "(2064)" ; hex address $0810 0 ; end of BASIC line EndOfLine: 0 0 ; end of BASIC program ENDD ;------------------------------------------------------------------------; SUB sSetup ;------------------------------------------------------------------------; Start: sei lda $0001 and #$fb sta $0001 ldx #$00 ldy #$08 Copy1: lda $d000,x ; copying the ROM char mem to 3000 and 2800 sta $3000,x sta $2800,x lda $d100,x sta $2900,x sta $3100,x dex bne Copy1 lda $0001 ora #$04 sta $0001 ldx #$06 lda #$08 Cursor: sta $2d00,x dex bpl Cursor ldx #$00 Flip: lda $3000,x ; flipping chars at 3000 and putting them lsr acc ; at 3800 rol Temp1 lsr acc rol Temp1 lsr acc rol Temp1 lsr acc rol Temp1 lsr acc rol Temp1 lsr acc rol Temp1 lsr acc rol Temp1 lsr acc rol Temp1 lda Temp1 sta $3800,x lda $3100,x lsr acc rol Temp1 lsr acc rol Temp1 lsr acc rol Temp1 lsr acc rol Temp1 lsr acc rol Temp1 lsr acc rol Temp1 lsr acc rol Temp1 lsr acc rol Temp1 lda Temp1 sta $3900,x dex bne Flip ; Make sure it's not already running: lda dProgVars|OldInterrupt cmp #$00 beq NotLoadedYet lda dProgVars|OldInterrupt + 1 cmp #$00 beq NotLoadedYet cli rts ; return to basic NotLoadedYet: lda $0314 ; Save the old interrupt: sta dProgVars|OldInterrupt lda $0315 sta dProgVars|OldInterrupt + 1 lda #sSpinner|Start sta $0315 lda #$00 sta Next lda #$1b sta $d018 lda #FlatPause sta CountDown cli rts ; return to basic ENDS ;------------------------------------------------------------------------; SUB sSpinner ;------------------------------------------------------------------------; ; ; This is just a lot of bit flipping. I sacrificed some readability to ; have the demo program do something entertaining. ; Start: sei dec CountDown bne GoOn ; jump to normal interrupt if CountDown <> 0 lda #TurnPause sta CountDown inc Next lda Next ; determines which part of the turn the cmp #$04 ; characters are currently in beq ToBlack bcc Go5 cmp #$05 beq Go1 cmp #$06 beq Go2 cmp #$07 beq Flip cmp #$0b beq ToBlue bcc Go5 cmp #$0c beq Go3 cmp #$0d beq Go4 lda #$00 sta Next jmp norm Go1: jmp eflip1 ; jmp reaches for the branches above Go2: jmp eflip2 Go3: jmp enorm1 Go4: jmp enorm2 Go5: jmp squish GoOn: jmp (dProgVars|OldInterrupt) ToBlack: ldx #$f9 lda #CharBackColor sta $0286 ; changes the color to CharBackColor Loop1: sta $d800,x sta $d8fa,x sta $d9f4,x sta $daee,x dex cpx #$ff bne Loop1 jmp kReturnFromInt ToBlue: ldx #$f9 lda #CharFrontColor sta $0286 ; changes the color to CharFrontColor Loop2: sta $d800,x sta $d8fa,x sta $d9f4,x sta $daee,x dex cpx #$ff bne Loop2 jmp kReturnFromInt norm: lda #FlatPause sta CountDown ldx #$00 dooper: lda $3000,x ; copies norm chars into visible sta $2800,x lda $3100,x sta $2900,x dex bne dooper jmp kReturnFromInt Flip: lda #FlatPause sta CountDown ldx #$00 dooper2: lda $3800,x ; copies flipped chars into visible sta $2800,x lda $3900,x sta $2900,x dex bne dooper2 jmp kReturnFromInt ; squishes the visible characters squish: ldx #$00 sqshmore: lda $2800,x tay and #$08 sta Temp2 tya asl acc and #$0f sta Temp1 tya lsr acc and #$f0 ora Temp1 ora Temp2 sta $2800,x lda $2900,x tay and #$08 sta Temp2 tya asl acc and #$0f sta Temp1 tya lsr acc and #$f0 ora Temp1 ora Temp2 sta $2900,x dex bne sqshmore jmp kReturnFromInt enorm1: ldx #$00 ; copies normal chars into view, squishing LoopA: lda $3000,x ; them at the same time (squishes less tay ; every time) to make them appear to expand and #$08 sta Temp2 tya asl acc asl acc and #$0f sta Temp1 tya lsr acc lsr acc and #$f0 ora Temp1 ora Temp2 sta $2800,x lda $3100,x tay and #$08 sta Temp2 tya asl acc asl acc and #$0f sta Temp1 tya lsr acc lsr acc and #$f0 ora Temp1 ora Temp2 sta $2900,x dex bne LoopA jmp kReturnFromInt enorm2: ldx #$00 ; same as above only expands less LoopB: lda $3000,x tay and #$08 sta Temp2 tya asl acc and #$0f sta Temp1 tya lsr acc and #$f0 ora Temp1 ora Temp2 sta $2800,x lda $3100,x tay and #$08 sta Temp2 tya asl acc and #$0f sta Temp1 tya lsr acc and #$f0 ora Temp1 ora Temp2 sta $2900,x dex bne LoopB jmp kReturnFromInt eflip1: ldx #$00 ; copies flipped characters into view LoopC: lda $3800,x ; "squishing" them at the same time tay and #$08 sta Temp2 tya asl acc asl acc and #$0f sta Temp1 tya lsr acc lsr acc and #$f0 ora Temp1 ora Temp2 sta $2800,x lda $3900,x tay and #$08 sta Temp2 tya asl acc asl acc and #$0f sta Temp1 tya lsr acc lsr acc and #$f0 ora Temp1 ora Temp2 sta $2900,x dex bne LoopC jmp kReturnFromInt eflip2: ldx #$00 ; same as above only less LoopD: lda $3800,x tay and #$08 sta Temp2 tya asl acc and #$0f sta Temp1 tya lsr acc and #$f0 ora Temp1 ora Temp2 sta $2800,x lda $3900,x tay and #$08 sta Temp2 tya asl acc and #$0f sta Temp1 tya lsr acc and #$f0 ora Temp1 ora Temp2 sta $2900,x dex bne LoopD jmp kReturnFromInt ENDS