;User Interface Guideline Sample Application (U1) ;For questions/comments/etc. contact Dan Englender (dan@calc.org). ;This applications illustrates how to implement many of the user ;interfaces described in the User Interface Guidelines. Contained are ;seven routines which simulate user interface compontents. They can ;be used as-is in an application, or modified for specific needs of an ;application. The routines are: ;NumberedMenu - A list menu with multiple headings. Like the menu ; displayed by pressing the MATH button. ;SelectionList - A listing good for a large number of items. Like the ; list displayed by pressing the CATALOG button. ;SoftKey - Displays five line bordered softkeys with text ;SoftKeyG - Displays five graphical softkeys with text ;DialogBox - Displays a dialog box windowed over the previous ; background. This routine can be used for both the "DIALOG BOX" and ; "MESSAGE BOX" interface elements. ;StringInput - Allows the user to input text. ;ListView - A listing of scrolling string data. ;Routine I/O: ;NumberedMenu ; Input ; HL points to menu data ; Output ; A = column ; D = currently selected item ;Menu data format: ;TestMenu: ; db Number_Of_Columns ; dw TestMenu_Column1 ; dw TestMenu_Column2 ; (etc.) ; db "Column1 Title",0 ; db "Column2 Title",0 ; (etc.) ;TestMenu_Column1: ; db Number_Of_Menu_Items ; db "Menu Item1",0 ; db "Menu Item2",0 ; (etc.) ;SelectionList ; Input ; HL points to list data ; Output ; B is the list item choosen ;List format: ;TestList: ; db Number_Of_Entries ; db "Item1",0 ; db "Item2",0 ; db "Item3",0 ; (etc.) ;SoftKey ; Input ; HL points to key text (just five zero terminated strings in a row) ; Output ; soft keys are displayed to screen ;DialogBox ; Input ; (H,L) = (y,x) upper left ; (D,E) = (y,x) lower right ;H and l must be >= 1 ;D must be <= 62 ;E must be <= 93 ;Text inside the box must be displayed manually ;StringInput ; Input ; HL points to where to save input ; B = max characters ; curRow,curCol = cursor location ; Output ; HL is preserved ; BC = number of characters inputted ;ListView ; Input ; HL points to list data ; Output ; B is the list item choosen ;List Format: ;TestList: ; db Number_Of_Entries ; db "Item1",0 ; db "Item2",0 ; db "Item3",0 ; (etc.) ;Specific information for using and modifying these routines are ;included as comments in the routines themselves. nolist include "ti83plus.inc" list ;Header db 080h,0Fh ;Field: Program length db 00h,00h,00h,00h db 080h,012h ;Field: Program type db 01h,04h db 080h,021h ;Field: App ID db 01h db 080h,031h ;Field: App Build db 01h db 080h,048h ;Field: App Name db "UITest " db 080h,081h ;Field: App Pages db 01h db 080h,090h ;No default splash screen db 03h,026h ,09h,04h, 04h,06fh,01bh,80h ;Field: Date stamp- 5/12/1999 db 02h,0dh,040h db 0a1h ,06bh ,099h ,0f6h ,059h ,0bch ,067h db 0f5h ,085h ,09ch ,09h ,06ch ,0fh ,0b4h ,03h ,09bh ,0c9h db 03h ,032h ,02ch ,0e0h ,03h ,020h ,0e3h ,02ch ,0f4h ,02dh db 073h ,0b4h ,027h ,0c4h ,0a0h ,072h ,054h ,0b9h ,0eah ,07ch db 03bh ,0aah ,016h ,0f6h ,077h ,083h ,07ah ,0eeh ,01ah ,0d4h db 042h ,04ch ,06bh ,08bh ,013h ,01fh ,0bbh ,093h ,08bh ,0fch db 019h ,01ch ,03ch ,0ech ,04dh ,0e5h ,075h db 80h,7Fh ;Field: Program Image length db 0,0,0,0 db 0,0,0,0 db 0,0,0,0 db 0,0,0,0 db 0,0,0,0 ;End of header data ;------------------------------------------------------------------ ;------------------------------------------------------------------ ;------------------------------------------------------------------ ; Test Code ;------------------------------------------------------------------ ;------------------------------------------------------------------ ;------------------------------------------------------------------ ;Code to test the interface routines. StartApp: set fullScrnDraw,(IY+apiFlg4) ;softkey needs to write last row/column res textWrite,(IY+sGrFlags) ld hl,uimenu ;Main Menu call NumberedMenu ld a,d dec a jr z,uiNMenu dec a jr z,uiSoftKey dec a jr z,uiSoftKeyG dec a jr z,uiMessageBox dec a jp z,uiInputString dec a jp z,uiSelectionList dec a jp z,uiListView B_JUMP JForceCmdNoChar ;Return to TIOS uiNMenu: ;numbered menu test ld hl,testmenu call NumberedMenu push de push af B_CALL ClrLCDFull pop af pop de ld hl,0 ld (curRow),hl ld hl,uinmcoltxt call nmPutS ld h,0 ld l,a push de B_CALL DispHL B_CALL NewLine pop de ld hl,uinmitemtxt call nmPutS ld h,0 ld l,d B_CALL DispHL B_CALL GetKey jr StartApp uinmcoltxt: db "Column:",0 uinmitemtxt: db "Item:",0 uiSoftKeyG: ;Graphical softkey test B_CALL ClrLCDFull B_CALL GrBufClr ld hl,testsoftkey2 call SoftKeyG B_CALL GetKey jr StartApp uiSoftKey: ;Regular softkey test B_CALL ClrLCDFull B_CALL GrBufClr ld hl,testsoftkey call SoftKey B_CALL GetKey jp StartApp uiMessageBox: ;Message/Dialog box test B_CALL ClrLCDFull B_CALL GrBufClr ld hl,18*256+8 ld de,40*256+86 call DialogBox ld hl,33*256+20 ld (penCol),hl ld hl,pressanykeytxt call vputsapp ld hl,21*256+14 ld (penCol),hl ld hl,uimsgtxt call vputsapp B_CALL GetKey jp StartApp uiInputString: ;String Input test B_CALL ClrLCDFull ld b,45 ld hl,0 ld (curRow),hl ld hl,appBackUpScreen call StringInput jp StartApp uiSelectionList: ;Selection List test ld hl,sltest call SelectionList push bc B_CALL ClrLCDFull ld hl,0 ld (curRow),hl ld hl,uinmitemtxt call putsapp pop bc ld l,b ld h,0 B_CALL DispHL B_CALL GetKey jp StartApp uiListView: ;List View test ld hl,testlv call ListView push bc B_CALL ClrLCDFull pop bc ld hl,0 ld (curRow),hl ld l,b B_CALL DispHL B_CALL GetKey jp StartApp ;------------------------------------------------------------------ ;------------------------------------------------------------------ ;------------------------------------------------------------------ ; Test Data ;------------------------------------------------------------------ ;------------------------------------------------------------------ ;------------------------------------------------------------------ ;This is data used to test the User Interface routines. uimenu: ;Main Menu db 1 dw uimenu1 db "Choose UI Type",0 uimenu1: db 8 db "Numbered Menu",0 db "Soft Key",0 db "Soft Key 2",0 db "Message Box",0 db "String Input",0 db "Selection List",0 db "List View",0 db "Quit",0 pressanykeytxt: ;Text Used to Demonstrate ;Message Boxes db "Press",6,"any",6,"key...",0 uimsgtxt: db "MESSAGE",6,"GOES",6,"HERE",0 testsoftkey: ;Soft Key test text db "Load",0 db 0 db 6,"F3",0 db "Blah",0 db "Quit",0 testsoftkey2: ;More Soft Key test text db 6,"F1",0 db " COL",0 db " ROW",0 db 6,"F4",0 db " DAN",0 sltest: ;Test data for selection ;list db 15 db "Item1",0 db "Item2",0 db "Item3",0 db "Item4",0 db "Item5",0 db "Item6",0 db "Item7",0 db "Item8",0 db "Item9",0 db "Item10",0 db "Item11",0 db "Item12",0 db "Another Item",0 db "Yet Another",0 db "Last Item",0 testlv: ;test data for list view db 10 db "SOME TEXT",0 db "MORE TEXT",0 db "EVEN MORE TEXT",0 db "REALLY LONG TEXT",0 db "REALLY LONGER TEXT",0 db "THIS TEXT IS REALLY REALLY LONG",0 db "BUT WAIT! EVEN LONGER! I THINK...",0 db "BORING",0 db "MORE BORING",0 db "THE END",0 testmenu: ;test data for numbered ;menu db 3 ;Number of columns dw testmenu1 ;Pointer to first column dw testmenu2 ;Pointer to second column dw testmenu3 ;Pointer to third column db "COL1",0 ;Label for column one db "COL2",0 ;Label for column two db "COL3",0 ;Label for column three testmenu3: db 7 db "In",0 db "Menu",0 db "Routine",0 db "...",0 db "Oh",0 db "Well",0 db "...",0 testmenu2: db 9 db "It",0 db "Would",0 db "Be",0 db "Nice",0 db "If",0 db "There",0 db "Was",0 db "A",0 db "Built",0 testmenu1: db 13 db "Item1",0 db "Item2",0 db "Item3",0 db "Item4",0 db "Item5",0 db "Item6",0 db "Item7",0 db "Item8",0 db "Item9",0 db "Item0",0 db "ItemA",0 db "ItemB",0 db "ItemC",0 ;------------------------------------------------------------------ ;------------------------------------------------------------------ ;------------------------------------------------------------------ ; List View ;------------------------------------------------------------------ ;------------------------------------------------------------------ ;------------------------------------------------------------------ ;This routine needs a buffer in ram equal to or greater than the size ;of the largest item in the list. By default it uses appBackUpScreen. ;This can be changed to any other safe ram. ListView: ;Input ;HL points to list data ;Output ;B is the list item choosen set textWrite,(IY+sGrFlags) ld b,1 ;b=selected item ld c,b ;c=top item on screen ld d,0 ;d=letters to skip lvReDisp: ;Display text and cursor push hl push bc push de B_CALL GrBufClr pop de pop bc pop hl call lvDispText ;Displays the Text call lvDispCursor ;Displays the inverted cursor lvLoop: push hl push bc push de B_CALL GrBufCpy ;Text and cursor are in graph ;buffer, so a buffer copy is ;necessary B_CALL GetKey ;Get a Key pop de pop bc pop hl cp kDown jr z,lvDown ;Selector moving down cp kUp jr z,lvUp ;Selector moving up cp kRight jr z,lvRight ;Try to scroll text right cp kLeft jr z,lvLeft ;Try to scroll text left cp kEnter jr nz,lvLoop res textWrite,(IY+sGrFlags) ret ;We're done lvLeft: ;Try to scroll left ld a,d or a ;Is d=0? are we all the ; way to the left? jr z,lvLoop ;If so, return to loop dec d ;We can scroll one less char now jr lvReDisp ;Scrolled, so we need to redisplay lvRight: ;Try to scroll right push bc push de push hl ld c,b call lvGetStrPtr ;HL now points to selected string ld e,d ld d,0 ;DE is the offset of the scroll add hl,de ld de,appBackUpScreen+1 B_CALL StrCopy ;string needs to be in RAM ;so SStringLength be used ld hl,appBackUpScreen+1 B_CALL StrLength dec hl ld (hl),c ;SStringLength requires length-leading B_CALL SStringLength cp 95 pop hl pop de pop bc jr c,lvLoop ;String not wider that screen, can't scroll inc d jr lvReDisp lvDown: ;Move cursor down ld a,(hl) cp b ;Already at bottom? jr z,lvLoop ld d,0 ;Reset horiz. scroll for new string inc b ld a,c add a,8 cp b ;Need to scroll down? jr nz,lvReDisp inc c jr lvReDisp lvUp: ;Move cursor up ld a,b dec a ;Already at top? jr z,lvLoop ld d,0 ld b,a cp c ;Need to scroll up? jr nc,lvReDisp dec c jr lvReDisp lvDispCursor: ;Display selction cursor push de push hl push bc ld a,b sub c ld l,a ld h,12*8 ;The cursor is 8 rows of ; 12 bytes in plotsscreen B_CALL HTimesL ;We multiply the cursor ; size (8*12=96) by the ; current position of the ; cursor to get the offset ; from plotsscreen ld de,plotSScreen add hl,de ld bc,12*8 ;Cursor size is 96 bytes lvDCLoop: ld a,(hl) cpl ;Invert graph buffer byte ld (hl),a inc hl dec bc ld a,b or c jr nz,lvDCLoop pop bc pop hl pop de ret lvDispText: ;Display text push hl push bc push de ld a,c add a,8 ld e,a ;Where to stop displaying call lvGetStrPtr push hl ld hl,0101h ld (penCol),hl pop hl lvDTLoop: ld a,b cp c jr nz,lvDTNotSel ;Current string not selected push de ld e,d ld d,0 ;DE holds the horiz. scrolling offset add hl,de pop de lvDTNotSel: call vputsapp ;Display the text jr nc,lvDTNoArrow ;Carry set if off screen ld a,91 ld (penCol),a ld a,5 ;Arrow character push hl push de B_CALL VPutMap pop de pop hl lvDTNoArrow: ld a,1 ld (penCol),a ;Reset penCol to left side of screen ld a,(penRow) add a,8 ;Go to next text/cursor position ld (penRow),a inc c ld a,c cp e ;At end of text list? jr nz,lvDTLoop pop de pop bc pop hl ret lvGetStrPtr: ;Returns HL=pointer to string C inc hl ld a,c dec a ret z ;Already pointing to first string push bc ld b,h ;Large enough value for CPIR lvDTCpirLoop: push af xor a cpir ;Find next zero terminator pop af dec a jr nz,lvDTCpirLoop pop bc ret ;------------------------------------------------------------------ ;------------------------------------------------------------------ ;------------------------------------------------------------------ ; Selection List ;------------------------------------------------------------------ ;------------------------------------------------------------------ ;------------------------------------------------------------------ SelectionList: ;Input ;HL points to list data ;Output ;B is the list item choosen push hl B_CALL ClrLCDFull pop hl ld b,1 ;B=Current item ld c,1 ;C=Top display item ld e,0 ;E = 0 = Need to Redisplay text slReDisp: inc e dec e ;Is E=0? (do we need to redisplay text?) jr nz,slReDispCont push bc push hl push de B_CALL ClrLCDFull pop de pop hl pop bc call slDispText ;Display text slReDispCont: call slDispCur ;Display cursor slLoop: push bc push hl push de B_CALL GetKey pop de pop hl pop bc cp kDown jr z,slDown ;Move cursor down cp kUp jr z,slUp ;Move cursor up cp kEnter ret z jr slLoop slUp: ld a,b dec a ;Already at first item? jr z,slLoop ;If so, can't move any higher ld b,a cp c ;Need to adjust top of screen (scroll up)? jr nc,slReDisp ld e,0 ;If we adjust top of screen, we need to ; redisplay text dec c jr slReDisp slDown: ld a,(hl) cp b ;Already at last item? jr z,slLoop ;If so, can't move lower inc b ld a,c add a,8 cp b ;Need to adjust top of screen (scroll down)? jr nz,slReDisp ld e,0 ;If adjust bottom of screen, need to redisplay inc c jr slReDisp slDispCur: ;Display cursor ld a,b sub c ;Selected item minus top of screen=where to display ld (curRow),a ld d,a xor a ld (curCol),a ld a,Lconvert ;Arrowish character B_CALL PutMap ;Now we need to erase previous cursor by clearing ; cursor positions above and below current ld a,d or a jr z,slDCZero ;Can't go any higher? dec a ld (curRow),a ld a,Lspace B_CALL PutMap slDCZero: ld a,d cp 7 ;Can't go any lower? ret z ;If so, done inc a ld (curRow),a ld a,Lspace B_CALL PutMap ret slDispText: ;Display text push de push hl push bc push bc ld e,(hl) inc hl ld d,c dec d jr z,slDispTextCont ;Already in place for first text item xor a ld b,h ;Enough for our CPIR slDTCpirLoop: cpir dec d jr nz,slDTCpirLoop slDispTextCont: ;HL points to first string pop bc ld a,e inc a sub c cp 9 ;Are there more than 8 strings left? jr c,slDTOverflow ld a,8 ;If so, set # of strings to display at 8 slDTOverflow: ld b,a ;Number of strings to display xor a ;curRow slDTLoop: ld (curRow),a inc a push af ld a,1 ld (curCol),a call putsapp ;Display text pop af djnz slDTLoop pop bc pop hl pop de ld e,1 ;Text updated, don't need to update next time ret putsapp: ;Display a string of large text ld a,(hl) inc hl or a ret z B_CALL PutC jr putsapp ;------------------------------------------------------------------ ;------------------------------------------------------------------ ;------------------------------------------------------------------ ; Graphic Soft Key ;------------------------------------------------------------------ ;------------------------------------------------------------------ ;------------------------------------------------------------------ SoftKeyG: push hl ld de,appBackUpScreen ld hl,skgPic ;Graphic button ld bc,26 ldir ;Need to copy graphic to ram for use ; with DisplayImage ld de,56*256+3 skgLoop: push de ld hl,appBackUpScreen B_CALL DisplayImage pop de ld a,e add a,18 ;Move right 18 pixels-next image location ld e,a cp 93 ;Are we done displaying? jr nz,skgLoop ;If not, display next graphic pop hl ld a,57 ld (penrow),a ld a,5 skgLoop2: ;Loop to display text inside graphics ld (pencol),a push af call vputsapp ;Display the text pop af add a,18 ;Next location for text cp 95 ;Done displaying? jr nz,skgLoop2 ret skgPic: db 8,17 db 00111111b,11111110b,00000000b db 01000000b,00000001b,00000000b db 10000000b,00000000b,10000000b db 10000000b,00000000b,10000000b db 10000000b,00000000b,10000000b db 10000000b,00000000b,10000000b db 01000000b,00000001b,00000000b db 00111111b,11111110b,00000000b ;------------------------------------------------------------------ ;------------------------------------------------------------------ ;------------------------------------------------------------------ ; String Input ;------------------------------------------------------------------ ;------------------------------------------------------------------ ;------------------------------------------------------------------ StringInput: ;Input ;HL points to where to save input ;B = max characters ;curRow,curCol = cursor location ;Output ;HL is preserved ;BC = number of characters inputted push hl ld de,(curRow) push de set curAble,(IY+curFlags) ld c,b ;C = Backup of max chars ld d,0 ;D = How many chars after current cursor location ; last inpuuted char is ld (hl),d ld a,Lspace ld (curUnder),a ;curUnder is the character that is shown during ; cursor blink B_CALL PutMap siLoop: push hl push de push bc B_CALL GetKey pop bc pop de pop hl cp kDel jr z,siDel ;Delete a character cp kClear jr z,siClear ;Clear entire prompt cp kEnter jp z,siEnter cp kLeft jp z,siLeft ;Attempt to move left cp kRight jp z,siRight ;Attempt to move right cp kDown jp z,siDown ;Attempt to move down cp kUp jp z,siUp ;Attempt to move up cp kSpace jp z,siSpace ;Non-regular character: space cp kComma jp z,siComma ;Non-regular character: comma sub k0 cp 10 jp c,siNumber ;It's a number sub kCapA-k0 cp 26 jp c,siLetter ;It's a letter jr nz,siLoop ld a,'X'-'A' ;XT0n key jp siLetter siDel: ;Delete a character inc d dec d ;Are we at the end of the string? jr z,siLoop push de push bc push hl ld b,d ld de,(curRow) push de ld d,h ld e,l inc de dec b ;Are we deleting the last character? ld c,Lspace jr z,siDelLoopSkip ;If so, we want to have curUnder=Lspace ; and we don't need to display shifted ; characters ld a,(de) ;Else, we want curUnder=next character ld c,a siDelLoop: ;This loop displays all the remaining ; characters after the one we're deleting, ; but shifted back one position ld a,(de) B_CALL PutC ld (hl),a inc hl inc de djnz siDelLoop siDelLoopSkip: ld (hl),0 ;Needs to be zero terminated, right? ld a,Lspace B_CALL PutC ld a,c ld (curUnder),a pop de ld (curRow),de pop hl pop bc pop de dec d jp siLoop siClear: ;Clear all characters ld a,c sub b add a,d or a ;Nothing to clear? jp z,siLoop ld e,d ld d,0 add hl,de ld (hl),0 ;Zero terminate current text pop de ld (curRow),de ;Restore original cursor location pop hl push bc B_CALL StrLength ;Get length of string inc c ;Need to erase cursor too push hl push de siClearLoop: ;Clear all previously entered text ld a,Lspace B_CALL PutC dec c jr nz,siClearLoop pop de ld (curRow),de pop hl pop bc ld b,c ;Restore backup of max # of chars jp StringInput siEnter: ld a,(curUnder) B_CALL PutMap ;Display character under cursor, so we ; don't get a black box ld hl,curRow dec d inc d jr z,siEnterLoopSkip siEnterLoop: ;Updates cursor position to end ld a,(curCol) inc a and 15 ld (curCol),a or a jr nz,siEnterLoopCont inc (hl) siEnterLoopCont: dec d jr nz,siEnterLoop siEnterLoopSkip: pop de pop hl B_CALL StrLength ;Find string length inc bc ;Add one for zero terminator res curAble,(IY+curFlags);Turn off cursor ret ;The End! siNumber: ;A number key was pressed add a,L0 ;Add number to '0' jr siLetCont siLetter: ;A letter key was pressed add a,LcapA ;Add letter number to 'A' siLetCont: dec b inc b ;Have we displayed the maximum # of ; characters? jp z,siLoop ld (hl),a B_CALL PutC inc hl ld a,d dec d dec b or a ld a,(hl) ld (curUnder),a ;Reset curUnder to next character jp nz,siLoop inc d ld a,Lspace ld (curUnder),a ld (hl),0 jp siLoop siSpace: ;Space was pressed ld a,' ' jr siLetCont siComma: ;Comma was pressed ld a,',' jr siLetCont siLeft: ;Try to move left ld a,b cp c ;Are we all the way to the left? jp z,siLoop ;If so, we can't go any further inc b ld a,d inc d ;We've moved farther away from the end call siLDAHL B_CALL PutMap dec hl ld a,(hl) ld (curUnder),a ;Update curUnder ld a,(curCol) dec a ;Cursor location one to the left ld (curCol),a jp p,siLoop ;Jumps if there was no overflow ld a,15 ld (curCol),a ld a,(curRow) dec a ld (curRow),a jp siLoop siUp: ;Try to move up ld a,b add a,15 cp c ;Have we typed more than 15 characters? jp nc,siLoop ;If not, we can't move up ld b,a inc b ld a,d add a,16 ld d,a call siLDAHL B_CALL PutMap push de ld de,16 sbc hl,de ;Text pointer up a row (row=16 bytes) pop de ld a,(curRow) dec a ;Move cursor up a row ld (curRow),a ld a,(hl) ld (curUnder),a jp siLoop siLDAHL: ;Loads a character from (hl) and ; converts it to Lspace if it is 0 ld a,(hl) or a ret nz ld a,Lspace ret siDown: ;Tries to move down ld e,16 ld a,d sub e ;Are there are least 16 after cursor? jp c,siLoop ; if not, we can't move down ld d,a ld a,b sub e ld b,a ld a,(hl) B_CALL PutMap ;Make sure character under cursor is displayed push de ld d,0 add hl,de pop de call siLDAHL ld (curUnder),a ld a,(curRow) inc a ld (curRow),a jp siLoop siRight: ;Try to move right ld a,d or a ;Are there any more chars after cursor? jp z,siLoop ;If not, we can't move right! dec b ld a,(hl) B_CALL PutMap inc hl dec d call siLDAHL ld (curUnder),a ld a,(curCol) inc a ;Move cursor over ld (curCol),a cp 16 ;Did we scroll? jp nz,siLoop ;If not, we're all done here xor a ;Else we have to reset curCol ld (curCol),a ld a,(curRow) inc a ;And increment curRow ld (curRow),a jp siLoop ;------------------------------------------------------------------ ;------------------------------------------------------------------ ;------------------------------------------------------------------ ; Dialog Box ;------------------------------------------------------------------ ;------------------------------------------------------------------ ;------------------------------------------------------------------ DialogBox: ;Input ; (H,L) = (y,x) upper left ; (D,E) = (y,x) lower right ; H and l must be >= 1 ; D must be <= 62 ; E must be <= 93 push hl push de dec h dec l inc d inc d inc e inc e B_CALL EraseRectBorder pop de pop hl push hl push de B_CALL DrawRectBorderClear pop de pop hl push hl push de inc d inc e B_CALL DrawRectBorder pop de pop hl ld a,h xor 63 ;Adjust for funny IPoint coordinates ld h,a ld a,d xor 63 ld b,l ld c,h ld d,0 B_CALL IPoint ;(b,c) = (x,y xor 63) - upper left ld b,e B_CALL IPoint inc b B_CALL IPoint dec c B_CALL IPoint ld c,a dec c B_CALL IPoint ld b,l B_CALL IPoint inc b B_CALL IPoint dec b inc c B_CALL IPoint ret ;------------------------------------------------------------------ ;------------------------------------------------------------------ ;------------------------------------------------------------------ ; Soft Key ;------------------------------------------------------------------ ;------------------------------------------------------------------ ;------------------------------------------------------------------ SoftKey: ;Input ; HL points to key text ;Ouput ; soft keys are displayed to screen push hl ld bc,0007h ld de,95*256+7 ld h,1 B_CALL ILine ld b,19 ld d,b ld e,0 B_CALL ILine ld b,38 ld d,b B_CALL ILine ld b,57 ld d,b B_CALL ILine ld b,76 ld d,b B_CALL ILine ld b,0 ld d,b B_CALL ILine ld b,95 ld d,b B_CALL ILine pop hl ld a,57 ;Text row position ld (penRow),a ld a,3 ;Starting column position SoftKeyLoop: ;Loop to display text inside boxes ld (penCol),a push af call vputsapp ;Display the text pop af add a,19 cp 98 ;Are we done? jr nz,SoftKeyLoop ret vputsapp: ;Display text in small font ld a,(hl) inc hl inc a dec a ;Use inc and dec to preserve carry ret z push hl push de B_CALL VPutMap pop de pop hl jr vputsapp ;------------------------------------------------------------------ ;------------------------------------------------------------------ ;------------------------------------------------------------------ ; Numbered Menu ;------------------------------------------------------------------ ;------------------------------------------------------------------ ;------------------------------------------------------------------ NumberedMenu: ;Input ; HL points to menu data ;Output ; A = column ; D = currently selected item ld b,(hl) nmRestart: ld c,1 ;C = top display item in column ld d,c ;D = currently selected item ld e,0 ;E = 0 = need to refresh text nmLoop: dec e inc e ;Do we need to refresh text? jr nz,nmLoopCont ;If not, we don't need to clear screen push hl ; (less flicker) push bc push de B_CALL ClrLCDFull pop de pop bc pop hl nmLoopCont: call nmDispHeaders ;Display column headers call nmDispNumbers ;Display row number/letters nmLoop2: push hl push bc push de B_CALL GetKey pop de pop bc pop hl cp kRight jr z,nmMoveRight cp kLeft jr z,nmMoveLeft cp kUp jr z,nmMoveUp cp kDown jr z,nmMoveDown cp kEnter jr z,nmQuit cp k0 jr z,nmPress0 ;Zero comes *after* other numbers sub k1 cp 10 jr c,nmPressNum ;Number (non-zero) pressed sub kCapA-k1 cp 27 jr c,nmPressLet ;Letter pressed jr nmLoop2 nmPressLet: add a,10 ;Letters come after numbers jr nmPressNum nmPress0: ld a,9 ;Zero comes after nine nmPressNum: inc a ld e,a call nmGetColSize ;How many items in this column? cp e ;Does the number/letter pressed exist? jr c,nmLoop2 ;If not, return to getkey loop ld d,e nmQuit: ld a,(hl) inc a sub b ;Columns are used backwards in routine ; so column needs to be reversed for ; output ret nmMoveLeft: ;Move left ld c,1 ld d,c ld e,0 ;Need to refresh text ld a,b inc b ;Goto previous column cp (hl) ;Were we at first column? jr nz,nmLoop ld b,1 ;If it was the first column, we need to ; reset the column to last jr nmLoop nmMoveRight: ;Move right ld c,1 ld d,c ld e,0 ;Need to refresh text dec b ;Go to next column ld a,b or a ;Were we at the last column? jr nz,nmLoop ld b,(hl) ;If it was the last column, we need to ; reset the column to first jr nmLoop nmMoveUp: ;Move up ld a,d dec d jr z,nmMUCarry ;Scrolling from top back to bottom cp c ;Is current = top? jr nz,nmLoop ;If not, don't worry about top ld e,0 ;Refresh text if we changed top dec c jr nmLoop nmMUCarry: ld e,0 ;Refresh text if going top to bottom inc d ld a,(8442h) ;Key repeat location cp 31h ;Was the key repeating? jr c,nmLoop2 ;If so, we don't want to jump to bottom call nmGetColSize ld d,a sub 6 ld c,a jp nc,nmLoop ld c,1 jp nmLoop nmMoveDown: ;Move down call nmGetColSize cp d jr z,nmMDCarry ;Scrolling from bottom back to top ld a,d inc d sub c cp 6 ;Do we need to adjust top too? jp nz,nmLoop ld e,0 ;Refresh text if adjusting top inc c jp nmLoop nmMDCarry: ld e,0 ;Refresh text for bottom to top ld a,(8442h) ;Key repeat location cp 31h jp c,nmLoop2 jp nmRestart nmGetColPointer: ;Returns HLl=pointer to column b push de ld a,(hl) sub b ld e,a sla e ld d,0 inc hl add hl,de B_CALL LdHLInd pop de ret nmGetColSize: ;Returns A=# items in current column push hl call nmGetColPointer ld a,(hl) pop hl ret nmDispNumbers: ;Display numbers and text push hl push bc push de push de ;Registers need to be saved call nmGetColPointer ld e,(hl) ;E=# of entries in column inc hl call nmCpirOffset ;HL->first text string to display ld b,1 nmDNLoop: ld a,b ld (curRow),a xor a ld (curCol),a ld a,c cp d ;Is it the current selected item? jr nz,nmDNNoInv set textInverse,(IY+textFlags) ;If so, we need to inver the number nmDNNoInv: call nmGetChar ;A=char representation of C B_CALL PutC ld a,b cp 1 ;If it's not the first, no up arrow jr nz,nmDNNoArrowUp cp c ;If there are non above, no up arrow jr z,nmDNNoArrowUp ld a,LupArrow B_CALL PutC jr nmDNCont nmDNNoArrowUp: cp 7 ;If it's not the last, no down arrow jr nz,nmDNNoArrowDown ld a,c cp e ;If there's none below, no down arrow jr z,nmDNNoArrowDown ld a,LdownArrow B_CALL PutC jr nmDNCont nmDNNoArrowDown: ;If we don't need an up or down arrow ld a,Lcolon ; we want a colon B_CALL PutC nmDNCont: pop af push af res textInverse,(IY+textFlags) ;Text shouldn't be inverted call nc,putsapp ;If E=0 then we need to display text ld a,c cp e jr z,nmDNEnd inc b inc c ld a,b cp 8 jr nz,nmDNLoop nmDNEnd: pop de pop de ld e,1 pop bc pop hl ret nmCpirOffset: ;Returns C strings into list HL ld b,c dec b ret z xor a nmCOLoop: push bc ld b,h ;Enough BC for our CPIR cpir pop bc djnz nmCOLoop ret nmGetChar: ;Returns A = char equate for char C ld a,c cp 10 jr z,nmGCZero jr nc,nmGCLetter add a,L0 ret nmGCZero: ld a,L0 ret nmGCLetter: add a,LcapA-11 ret nmDispHeaders: ;Display the headers push hl push bc push de ld a,b ;A = highlighted column = current column ld b,(hl) ld e,b sla e ld d,0 add hl,de inc hl ld de,0 ld (curRow),de nmDHLoop: cp b ;Is this the inverted text header? jr nz,cmDHNoInv set textInverse,(IY+textFlags) ;Set inverse text mode cmDHNoInv: call nmPutS ;Display header djnz nmDHLoop pop de pop bc pop hl ret nmPutS: ;Display string with a space after it push af call putsapp res textInverse,(IY+textFlags) ;In general, we don't want inverse ld a,Lspace B_CALL PutC pop af ret