; ======================================== ; Project : 3dMaze2 ; Target : Commodore 64 ; Comments : ; Author : Michael Cassera ; ======================================== cROM = $d000 ;character ROM start location cRAM = $3000 ;location for new character RAM cchar = $3280 ;start of custom chars vncsb = $d018 ;VIC-II Memory Chip Control Register ciacra = $dc0e ;Control register A vicscn = $0400 ;starting location of graphics screen ColorR = $d800 ;starting location of color ram r6510 = $01 ;6510 chip memory selector chrout = $ffd2 ;kernal print routine cls = $93 ;Clear screen character vcreg3 = $d412 ;SID V3 CONTROL REGISTER frelo3 = $d40e ;SID V3 frequence LO random = $d41b ;READ SID V3 OSCILLATOR stack = $3800 ;start of stack space charc = $0f ;charactrer color of maze (grey) charb = $0e ;maze frame color (light blue) *=$0801 ; 10 SYS (2064) BYTE $0E, $08, $0A, $00, $9E, $20, $28, $32, $30, $36, $34, $29, $00, $00, $00 ;Start Program cld lda #$06 ;blue sta $d020 ;screen and border sta $d021 jsr CopyChars: ;copy the Character Set to Ram jsr CustomChars: ;program the maze characters start: jsr MakeGrid: ;draw the graph on the screen jsr MakeMaze: ;Make the maze clc ;clear carry for addition lda $a1 ;load jiffy clock 4.2 seconds incr. adc #$02 ;add 2 (approximately 8.4 seconds delay) clock: cmp $a1 ;compare with current $a1 value bne clock: ;haven't reached the 8 seconds yet - keep looping jmp start: CopyChars: ;turn off keyboard lda ciacra ;get value in register and #%11111110 ;remove bit 0 sta ciacra ;store new value in register ;set 6510 to see character ROM lda r6510 ;get 6510 value and #%11111011 ;remove bit 2 sta r6510 ;store value in register ;now ready to copy character data from ROM to RAM lda #cROM ;hi byte of cROM sta $fc ;store on zero page for indirect indexing lda #cRAM ;hi byte of cRAM sta $fe ;store on zero page for indirect indexing ldy #$00 ldx #$08 loop1: lda ($fb),y ;indirect index from character ROM sta ($fd),y ;store in indirect index of RAM iny ;increment our index bne loop1: ;have we looped around to 0 again? ;no, keep looping to loop1: inc $fc ;increment hi byte for ROM Reference inc $fe ;increment hi byte for RAM Reference dex ;decrement x bne loop1: ;has x hit zero? No, loop1: ;yes exit out ;restore registers ;set 6510 to see I/O lda r6510 ;get 6510 value ora #%00000100 ;add bit 2 sta r6510 ;store value in register ;turn keyboard back on lda ciacra ;get value in register ora #%00000001 ;add bit 0 sta ciacra ;store new value in register ;set character pointer to RAM lda vncsb ;get Vic-II Register info and #%11110000 ;keep the values of bits 4-7 ora #%00001100 ;add bits 2 and 3 to change where Vic-II sees ;character matrix data. sta vncsb ;store new value rts CustomChars: ;Now program custom characters ldx #$80 ;set x to 80 for index (last byte) loop2: lda custom:,x ;get custom byte sta cchar,x ;store into RAM character data dex ;reduce x by 1 bne loop2: ;not zero, keep looping lda custom: ;get 1st custom byte sta cchar ;store into RAM character data rts MakeGrid: lda #cls ;get the clear screen character jsr chrout ;print clear screen lda #vicscn ;get hi byte of the screen sta $fc ;store in zero page for indirect indexing lda #ColorR ;hi byte for color ram sta $fe ;store on zero page for indirect indexing ldx #$17 ;number of vertical lines for loop 3 loop3: ldy #$00 ;left side of grid lda #charb ;character color sta ($fd),y ;left side color lda #$51 ;left side character sta ($fb),y ;put on screen ldy #$27 ;right side of grid lda #charb ;grey sta ($fd),y ;right side color lda #$54 ;right side character sta ($fb),y ;put on screen ldy #$26 ;number of character per row for loop 4 loop4: lda #charc ;character color sta ($fd),y ;put the color on the screen lda #$5f ;The custom square character sta ($fb),y ;put on the screen using indirect indexing dey ;reduce y by 1 bne loop4: ;not zero yet, keep looping clc ;clear the carry for some addition lda $fb ;load lo byte adc #$28 ;add 40 to go to next line sta $fb ;and store lda $fc ;load hi byte adc #$00 ;add zero (and the carry bit) sta $fc ;store hi bytes clc ;clear the carry for some addition lda $fd ;load lo byte adc #$28 ;add 40 to go to next line sta $fd ;and store lda $fe ;load hi byte adc #$00 ;add zero (and the carry bit) sta $fe ;store hi bytes dex ;reduce x by 1 (number of lines) bne loop3: ;not zero yet? loop for another line ;now top and bottom ldy #$26 ;number of characters per line loop5: lda #charb ;character color sta ColorR,y ;make top row grey sta ColorR+$3c0,y ;make bottom row grey (top row +960) lda #$52 ;top row character sta vicscn,y ;put on screen lda #$58 ;bottom row character sta vicscn+$3c0,y ;put on bottom row (top row +960) dey bne loop5: ;y not yet zero, keep looping rts MakeMaze: ;time to make the maze ;set SID V3 oscillator to make random numbers lda #$ff sta frelo3 ;SID V3 REGISTER LO sta frelo3+1 ;SID V3 REGISTER HI lda #$80 sta vcreg3 ;TRIGGER SID CHIP lda #$00 ;clear the temps vars sta temp: sta temp:+1 sta temp:+2 sta temp:+3 sta temp:+4 sta scount: ;clear the stack counter sta scount:+1 ;reset the stack pointer lda #stack ;get stack hi address sta spoint:+1 ;select x starting coordinate ;to get a random number between ;0 and 38, I will pick two random ;numbers, 31 and 7 and add them together lda random ;get random number and #%00011111 ;filter to 31 sta temp:+4 ;save for a moment nop nop ;need to waste time nop ;so a new random number nop ;can be generated nop nop lda random ;get random number and #%00000111 ;filter to 7 clc ;clear carry for add adc temp:+4 ;add the first nnumber adc #$01 ;add 1 to get between 1 and 23 sta x: ;store in X nop nop nop ;select Y starting coordinate ;to get a random number between ;0 and 22, I will pick two random ;numbers, 15 and 7 and add them together lda random ;get random number and #%00001111 ;filter to 15 sta temp:+4 ;save for a moment nop nop ;need to waste time nop ;so a new random number nop ;can be generated nop nop lda random ;get random number and #%00000111 ;filter to 7 clc ;clear carry for add adc temp:+4 ;add the first nnumber adc #$01 ;add 1 to get between 1 and 23 sta y: ;store in Y loopa: ;loop to build the maze jsr pushstack: ;put on the stack loopb: lda random ;get a random number and #%00000011 ;filter to only 0 to 3 sta dir: ;store for later asl ;multiply by two for x and y tax ;transfer to x for indexing lda directions:,x ;get x adder for new location clc adc x: ;add to current position sta xpos: ;temp storage and lookup lda directions:+1,x ;get y adder for new location clc adc y: ;add to currnt position sta ypos: ;temp storage and lookup jsr locate: ;get address that coorisponds to x and y jsr peek: ;get character from that address cmp #$5f ;compare result with non-visited graph char. beq wander: ;we can go that way jmp to wander ;we can't go that way mark as bad and try again ldx dir: ;get the direction we tried lda #$01 ;set the flag sta dflag:,x ;and store in its bytes clc lda dflag: ;add up the 4 direction flags adc dflag:+1 ;if they are not all marked, adc dflag:+2 ;there is still a direction to try adc dflag:+3 ;so loop back to a: cmp #$04 bne loopb: jmp backtrack: ;if it equals 4 then we need to backtrack wander: ;knock down some walls and make new x,y current and #$0f ;get the nibble that represent the character sta temp:+4 ;store temporarily ldy loclo: ;get locate lo sty writen:+1 ;alter code below ldy lochi: ;get locate hi sty writen:+2 ;alter code below lda dir: ;get direction again asl a ;multiply by two tax ;transfer to x for indexing lda dbits:+1,x ;get the bit for new pos. and temp:+4 ;remove the line you want clc adc #$50 ;add 80 to the result writen: sta $c000 ;dummy location - altered by above lda xpos: ;now to do the old current location sta xtemp: ;need to move some data around lda ypos: ;but keep the new position safe sta ytemp: ;for after this routine lda x: sta xpos: lda y: sta ypos: jsr locate: ;get address of current position jsr peek: ;get character in that position and #$0f ;get the nibble for that character sta temp:+4 ;store temporarily ldy loclo: ;get locate lo sty writec:+1 ;alter code below ldy lochi: ;get locate hi sty writec:+2 ;alter code below lda dir: ;get direction again asl a ;multiply by two tax ;transfer to x for indexing lda dbits:,x ;get the bit for current pos. and temp:+4 ;remove the line you want clc adc #$50 ;add 80 to the result writec: sta $c000 ;dummy location - altered by above lda xtemp: ;copy temp x and y to current x and y sta x: lda ytemp: sta y: lda #$00 sta dflag: ;clear the direction flags because we've moved on sta dflag:+1 sta dflag:+2 sta dflag:+3 jmp loopa: ;keep going backtrack: lda x: ;copy x and y to xpos and ypos sta xpos: lda y: sta ypos: jsr locate: ;run locate command to get screen address clc lda loclo: ;add $d400 to get color address sta ccolor:+1 lda lochi: adc #$d4 sta ccolor:+2 ;increment the color cell ccolor: dec $d800 ;dummy location - altered above jsr pullstack: ;pull x and y off the stack lda #$00 sta dflag: ;clear the direction flags because we've moved on sta dflag:+1 sta dflag:+2 sta dflag:+3 lda scount:+1 ;get stack count hi bne cmaze: ;not at the end, continue maze building lda scount: ;get stack count lo bne cmaze: ;not at the end, continue maze building jmp startstop: ;maze done make start and stop points cmaze: jmp loopb: ;continue maze building startstop: lda random ;get random number and #%00001111 ;filter to 15 sta temp:+4 ;save for a moment nop nop ;need to waste time nop ;so a new random number nop ;can be generated nop nop lda random ;get random number and #%00000111 ;filter to 7 clc ;clear carry for add adc temp:+4 ;add the first nnumber adc #$01 ;add 1 to get between 1 and 23 sta starty: ;store in starty lda #$00 sta startx: lda random ;get random number and #%00001111 ;filter to 15 sta temp:+4 ;save for a moment nop nop ;need to waste time nop ;so a new random number nop ;can be generated nop nop lda random ;get random number and #%00000111 ;filter to 7 clc ;clear carry for add adc temp:+4 ;add the first nnumber adc #$01 ;add 1 to get between 1 and 23 sta endy: ;store in endy lda #$27 sta endx: ;now make holes lda startx: ;copy start x and y to xpos and ypos sta xpos: ;to use locate routine lda starty: sta ypos: jsr locate: lda loclo: sta $fb ;indirect index lo lda lochi: sta $fc ;indirect index hi lda #$50 ;blank space character ldy #$00 sta ($fb),y iny lda ($fb),y ;get maze character and #%00001111 ;filter down to a nibble and #$fb ;remove the edge we want clc adc #$50 ;add 80 back to get the right poke code sta ($fb),y ;and store lda endx: ;same thing as start x an y sta xpos: ;but at the end dec xpos: lda endy: sta ypos: jsr locate: lda loclo: sta $fb ;indirect index lo lda lochi: sta $fc ;indirect index hi lda #$50 ;blank space character sta ($fb),y dey lda ($fb),y ;get maze character and #%00001111 ;filter down to a nibble and #$fe ;remove the edge we want clc adc #$50 ;add 80 back to get the right poke code sta ($fb),y ;and store rts peek: lda loclo: ;get lo byte from locate: sta peekin:+1 ;alter code below lda lochi: ;get hi byte from locate: sta peekin:+2 ;alter code below peekin: lda $c000 ;dummy location - altered by program above rts locate: ;(ypos * 40) + xpos + map ;(ypos * 32) + (ypos * 8) + xpos + 1024 lda #$00 ;clear some temp vars sta temp: sta temp:+1 sta temp2: sta temp2:+1 lda ypos: ;get y ldx #$05 loop7: ;ypos * 32 clc ;clear carry asl a ;shift left 1 bit (x2) (lo) rol temp:+1 ;rol left 1 bit with carry (x2) (hi) dex ;countdown bne loop7: sta temp: ;store val lo lda ypos: ;get ypos again ldx #$03 loop8: ;ypos * 8 clc ;clear carry asl a ;shift left 1 bit (x2) (lo) rol temp2:+1 ;rol left 1 bit with carry (x2) (hi) dex ;countdown bne loop8: sta temp2: ;store val lo ;add two values for ypos together clc ;clear the carry bit lda temp: ;load lo adc temp2: ;add second lo sta temp: ;store back in temp lda temp:+1 ;load hi adc temp2:+1 ;add second hi (with carry bit) sta temp:+1 ;store second hi ;add xpos to ypos clc ;clear carry bit lda temp: ;load temp value lo adc xpos: ;add xpos sta temp: ;save in temp again lda temp:+1 ;load temp value hi adc #$00 ;add 0 to include carry sta temp:+1 ;store hi value ;add screen location clc ;clear carry flag lda temp: ;load temp lo adc #$00 ;add map location lo sta loclo: ;store in location lo (loclo:) lda temp:+1 ;load temp hi adc #$04 ;add map location hi with carry sta lochi: ;store in location hi (lochi:) rts pushstack: clc lda spoint: ;load stack position lo adc #$02 ;add 2 sta spoint: sta $fd ;setting up indirect indexing lo lda spoint:+1 ;load stack position hi adc #$00 ;add carry sta spoint:+1 sta $fe ;indirect indexing hi lda x: ;get current xpos ldy #$00 ;index sta ($fd),y ;store xpos value on stack lda y: ;get current ypos ldy #$01 sta ($fd),y ;story ypos on stack clc lda scount: ;get stack counter lo adc #$01 ;add 1 sta scount: ;and store lda scount:+1 ;get stack counter hi adc #$00 ;add carry sta scount:+1 ;and store rts pullstack: sec ;set carry for subtraction lda spoint: ;load stack position lo sbc #$02 ;subtrack 2 sta spoint: sta $fd lda spoint:+1 ;load stack position hi sbc #$00 ;pull from carry sta spoint:+1 sta $fe ;indirect indexing hi ldy #$00 ;set index lda ($fd),y ;get stored x: sta x: ;store x ldy #$01 lda ($fd),y ;get stored y sta y: sec lda scount: ;get stack counter lo sbc #$01 ;subtract 1 sta scount: lda scount:+1 ;get stack counter hi sbc #$00 ;pull carry sta scount:+1 rts ;Variables x: byte $00 xtemp: byte $00 y: byte $00 ytemp: byte $00 xpos: byte $00 ypos: byte $00 startx: byte $00 starty: byte $00 endx: byte $00 endy: byte $00 dir: byte $00 temp: byte $00,$00,$00,$00 temp2: byte $00,$00 loclo: byte $00 lochi: byte $00 multlo: byte $00 multhi: byte $00 spoint: byte $00,$00 scount: byte $00,$00 dflag: byte $00,$00,$00,$00 directions: byte $01,$00 ;east byte $00,$01 ;south byte $ff,$00 ;west byte $00,$ff ;north dbits: byte $fe,$fb ;east byte $fd,$f7 ;south byte $fb,$fe ;west byte $f7,$fd ;north ;custom Character data custom: byte $00,$00,$00,$00,$00,$00,$00,$00 byte $01,$01,$01,$01,$01,$01,$01,$01 byte $00,$00,$00,$00,$00,$00,$00,$ff byte $01,$01,$01,$01,$01,$01,$01,$ff byte $80,$80,$80,$80,$80,$80,$80,$80 byte $81,$81,$81,$81,$81,$81,$81,$81 byte $80,$80,$80,$80,$80,$80,$80,$ff byte $81,$81,$81,$81,$81,$81,$81,$ff byte $ff,$00,$00,$00,$00,$00,$00,$00 byte $ff,$01,$01,$01,$01,$01,$01,$01 byte $ff,$00,$00,$00,$00,$00,$00,$ff byte $ff,$01,$01,$01,$01,$01,$01,$ff byte $ff,$80,$80,$80,$80,$80,$80,$80 byte $ff,$81,$81,$81,$81,$81,$81,$81 byte $ff,$80,$80,$80,$80,$80,$80,$ff byte $ff,$81,$81,$81,$81,$81,$81,$ff