;Diamonds 1.3 ;by Jonah Cohen #include "TI86.inc" .org _asm_exec_ram nop jp start .dw 1 grayscale_counter = $-1 ;save memory :-) .dw description .dw icon getkey: halt call _getcsc or a jr z,getkey ret MultHL: xor a cp h jr z,SetZero cp l jr z,SetZero push bc call _HTIMESL pop bc ret SetZero: ld hl,0 ret ; modified routine originally by Matthew Shepcar GetA: ld l,a ld h,0 GetHL: xor a ld de,-1 ld (_curRow),de push bc call $4a33 pop bc dec hl DiscardSpaces: ld a,(hl) inc hl cp ' ' jr z,DiscardSpaces dec hl ret DispA: ld l,a ld h,0 jr DispHL DispAStatus: ld l,a ld h,0 DispHLStatus: ld c,$72 DispHL: call GetHL push bc push hl ld bc,10 xor a cpir ;bc=9-size ld a,9 sub c pop hl pop bc add a,a ;multiply by 2 cpl add a,c ;center column ld c,a ;load into current column jr vputs vputs_b: ld b,(hl) inc hl vputs_loop: push bc call vputs_ pop bc djnz vputs_loop ret vputs_: ld c,(hl) inc hl ld b,(hl) inc hl vputs: ld (_penCol),bc jp _vputs disp_title: ld hl,titlepic ld de,buffer_dark call DispRLE ld de,buffer_light DispRLE: ld bc,256 ; we need to copy DispRLEL: ld a,(hl) ; get the next byte cp $91 ; is it a run? jr z,DispRLERun ; then we need to decode the run ldi ; copy the byte, and update counters DispRLEC: ld a,b ; check the low byte and or c ; the high byte for 0 jr nz,DispRLEL ; if not, then we're not done either ret ; it's zero, we're done DispRLERun: inc hl ; move to the run value ld a,(hl) ; get the run value inc hl ; move to the run count push hl ; save source pointer ld h,(hl) ; get the run count ex de,hl ; swap source and destination pointers DispRLERunL: ld (hl),a ; copy the byte inc hl ; increase destination pointer dec bc ; decrease byte count dec d ; decrease run count jr nz,DispRLERunL ; if we're not done, then loop ex de,hl ; swap pointers back pop hl ; recover source pointer inc hl ; advance the source pointer jr DispRLEC ; check to see if we should loop split: ;copy from buffer to screen ld de,32 ;to get to next row split_bytes: ld a,8 ;8 bits split_byte: ;get right-shift addresses (we add 32 before accessing) ld hl,screen_light-32 ld (dest_right),hl ld hl,buffer_light+$0f-32 source_right_start = $-2 ld (source_right),hl ;get left-shift addresses ld hl,screen_light+$1f-32 ld (dest_left),hl ld hl,buffer_light+$10-32 source_left_start = $-2 ld (source_left),hl ;split the screen once ld b,64 ;number of rows / 2 split_screen: ;shift left ld hl,0 source_left = $-2 add hl,de ;next row ld (source_left),hl rlc (hl) push af ;save carry ld hl,0 dest_left = $-2 add hl,de ld (dest_left),hl pop af ;get carry call shift_left ;shift right ld hl,0 source_right = $-2 add hl,de ;next row ld (source_right),hl rrc (hl) push af ;save carry ld hl,0 dest_right = $-2 add hl,de ;next row ld (dest_right),hl pop af ;get carry call shift_right ;loop djnz split_screen dec a jr nz,split_byte ld hl,source_right_start dec (hl) ld hl,source_left_start inc (hl) jr nz,split_bytes ld (hl),$f0 ld hl,source_right_start ld (hl),$ef ret vert_line ld b,62: ld de,16 vert_line_loop: ld a,c or (hl) ld (hl),a add hl,de djnz vert_line_loop sbc hl,de ret horiz_line: ld (hl),%01111111 ld bc,$0fff horiz_line_loop: inc hl ld (hl),c djnz horiz_line_loop res 0,(hl) ret duplicate_buffer: ld hl,buffer_dark ld de,buffer_light ld bc,1024 jr copy copy_screen: ;just copy to video mem ld hl,buffer_light ld de,screen_light ld bc,2048 copy: ldir ret draw_spaces: ;display d spaces at (b,c) push af push bc push hl ld (_penCol),bc space_loop: push de call _VPUTBLANK pop de dec d jr nz,space_loop pop hl pop bc pop af ret create_shift_loop: ld bc,$10cb create_routine: inc hl ld (hl),c inc hl ld (hl),d inc hl ld (hl),e djnz create_routine ld (hl),$c9 ret check_level: ;nz if not a diamonds level rst 10h ;do a _findsym to get bde ret c call _DATA_SIZE_TO_DE call _GETB_AHL ;get first byte and hl->string now cp $dd ret nz inc hl ld a,(hl) ;get second byte dec a ;cp $01 ret load_levels: push bc ld hl,level_name rst 20h ;move to op1 rst 10h ;_findsym call _DATA_SIZE_TO_DE ;de=size, ahl=bde+2 push de call _SET_ABS_SRC_ADDR pop hl xor a call _SET_MM_NUM_BYTES ;size to copy inc a ld hl,highscore-2-$8000 ;signature bytes go right before highscore call _SET_ABS_DEST_ADDR ;copy here for now call _MM_LDIR call _RAM_PAGE_1 ld hl,num_levels pop bc ;retrieve description call vputs ;display description ld a,(hl) ;get number of levels push hl ld h,a ld l,42 call MultHL ;get size inc hl push hl ld de,num_levels pop bc ;retrieve size pop hl ;retrieve pointer to end of string ldir ;copy over description ret resume_game: im 2 ld hl,level_name rst 20h call check_level jr nz,no_resume ld c,200 ;off screen call load_levels ld a,(num_levels) ld b,a ld a,(level_num) cp b jr nc,no_resume ld hl,bonus inc (hl) jp start_playing start: call _runIndicOff call _flushAllMenus ld hl,$f7ff-$fbff add hl,sp ld sp,hl ld hl,$fbff ld de,$f7ff ld bc,256 lddr ld (save_sp),sp ;save stack pointer ld hl,_contrast ld a,(hl) inc a cp $20 jr nc,no_contrast ld (hl),a out (2),a no_contrast: ld hl,shift_left-1 ld de,$162b call create_shift_loop ld de,$1e23 call create_shift_loop call duplicate_buffer call copy_screen ;install grayscale ld hl,int_start ld de,$f0f0 ld bc,int_end-int_start ldir ld hl,int_table ld (hl),$f0 ld de,int_table+1 inc b ldir ld a,int_table/256 ld i,a ;check game saved ld hl,resumed srl (hl) jr c,resume_game no_resume: xor a ld (level_num),a ;a=0, so first level title_screen: ld sp,0 save_sp = $-2 im 2 ld a,$37 ld (first_screen),a call _clrLCD call disp_title ld hl,name ld bc,$1128 call vputs ld hl,level_name ;load previously saved level rst 20h call check_level jr z,finish_title_screen ;valid level, so we just keep it get_new_level: ld hl,starting_name rst 20h ;copy starting varname to op1 find_first_level: rst 08h ;op1 to op2 xor a call _findAlphaUp ;search for string jr c,no_levels ;no strings call check_level jr z,finish_level_detect ;valid level ;now we check if we're getting anywhere in this search ld hl,_OP1+1 ld de,_OP2+1 call _pstrCmp ;see if name has changed jr nz,find_first_level ;keep searching if name is changing no_levels: ld hl,error_txt call vputs_ call duplicate_buffer call split call getkey jp exit finish_level_detect: ld de,level_name call _MOVFROP1 ;save level name finish_title_screen: ld hl,menu_txt call vputs_b ld hl,0 ld (score),hl ;starting score update_level: ld bc,$323a push bc ;save coordinates ld d,70 call draw_spaces ;erase previous description pop bc call load_levels ld bc,$3a52 push bc ld d,40 call draw_spaces pop bc ld hl,initials call vputs ;display initials call _VPUTBLANK call _VPUTBLANK ;for spacing ld hl,(highscore) call GetHL call _vputs ;display after initials update_speed: ld a,(speed) ld bc,$2a55 call DispA ;display speed update_level_num: ld bc,$224c push bc ld d,15 call draw_spaces ;overwrite last level number ld a,(level_num) inc a call GetA pop bc ;retrieve coordinates call vputs ld hl,buffer_dark+256 ld de,buffer_light+256 ld bc,1024-256 ldir first_screen: scf call c,split ld a,$b7 ld (first_screen),a call copy_screen get_selections: call getkey cp K_EXIT jp z,exit dec a ;cp K_DOWN jr z,level_down sub K_F1-1 jr z,first_level inc a jr z,speed_up inc a jr z,get_next_level cp K_UP-K_F3 jr nz,get_selections level_up: ld hl,level_num inc (hl) ld a,(num_levels) cp (hl) ;check if we're at the max jr nz,update_level_num ld (hl),0 ;first level jr update_level_num level_down: ld hl,level_num dec (hl) ld a,(hl) inc a ;see if we're at -1 jr nz,update_level_num ld a,(num_levels) ld (hl),a ;go to max jr level_down ;now decrement it once speed_up: ld hl,speed inc (hl) ld a,(hl) cp 6 jp nz,update_speed ld (hl),1 jr update_speed get_next_level: xor a ld (level_num),a ;reset level number for new level ld hl,level_name rst 20h ;mov10toop1 detect_level: ld de,temp_search_name call _MOVFROP1 xor a call _findAlphaUp ;search for string ld hl,_OP1+1 ld de,temp_search_name+1 call _pstrCmp jr z,get_first_level ;same var, so we're at end of alphabet. call check_level jr nz,detect_level ;invalid level save_new_level: ld de,level_name call _MOVFROP1 ;copy new name jp update_level ;same name, so we load default name and find first level get_first_level: ld hl,starting_name rst 20h ;copy starting varname to op1 find_a_level: xor a call _findAlphaUp call check_level jr nz,find_a_level ;keep searching until we find something jr save_new_level first_level: ld a,5 ld (lives),a ;starting lives start_level: ld a,(level_num) ld h,a ld l,42 call MultHL ld de,levels add hl,de ;hl->level data ld de,start_coords ldi ldi ;copy ball coordinates ld b,40 ;40 bytes to copy xor a decomp_level: rld ld (de),a inc de rld ld (de),a inc de inc hl djnz decomp_level ld hl,1*256+61 ld (bonus),hl ;the bonus score for the round, direction=down xor a ld (hit_key),a ;not active yet ld (reverse_mode),a ;regular keys inc a ld (brick_mode),a ;white bricks ld hl,(start_coords) ld (ball_y),hl start_playing: ld hl,speed_table ld a,(speed) ld e,a ld d,0 add hl,de ;add offset ld h,(hl) ;get bonus delay ld a,5 sub e ;get regular delay ld l,a ld (delay_amount),hl call _clrLCD ld hl,$fc10 push hl ld c,%01000000 call vert_line call horiz_line pop hl call horiz_line ld c,%00000010 call vert_line ld hl,$fc1c ld c,%00100000 call vert_line ld de,row_table ld h,$fc draw_rows: ld a,(de) ld l,a inc de ld (hl),%00111111 inc l ld (hl),%11111111 inc l ld (hl),%11111111 inc l ld (hl),%11111110 inc h jr nz,draw_rows call duplicate_buffer bit 3,(iy+5) call nz,invert_screen ld hl,side_txt call vputs_b call draw_bonus ld hl,(score) ld b,$24 call DispHLStatus ;display starting score call draw_lives ;display the level ld hl,current_level ld bc,$0202 ;start drawing at (2,2) level_loop: push hl ld h,(hl) ;get the current tile call put_brick ;draw the sprite pop hl ;restore map pointer inc hl ;go to next tile ld a,b add a,12 ld b,a cp 98 ;end of row jr nz,level_loop ;only jump if the row isn't complete ld b,2 ;draw at the left again ld a,c add a,6 ld c,a ;move location down a row cp 62 ;check if it's done jr nz,level_loop ;jump back to the top if not done ld a,(level_num) inc a ld b,$16 call DispAStatus ;display the level call draw_brick_mode ;display brick mode ld a,1 ;set bonus delay ld (bonus_delay),a call draw_bonus ;display bonus call draw_ball ;display the ball call split ;copy to screen new_life: call copy_screen ;show ball ld b,80 ;delay with ball showing start_delay_loop: halt djnz start_delay_loop ;************************************************main loop main_loop: call check_bricks ;check how many bricks left call anim_ball ;draw the ball call draw_bonus ;display the bonus call check_keys ;check for keys call delay ;speed control call copy_screen ;copy buffer to display jr main_loop ;************************************************update lives draw_lives: ld a,(lives) ld bc,$642d ball_draw_loop: push af call put_ball ld a,b add a,5 ld b,a pop af dec a jr nz,ball_draw_loop ret ;************************************************update bonus draw_bonus: ld hl,bonus_delay dec (hl) ret nz ld a,(bonus) or a ret z ld a,(bonus_delay_amount) ld (hl),a ;new counter bonus_skip_delay: ;skip delay ld bc,$086d ld hl,bonus dec (hl) ld a,(hl) cp 9 jr nz,skip_spaces ld d,7 call draw_spaces ;overwrite old bonus with spaces skip_spaces: jp DispAStatus ;display the bonus ;************************************************update score draw_score: ;increment score and display it ld hl,(score) inc hl ld (score),hl push hl ld b,$24 call DispHLStatus pop hl ld a,(lives) cp 5 ret z ;can't have more than 5 lives ld de,400 sub_loop: or a sbc hl,de ret c ;not divisible by 400 jr nz,sub_loop ;not done yet ;divisible by 400, so we get an extra life call draw_lives ld hl,lives inc (hl) jr draw_lives ;draw new lives ;************************************************check keys check_keys: ld a,%01111101 out (1),a in a,(1) cpl and 24 cp 24 jr z,invert ld a,$b7 ld (invert),a no_invert: ld a,%01111110 out (1),a in a,(1) rra \ rra ;left push af call nc,move_left pop af rra ;right call nc,move_right call _getcsc cp K_CLEAR jp z,lose_life cp K_DEL jr z,save cp K_EXIT jp z,check_hiscore cp K_MORE ret nz ;2nd pause: call getkey ld b,1 cp K_PLUS jr z,set_contrast ld b,-1 cp K_MINUS ret nz set_contrast: ld hl,_contrast ld a,(hl) add a,b cp 32 jr nc,pause ld (hl),a out (2),a jr pause save: ld a,1 ld (resumed),a ld sp,(save_sp) jp exit invert: or a jr c,no_invert ld a,$37 ld (invert),a ld hl,_Flags+textFlags ld a,(hl) xor %00001000 ;toggle inverted text ld (hl),a invert_screen: ld hl,buffer_light ld bc,8 invert_loop: ld a,(hl) cpl ld (hl),a inc hl djnz invert_loop dec c jr nz,invert_loop ret ;************************************************check high score check_hiscore: res 3,(iy+5) ;not inverted text ld hl,(highscore) ld de,(score) call _cphlde jp nc,title_screen ;no high score ld (new_highscore),de ;save new high score call _clrScrn ld hl,high_score call vputs_b ld hl,$0904 ld (_curRow),hl call duplicate_buffer call split im 1 ld a,(screen_dark/256)-$80 out (0),a ld hl,new_initials get_string: push hl ld a,(_curCol) cp 12 ld a,'_' call nz,_putmap call copy_screen get_hiscore: call getkey cp K_DEL jr z,backspace cp K_ENTER jr z,name_done cp K_SECOND jr z,name_done cp K_SIGN jr nz,checkletter ld a,' ' jr putletter checkletter: ld hl,letters ld bc,26 cpir ;search for letter jr nz,get_hiscore ld a,'A' add a,c putletter: ld c,a ld a,(_curCol) cp 12 ;3 letters for initials jr z,get_hiscore pop hl ld (hl),c inc hl ld a,c call _putc jr get_string backspace: ld hl,_curCol ld a,(hl) cp 9 jr z,get_hiscore ld a,' ' call _putmap dec (hl) pop hl dec hl jr get_string name_done: pop hl ld (hl),0 ;null terminator ;now we save it back to the level ld hl,level_name rst 20h rst 10h xor a ld hl,4 add hl,de adc a,b ld b,6 ;6 bytes ld de,new_highscore call save_data jp title_screen ;************************************************exit exit: ld hl,_asapvar rst 20h ;copy to OP1 rst 10h ;_findsym xor a ld hl,data_start-_asm_exec_ram+4 ;offset add hl,de ;hl=pointer to data in original prog adc a,b ;in case we overlapped pages ld de,data_start ;copy from here ld b,data_end-data_start call save_data im 1 ld a,$7c out (0),a ;restore video mem ld hl,_contrast ld a,(hl) dec (hl) ld a,(hl) out (2),a ld hl,$fbff-$f7ff add hl,sp ld sp,hl ld hl,$f7ff ld de,$fbff ld bc,256 lddr res 4,(iy+9) jp _clrWindow ;************************************************save data save_data: ;ahl->dest ;de->src ;b=num bytes push af push hl call _GETB_AHL ld a,(de) ld (hl),a pop hl pop af call _INC_PTR_AHL inc de djnz save_data ret ;************************************************move ball draw_ball: ld bc,(ball_y) jp put_ball anim_ball: xor a ld (collision),a ;default is no change ld a,(ball_y) cp 1 jr z,bounce cp 58 jr nz,no_bounce bounce: ld a,(direction) neg ld (direction),a no_bounce: call draw_ball ;erase old ball ld a,(direction) ;get ball direction add a,c ;add to y-coordinate ld (ball_y),a ;update coordinate call draw_ball ;redraw ball at new coordinates push bc dec b ;left side call check_col pop bc inc b ;right side call check_col ld a,(collision) or a ret z ;no collision ld a,(direction) neg ld (direction),a ;new direction ret move_horiz: xor a ld (collision),a ;no collision yet ld bc,(ball_y) ld a,b ret move_left: ld a,(reverse_mode) or a jr nz,move_right_nocheck move_left_nocheck: call move_horiz dec a cp 1 ret z ld b,a dec b ;left side call check_col ret nz ;a collision, so we don't move call draw_ball ;erase old ball ld hl,ball_x dec (hl) jp draw_ball ;draw new ball move_right: ld a,(reverse_mode) or a jr nz,move_left_nocheck move_right_nocheck: call move_horiz inc a cp 94 ret z ld b,a inc b ;right side call check_col ret nz ;a collision, so we don't move call draw_ball ;erase old ball ld hl,ball_x inc (hl) jp draw_ball ;draw new ball check_col: ;nz if collision push bc dec c ;top call check_collision pop bc inc c ;bottom row call check_collision ld a,(collision) or a ret check_collision: ;checks collision at (b,c) ;clears brick if necessary ;activates collision if a collision call GetTile ret c ;a clear tile ld (collision),a ;collision (a greater than 0 anyway) ld a,(brick_mode) cp (hl) jr z,clear_tile ;remove the tile if same mode ld a,(hl) sub 6 ret c ;a regular brick which we can't break jr nz,not_key inc a ld (hit_key),a ;1=key active jr clear_tile ;remove the key not_key: dec a jr nz,not_lock ld a,(hit_key) or a ret z jr clear_tile ;remove lock not_lock: dec a jp z,lose_life ;a killer brick dec a ret z ;solid brick (never breaks) cp 4 jr nz,not_reverse ld de,reverse_mode ld a,(de) xor 1 ;toggle reverse mode ld (de),a jr clear_tile not_reverse: push af ld a,(brick_mode) cp 5 jr nz,normal_brick pop af ret normal_brick: call draw_brick_mode ;remove old mode pop af inc a ld (brick_mode),a ;new brick mode jp draw_brick_mode ;draw new mode clear_tile: ;erase tile pointed to by hl ld a,(hl) push af ld (hl),0 ld de,current_level or a sbc hl,de ld a,8 call _divHLbyA ;separate x and y dimensions ;l=y, a=x ld b,a ld h,6 call MultHL ld c,l ;y-coordinate ld l,b ld h,12 call MultHL ld b,l ;x-coordinate inc b inc b inc c inc c pop hl call put_brick ;clear the tile from the screen jp draw_score ;increment score and quit ; bc = coords to get tile at (x, y) ; returns: hl = pointer to map tile ; tile = (((y-2) / 6) * 8) + ((x-2) / 12) GetTile: ld h,0 ld l,b ld a,12 push bc call _divHLbyA pop bc ld b,l ;store x value ld l,c ld a,6 ;divide by 6 push bc call _divHLbyA pop bc ld a,l ;a=y coordinate add a,a add a,a add a,a ;y*8 add a,b ;add to x ld hl,current_level ld e,a ld d,0 add hl,de ;get offset of tile ld a,(hl) cp 1 ;c flag if solid ret draw_brick_mode: ld bc,$6a36 ld a,(brick_mode) ld h,a jp put_brick ;draw the brick ;************************************************check bricks check_bricks: ld de,0 ;d=number of regular bricks, e=number of weird bricks ld hl,current_level ld b,80 ;size of level bricks_loop: ld a,(hl) inc hl dec a cp 7 jr nc,bricks_next_loop inc d cp 4 ;check if it's an ending brick jr nz,bricks_next_loop dec d inc e bricks_next_loop: djnz bricks_loop ld a,d or e jr z,done_level ld a,d or a ret nz ;still some regular bricks ld a,(brick_mode) cp 5 ret z call draw_brick_mode ld a,5 ld (brick_mode),a jp draw_brick_mode done_level: ld a,(bonus) or a jr z,done_bonus ld b,5 countdown_delay: halt djnz countdown_delay call bonus_skip_delay ;decrement bonus call draw_score ;increment score call copy_screen jr done_level done_bonus: ld hl,level_num ld a,(hl) ld b,a ld a,(num_levels) dec a cp b jp z,check_hiscore ;played all levels inc (hl) jp start_level ;************************************************delay delay: ld a,(delay_amount) or a ret z delay_loop: halt dec a jr nz,delay_loop ret ;************************************************dead lose_life: call draw_ball ;erase ball call draw_lives ;remove lives ld hl,lives dec (hl) jp z,check_hiscore ;dead call draw_lives ld hl,(start_coords) ld (ball_y),hl ld a,1 ld (direction),a call draw_ball call draw_brick_mode ld a,1 ld (brick_mode),a call draw_brick_mode jp new_life put_ball: ;bc=coords ld ix,ball jr put_sprite put_brick: ;h=brick number, bc=coords ld l,24 call MultHL ld ix,bricks ;load the start of the sprites ex de,hl add ix,de ;add together to get correct sprite put_sprite: ;16x6 xor-ed grayscale putsprite ;ix=sprite ;b,c=(x,y) push bc ld h,$fc00/1024 ld a,c add a,a add a,a ld l,a ld a,b rra add hl,hl rra add hl,hl rra or l ld l,a ld a,b and 7 ld (bit_shift),a ld b,2 place_sprite: push bc ld b,6 draw_sprite: ld c,(ix) inc ix ld d,(ix) inc ix ld e,0 ld a,0 bit_shift = $-1 or a jr z,no_shift shift_bytes: srl c rr d rr e dec a jr nz,shift_bytes no_shift: ld a,c xor (hl) ld (hl),a inc hl ld a,d xor (hl) ld (hl),a inc hl ld a,e xor (hl) ld (hl),a ld de,14 add hl,de djnz draw_sprite ld de,screen_light-screen_dark-96 add hl,de pop bc djnz place_sprite pop bc ret int_start: ;from bomber bloke exx ex af,af' in a,(3) bit 3,a jr z,no_down_left_bug and %11111110 out (3),a no_down_left_bug: bit 1,a jr z,no_swap ld hl,grayscale_counter inc (hl) ld a,(hl) cp 3 ld a,(screen_dark/256)-$80 jr c,set_video_port ld a,(screen_light/256)-$80 ld (hl),0 set_video_port: out (0),a no_swap: jp $3a int_end: ball: .db %01110000,0 .db %10111000,0 .db %11111000,0 .db %11111000,0 .db %01110000,0 .db %00000000,0 .db %01110000,0 .db %11011000,0 .db %10011000,0 .db %11111000,0 .db %01110000 bricks: ;start of bricks ;0 .db %00000000, %00000000 .db %00000000, %00000000 .db %00000000, %00000000 .db %00000000, %00000000 .db %00000000, %00000000 .db %00000000, %00000000 .db %00000000, %00000000 .db %00000000, %00000000 .db %00000000, %00000000 .db %00000000, %00000000 .db %00000000, %00000000 .db %00000000, %00000000 ;1 .db %01111111, %11100000 .db %10000000, %00010000 .db %10000000, %00010000 .db %10000000, %00010000 .db %10000000, %00010000 .db %01111111, %11100000 .db %01111111, %11100000 .db %11111111, %11110000 .db %11111111, %11110000 .db %11111111, %11110000 .db %11111111, %11110000 .db %01111111, %11100000 ;2 .db %01111111, %11100000 .db %10101010, %10110000 .db %11010101, %01010000 .db %10101010, %10110000 .db %11010101, %01010000 .db %01111111, %11100000 .db %01111111, %11100000 .db %10000000, %00010000 .db %10000000, %00010000 .db %11111111, %11110000 .db %11111111, %11110000 .db %01111111, %11100000 ;3 .db %01111111, %11100000 .db %10000000, %00010000 .db %10111111, %11010000 .db %10111111, %11010000 .db %10000000, %00010000 .db %01111111, %11100000 .db %01111111, %11100000 .db %11111111, %11110000 .db %11100110, %01110000 .db %11100110, %01110000 .db %11111111, %11110000 .db %01111111, %11100000 ;4 .db %01111111, %11100000 .db %10100100, %10010000 .db %10010010, %01010000 .db %11001001, %00110000 .db %10100100, %10010000 .db %01111111, %11100000 .db %01111111, %11100000 .db %11001001, %00110000 .db %10100100, %10010000 .db %10010010, %01010000 .db %11001001, %00110000 .db %01111111, %11100000 ;5 .db %01111111, %11100000 .db %11111111, %11110000 .db %11100000, %01110000 .db %11100000, %01110000 .db %11111111, %11110000 .db %01111111, %11100000 .db %01111111, %11100000 .db %11000000, %00110000 .db %10000000, %00010000 .db %10000000, %00010000 .db %11000000, %00110000 .db %01111111, %11100000 ;6 .db %01111111, %11100000 .db %11111110, %00110000 .db %10000000, %10110000 .db %11001110, %00110000 .db %11111111, %11110000 .db %01111111, %11100000 .db %01111111, %11100000 .db %11000001, %11110000 .db %11111111, %01010000 .db %10110001, %11010000 .db %11000000, %00110000 .db %01111111, %11100000 ;7 .db %01111111, %11100000 .db %11111001, %11110000 .db %11110110, %11110000 .db %11110000, %11110000 .db %11110000, %11110000 .db %01111111, %11100000 .db %01111111, %11100000 .db %11000110, %00110000 .db %10001001, %00010000 .db %10001111, %00010000 .db %11001111, %00110000 .db %01111111, %11100000 ;8 .db %01111111, %11100000 .db %11100111, %11110000 .db %10000000, %00010000 .db %10000000, %00010000 .db %11100111, %11110000 .db %01111111, %11100000 .db %01111111, %11100000 .db %11011000, %00110000 .db %11111111, %11110000 .db %11111111, %11110000 .db %11011000, %00110000 .db %01111111, %11100000 ;9 .db %01111111, %11100000 .db %11011110, %11110000 .db %11111011, %11110000 .db %11101111, %10110000 .db %11111101, %11110000 .db %01111111, %11100000 .db %01111111, %11100000 .db %11100001, %00110000 .db %10000100, %00010000 .db %10010000, %01010000 .db %11000010, %00110000 .db %01111111, %11100000 ;10 .db %01111111, %11100000 .db %10101011, %11110000 .db %11010101, %11110000 .db %10101011, %11110000 .db %11010101, %11110000 .db %01111111, %11100000 .db %01111111, %11100000 .db %10000001, %11110000 .db %10000001, %11110000 .db %11111111, %11110000 .db %11111111, %11110000 .db %01111111, %11100000 ;11 .db %01111111, %11100000 .db %10000001, %11110000 .db %10111111, %11110000 .db %10111111, %11110000 .db %10000001, %11110000 .db %01111111, %11100000 .db %01111111, %11100000 .db %11111111, %11110000 .db %11100111, %11110000 .db %11100111, %11110000 .db %11111111, %11110000 .db %01111111, %11100000 ;12 .db %01111111, %11100000 .db %10100101, %11110000 .db %10010011, %11110000 .db %11001001, %11110000 .db %10100101, %11110000 .db %01111111, %11100000 .db %01111111, %11100000 .db %11001001, %11110000 .db %10100101, %11110000 .db %10010011, %11110000 .db %11001001, %11110000 .db %01111111, %11100000 ;13 .db %01111111, %11100000 .db %11111111, %10110000 .db %11011100, %00010000 .db %10000011, %10110000 .db %11011111, %11110000 .db %01111111, %11100000 .db %01111111, %11100000 .db %11111111, %11110000 .db %11111111, %11110000 .db %11111111, %11110000 .db %11111111, %11110000 .db %01111111, %11100000 description: .db "Diamonds 2.0 " name: .db "by Jonah Cohen",0 menu_txt: .db 5 .db $2c,$1a,"F1 - Start",0 .db $2c,$22,30,31," Level:",0 ;30=up, 31=down .db $2c,$2a,"F2 - Speed:",0 .db $2c,$32,"F3 -",0 .db $2c,$3a,"High score:",0 error_txt: .db $22,$25,"No levels detected",0 side_txt: .db 3 .db $67,$02,"Bonus",0 .db $67,$10,"Level",0 .db $67,$1e,"Score",0 high_score: .db 2 .db $1d,$0d,"You have a high score!",0 .db $2b,$16,"Enter initials:",0 speed_table = $-1 .db 34 .db 40 .db 50 .db 66 .db 90 row_table: .db $fc,$dc,$bc,$3c letters: ;used in string input .db $19,$21,$0a,$12,$1a,$22,$0b,$13,$1b,$23,$2b,$0c,$14 .db $1c,$24,$2c,$0d,$15,$1d,$25,$2d,$0e,$16,$1e,$26,$2e starting_name: .db $0c,1,0 data_start: level_name: .db $0c,7,"dlevels",0,0 ;store the current level name speed: .db 3 ;1-5 resumed: .db 0 ;1=resumed level_num: .db 0 ;which level we're on score: .db 0,0 ;player's score ball_y: .db 0 ;y-coordinate ball_x: .db 0 ;x-coordinate bonus: .db 0 ;the bonus score direction: .db 0 ;1=down, -1=up reverse_mode: .db 0 ;1=reversed directions brick_mode: .db 0 ;code of current brick type lives: .db 0 ;number of balls left hit_key: .db 0 ;whether they hit the key yet start_coords: .db 0,0 ;initial coordinates for level (2 bytes) current_level: .db 0,0,0,0,0,0,0,0 ;decompressed level .db 0,0,0,0,0,0,0,0 .db 0,0,0,0,0,0,0,0 .db 0,0,0,0,0,0,0,0 .db 0,0,0,0,0,0,0,0 .db 0,0,0,0,0,0,0,0 .db 0,0,0,0,0,0,0,0 .db 0,0,0,0,0,0,0,0 .db 0,0,0,0,0,0,0,0 .db 0,0,0,0,0,0,0,0 data_end: titlepic: #if 0 .db $91,$00,$04,$f0,$c0,$91,$00,$05,$c0,$91,$00,$08 .db $f8,$c0,$91,$00,$05,$c0,$91,$00,$08,$dc,$91,$00 .db $06,$c0,$91,$00,$08,$ce,$c3,$de,$f0,$1e,$1e,$03 .db $c3,$c0,$91,$00,$07,$c6,$c7,$df,$f8,$3f,$1f,$07 .db $c7,$c0,$91,$00,$07,$c6,$ce,$db,$dc,$73,$9b,$8e .db $ce,$91,$00,$08,$c6,$dc,$d9,$ce,$e1,$d9,$dc,$dc .db $91,$00,$08,$c6,$d8,$d8,$c6,$c0,$91,$d8,$03,$91 .db $00,$08,$c6,$d8,$d8,$c6,$c0,$d8,$d8,$df,$c0,$91 .db $00,$07,$c6,$d8,$d8,$c6,$c0,$d8,$d8,$df,$c0,$91 .db $00,$07,$c6,$d8,$d8,$c6,$c0,$d8,$d8,$c0,$c0,$91 .db $00,$07,$ce,$dc,$d8,$c6,$e1,$d8,$dc,$c1,$c0,$91 .db $00,$07,$dc,$ce,$d8,$c6,$73,$98,$ce,$c3,$80,$91 .db $00,$07,$f8,$c7,$d8,$c6,$3f,$18,$c7,$df,$91,$00 .db $08,$f0,$c3,$d8,$c6,$1e,$18,$c3,$de,$91,$00,$14 .db $91,$00,$00 #endif #if 1 Layer1: .db $91,$00,$12,$20,$91,$00,$1F,$90,$1F,$87,$C1,$C3,$9C,$78,$E7,$7E .db $1F,$00,$07,$91,$00,$05,$0F,$C3,$83,$E3,$FC,$FC,$E7,$3F,$3B,$80 .db $0F,$80,$00,$00,$07,$20,$0E,$E3,$87,$73,$FD,$CE,$F7,$3B,$BB,$80 .db $0F,$80,$00,$00,$0F,$80,$0E,$E3,$87,$73,$FD,$CE,$FF,$3B,$B8,$00 .db $0F,$80,$00,$00,$0F,$80,$0E,$E3,$87,$73,$FD,$CE,$FF,$3B,$9E,$00 .db $07,$91,$00,$03,$0F,$80,$0E,$E3,$87,$F3,$9D,$CE,$FF,$3B,$87,$00 .db $20,$91,$00,$03,$07,$00,$0E,$E3,$87,$73,$9D,$CE,$EF,$3B,$BB,$80 .db $04,$91,$00,$05,$0F,$C3,$87,$73,$9C,$FC,$E7,$3F,$3B,$80,$80,$91 .db $00,$05,$1F,$87,$C7,$73,$9C,$78,$E7,$7E,$1F,$00,$10,$91,$00,$42 Layer2: .db $00,$3F,$91,$FF,$0C,$FC,$00,$00,$20,$20,$91,$00,$0B,$04,$00,$00 .db $20,$91,$00,$0C,$04,$00,$00,$20,$90,$1F,$87,$C1,$C3,$9C,$78,$E7 .db $7E,$1F,$00,$07,$04,$00,$00,$20,$00,$3F,$CF,$83,$E7,$FC,$FD,$EF .db $7F,$3B,$80,$0F,$84,$00,$00,$27,$20,$1E,$E7,$87,$77,$FD,$CF,$FF .db $7B,$FB,$80,$0F,$84,$00,$00,$2F,$80,$1E,$E7,$8F,$77,$FD,$DE,$FF .db $7B,$BA,$00,$0F,$84,$00,$00,$2F,$80,$1E,$E7,$8F,$77,$FD,$DE,$FF .db $7B,$BF,$80,$07,$04,$00,$00,$2F,$80,$1E,$E7,$8F,$F7,$9D,$DE,$FF .db $7B,$B7,$00,$20,$04,$00,$00,$27,$00,$1E,$E7,$8F,$77,$BD,$DE,$EF .db $7B,$BF,$80,$04,$04,$00,$00,$20,$00,$1F,$C7,$8F,$77,$BD,$FC,$EF .db $7F,$3B,$80,$80,$04,$00,$00,$20,$00,$1F,$87,$CF,$77,$BD,$F9,$EF .db $7E,$7F,$00,$10,$04,$00,$00,$20,$00,$30,$0C,$0C,$46,$30,$C1,$8C .db $40,$30,$00,$00,$04,$00,$00,$20,$00,$1F,$87,$C7,$73,$9C,$78,$E7 .db $7E,$1F,$00,$00,$04,$00,$00,$20,$91,$00,$0C,$04,$00,$00,$3F,$91 .db $FF,$0C,$FC,$00 #endif #if 0 Layer1: .db $91,$00,$42,$01,$91,$FF,$09,$FC,$91,$00,$05,$03,$91,$FF,$09,$FE .db $91,$00,$05,$03,$91,$FF,$0A,$91,$00,$05,$07,$91,$FF,$0A,$91,$00 .db $05,$07,$80,$91,$00,$08,$07,$80,$91,$00,$04,$0F,$91,$00,$09,$03 .db $80,$91,$00,$04,$0F,$0C,$0F,$C0,$41,$8C,$1F,$18,$33,$00,$73,$C0 .db $91,$00,$04,$1E,$0F,$0F,$C0,$C3,$9C,$7F,$98,$33,$C1,$F9,$C0,$91 .db $00,$04,$1E,$1B,$86,$01,$C3,$9C,$E1,$B8,$66,$E1,$81,$E0,$91,$00 .db $04,$1C,$19,$86,$03,$C7,$B9,$C1,$BC,$66,$63,$01,$E0,$91,$00,$04 .db $1C,$19,$86,$06,$87,$39,$81,$B4,$66,$63,$F0,$E0,$91,$00,$04,$1E .db $31,$8C,$0F,$8D,$7B,$03,$66,$CC,$63,$F0,$E0,$91,$00,$04,$1E,$31 .db $8C,$1F,$8F,$DB,$07,$66,$CC,$60,$31,$E0,$91,$00,$04,$0E,$33,$0C .db $31,$9B,$DB,$8E,$63,$CC,$CC,$71,$E0,$91,$00,$04,$0F,$7F,$3E,$31 .db $9B,$9B,$FC,$C1,$9F,$CF,$E1,$E0,$91,$00,$04,$07,$3C,$7E,$60,$B3 .db $10,$F0,$C1,$8F,$0F,$83,$C0,$91,$00,$04,$07,$80,$91,$00,$08,$03 .db $C0,$91,$00,$04,$03,$91,$FF,$0A,$80,$91,$00,$04,$03,$91,$FF,$0A .db $80,$91,$00,$04,$01,$91,$FF,$0A,$91,$00,$06,$91,$FF,$09,$FE,$91 .db $00,$73 Layer2: .db $91,$00,$42,$01,$91,$FF,$09,$FC,$91,$00,$05,$03,$91,$FF,$09,$FE .db $91,$00,$05,$03,$91,$00,$09,$03,$91,$00,$05,$06,$91,$00,$09,$03 .db $91,$00,$05,$06,$91,$00,$09,$01,$80,$91,$00,$04,$0C,$91,$00,$09 .db $01,$80,$91,$00,$04,$08,$0C,$0F,$C0,$41,$8C,$1F,$18,$33,$00,$70 .db $C0,$91,$00,$04,$18,$0F,$0F,$C0,$C3,$9C,$7F,$98,$33,$C1,$F8,$C0 .db $91,$00,$04,$10,$1B,$86,$01,$C3,$9C,$E1,$B8,$66,$E1,$80,$60,$91 .db $00,$04,$10,$19,$86,$03,$C7,$B9,$C1,$BC,$66,$63,$00,$20,$91,$00 .db $04,$10,$19,$86,$06,$87,$39,$81,$B4,$66,$63,$F0,$20,$91,$00,$04 .db $10,$31,$8C,$0F,$8D,$7B,$03,$66,$CC,$63,$F0,$20,$91,$00,$04,$18 .db $31,$8C,$1F,$8F,$DB,$07,$66,$CC,$60,$30,$20,$91,$00,$04,$08,$33 .db $0C,$31,$9B,$DB,$8E,$63,$CC,$CC,$70,$60,$91,$00,$04,$0C,$7F,$3E .db $31,$9B,$9B,$FC,$C1,$9F,$CF,$E0,$60,$91,$00,$04,$04,$3C,$7E,$60 .db $B3,$10,$F0,$C1,$8F,$0F,$80,$C0,$91,$00,$04,$06,$91,$00,$0A,$C0 .db $91,$00,$04,$03,$91,$00,$09,$01,$80,$91,$00,$04,$03,$91,$00,$09 .db $01,$80,$91,$00,$04,$01,$91,$FF,$0A,$91,$00,$06,$91,$FF,$09,$FE .db $91,$00,$73 #endif #if 0 Layer1: .db $91,$00,$42,$01,$91,$FF,$09,$FC,$91,$00,$05,$03,$91,$FF,$09,$FE .db $91,$00,$05,$03,$91,$00,$09,$03,$91,$00,$05,$06,$91,$00,$09,$03 .db $91,$00,$05,$06,$7F,$91,$FF,$08,$F9,$80,$91,$00,$04,$0C,$91,$FF .db $09,$FD,$80,$91,$00,$04,$08,$91,$FF,$09,$FC,$C0,$91,$00,$04,$19 .db $91,$FF,$09,$FE,$C0,$91,$00,$04,$11,$91,$FF,$09,$FE,$60,$91,$00 .db $04,$13,$91,$FF,$09,$FE,$20,$91,$00,$04,$13,$91,$FF,$0A,$20,$91 .db $00,$04,$11,$91,$FF,$0A,$20,$91,$00,$04,$19,$91,$FF,$09,$FE,$20 .db $91,$00,$04,$09,$91,$FF,$09,$FE,$60,$91,$00,$04,$0C,$91,$FF,$09 .db $FE,$60,$91,$00,$04,$04,$91,$FF,$09,$FC,$C0,$91,$00,$04,$06,$7F .db $91,$FF,$08,$FC,$C0,$91,$00,$04,$03,$91,$00,$09,$01,$80,$91,$00 .db $04,$03,$91,$00,$09,$01,$80,$91,$00,$04,$01,$91,$FF,$0A,$91,$00 .db $06,$91,$FF,$09,$FE,$91,$00,$73 Layer2: .db $91,$00,$42,$01,$91,$FF,$09,$FC,$91,$00,$05,$03,$91,$FF,$09,$FE .db $91,$00,$05,$03,$91,$FF,$0A,$91,$00,$05,$07,$91,$FF,$0A,$91,$00 .db $05,$07,$80,$91,$00,$08,$07,$80,$91,$00,$04,$0F,$91,$00,$09,$03 .db $80,$91,$00,$04,$0F,$0C,$0F,$C0,$41,$8C,$1F,$18,$33,$00,$73,$C0 .db $91,$00,$04,$1E,$0F,$0F,$C0,$C3,$9C,$7F,$98,$33,$C1,$F9,$C0,$91 .db $00,$04,$1E,$1B,$86,$01,$C3,$9C,$E1,$B8,$66,$E1,$81,$E0,$91,$00 .db $04,$1C,$19,$86,$03,$C7,$B9,$C1,$BC,$66,$63,$01,$E0,$91,$00,$04 .db $1C,$19,$86,$06,$87,$39,$81,$B4,$66,$63,$F0,$E0,$91,$00,$04,$1E .db $31,$8C,$0F,$8D,$7B,$03,$66,$CC,$63,$F0,$E0,$91,$00,$04,$1E,$31 .db $8C,$1F,$8F,$DB,$07,$66,$CC,$60,$31,$E0,$91,$00,$04,$0E,$33,$0C .db $31,$9B,$DB,$8E,$63,$CC,$CC,$71,$E0,$91,$00,$04,$0F,$7F,$3E,$31 .db $9B,$9B,$FC,$C1,$9F,$CF,$E1,$E0,$91,$00,$04,$07,$3C,$7E,$60,$B3 .db $10,$F0,$C1,$8F,$0F,$83,$C0,$91,$00,$04,$07,$80,$91,$00,$08,$03 .db $C0,$91,$00,$04,$03,$91,$FF,$0A,$80,$91,$00,$04,$03,$91,$FF,$0A .db $80,$91,$00,$04,$01,$91,$FF,$0A,$91,$00,$06,$91,$FF,$09,$FE,$91 .db $00,$73 #endif icon: .db 15,2 .db $0F .db $F8,$0C .db $18,$0F .db $F8,$07 .db $F0,$00 .db $00,$00 .db $00,$00 .db $70,$00 .db $F8,$00 .db $F8,$00 .db $F8,$04 .db $70,$00 .db $00,$10 .db $80,$02 .db $00,$FF .db $F8 shift_left equ $ shift_right equ shift_left+48 temp_search_name equ shift_right+48 ;name of var in search (11 bytes) new_highscore equ temp_search_name+11 ;new high score (2 bytes) new_initials equ new_highscore+2 ;initials (4 bytes) screen_light equ ((new_initials+3) | $ff)+1 ;next aligned address screen_dark equ screen_light+1024 int_table equ screen_dark+1024 ;table for im 2 interrupt buffer_light equ $f800 buffer_dark equ buffer_light+1024 delay_amount equ $8100 ;regular delay speed bonus_delay_amount equ delay_amount+1 ;bonus delay speed bonus_delay equ bonus_delay_amount+1 ;countdown for bonus collision equ bonus_delay+1 ;1=collision highscore equ collision+1 ;the high score (2 bytes) initials equ highscore+2 ;initials for high score (4 bytes) num_levels equ initials+4 ;number of levels levels equ num_levels+1 ;the entire level string (unlimited size) .end