Написал ближе к твоим требованиям. Структура меню - в данных, а код - отдельно, один для всех. Код обильно прокомментировал.
Единственное - ввод-вывод. Так как не знаю, как прикрутить LCD и AT keyboard в эмуляторе, сделал ввод через Waitkey(), а вывод через Print. И вместо клавиш влево (<-), вправо (->) и Enter использовал, соответственно, "1", "3" и "2". Но это, думаю, не важно. Ввод-вывод свои поставишь.
Для добавления пунктов код трогать не надо. Надо только добавлять пункты с связями в секцию $data, и писать подпрограммы для действий.
$regfile = "M644def.dat"
$crystal = 8000000
$hwstack = 64
$swstack = 64
$framesize = 64
$lib "adr2.lib"
Dim Menupointer As Word
Dim B As Byte
Dim Type As Byte
Dim Dummy As Byte
Dim Message As String * 32
\' Типы меню
Const Id_submenu = &HAA
Const Id_command = &H55
Main_menu:
\' Ставим указатель Data на первый пункт главного меню
Restore Menu1
\' Сохраняем в MenuPointer текущий указатель Data,
\' который лежит в регистрах R8 и R9 (ассемблерный код).
sts {MenuPointer}, R8
sts {MenuPointer + 1}, R9
Display_new_menu:
\' Извлекаем из MenuPointer указатель в регистры R8 и R9,
\' то есть передвигаем указатель Data в позицию MenuPointer.
lds R8, {MenuPointer}
lds R9, {MenuPointer + 1}
\' Читаем тип меню (подменю или команда), название и печатаем название
Read Type
Read Message
Print Message
\' Ждем клавишу, пока она не 1 (<-) или 2 (Enter) или 3 (->).
Wait_key:
B = Waitkey()
If B < 49 Then
Goto Wait_key
End If
If B > 51 Then
Goto Wait_key
End If
\' Проверяем, нажата ли 2 (Enter)
If B = 50 Then
\' Если тип у нас - подменю, то:
If Type = Id_submenu Then
\' Читаем адрес дочернего меню (идет в Data сразу за названием)
Read Dataptr
\' Записываем его в MenuPointer и идем читать и рисовать это новое меню
sts {MenuPointer}, R8
sts {MenuPointer + 1}, R9
Goto Display_new_menu
\' Иначе (если тип - команда), то:
Else
\' Читаем адрес метки команды (идет в Data сразу за названием)
Read Dataptr
\' Вызываем подпрограмму по этому адресу.
movw R30,R8
icall
\' И после ее отработки идем в самое начало. Здесь можно и выйти
\' из меню вообще или остаться в этом пункте меню или еще что-нибудь.
Goto Main_menu
End If
End If
\' Если нажата не 2 (Enter), то пропускаем 2 байта с адресом
\' команды или подменю - они нам не нужны.
Read Dummy
Read Dummy
\' Проверяем, нажата ли 1 (<-)
If B = 49 Then
\' Читаем адрес предыдущего меню на этом уровне (сосед слева)
Read Dataptr
\' Записываем его в MenuPointer и идем читать и рисовать это новое меню
sts {MenuPointer}, R8
sts {MenuPointer + 1}, R9
Goto Display_new_menu
End If
\' Если нажата и не 1 (<-), то снова пропускаем 2 байта с адресом
\' соседа слева - они нам тоже не нужны.
Read Dummy
Read Dummy
\' Проверяем, нажата ли 3 (->)
If B = 51 Then
\' Читаем адрес следующего меню на этом уровне (сосед справа)
Read Dataptr
\' Записываем его в MenuPointer и идем читать и рисовать это новое меню
sts {MenuPointer}, R8
sts {MenuPointer + 1}, R9
Goto Display_new_menu
End If
End
\' ---------
\' Подпрограммы для команд
Runmenu11:
\' Здесь делаем полезные дела
Print "Running command from menu 1 -> 1"
Return
Runmenu12:
\' Полезные дела
Print "Command of menu 1 -> 2"
Return
Runmenu2:
\' Полезные дела
Print "Command of menu 2"
Return
Runmenu3:
\' Полезные дела
Print "Command of menu 3"
Return
\' ---------
\' Блок данных. Здесь и находится структура меню. Порядок пунктов меню не важен,
\' главное правильно указать связи-адреса на дочерний элемент (подменю или
\' команду) и соседей слева и справа. Структура такая:
\'
\' Метка_своя:
\' Data Тип_Меню
\' Data "Название_меню"
\' Data Метка_дочернего
\' Data Метка_соседа_слева
\' Data Метка_соседа_справа
\'
$data
Menu1:
Data Id_submenu
Data "Menu 1 v"
Adr2 Menu10
Adr2 Menu3
Adr2 Menu2
Menu10:
Data Id_submenu
Data "Menu up^"
Adr2 Menu1
Adr2 Menu12
Adr2 Menu11
Menu11:
Data Id_command
Data "Menu 11!"
Adr Runmenu11
Adr2 Menu10
Adr2 Menu12
Menu12:
Data Id_command
Data "Menu 12!"
Adr Runmenu12
Adr2 Menu11
Adr2 Menu10
Menu2:
Data Id_command
Data "Menu 2 !"
Adr Runmenu2
Adr2 Menu1
Adr2 Menu3
Menu3:
Data Id_command
Data "Menu 3 !"
Adr Runmenu3
Adr2 Menu2
Adr2 Menu1