Что то типа такого. Сегодня проверить, чего я там накропал - не могу, возможно, получится завтра.
Код:
;
; .PSECT DATA,RW
;
;; Имена команд
;CMD1: .ASCIZ /COM1/
;CMD2: .ASCIZ /COM2/
; .EVEN
;; Ссылка на процедур (порядок тот же, как и в именах команд)
;METH1: .WORD RMETH1
;METH2: .WORD RMETH2
;
;; Описатель - команда-процедура. Окончание - нулевое слово
;DESC: .WORD CMD1
; .WORD METH1
; .WORD CMD2
; .WORD METH2
; .WORD 0
;
; .PSECT CODE,RO
;
; MOV #CMD, R0 ; Строка команды в формате .ASCIZ
; MOV #DESC, R1 ; Дескриптор команд-процедур
; CALL PARSE
;
PARSE::
MOV R1, -(SP) ; Сохраним описатель команд
LOOP: TSTB (R0) ; Дошли до конца строки команд
BEQ EXIT ; Да - выход
CMPB (R0), #', ; Нет. Разделитель команд?
BNE NCOMMA ; Нет - дальше повторитель-команда или команда
INC R0 ; Пропуск запятой
BR LOOP ; Дальше по командной строке
NCOMMA:
CLR R3 ; Повторитель команды
DIG: CMPB (R0), #'0 ; Цифра?
BLO NDIG ; Нет - дальше пошла команда
CMPB (R0), #'9 ; Цифра
BHI NDIG ; Нет - дальше пошла команда
MUL #10., R3 ; Предыдущее*10
SUB #'0, R3 ; Минус код ASCII минус код нуля
MOVB (R0)+, R2 ; Очердной символ-цифра
ADD R2, R3 ; Плюс следующаяя цифра в коде ASCII
BR DIG ; Смотрим дальше
NDIG: TST R3 ; Повторитель задан?
BNE SCMD ; Да - ищем команду
INC R3 ; Нет - но один раз команду выполнить надо
SCMD: MOV (SP), R1 ; Описатель команд
MOV R0, -(SP) ; Начало имени команды
LCMD: MOV (R1)+, R2 ; Имя следующей команды. Описатель закончился?
BEQ ECMD ; Да - (тут в принципе можно вставить переход на обработку ошибки)
MOV (R1)+, R5 ; Процедура, её выполняющая
MOV (SP), R0 ; Начало имени команды - для очередного сравнения
SCMP:
TSTB (R0) ; В конце строки (окончание имени команды)?
BEQ CCHECK ; Да
CMPB (R0), #', ; Запятая (тоже окончание имени команды)?
BEQ CCHECK ; Да
TSTB (R2) ; Имя команды в описателе закончилось (а в строке команды - нет)?
BEQ LCMD
CMPB (R0)+, (R2)+ ; Символ тот же?
BEQ SCMP ; Да, продолжаем сравнение
BR LCMD ; Нет - смотрим следующую команду
CCHECK: TSTB (R2) ; В строке команда закончилась. А в описателе?
BNE LCMD ; Нет - не та команды
CALL MCMD ; Да - выполнить связанную с ней процедуру
ECMD: TST (SP)+
BR LOOP
EXIT: TST (SP)+
RETURN
MCMD: CALL $SAVAL
CALL (R5)
RETURN
;
;В принципе, стандартная процедура сохранения восстановления всех регистров,
;но с этим кодом процедура становится самодостаточной.
;Можно выкинуть :)
;
$SAVAL: MOV R4,-(SP)
MOV R3,-(SP)
MOV R2,-(SP)
MOV R1,-(SP)
MOV R0,-(SP)
MOV 12(SP),-(SP)
MOV R5,14(SP)
JSR PC,@(SP)+
MOV (SP)+,R0
MOV (SP)+,R1
MOV (SP)+,R2
MOV (SP)+,R3
MOV (SP)+,R4
MOV (SP)+,R5
RETURN