====== 4 ways scroll part 2 ====== ; 4 Ways Scroll ; by malcolm bamber ; http://www.dark-well.pwp.blueyonder.co.uk/ ; Assembler Used C64ASM.EXE ; part 2 ;*********** ;** SETUP ** ;*********** setup lda #<55296 ; store colour map address sta Ptrcolour lda #>55296 sta Ptrcolour+1 lda #sparecolour sta PtrSparecolour+1 lda #<(level+0) ; store map address sta Ptrmap lda #>(level+0) sta Ptrmap+1 lda #<(levelcolour+0) ; store colour map address sta Ptrmapcolour lda #>(levelcolour+0) sta Ptrmapcolour+1 lda #255 ; turn cursor off sta 204 lda #1 sta 649 ; POKE 649,1 disable keyboard buffering lda $D018 ; set the computer to were the new chars set are and use them and #240 ; 11110000 ora #12 ; 00001100 sta $D018 ; set it at bank 1 ;+-------+------+-------+----------+-------------------------------------+ ;| VALUE | BITS | BANK | STARTING | VIC-II CHIP RANGE | ;| OF A | | | LOCATION | | ;+-------+------+-------+----------+-------------------------------------+ ;| 0 | 00 | 3 | 49152 | ($C000-$FFFF)* | ;| 1 | 01 | 2 | 32768 | ($8000-$BFFF) | ;| 2 | 10 | 1 | 16384 | ($4000-$7FFF)* | ;| 3 | 11 | 0 | 0 | ($0000-$3FFF) (DEFAULT VALUE) | ;+-------+------+-------+----------+-------------------------------------+ LDA $01 ; switch off basic AND #$FE STA $01 lda #7 sta $D020 ; border colour lda #0 sta $D021 ; screen background colour lda #11 ; Brown sta $D022 ; background colour 1 lda #15 ; Lt Red sta $D023 ; background colour 1 ; D011 VIC Control Register ; 7 Raster Compare: (Bit 8) See 53266 ; 6 Extended Color Text Mode 1 = Enable ; 5 Bit Map Mode. 1 = Enable ; 4 Blank Screen to Border Color: 0 = Blank ; 3 Select 24/25 Row Text Display: 1 = 25 Rows ; 2 Smooth Scroll to Y Dot-Position (0-7) ; 1 Smooth Scroll to Y Dot-Position (0-7) ; 0 Smooth Scroll to Y Dot-Position (0-7) lda #%00010111 ; Select 24/25 Row Text Display: 1 = 25 Rows sta $d011 lda $d011 ; set screen scroll position and #%01111000 ora yscroll ; Smooth Scroll to Y Dot-Position (0-7) sta $d011 ; bit 0 1 2 of $d016 scroll screen left or right ; 0 = all the way to the right ; 7 = all the way to the left ; 3 = middle ; bit 4 of $d016 Select 38/40 Column Text Display: 1 = 40 Cols ; bit 5 of $d016 switch on mult colour ;+----------+---------------------------------------------------+ ;| Bits 7-6 | Unused | ;| Bit 5 | Reset-Bit: 1 = Stop VIC (no Video Out, no RAM | ;| | refresh, no bus access) | ;| Bit 4 | Multi-Color Mode: 1 = Enable (Text or Bitmap) | ;| Bit 3 | Select 38/40 Column Text Display: 1 = 40 Cols | ;| Bits 2-0 | Smooth Scroll to X Dot-Position (0-7) | ;+----------+---------------------------------------------------+ lda #%00010111 ; Select 38/40 Column Text Display: 1 = 40 Cols sta $d016 lda $d016 ; set screen scroll position and #%11111000 ora xscroll ; Smooth Scroll to x Dot-Position (0-7) sta $d016 rts ;****************** ;* set up the irq * ;****************** setupirq SEI LDA #$01 STA $D01A ; VIC Interrupt Mask Register (IMR) LDA #vblank STA $0314 ; irq address STX $0315 ; irq address LDY #raster ; 251 raster position STY $D012 ; Raster Position LDA #$7F STA $DC0D ; CIA Interrupt Control Register LDA $DC0D ; CIA Interrupt Control Register CLI rts ;************************************************* ;* SWAP THE HIDDEN SCREEN FOR THE CURRENT SCREEN * ;************************************************* swapscreen lda whichscreen ; which screen is beening shown cmp #0 ; screen address 3072 is not beening shown bne _buf lda $D018 ; current screen and #%00001111 ora #16 ; set current screen that you can see to 1024 sta $D018 lda #(3072/256) ; not need on pcKERNAL'S screen editor sta 648 lda #<1024 ; set address of screen you can see sta Ptrscreen ; set current screen bitmap lda #>1024 sta Ptrscreen+1 ; set current screen bitmap lda #<3072 ; set address of screen that is hidden sta Ptrhiddenscreen ; set hidden screen bitmap lda #>3072 sta Ptrhiddenscreen+1 ; set hidden screen bitmap lda #1 sta whichscreen ;inc $d020 rts _buf lda $D018 ; set default screeh and #%00001111 ora #48 ; set current screen that you can see to 3072 sta $D018 lda #(1024/256) ; not need on pc KERNAL'S screen editor sta 648 lda #<3072 ; set address of screen you can see sta Ptrscreen ; set current screen bitmap lda #>3072 sta Ptrscreen+1 ; set current screen bitmap lda #<1024 ; set address of screen that is hidden sta Ptrhiddenscreen ; set hidden screen bitmap lda #>1024 sta Ptrhiddenscreen+1 ; set hidden screen bitmap lda #0 sta whichscreen ;inc $d020 _swapquit rts ;************** ;* SET CURSOR * ;************** setcursor clc ldy xcursor ; across horizontal column number in the .Y register ldx ycursor ; down the vertical row number in the .X register jsr 65520 rts ;************** ;* GET CURSOR * ;************** getcursor sec jsr 65520 sty xcursor ; across horizontal column number in the .Y register stx ycursor ; down the vertical row number in the .X register rts xcursor .byte 8 ; cursor position were any printing will be done on screen ycursor .byte 2 ; ditto ;*************************************** ;* PRINT A 16 BIT NUMBER TO THE SCREEN * ;* X = low byte = temp0 * ;* Y = high byte =temp1 * ;*************************************** printnum stx temp20 sty temp21 jsr clearbuffer ldy #5 ; were in buffer to store number image _LOOP lda #00 ; **** DO 16 bit divide **** ldx #16 ; 16-bit number (in temp16..temp16+1 count ; how many number we have done _loop0 asl temp20 ; shift one bit position towards the "left" ; Shift least significant byte rol temp21 ; Shift next-to-least-significant byte with carry rol ; Shift next-to-least-significant byte with carry cmp #10 ; 8-bit number must be 10 to show a 16 bit number bcc _loop2 ; 10>a sbc #10 ; 8-bit number must be 10 to show a 16 bit number inc temp20 _loop2 dex ; bne _loop0 ; IF NOT ZERO **** STOP 16 bit divide **** clc ; move left one position for next number to be save adc #48 ; 0 plus 48 = zero to nine ancii number sta stringbuffer,y ; store it dey ; next memory address in buffer cpy #0 bne _LOOP ; no more number to convert ; from here the number is in the stringbuffer ; go past any leading zeros in number buffer ldy #1 ; first number position in buffer _donext lda stringbuffer,y ; get number cmp #48 ; look for zero bne _print ; yes iny ; move to next number cpy #5 ; are we on the last number position bne _donext ; jump out and print what ever is there _print lda #28 ; text colour red jsr $ffd2 _getnextchar lda stringbuffer,y ; address of string jsr $ffd2 ; call CHROUT iny ; move to next letter cpy #6 ; 5 numbers in 16 bit address last letter to print bne _getnextchar ; rts stringbuffer .byte 0,0,0,0,0,0 ; maximum 65535 ;*********************************************************** ; SET THE PRINTNUM TO MOVE TO THE NEXT LINE AFTER PRINTING * ;*********************************************************** carryagereturn lda #13 jsr $ffd2 lda #10 jsr $ffd2 lda #0 jsr $ffd2 rts clearbuffer ldy #0 _clearbuffer0 lda #48 ; this clear the buffer we use to print a 16 bit number sta stringbuffer,y iny cpy #5 bne _clearbuffer0 rts ;************************************* ;* MULTIPLIY * ;* temp0 - temp7 * ;* temp0 = low byte of number * ;* temp1 = high byte of number * ;* temp2 = low byte of multiplicand * ;* temp3 = high byte of multiplicand * ;* temp4 = low byte of result * ;* temp5 = high byte of result * ;************************************* mult16 lda #0 ; product sta temp4 lda #0 sta temp5 lda #$00 sta temp6 ; clear upper bits of product sta temp7 ldx #$10 ; set binary count to 16 shift_r lsr temp1 ; divide multiplier by 2 ror temp0 bcc rotate_r lda temp6 ; get upper half of product and add multiplicand clc adc temp2 sta temp6 lda temp7 adc temp3 rotate_r ror ; rotate partial product sta temp7 ror temp6 ror temp5 ror temp4 dex bne shift_r rts ;******************** ;* DO SCREEN SCROLL * ;******************** vblank lda #1 sta sync lda scrollstop ; FLAG FOR WAITING FOR JOYSTICK TO SET XSCROLL FOR SCROLLING ; THE SCREEN cmp #0 ; STILL WAITING FOR JOYSTICK beq vblankquit lda scrollstop cmp #2 beq updownscroll ; DO UP OR DOWN SCREEN SCROLL jmp leftrightscroll ; DO LEFT OR RIGHT SCREEN SCROLL vblankquit lda #$ff ; QUIT OUT AND WAIT sta $D019 ; VIC Interrupt Request Register (IRR) jmp $ea31 ; quit out ;********************************************************* ;** SCROLL THE SCREEN UP OR DOWN USING YSCROLL AND MAPY ** ;********************************************************* updownscroll lda yscroll ; CURRENT YSCROLL VALUE ;dec $d020 _ck7 cmp #7 ; DOING NOUT bne _ck6 ; NO MATCH SO CHECK NEXT VALUE lda #1 ; SET NEW FLAG VALUE sta yscroll ; SET YSCROLL FOR NEXT IRQ CALL lda $d011 ; set screen scroll position and #%01111000 ora #7 ; Smooth Scroll to x Dot-Position (0-7) sta $d011 lda udflag ; WE SCROLL EACH WAY TWO TIMES cmp #1 bne _not7next LDA #