home *** CD-ROM | disk | FTP | other *** search
- ;DoBarMenu version 1.0 table-driven menu routine
- ;by Cassady Roop
- ;INPUT: hl- points to datatable
- ;OUTPUT: Displays and runs a TI-BASIC-like menu, ignoring all input but the F keys.
- ;Note: save any important reg's before using this.
- ;Note2: JP to this routine, don't call.
- ;Note3: This routine JPs to addresses, it doesn't call.
- ;It's big, but it works. Example datatable at end of document.
- ;-----------------------------------------------------------------------------------------
- DoBarMenu:
- push hl ;save datatable pointer
- ld hl, $FF80 ;start byte of row 56 in video mem. HLine makes horizontal line at top of menu.
- ld b, $FF ;%11111111
- ld a, $00 ;initialize counter
- DBM_HLineLoop:
- ld (hl), b ;darken 8 pixels
- inc hl ;next byte
- inc a ;increment counter
- cp 32 ;two complete rows done yet?
- jr nz, DBM_HLineLoop ;recycle
- ld hl, $FFA0 ;vidmem, first byte of row 58. VLine makes vertical posts between menu slots.
- ld b, $00 ;initialize line counter
- ld de, $0003
- DBM_VLineLoop:
- ld a, (DBM_byte1) ;%11000000
- ld (hl), a ;move to vidmem
- add hl, de ;HL+3=HL
- ld (hl), a ;uses same byte as last one
- add hl, de
- ld a, (DBM_byte7) ;%01100000
- ld (hl), a
- add hl, de
- ld a, (DBM_byte10) ;%00011000
- ld (hl), a
- add hl, de
- ld a, (DBM_byte13) ;%00001100
- ld (hl), a
- add hl, de
- ld a, (DBM_byte16) ;%00000110
- ld (hl), a
- inc hl ;next line
- inc b ;increment line counter
- ld a, b
- cp 6 ;6 lines done?
- jr nz, DBM_VLineLoop ;if not, recycle
- ld hl, $FF8F
- res 0, (hl) ;remove unsightly piece of overshot
- ld hl, $FF9F
- res 0, (hl)
- pop hl ;retrieve
- push hl ;save it again
- ld a, (hl)
- ld b, a
- inc b
- DBM_FillLoop: ;fill the menu slots with their texts
- dec b
- ld a, b
- cp $00
- jp z, DBM_Key ;if skipped a null and got a zero count
- inc hl
- ld e, (hl)
- inc hl
- ld d, (hl) ;addresses are stored backwards
- ld a, d
- cp $00
- jr z, DBM_FillLoop ;null entry, so skip it
- inc de
- inc de
- push hl
- ld a, b
- cp 5
- call z, DBM_5 ;five left, so first entry
- cp 4
- call z, DBM_4 ;four left, so second entry
- cp 3
- call z, DBM_3
- cp 2
- call z, DBM_2
- cp 1
- jp z, DBM_1
- ld (_pencol), hl
- ld h, d
- ld l, e ;ld hl, de. hl now points to string
- call _vputs
- pop hl
- jr DBM_FillLoop
- DBM_5 ;first entry
- ld hl, $3A03
- ret
- DBM_4 ;second entry
- ld hl, $3A1B
- ret
- DBM_3:
- ld hl, $3A34
- ret
- DBM_2
- ld hl, $3A4E
- ret
- DBM_1
- ld hl, $3A67
- ld (_pencol), hl
- ld h, d
- ld l, e ;ld hl, de
- call _vputs
- pop hl
- jp DBM_Key
- DBM_Key: ;interpret keypresses
- call _getkey
- cp $C7
- jp p, DBM_Key ;if a-$C7=positive, then too big to be an Fkey
- cp $C2
- jp m, DBM_Key ;if a-$C2=positive, then too small to be an Fkey
- pop hl ;hl now points to DataTable
- push hl ;store it again for later use
- sub $C1 ;returns 1-5 for the function keys, in register a
- rlca ;a=a*2
- dec a ;a=a*2-1
- DBM_keyloop: ;advance hl to the correct entry pointer for that key
- inc hl
- dec a
- cp $00 ;if zero, we've found our entry pointer for that key
- jr nz, DBM_keyloop
- ld e, (hl)
- inc hl
- ld d, (hl) ;entry address now in de
- ld a, d
- cp $00 ;if null (blank), it'll be zero
- jr z, DBM_key
- pop bc ;cleanup the stack
- ld a, (de)
- ld l, a
- inc de
- ld a, (de)
- ld h, a ;jump address should now be in hl
- push hl ;save it
- ld a, $80 ;number of bytes from top left of menu to bottom right
- ld hl, $FF7F
- DBM_delmenu: ;erase menu before making the jump
- inc hl
- ld (hl), $00 ;8 blank pixels
- dec a
- cp $00
- jr nz, DBM_delmenu ;reloop
- pop hl ;restore jump address
- jp (hl) ;make the jump
- DBM_byte1: ;bytes used in making the vertical lines
- .db %11000000
- DBM_byte7:
- .db %01100000
- DBM_byte10:
- .db %00011000
- DBM_byte13:
- .db %00001100
- DBM_byte16:
- .db %00000110
- ;-----------------------------------------------------
-
-
-
-
-
-
- ;-------------------
- ;Example datatable- point to with HL
-
- datatable:
- .db $05 ;length (number of entries). currently only supports $05!
- .dw entry1,entry2,entry3,entry4,entry5 ;pointers to entries. Blanks can be made by replacing 'entry4', for
- ;example, with $0000. That leaves a blank spot for menu spot 4.
- entry1:
- .dw jump_here_1 ;address to jump to if F1 is selected by the user
- .db "1",0 ;text to display in menu slot 1
- entry2:
- .dw jump_here_2
- .db "2",0
- entry3:
- .dw jump_here_3
- .db "3",0
-
- .... ;blank menu slots need not have an entry address, as long as
- ;$0000 is in their slot in the pointer list above.
- ;-------------------------
-