**************************************************************************** **************************************************************************** ** ** Monster - variable handling ** ** Copyright 2009 by Patrick Davidson. This software may be freely ** modified and/or copied with no restrictions. There is no warranty. ** ** by Patrick Davidson (pad@calc.org, http://pad.calc.org/) ** ** Last updated April 18, 2009 ** **************************************************************************** **************************************************************************** ******************************************** get variable pointer in A0 _get_data_file: pea variable_name(pc) JSR_ROM SymFind ; get SYM_ENTRY in D0 move.l d0,-(sp) JSR_ROM DerefSym ; get VAT entry pointer in A0 addq.w #8,sp move.l a0,d0 beq.s \failed move.w 12(a0),-(sp) ; push handle of variable data JSR_ROM HeapDeref ; dereference heap entry (A0->data) addq.w #2,sp \failed: rts ******************************************** find level saved from Load_Last_Level: lea level_name+1(a5),a0 \l: tst.b (a0)+ bne.s \l pea -1(a0) JSR_ROM SymFind ; get SYM_ENTRY in D0 move.l d0,-(sp) JSR_ROM DerefSym ; get VAT entry pointer in A0 addq.w #8,sp bsr.s verify_level beq.s \quit move.l a4,a0 cmp.w num_levels(a4),d0 beq Load_A0_Level \quit: rts ******************************************** validate file in A0 * * Takes A0 as a pointer to the SYM_ENTRY. * Returns zero flag set for invalid, clear for valid. * Returns number of levels in file in D0 on success. * Returns the SYM_ENTRY in A4. * Modifies D0-D1/A0-A4. * ******** verify_level: move.l a0,d0 ; null pointer = invalid beq.s variable_not_level move.l a0,-(sp) move.w 12(a0),-(sp) ; handle JSR_ROM HToESI ; get pointer to tag end addq.w #2,sp move.l (sp)+,a4 ; A4 = current SYM_ENTRY lea level_tag(pc),a1 ; variable type at end of level file moveq #5,d0 lea -5(a0),a2 ; A2 -> tag \check_tag: cmp.b (a2)+,(a1)+ bne.s variable_not_level dbra d0,\check_tag move.w 12(a4),-(sp) ; push handle of variable data JSR_ROM HeapDeref ; dereference heap entry (A0->data) addq.w #2,sp addq.w #2,a0 move.w (a0)+,d0 ; get number of levels beq.s variable_not_level ; 0 levels - not valid cmp.w #$6a4f,(a0) ; identifier must be present bne.s variable_not_level tst.w 12(a0) ; required version must be 0 bne.s variable_not_level mulu #216,d0 ; expected size of all levels lea 34(a0,d0.l),a3 ; expected end of file cmp.l a3,a2 beq.s valid_level ; only accept if size matches variable_not_level: moveq #0,d0 rts valid_level: move.w -(a0),d0 rts ******************************************** create level list Select_Level: moveq #0,d7 ; D7 = # of levels found so far lea map(a5),a6 ; A0 -> variable data structures move.w #14,-(sp) ; searching all variables/folders clr.l -(sp) JSR_ROM SymFindFirst ; get first item in a0 lea 6(sp),sp var_search_loop: move.l a0,d0 beq var_search_done ; exit if item is NULL (nothing left) btst #7,11(a0) ; test whether it is a folder beq.s found_variable found_folder: move.l (a0)+,temp_buffer(a5) ; if folder, set current folder name move.l (a0)+,temp_buffer+4(a5) bra.s skip_variable found_variable: bsr verify_level beq.s skip_variable move.l a4,(a6)+ move.l temp_buffer(a5),(a6)+ move.l temp_buffer+4(a5),(a6)+ addq.w #1,d7 skip_variable: JSR_ROM SymFindNext ; get next item in A0 cmp.w #12,d7 ; continue only if < 12 found so far bne var_search_loop var_search_done: subq.w #1,d7 bge.s levels_found move.w #EXIT_NOLEVEL,exit_status(a5) moveq #0,d0 rts ******************************************** display level list levels_found: move.w d7,d6 ; D6 = # left to display beq level_selected moveq #1,d0 bsr Set_Font lea (a5),a0 ; clear screen move.w #PLANE_SIZE/4-1,d0 \c: clr.l (a0)+ dbra d0,\c clr.w temp_buffer+8(a5) moveq #0,d5 ; D5 = Y coordinate lea map(a5),a4 ; A4 = position in list level_list_loop: move.l (a4)+,a3 ; A3 = SYM_ENTRY move.w 12(a3),-(sp) JSR_ROM HeapDeref ; dereference handle (A0->data) addq.w #2,sp move.w 2(a0),-(sp) ; push level number pea (a3) ; push pointer to var name move.l (a4)+,temp_buffer(a5) move.l (a4)+,temp_buffer+4(a5) pea temp_buffer(a5) ; push pointer to folder name pea level_list_format(pc) pea _string_buffer(a5) JSR_ROM sprintf lea 18(sp),sp lea _string_buffer(a5),a0 moveq #0,d1 move.w d5,d0 addq.w #8,d5 bsr Display_String dbra d6,level_list_loop ******************************************** select level from list moveq #0,d6 ; D6 = level selected level_select_loop: bsr Wait_VBL bsr Invert_Piece bsr Display_Half bsr Invert_Piece bsr Read_All_Keys GETEDGE 0,0,0,5 bne.s \noup tst.w d6 beq.s \noup subq.w #1,d6 \noup: GETEDGE 0,2,0,7 bne.s \nodown cmp.w d6,d7 beq.s \nodown addq.w #1,d6 \nodown: IFND ti89 GETEDGE THIS_IS_FOR,TI92_ONLY,6,6 beq.s level_selected ENDIF GETEDGE 1,0,9,1 ; ENTER beq.s level_selected GETEDGE 0,4,0,3 ; 2nd beq.s level_selected GETEDGE 6,0,8,6 ; ESC beq.s level_load_failed GETKEY 3,0,9,6 ; Test status of . key bne.s level_select_loop level_load_failed: moveq #0,d0 rts level_selected: mulu #12,d6 lea map(a5),a0 lea 0(a0,d6.w),a1 ; A1 = entry in level list move.l (a1)+,a4 ; psuh SYM_ENTRY of selected level move.l (a1)+,temp_buffer(a5) ; copy folder name move.l (a1),temp_buffer+4(a5) pea (a4) ; push pointer to var name pea temp_buffer(a5) ; push pointer to folder name pea level_name_format(pc) pea level_name+1(a5) JSR_ROM sprintf lea 16(sp),sp clr.b level_name(a5) move.l a4,a0 Load_A0_Level: move.w 12(a0),-(sp) ; push handle of variable data JSR_ROM HeapDeref ; dereference heap entry (A0->data) addq.w #2,sp move.w 2(a0),num_levels(a5) lea 32(a0),a0 move.l a0,level_pointer(a5) rts Invert_Piece: lea (a5),a0 move.w d6,d0 mulu #8*WIDTH_BYTES,d0 moveq #WIDTH_BYTES*2-1,d1 add.w d0,a0 \l: not.l (a0)+ dbra d1,\l rts ******************************************** Create save file * * Deletes file if it already exists. * Takes size in D6. * Returns pointer to variable start in A0. * ******** _create_save_file: clr.l -(sp) pea variable_name(pc) JSR_ROM EM_moveSymFromExtMem ; unarchive variable pea variable_name(pc) JSR_ROM SymDel ; delete variable ext.l d6 move.l d6,-(sp) JSR_ROM HeapAlloc ; allocate memory (D0.w = handle) add.w #16,sp move.w d0,d3 ; D3 = handle beq.s \failed pea variable_name(pc) JSR_ROM SymAdd ; create variable (D0 = SYM_ENTRY) move.l d0,-(sp) JSR_ROM DerefSym ; get VAT entry in A0 move.l a0,d4 beq.s \var_create_failed move.w d3,12(a0) ; save data handle in VAT entry move.w d3,-(sp) JSR_ROM HeapDeref ; get data pointer in A0 add.w #10,sp rts \failed: suba.l a0,a0 rts \var_create_failed: move.w d3,-(sp) ; free heap entry JSR_ROM HeapFree add.w #10,sp suba.l a0,a0 rts ******************************************** data dc.b 0 dc.b 'mnstdata' variable_name: dc.b 0 level_tag: dc.b 0,'mlv',0,$f8 level_list_format: dc.b '%s\%s (%d)',0 level_name_format: dc.b '%s\%s',0 EVEN