;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. ;-------------------------