V Команди (компилатор C5.EXE v2010.)
Всяка линия в програмата е поредица от 1.Команда 2.Операнди. Операндите са регистри, променливи, указатели, етикети, константи.
След командата трябва да има интервал. Между операндите се слага запетая.
От гледна точка на този който пише програма, командите предствляват трибуквени думи - по долу наричани макрокоманди. Техният брой е около 30. Всяка макрокоманда една или повече микро версии според адресирането и други подробности. Спазен е ред на декларациите, тоест нито азбучен, нито подреден по теми. Веднага след макроса следва операндна линия. Линия "o" или "oo" означава един или два операнда. След това е български еквивалент на записания макрос, както и английска фраза - източник на съкращението.
Микроверсиите са представени като шестбуквени съкращения-направо от сорса на V, за сведение. Компилаторът ги подбира автоматично според граматиката в текста. Първите три букви съвпадат с макроса. Четвърта и пета буква са адресиращи указания за двата операнда. Буква "R" означава регистър; Буква "M" означава памет; Буква "I" означава пряка стойност в кода; Буква "V" означава че операнда ще бъде третиран като целочислен указател към друг адрес в паметта. Шестата буква е типа на съдържанието, което се пренася. "I" значи целочислено; "D" значи числено дробно; "S" значи стрингово;


Списък команди
MOV oo ПОСТАВИ move копиране от втори към първи опреранд
INP o ВХОД input команда към приемника, зависи от I/S
OUT o ИЗХОД output команда към предавателя
ADD oo СЪБЕРИ add събери o1 <= o1+o2
JMP o ПРЕХОД jump преход към относителен адрес о
JMZ o ПРИНУЛА jump if RegI=0 преход към o при условие I=0
JMF oo УСЛОВНО jump if (flag and o2)<>0 преход към o1 при условие (flag and o2)<>0
CLF o ФЛАГ clear (flag=op) установява регистър Флаг
MSP o СЪОБЩИ put a message to pridизпраща съобщение на процеса в o
MSG ВЗЕМИ get a message вземи съобщение
IDL ОСВОБОДИ set idle stateостани в бездейно състояние
DIE СПРИ die изключи програмата
CMP oo СРАВНИ compare сравни o1 и o2 (резултатът остава в регистър FLAG)
JSU o ПОДПРЕХОД jump to a subroutineпреход към подпрограма и запис на текущата позиция в стека
RET ОБРАТНО return from subroutineвръщане от подпрограма
STR o ПРЕВЪРНИ string operationкоманда към стринговия регистър
SPO oo СЪДЪРЖА string positionпозиция на подстринг
GME oo ПАМЕТ get memory blockзаемане на памет
FME o ЗАБРАВИ free memory blockосвобождаване на памет
PUT oo БУТНИ push into the stackпъхни в стека променлива
POP oo ДРЪПНИ pop from the stackизвади от стека променлива
EXE oo ПУСНИ execute a programстартирай RVM програма
SYS o СИСТЕМА ask for system valueсистемна команда или въпрос
LDE oo LDE set local procedure descriptor
MVM oo ПРЕНЕСИ copy mem to mem bytes /num=RegIпренос на данни
REG oo МЕЖДУ test op1<=regi<op2питане за принадлежност в интервал
SUB oo ИЗВАДИ subtractизваждане o1=o1-o2
PME ВДИГНИ peek a messageИзтегля съобщение от опашката без да го изтрива
PUR o ВСТЕК put a register to the stackЗаписва регистър в стека
POR o ОТСТЕК pop a register from the stackИзтегля регистър от стека
DSK o ДИСК disk operationДискова операция
MUL oo УМНОЖИ multiplyУмножение
DIV oo РАЗДЕЛИ divisionДеление
ABS oo ABS get abs/signАбсолютна стойност

_________________________________________________________________

mov копиране
Синтаксис: mov o1,o2
Действие : копира втория операнд в първия

Примери :
mov i,42
mov name,'hristo'

Микроверсии :
 {целочислени}
 addfroms('MOVRII', 'i');    // load immediate integer into RegI 1
 addfroms('MOVRMI', 'i');    // load RegI from memory            2
 addfroms('MOVRVI', 'i');    // load RegI from pointer           3
 addfroms('MOVMRI', 'i');    // save RegI to memory              4
 addfroms('MOVVRI', 'i');    // save RegI to pointer             5
 addfroms('MOVMMI', 'ii');   // move memory to memory            6
 addfroms('MOVMVI', 'ii');   // move pointer to memory           7
 addfroms('MOVVMI', 'ii');   // move memory to pointer           8
 addfroms('MOVVVI', 'ii');   // move pointer to pointer          9

 {дробни}
 addfroms('MOVRID', 'd');    // load immediate double into RegD  10
 addfroms('MOVRMD', 'i');    // load RegD from memory            11
 addfroms('MOVRVD', 'i');    // load RegD from pointer           12*n
 addfroms('MOVMRD', 'i');    // save RegD to memory              13
 addfroms('MOVVRD', 'i');    // save RegD to pointer             14
 addfroms('MOVMMD', 'ii');   // move double memory to memory     15
 addfroms('MOVMVD', 'ii');   // move double memory to pointer    16*n
 addfroms('MOVVMD', 'ii');   // move double pointer to memory    17*n
 addfroms('MOVVVD', 'ii');   // move double pointer to pointer   18*n

 {стрингови}
 addfroms('MOVRIS', 's');    // load immediate string into RegS  19*fe
 addfroms('MOVRMS', 'i');    // load RegS from memory            20*fe
 addfroms('MOVRVS', 'i');    // load RegS from pointer           21
 addfroms('MOVMRS', 'i');    // save RegS to memory              22
 addfroms('MOVVRS', 'i');    // save RegS to pointer             23*fe
 addfroms('MOVMMS', 'ii');   // move string memory to memory     24
 addfroms('MOVMVS', 'ii');   // move string pointer to memory    25
 addfroms('MOVVMS', 'ii');   // move string memory to pointer    26*n
 addfroms('MOVVVS', 'ii');   // move string pointer to pointer   27*n

 {по-късно добавени}
 addfroms('MOVMIS', 'is');   // move immediate string to memory  96
 addfroms('MOVVII', 'ii');   // immediate to mem pointer         99
 addfroms('MOVMII', 'ii');   // immediate to memory             100
 addfroms('MOVRRI', 'rr');   // move regd <- regi               122*ct
 addfroms('MOVRRD', '');     // move regi <- regd               145*ct*fo
 addfroms('MOVMID', 'id');   // memd<=immd                      162

*n = не работи, води до грешка v1e_not_supported
*fe вдига флаг "v1fl_sempt", тоест "if_empty" ще работи
*ct сменя типа на съдържанието, новия тип е на първия операнд
*fo вдига флаг "v1fl_iover"
_________________________________________________________________

INP команда към приемника
Синтаксис: inp o
Действие : Според операнда o и текущото съдържание на регистър I/S подава команда към приемника
Регистър I може да има следните стойности: /посочени са в сорса CONSTANTS_IC.RVA/

ic_settcpinputport установява порт (o) на TPC приемащия сокет
ic_setudpinputport установява порт (o) на UDP приемащия сокет
ic_settcpinputaddr установява адрес (целочислен-o) на TCP-сокета, който посреща конекциите
ic_setudpinputaddr установява адрес (посочен в регистър S като "127.0.0.1") на UDP-сокета
ic_settcprecvbuf установява буфер за приемане (o^) на TCP-сокета
ic_settcprecvbsz установява размер на буфера за приемане (o) на TCP-сокета
ic_gettcprecvbsz връща в регистър I размера на буфера за приемане (o) на TCP-сокета
ic_gettcprecvrsz връща в регистър I размера на последната получена порция данни в TCP-сокета
ic_gettcprecvdsz връща в регистър I размера на всички получени данни в TCP-сокета
ic_gettcprecvlsz връща в регистър I водещия размер на първия готов пакет данни в TCP-сокета
ic_getinputerror връща в регистър I код за грешка в TCP-сокета
ic_getinputstate връща в регистър I статуса на приемащия TCP-сокет и установява "ista_read"
ic_gettcpinputsocket връща в регистър I приемащия TCP-сокет
ic_gettcpinputaddr връща в регистър S адреса на приемащия TCP-сокет като "127.0.0.1"
ic_inputsettimeout1 установява временен ограничител1 (o) за работа с TCP/UDP-сокета
ic_inputsettimeout2 установява временен ограничител2 (o) за работа с TCP/UDP-сокета
ic_setforkacception установява флаг за размножаване (o) на TCP сокета
ic_gettcprecvstr връща в регистър S получена текстова линия по TCP сокета
вдига флагове v1fl_irecv + v1fl_izero
ако в получения пакет е разпозната команда за файлов пренос, го приготвя и записва в юзерската директория
ic_shiftlefttcprecvbuf премахва първия (най-левия) пакет от TCP буфера-значи приет и обработен пакет
ic_settcprecvstr установява стринг от регистър S -> в буфера на TCP-приемащия сокет.
Тази операция е удобна преди изпращането на данни обратно към терминала.
ic_settcprecvbacklen установява дължина на TCP пакета който ще бъде изпратен обратно към терминала.
ic_inittcpreceiver включва TCP-сокета на приемника в действие. Само О-програмата трябва да прави това.
новопроизведения сокет ще се вдигне в състояние "listen", според TCP-терминологията.
ic_receivetcp ако може, възбужда операция "recv" в TCP-сокета и приема поредния TCP-пакет.
ic_closetcpreceiver затваря TCP-сокета и премахва сесията на юзера.
ic_sendbacktcp изпраща TCP пакет към терминала. В регистър I се връща броя на изпратените байтове.
ic_initudpreceiver включва UDP-приемника. Само програма за групово управление прави това.

Пример : /извадка от W.RVA/
...
@init_tcp_state
gme  obuf,obufsize
mov  i,ic_settcprecvbuf        // sets the receive buffer
inp  obuf
mov  i,ic_settcprecvbsz        // sets receive buffer size
inp  obufsize
jsu  @init_out_pointers
ret
...

Микроверсии :

 addfroms('INPI_I', 'i');    // input immediate operand          31
 addfroms('INPM_I', 'i');    // input memory operand             32
 addfroms('INPV_I', 'i');    // input pointer operand            33*n

*n - не работи, излъчва грешка v1e_not_supported

Коментар:
константите IC_ са дефинирани в сорса CONSTANTS_IC.RVA
_________________________________________________________________

add събиране
Синтаксис: add o1,o2
Действие : събира първия и втория операнд, резулататът остава в първия

Примери :
add i,42
add name,'Europe'
add s, 'Иванов'
add 'Д-р ',s

Микроверсии :
 {целочислени}
 addfroms('ADDRII', 'i');    // add to RegI immediate number    34*fz
 addfroms('ADDRMI', 'i');    // add memory + RegS               35*fz
 addfroms('ADDRVI', 'i');    // add pointer + RegS              36*fz
 addfroms('ADDMRI', 'i');    // add RegS + memory               37*fz
 addfroms('ADDVRI', 'i');    // add RegS + pointer              38*fz
 addfroms('ADDMMI', 'ii');   // add memory + memory             39*fz
 addfroms('ADDMVI', 'ii');   // add pointer + memory            40*n
 addfroms('ADDVMI', 'ii');   // add memory + pointer            41*fz
 addfroms('ADDVVI', 'ii');   // add pointer + pointer           42*n

 {дробни}
 addfroms('ADDRID', 'd');    // add to RegD immediate double    43*fz
 addfroms('ADDRMD', 'i');    // add RegD + memory               44
 addfroms('ADDRVD', 'i');    // add RegD + pointer              45*n
 addfroms('ADDMRD', 'i');    // add memory + RegD               46
 addfroms('ADDVRD', 'i');    // add pointer + RegD              47*n
 addfroms('ADDMMD', 'ii');   // add memory + memory             48*fz
 addfroms('ADDMVD', 'ii');   // add pointer + memory            49*n
 addfroms('ADDVMD', 'ii');   // add memory + pointer            50*n
 addfroms('ADDVVD', 'ii');   // add pointer + pointer           51*n

 {стрингови}
 addfroms('ADDRIS', 's');    // add RegS + immediate string     52
 addfroms('ADDRMS', 'i');    // add RegS + mem                  53
 addfroms('ADDRVS', 'i');    // add RegS + ptr                  54*fe
 addfroms('ADDMRS', 'i');    // add mem + RegS                  55
 addfroms('ADDVRS', 'i');    // add ptr + RegS                  56
 addfroms('ADDMMS', 'ii');   // add mem + mem                   57*fe
 addfroms('ADDMVS', 'ii');   // add ptr + mem                   58*n
 addfroms('ADDVMS', 'ii');   // add mem + ptr                   59*n
 addfroms('ADDVVS', 'ii');   // add ptr + ptr                   60*n

 {по-късно добавени}
 addfroms('ADDIRS', 's');    // add immediate+RegS              90*r
 addfroms('ADDMII', 'ii');   // add mem + immediate            102
 addfroms('ADDMIS', 'is');   // add mem,immediate              138
 addfroms('ADDMID', 'id');   // add mem + immediate double     152*fz

*n = не работи, води до грешка v1e_not_supported
*fz вдига флаг "v1fl_izero", тоест "if_zero" ще работи
*fe вдига флаг "v1fl_sempt", тоест "if_empty" ще работи
*r в този случай резултатът остава в регистър, тоест не в първи операнд.
_________________________________________________________________

jmp преход
Синтаксис: jmp o
Действие : Това е безусловен преход.

Пример : /Извадка от кода на групов менажер - виж последната линия "jmp @cycle" /
@cycle
msg
jmf  @check_msg,if_message_received
sys  v1sq_get_time_tick
mov  tick,i
sub  i,lasttick
cmp  stepinterval,i
jmf  @cycle,if_bigger
mov  lasttick,tick
mov  i,ctxtype_chart
sys  v1sq_stepctx
mov  numusers,i
cmp  i,0
jmf  @no_action,if_equal
jmp  @cycle
Коментар :
-- Операндът о трябва да е точна разлика между адреса на желаната и текущата команда.
-- Компилаторът автоматично изчислява операнда. Програмистът трябва да посочи мястото в кода като етикет,
-- тоест както е в примера @cycle. Етикетът може да е по-нагоре или по-надолу от текущата линия.
Микроверсии :
 addfroms('JMPI_I', 'i');    // jump immediate                  61
 addfroms('JMPM_I', 'i');    // jump memory                     62*n
 addfroms('JMPV_I', 'i');    // jump ptr                        63*n

*n = не работи, води до грешка v1e_not_supported
_________________________________________________________________

jmz преход при условие I=0
Синтаксис: jmz o
Действие : Това е условен преход, тоест той ще работи, ако регистър I има нулево съдържание.

Пример : /Извадка от кода на O-програмата - виж линия "jmz @callsocketsend" /
...
@callsocketsend
mov  i,ic_sendbacktcp
inp  0
jmz  @callsocketsend
mov  i,ic_settcprecvbuf
inp  ibuf
mov  outsize,0
...
Коментар :
-- Операндът о трябва да е точна разлика между адреса на желаната и текущата команда.
-- Компилаторът автоматично изчислява операнда. Програмистът трябва да посочи мястото в кода като етикет,
-- тоест както е в примера @callsocketsend. Етикетът може да е по-нагоре или по-надолу от текущата линия.
Микроверсии :
 addfroms('JMZI_I', 'i');    // jump relative if RegI is not 0 imm    64
 addfroms('JMZM_I', 'i');    // jump memory                     65*n
 addfroms('JMZV_I', 'i');    // jump pointer                    66*n

*n = не работи, води до грешка v1e_not_supported
_________________________________________________________________

jmf преход към о1 при условие о2
Синтаксис: jmf o1,o2
И двата операнда са преки стойности в кода.
Действие : Това е условен преход, тоест той ще работи, ако FLAG AND O2 дава ненулев резултат.

Пример : /Извадка от кода на програмата WMSG.RVA - виж линия "jmf @wmsg_cycle,if_equal" /
...
CODE
LABEL @f1_main
cmp  ready_state,1
jmf  @wmsg_cycle,if_equal
mov  entry_line,s
...
@wmsg_cycle
msg
mov  sender_pid,i
...
Коментар1 :
-- Операндът о1 трябва да е точна разлика между адреса на желаната и текущата команда.
-- Компилаторът автоматично изчислява първия операнд. Програмистът трябва да посочи мястото в кода като етикет,
-- тоест както е в примера @wmsg_cycle. Етикетът може да е по-нагоре или по-надолу от текущата линия.
Коментар2 :
За по-лесно избиране на вторият операнд, в сорса на IF_CONSTANTS.RVA са дефинирани следните константи:
if_zero =1; //нулев резултат, някои версии на add, mov, sub и др. го включват
if_equal =2; //равенство, командите cmp spo reg и др. го включват
if_bigger =4; //по-голямо, команди cmp и др. го включват
if_big_or_equal =6; //по-голямо или равно, команди cmp reg и др. го включват
if_differ =128; //различно, команди cmp reg и др. го включват
if_tcp_received =16; //пристигнал е TCP пакет, команда inp и др. го включват
if_message_received =32; //пристигнало е съобщение, команди msg, pms и др. го включват
if_empty =64; //празен стринг, някои версии на add, mov и др. го включват
if_overflow =8; //препълване, някои версии на числени add, sub, mul, div и др. го включват

Микроверсии :
 addfroms('JMFIII', 'ii');   // jump rel if (flag and i2)<>0 ii 67
 addfroms('JMFIMI', 'ii');   // jump imm mem                    68*n
 addfroms('JMFIVI', 'ii');   // jump imm ptr                    69*n

*n = не работи, води до грешка v1e_not_supported
_________________________________________________________________

clf установява регистър флаг
Синтаксис: clf o
Действие : Регистър F ще приеме стойността на операнда o.

Пример :
clf 0

Микроверсии :
 addfroms('CLFI_I', 'i');    // flag=o im                       70
 addfroms('CLFM_I', 'i');    // mem                             71
 addfroms('CLFV_I', 'i');    // ptr                             72*n

*n = не работи, води до грешка v1e_not_supported
_________________________________________________________________

msp изпраща съобщение на процеса посочен от o
Синтаксис: msp o
Действие : Регистър S ще бъде изпратен на процеса, чийто номер е посочен в o (ако има такъв процес).

Пример :
...
mov s,atoo_close_sender_window
msp parrent_osid
...

Микроверсии :
 addfroms('MSPI_I', 'I');    // put a message-immediste number  73
 addfroms('MSPM_I', 'I');    // put a message-memory            74
Коментар :
Всяка работеща програма във V-процесора заема [място подобно на коловоз с] номер, наричан тук идентификатор на процеса.
Така, че в един момент не може да има два процеса с еднакъв идентификатор. Процесът може да научи своя идентификатор чрез запитване sys v1sq_process_id_by_name (виж команда sys). При получаване на съобщение, в регистър I идва идентификатор на прекия изпращач на съобщението.
Ако процесът посочен в операнда не съществува, регистър I връща -1, иначе регистър I връща числото o.
_________________________________________________________________

msg вземи най-старото съобщение
Синтаксис: msg
Действие : В регистър S ще бъде получено най-старото съобщение от опашката.
-- После съобщението ще бъде премахнато от опашката.
-- В регистър I идва идентификато на процеса, който е изпратил съобщението.
Пример :
...
msg
mov sender_pid,i
cmp s,'COMMAND1'
jmf @exec_command1,if_equal
...

Микроверсии :
 addfroms('MSG___', '');     // get a message                   75
Коментар :
Всяка работеща програма във V-процесора заема [място подобно на коловоз с] номер, наричан тук идентификатор на процеса.
Така, че в един момент не може да има два процеса с еднакъв идентификатор. Процесът може да научи своя идентификатор чрез запитване sys v1sq_process_id_by_name (виж команда sys).
_________________________________________________________________

idl остани в бездейно състояние
Синтаксис: idl
Действие : Изпълнението на програмата спира. Тя ще бъде рестартирана ако в опашката има съобщение.

Пример :
...
@exec_command1
jsu @init_out_pointers
jsu @add_window_command
jsu @send_buffer_to_terminal
idl
...

Микроверсии :
 addfroms('IDL___', '');     // set idle                        76
Коментар :
Когато програмата е възбудена от съобщение, тя изпълнява съответната команда и остава в бездейно състояние, очаквайки ново съобщение. Грижа на програмиста е процеса винаги да завършва с команда idl.

_________________________________________________________________

die изключи програмата
Синтаксис: die
Действие : Изпълнението на програмата спира. Статуса се установява в v1st_dead. Тя ще бъде унищожена и ще освободи паметта.

Пример :
...
@exec_end_program
jsu @init_out_pointers
jsu @add_clear_window_command
jsu @send_buffer_to_terminal
die
...

Микроверсии :
 addfroms('DIE___', '');     // die                             77
Коментар :
Заедно с изключването на програмата ще бъдат освободени всички порции памет, които тя е заела с gme. Кода ще бъде унищожен, ако променливата level в процеса е нулева. Само онези програми, които се зареждат при старта на V-машината имат ненулев level при изпълнение. Променливата level се ползува за да означи, че два или повече процеси ползуват един и същ програмен код.
_________________________________________________________________

CMP сравни двата операнда
Синтаксис: cmp o1 o2
Действие : Сравняват се двата операнда o1 и O2.
Резултатът от сравнението остава в регистър FLAG.

Пример :
...
cmp s,'CMD1'
jmf @exec_cmd1,if_equal
cmp s,'CMD2'
jmf @exec_cmd2,if_equal
...

Микроверсии :
 {стрингови}
 addfroms('CMPRIS', 's');    // cmp RegS + immediate string     78*fb*fe*fd*fbe
 addfroms('CMPRMS', 'i');    // cmp RegS + mem                  79*fb*fe*fd*fbe
 addfroms('CMPRVS', 'i');    // cmp RegS + ptr                  80*n
 addfroms('CMPMMS', 'ii');   // cmp mem + mem                   81*fb*fe*fd*fbe
 addfroms('CMPVMS', 'ii');   // cmp mem + ptr                   82*n
 addfroms('CMPVVS', 'ii');   // cmp ptr + ptr                   83*n

 {по-късно добавени}
 addfroms('CMPMII', 'ii');   // cmp mem + immediate            101*fb*fe*fd*fbe
 addfroms('CMPRII', 'i');    // cmp regi=immediate             105*fb*fe*fd*fbe
 addfroms('CMPMMI', 'ii');   // cmp mem=mem                    106*fb*fe*fd*fbe
 addfroms('CMPMIS', 'is');   // cmp mem=imm                    111*fb*fe*fd*fbe
 addfroms('CMPRMI', 'i');    // cmp RegS + mem                 119*fb*fe*fd*fbe
 addfroms('CMPVMI', 'ii');   // cmp ptr=memi                   123*fb*fe*fd*fbe
 addfroms('CMPIRI', 'i');    // cmp immediate - regI           144*fb*fe*fd*fbe
 addfroms('CMPRID', 'rd');   // cmp regd - immediate           149*fb*fe*fd*fbe
 addfroms('CMPIRS', 's');    // cmp immediare RegS             156*fb*fe*fd*fbe
 addfroms('CMPMRI', 'ii');   // cmp mem RegI                   157*fb*fe*fd*fbe
 addfroms('CMPIMI', 'ii');   // cmp imm + mem                  158*fb*fe*fd*fbe
 addfroms('CMPVII', 'ii');   // cmp ptr^=immediate             160*fb*fe*fd*fbe


*fb if_bigger ще работи
*fe if_equal ще работи
*fd if_differ ще работи
*fbe if_big_or_equal ще работи
*n не работи, грешка v1e_not_supported
Коментар :
Сравненията обикновено се ползуват непосредствено преди команда за условен преход. (jmf - виж по-горе)
_________________________________________________________________

jsu преход към подпрограма
ret връщане от подпрограма
Синтаксис:
jsu o
ret o
Действие : При команда jsu Процесорът записва указателя на кода в стека
-- и прескача към подпрограма, посочена от операнда o.
-- При команда ret процесорът ще издърпа от стека записания адрес и ще се върне,
-- за да продължи изпълнението от следващата линия.

Пример : /участък от CONFIRM.RVA - виж линията "jsu @add_a_command"/
...
//================ subroutines =========================
@add_list
cmp  listmode,0
jmf  @exit_build_list,if_equal
mov  listbox_cmd_wid,edit_rect_ident
mov  s,listbox_cmd_cmline
str  soc_getlength
add  i,41
mvm  s,listbox_cmd_num,S
jsu  @add_a_command
@exit_build_list
ret
...

@add_a_command
put  s,254
mov  aux_point,p2
mov  s,'0000'
jsu  @insert_string_aux
pop  s,254
jsu  @insert_string_aux
mov  [aux_point],i
add  outsize,i
add  outsize,4
ret
...
Микроверсии :
 addfroms('JSUI_I',  'i');   // jump to a subroutine            84
 addfroms('RET___',  '');    // return from subroutine          85
Коментар :
-- Компилаторът автоматично изчислява операнда за преход. Програмистът трябва само да посочи мястото в кода като етикет,
-- тоест както е в примера @callsocketsend. Етикетът може да е по-нагоре или по-надолу от текущата линия.
-- Програмите изобилствуват от команди за подпреход. Грижа на програмиста е всеки от подпреходите
-- действително да завършва с команда ret за обратно връщане.
_________________________________________________________________

str команда за превръщане към/от стринговия регистър
Синтаксис: str o
Действие : Операнда е константа - пряко указание.
може да има следните стойности: /Дефинициите се намират в сорса на CONSTANTS_SOC.RVA/
soc_getlength връща дължината на S в I;
soc_getsubstr връща подстринг S=copy(S,I,round(D));
soc_wordnum връща дума номер i от S :S=wordn(S,i);
soc_UpCase връща s от главни букви;
soc_LoCase връща s от малки букви;
soc_Clip връща s без водещи и последни интервали;
soc_ClipLeft връща s без водещи интервали;
soc_ClipRight връща s без последни интервали;
soc_tointeger връща в I числото написано като стринг в S;
soc_todouble превръща S в дробно число, и го връща в D;
soc_frominteger превръща I в текстово число и го връща в S;
soc_fromdouble превръща D в текстово число с I-дестични знаци и го връща в S;
soc_ord превръща I-тата буква от S в ANSI код и го връща в I;
soc_chr превръща I в символ с ANSI код I;
soc_monoline връща в S линия от I символа с номер round(D);
soc_addcleft прибавя отляво към S буква номер I;
soc_addcright прибавя отдясно към S буква номер I;
soc_isnumber връща 1 в I, ако в S има число;
soc_toright връща RightPart(S,I);
soc_fileexists връща 1 ако в S е записан съществуващ файл или нула в противен случай;
soc_rendertxt регистър i трябва да сочи текстов обект. Това изпълнява команда от две букви в S;
soc_inttohex превръща i в шестнадесетичен запис (8 буквен)
soc_strfromw връща всичко от i-тата дума надясно
soc_editline регистър i трябва да сочи обект - текстова линия. Това изпълнява статуса;
soc_fnmandeonly премахва от името на файла в S цялата пътека и диск в лявата му част;
soc_reducepathnameпревръща '..\' участък в действителна пътека от името на файла в S;
soc_formatileadz превръща i в текст с допълнени от ляво нули колкото е round(D);
soc_clearname премахва от името на файла разширението (.EEE)
soc_basename връща име на таблица в S
soc_formatname връща име на форматен файл за таблица в S
soc_fromfile ако има файл с име S, връща първата текстова линия от файла;
soc_preparehjmp подготвя скок към диспечер - разпределител на команди;
soc_forseext залепва към S посочено разширение;
soc_programstate връща състояние на програмата в S
soc_getprevpath връща предпоследната пътека на файла от S;
soc_getpathonly връща пътеката на файла от S;
soc_validsavenameвръща 1 ако файла от S е с валидно име за запис;
soc_substitute замества означенията %WPATH% ,%UPATH%, %UP%, %OP%, %WP% с работните пътеки
soc_extracttlinesизвежда от текстов обект страница
soc_compilerva компилира RVA сорс в посочен текстов обект
soc_toclipfile записва S в текстов файл предназначен за клипборд-copy операция
soc_tomoneystr форматира числото от D като паричен стринг
soc_encodespaces кодира интервалите с ANSI символ 4
soc_decodespaces декодира интервалите с ANSI символ 4

Пример : /участък от CONFIRM.RVA - виж линията "str soc_getlength"/
...
//================ subroutines =========================
@add_list
cmp  listmode,0
jmf  @exit_build_list,if_equal
mov  listbox_cmd_wid,edit_rect_ident
mov  s,listbox_cmd_cmline
str  soc_getlength
add  i,41
mvm  s,listbox_cmd_num,S
jsu  @add_a_command
@exit_build_list
ret
...
Микроверсии :
 addfroms('STRI_I',  'i');   // string operation immediate code 86
Коментар :
Рендването на текстови обекти и линии е специална операция. Необходимо е съгласуване на дефинициите в RVA-сорса с тези от V-сървъра и терминала.
_________________________________________________________________

spo позиция на подстринг
Синтаксис: spo o1,o2
Действие : ако думата o1 се среща в o2, в Регистър I се връща позицията.

Пример : /участък от E.RVA - виж линията "spo 'PLAYER',s"/
...
mov  s,itm_command_str
spo  'PLAYER',s
jmf  @work_group_cmd,if_equal
spo  'VSCR',s
jmf  @set_vscroll_position,if_equal
spo  'HSCR',s
jmf  @set_hscroll_position,if_equal
spo  'DT',s
jmf  @set_drag_position,if_equal
spo  'SEARCHTEXT',s
jmf  @launch_textsearch_dialog,if_equal
...
Микроверсии :
 addfroms('SPORIS',  's');   // RegI=pos (immediate str,RegS)  87*fe
 addfroms('SPOIRS',  's');   // RegI=pos (immediate str,RegS)  88*fe
 addfroms('SPORMS',  'ii');  // RegI=pos (memory str,RegS)     89*fz

*fe ако позицията е 1, if_equal ще работи
*fz ако позицията е 0, if_zero ще работи
Коментар :
първоначално разчитах само на съдържанието на регистър I, тоест на поредица от типа:
...
@check_msg
spo 'EXITCHART',s
cmp i,1
jmf @exit_chart,if_equal
spo 'ENTERCHART',s
cmp i,1
jmf @enter_chart,if_equal
...

В последствие реших, че ако наредя флаг if_equal да се вдига за първа позиция, е по-удобно и така остана.

_________________________________________________________________

gme заемане на памет
fme освобождаване на памет

Синтаксис: gme o1,o2
Синтаксис: fme o1

Действие gme: в първия операнд ще се върне адреса на зает нов участък памет с размер o2.
Действие fme: паметта заета от o1 ще бъде освободена.

Пример : /участък от E.RVA - виж линията "gme ubuf,ubsize"/
...
MAIN
cmp  ready_state,1
jmf  @cycle,if_equal
gme  ubuf,ubsize
...
Микроверсии :
 addfroms('GMEMII', 'ii');   // get memory                      91
 addfroms('FMEM_I', 'i');    // free memory                     92
Коментар :
Паметта се брои локално от указателя за този екземпляр на програмата.
Ако програмата не освободи заета памет, това ще стане автоматично при изключване на тази програма.

_________________________________________________________________

put пъхни в стека данни
pop извади от стека данни

Синтаксис: put o1,o2
Синтаксис: pop o1,o2

Действие put: в стека ще бъде поставена порция данни от o1 с размер o2.
Действие pop: от стека ще бъде изтеглена порция данни в o1 с размер o2.

Пример : /участък от G.RVA - виж линията "put/pop notify_cmd_num,150"/
...
@asquire_startplayer_data
mov  i,12
mov  d,150.0
str  soc_getsubstr 
put  notify_cmd_num,150
mvm  notify_cmd_num,s
mov  startplayertype,notify_rect_kind
mov  startplayerwid,notify_cmd_id
mov  incomingplayertext,notify_cmd_rest
pop  notify_cmd_num,150
cmp  startplayertype,v1gutp_baloon
jmf  @send_baloontext_to_terminal,if_equal
cmp  startplayertype,v1gutp_clubman
jmf  @check_man_name,if_equal
ret
...
Микроверсии :
 addfroms('PUTMII', 'ii');   // push into the stack mem,imm     93
 addfroms('POPMII', 'ii');   // pop from the stack mem,imm      94
Коментар :
Грижа на програмиста е да остави стека в начално състояние.
Размера на стековата памет се определя с клауза "STACK 2000" в началото на програмата.

_________________________________________________________________

exe стартирай RVM програма

Синтаксис: exe o1,o2

Действие : o1 трябва да е името на програмата, o2 трябва да е работната директория.
-- В зависимост от съдържанието на регистър I програмата ще бъде стартирана по следните начини:
ако I е четно число, програмата ще бъде стартирана като копие на вече работеща програма с level 1 или повече;
ако I е нечетно число, кода на програмата ще бъде прочетен от диска;
ако (I AND 2) е ненулево, процесът ще бъде модално свързан с викащият процес.
-- в този случай викащата програма ще спре напълно действието си и ще чака (v1st_wait),
-- докато дъщерната програма не приключи.

Пример : /участък от SNDR.RVA - виж линията "exe uploadcmd,''"/
...
@cansendit
mov  uploadcmd,uploadprogramname
mov  i,this_process_pid
str  soc_frominteger
add  s,filetypestr
add  s,bagfilename
add  s,voption
str  soc_upcase
mov  d,1.0
mov  i,2
exe  uploadcmd,''
mov  s,bagfilename
dsk  dsk_deletefile
ret
...
Микроверсии :
 addfroms('EXEMIS', 'is');   // execute another program         95
 addfroms('EXEMMS', 'ii');   // execute mem                    120
 addfroms('EXEIIS', 'ss');   // imm imm                        163
 addfroms('EXEIMS', 'ss');   // imm mem                        164
Коментар :
I=0 се ползува за старт на кеширани процеси.
I=1 осигурява нормален старт на програмата от диска при свободен режим.
I=2 се ползува за модален (тоест сляп за викащата програма) кеширан старт.
I=3 се ползува за модален файлов старт.
I=4 се ползува за свободен (тоест прозрачен за викащата програма) файлов дъщерен старт.
I=5 се ползува за свободен кеширан дъщерен старт.
I=251 се ползува за старт на O-програмата.

_________________________________________________________________

sys команда към системата

Синтаксис: sys o

Действие : o трябва да е константа. Може да има следните стойности /CONSTANTS_V1SQ.RVA/ :
v1sq_jumptodispatcher скок към подготвена преходна точка
v1sq_getprogramlevel връща в I променливата level на програмата
v1sq_process_id_by_name връща в I идентификатора на процес (наричан по-долу pid), с име на програмата зададено в S.
Ако S е празен стринг, връща идентификатор на текущия процес.
В противен случай процесите се изследват от края към началото и се връща най-големия номер,
чието програмно име съвпада със зададеното в S.
v1sq_get_intvar_from_id връща в I целочислена променлива посочена в round(D) от друг процес чийто идентификатор е зададен в I.
v1sq_get_intptr_from_id както по-горното, но връща указател вместо пряка променлива
v1sq_set_user_name установява име на юзера, каквото е посочено в S. Само О-програмата прави това.
v1sq_set_user_ctx обявява контекст (посочен в регистър S) предназначен за участие в група.
v1sq_get_user_name връща в S текущото име на юзера.
v1sq_get_all_process_numвръща в I най-големия номер на работещ процес плюс 1.
v1sq_get_process_type връща в I типа на посочения процес. Ако е мъртъв, връща -1. Ако процесът е на друг юзер,
В регистър D се връща 1.0; Ако процесът е модален дъщерен, в регистър D се връща 2.0
v1sq_get_program_state връща в I програмния статус на посочен процес от I (или -1, ако няма такъв)
v1sq_get_programname_by_pidвръща в S името на програмата, чийто процес е посочен в I.
Регистър D връща 1.0 при друг юзер и 2.0 при дъщерен процес.
v1sq_pid_by_program_ctx връща идентификатор на следващия (всъщност ОТ посочения в I включително) процес,
чийто контекст отговаря на е посоченото в S. Ако няма повече такива процеси,
регистър Flag връща v1sq_equal иначе Flag се установява в v1sq_bigge.
v1sq_getchartnameвръща в S името на картата, определена от регистър I. Регистър I трабва да е индекс на картовия групов управител (cid);
v1sq_ctxindexbyctxnameвръща в I индекс на групов управител по посочен контекст в S.
v1sq_get_time_tickвръща в I текущата милисекунда (tick)
v1sq_getprocesscountвръща в I брой на процесите за текущия юзер с посоченото име на програма в S
v1sq_stepctxKоманда към групов контекст за стъпка във времето.
Само програмите - управители на група трябва да правят това. Ако регистър I е нула,
всички контексти ще направят стъпка. Ако I е нула, ще задействува само контекста
съответен на записаното в регистър S.
v1sq_addctxОбявява нова контекстна група зададена в S. Само програмите управляващи група трябва да правят това.
v1sq_donectxУнищожава контекстна група зададена в S. Само програмите управляващи група трябва да правят това.
v1sq_addunitСъздава нова контекстна единица.
Това се прави от програмите управляващи регламентирани даннови обекти - текстове, таблици, карти.
v1sq_signalregionПроменен е зададен картов регион. Груповата машинка реагира на това като сигнализира
участниците наблюдаващи този регион, да обновят образа.
v1sq_getuserhomepositionВръща в S записаната в юзерския регистър домашна точка като "X Y SIZE CTXINDEX"
v1sq_getuserchartfileВръща в S името на картовия файл, съответен на домашния регион за юзера посочен в S.
Flag връща v1fl_equal или v1fl_diffe, при успех/неуспех да бъде намерен файла.
v1sq_getchartobjectownerВръща в S името на юзера, който е собственик на картов обект с име посочено в S.
v1sq_removeunitПремахва контекстна единица посочена в S. Това го правят програмите за таблици, текстове, карти.
v1sq_get_user_sessionВръща в S сесията на юзера посочен в S.
v1sq_remove_user_sessionПремахва сесията на текущия юзер.
v1sq_setunitwalkstateПренастройва подвижен обект върху картата.
v1sq_set_program_velocityСкорост на програмата. В регистър I трябва да е зададена новата скорост, а в регистър D-стъпка.
v1sq_get_program_velocityВръща текущата скорост на програмата в I
v1sq_getosnameВръща името на О-програмата в регистър S
v1sq_set_netwait_stateУстановява режим на сокета "listen" и бездеен-очакващ връзка статус. Само О-програмата прави това и то ако няма свързани терминали.
v1sq_process_uid_by_pidВръща в I текущия UID на програмата. За разлика от обикновения идентификатор PID на процеса,
UID е уникален до изключването на V-сървъра.
v1sq_process_pid_by_uidВръща в I PID по посочен UID (виж по-горе).
v1sq_getworkpathВръща в S работната пътека на програмата.
v1sq_setworkpathУстановява работна пътека зададена в S.
v1sq_getv1portВръща порта на текущия TCP-сокет.
v1sq_uncompress_inputДекомпресира участък посочен от I-регистъра.
v1sq_recentprogramРабота с програмния списък.
О-програмата поддържа в списъка си всички следващи, тоест първо ниво на юзерското дърво от процеси.
Съпътствуващата DESK.RVA се ползува от това дърво за да докладва в терминала статуса на работещите програми. По аналогичен начин и други програми се ползуват от този списък.
В зависимост от регистър D действията са:
dcmd_addrecentprogramДобавя програма посочена в S
dcmd_deletelastrecentИзтрива последната в списъка
dcmd_buildtasklistПодготвя списък работещи за DESK.RVM
dcmd_deleterecentpidИзтрива посочената от I
dcmd_buildprocesslistПодготвя списък работещи за TASK-менажера
dcmd_setdebugpauseПауза за посочена програма
dcmd_setdebugreleaseПусни задържаната с горната команда
dcmd_setdebugstepinСтъпка за паузираната програма - навътре
dcmd_setdebugstepoverСтъпка за паузираната програма - с прескок
dcmd_setdebugstoponlineСпри на зададена програмна линия
dcmd_initvarmemorylistСъздава списък променливи
dcmd_buildvarmemorylistПопълва списъка с променливи
dcmd_builddirlistПрави списък директории за юзера.
dcmd_buildfilelistПрави списък файлове за юзера.
dcmd_finddirectoryindexВръща индекса на дадена директория
dcmd_addrecentvalueДобавя линия в списъка
dcmd_buildrecentlistСъставя списък удобен за изпращане към терминала
dcmd_getrecentvalueВръща по индекс в I линия от списъка
dcmd_readrecentlistПрочита списъка от файл посочен от S
dcmd_writerecentlistЗаписва списъка във файл посочен от S
dcmd_deleterecentПремахва посочена от S линия
dcmd_getindexvalueВръща линия с индекс I (в обратен ред)
dcmd_copyrecentlistКопира списъка от програма с посочен PID в I
v1sq_workwithusertreeРабота с юзерското дърво. В зависимост от съдържанието на I
ut_option_messagetoall - изпраща съобщение (от регистър S) към всички останали
ut_option_countalive - преброява колко работещи процеса има
ut_option_killprocess - изпраща на процесите съобщение otoa_killprocess_cmd
v1sq_process_type_by_uidВръща тип на процеса намерен по UID в регистър I
v1sq_process_name_by_pidВръща името на процеса чийто пид е зададен в I
v1sq_gettickcountВръща брояча в V-процесора.
v1sq_getservernameВръща името на V-сървъра.
v1sq_getserverversionВръща версията на V-сървъра.
v1sq_renewserverОбновява програмата на сървъра.
v1sq_setunitconstrainregionВключва ограничения в движението на обект върху карта.
v1sq_finduserinctxНамира индекса на юзер с име S в контекста (флаговия регистър трябва да е CID)
v1sq_check_aliveНа всеки 10 бездейни секунди терминалът трябва да изпраща към сървъра TCP съобщение "KEEPALIVE".
Ако дълго време О-програмата не е получила вест от терминала, се самоизключва с тази опция.
Иначе тя работи непрекъснато, докато юзера е свързан. С други думи О-програмата ползува тази команда за да изключи юзера при дълго бездействие.
След изпълнението, ако бездействието на приемника е превишило лимита (около 50 секунди), регистър Флаг връща v1fl_bigge + v1fl_diffe, Тоест if_differ ще работи.

Пример : /участък от G.RVA - виж линията "sys v1sq_getuserhomeposition"/
...
@obtain_homeregion
mov  s,''
mov  i,0
mov  d,0.0
sys  v1sq_getuserhomeposition
mov  userhomeline,s
ret
...
Микроверсии :
 addfroms('SYSI_I', 'i');    // ask a question                  97
Коментар :

_________________________________________________________________

mvm пренос на данни

Синтаксис: mvm o1,o2

Действие : От o1 се пренасят данни към o2, най-често колкото е числото в регистър I.
-- Но при стрингове може е друго - виж микроверсиите по-долу

Пример : /участък от G.RVA - виж линията "mvm shiftpressed,[os_ptr_shiftstate]"/
...
@asquire_shiftstate
mov  i,os_shiftstate_address
mov  d,i
mov  i,parrent_osid
sys  v1sq_get_intptr_from_id
mov  os_ptr_shiftstate,i
mov  i,8
mvm  shiftpressed,[os_ptr_shiftstate]
ret
...
Микроверсии :
 addfroms('MVMMMI', 'ii');   // copy mem <- mem                103*li
 addfroms('MVMVVI', 'ii');   // copy ptr <- ptr                104*li

 addfroms('MVMMVI', 'ii');   // cmp mem <- ptr                 107*li
 addfroms('MVMVMI', 'ii');   // cmp ptr <- mem                 108*li

 addfroms('MVMRMS', 'i');    // move regs <- mem, length=regi  114*lis1
 addfroms('MVMMRS', 'i');    // move mem <- regs, length(regs) 115*s1
 addfroms('MVMVRS', 'i');    // move ptr <- regs, length(regs) 116*s1

 addfroms('MVMRVS', 'i');    // move reg <-ptr, length(regs)   121*lis1

 addfroms('MVMRMI', 'ri');  // move regd <- mem, length=regi   132*li
 addfroms('MVMMRD', 'ir');  // move mem <-regd, length=regi    133*li

*li дължината на преноса идва от регистър I
*lis1 дължината на преноса е в I, но не повече от 254 и данните се настаняват от първата буква на S надясно
*s1 дължината на преноса е колкото дължината на стринга; преноса започва от първата буква на S надясно
Коментар :

_________________________________________________________________

reg питане за принадлежност в интервал

Синтаксис: reg o1,o2

Действие : Питане дали съдържанието на I е по-голямо или равно на o1 и е по-малко от o2.
-- Резултатът остава в регистър FLAG

Пример :
...
mov i, xcoord
reg x1, x2
jmf @inside, if_equal
...

Микроверсии :
 addfroms('REGMMI', 'ii');   // cmp mem <- mem                 109
Коментар :
Ако I>=o1 AND I<o2 се вдига флаг v1fl_equal тоест if_equal ще работи
иначе се вдигат флагове v1fl_izero OR v1fl_diffe, тоест if_zero и if_differ ще работят
ако I>o2 се добавя флаг v1fl_bigge тоест if_bigger ще работи

_________________________________________________________________

sub изваждане

Синтаксис: sub o1,o2

Действие : изважда от o1 o2. Резултатът остава в о1.

Пример :
...
mov i, xcoord
sub i,8
cmp i,upperlimit jmf @over, if_bigger
...

Микроверсии :
 addfroms('SUBMMI', 'ii');   // sub mem mem                    110*fz
 addfroms('SUBMRI', 'i');    // sub m-regi                     112*fz
 addfroms('SUBMII', 'ii');   // sub m-imm                      113*fz
 addfroms('SUBRII', 'ii');   // sub reg-imm                    136
 addfroms('SUBVMI', 'ii');   // sub ptr-mem                    141*fz
 addfroms('SUBRMI', 'ri');   // sub reg-mem                    142*fz
 addfroms('SUBMID', 'id');   // sub mem + immediate double     153*fz
 addfroms('SUBMMD', 'ii');   // sub mem + immediate double     154*fz

*fz вдига флаг v1fl_izero, тоест if_zero ще работи

Коментар :

_________________________________________________________________

pme изтегля съобщение без да го изтрива

Синтаксис: pme

Действие : изважда съобщението без да го премахва от опашката.

Пример : Откъс от E.RVM - виж линията "pme" в началото
@cp_alive
pme
cmp  i,child_pid
jmf  @c_have_msg,if_equal
cmp  s,'0002'
jmf  @unfocus_child_tree,if_equal
cmp  s,'0003'
jmf  @focus_child_tree,if_equal
cmp  s,'0004'
jmf  @end_child_tree,if_equal
spo  '0008 0000PLAYER',s
cmp  i,1
jmf  @get_group_cmd,if_equal
@translate_to_child
msg
msp  child_pid
idl

Микроверсии :
 addfroms('PME___', '');    // peek a message                  124
Коментар :
Следващата команда msg ще изтегли (но и ще изтрие) същото съобщение.
_________________________________________________________________

pur записва регистър в стека
por изтегля регситър от стека

Синтаксис: pur o / por o

Действие : записва посочения регистър в стека, или го прочита оттам.

Пример : Откъс от E.RVM - виж линията "pur s" и "por s"
@doopenfile
pur  s
cmp  textfilename,''
jmf  @dontsaverecent,if_equal
jsu  @save_recentname
@dontsaverecent
por  s
mov  i,2
str  soc_strfromw
jsu  @sub_openfile
jmp  @end_tmmsg_cycle

Микроверсии :
 addfroms('PURR_I', 'r');   // push into the stack reg         125
 addfroms('PORR_I', 'r');   // pop from the stack reg          126
 addfroms('PURR_D', 'r');   // push into the stack reg         127
 addfroms('PORR_D', 'r');   // pop from the stack reg          128
 addfroms('PURR_S', 'r');   // push into the stack reg         129
 addfroms('PORR_S', 'r');   // pop from the stack reg          130
Коментар :
Размерът на стека се управлява с клауза "STACK 3400" в началото на програмата.
_________________________________________________________________

dsk команда за дискова операция

Синтаксис: dsk o

Действие : o трябва да е константа. Може да има следните стойности /CONSTANTS_DSK.RVA/ :
dsk_getfilesizeвръща размера на файл - BuildUserFileName(в регистър S е името на файла)
dsk_savefileзаписва файл - BuildUserFileName(в регистър S е името на файла)
Регистър I трябва да сочи данните; Размера се прочита като цяло число от първите четири байта на Регистър D; ето пример за запис на файл (откъс от EDITLINE.RVA)
VARI
 ...
 eline_container      ''
 eline_cont_ptr       ^eline_container
 ...
CODE
...
@saveresultondisk
cmp  textfilename,''
jmf  @exitsaveresult,if_equal
mov  s,eline_container
str  soc_getlength
mov  textfilesize,i
mov  d,0.0
mov  i,4
mvm  d,textfilesize
mov  s,textfilename
add  '__',s
mov  i,eline_cont_ptr
add  i,1
dsk  dsk_savefile
@exitsaveresult
ret
...
dsk_loadfileзарежда файл - BuildUserFileName(регистър S е име на файла)
Регистър I трябва да сочи данните. В първите 4 байта на Регистър D е размера на буфера за данни в целочислен вид. На изхода регистър I връща код за грешка. Ето пример за ползуване: (откъс от RECENTUTILS.RVA):
VARI
...
 isfilesze                 0
 saved_wx1                 0
 saved_wy1                 0
 saved_wdx                 0
 saved_wdy                 0
 ...
 windowstate_ptr           ^saved_wx1
 initstate_filename        'MAINWINDOWSTATE.DAT'
...
CODE
...
@read_windowstate
mov  isfilesze,24
mov  i,4
mvm  d,isfilesze
mov  i,windowstate_ptr
mov  s,'APP\'
add  s,workpath
add  s,'\'
add  s,initstate_filename
dsk  dsk_loadfile
cmp  i,0
jmf  @exit_read_wstate,if_differ
mov  window_start_centered,0
....
dsk_direxistsАко няма пътека - BuildUserFileName(регистър S) вдига флаг vqfl_izero
dsk_fileexistsАко няма файл - BuildUserFileName(регистър S) вдига флаг vqfl_izero
dsk_loadtextзарежда текстов обект от стандартен текстов файл - BuildUserFileName(регистър S)
dsk_readfilebufчете данни в буфер - BuildUserFileName(name= wordn(S,2))
dsk_tableработи с таблица посочена от I като обект /ProcessTable/
На вход регистър Флаг трябва да има една от следните стойности-константи /CONSTANTS_DSK.RVA/
ttc_buildtableimageСтрои буфер-образ в терминала
ttc_findfctorightНамира първата видима колона от таблицата, достатъчна за да се види текущата клетка
ttc_putrcinwindowНаглася прозореца около маркера
ttc_execb4commandСтартира Б4-команда
ttc_setoptionВключва таблична опция на видимост
ttc_getoptionПрочита таблична опция на видимост
ttc_statetostringПрави стринг за запис на видимия статуса в recent-таблица
ttc_stringtostateПрочита видимия статус от стринг в recent-таблица
ttc_putrcintableКоригира текущата клетка от таблицата
ttc_getlockrcstateПита заключена ли е текущата клетка
ttc_writecurrentcellЗаписва текущата клетка на диска
ttc_findnomenclinkНамира номенклатурна връзка в текущата клетка
ttc_putblockintableКоригира текущия блок
ttc_getcellwidthПита каква е ширината на текущата клетка
ttc_extractprintpageИзвлича страница за печат
ttc_refreshtablecellПрочита текущата клетка от таблицата
dsk_tableexistsТърси табличен файл с име S и връща FLAG=v1fl_equal/v1fl_diffe
dsk_loadtextfastзарежда текстов обект файл - BuildUserFileName(регистър S)
dsk_regstofileСъздава празен файл с име посочено от S
dsk_buildchartСтрои карта около текущия подвижен обект
dsk_createchartobjectСъздава обект на картата
dsk_deletefileИзтрива файл - BuildUserFileName(регистър S)

Пример : /участък от T.RVA - виж линията "dsk dsk_table"/
...
@set_cursor_in_window
mov  i,obufsize
mov  d,i
mov  i,table_head_ptr
mov  s,table_name
clf  ttc_putrcinwindow
dsk  dsk_table
ret
...
Микроверсии :
 addfroms('DSKI_I', 'i');   // disk oper                       131
Коментар :

_________________________________________________________________

mul умножение

Синтаксис: mul o1,o2

Действие : умножава o1 и o2. Резултатът остава в о1.

Пример : /откъс от CONFIRM.RVA/
...
@find_offsetxy //subroutine
mov offset_wx,window_count
mul offset_wx,unit_wdx
mov offset_wy,window_count
mul offset_wy,unit_wdy
ret

Микроверсии :
 addfroms('MULMMI', 'ii');  // mul mem <-mem                   134*fz
 addfroms('MULRII', 'ri');  // mul reg <-immediate             139
 addfroms('MULRMD', 'ri');  // mul regd <- memory              146*fz
 addfroms('MULRMI', 'ri');  // mul regi <- memory              148
 addfroms('MULMII', 'ii');  // mul memory <-immediate          150*fz
 addfroms('MULMMD', 'ii');  // mul mem + mem double            155*fz
 addfroms('MULRID', 'rd');  // mul reg*imm                     159*fz

*fz вдига флаг v1fl_izero, тоест if_zero ще работи

Коментар :

_________________________________________________________________

div деление

Синтаксис: div o1,o2

Действие : Разделя o1 на o2. Резултатът остава в о1.

Пример : /откъс от C.RVA/
...
@calc_eline_length
mov  i,edit_rect_dx
mov  i,btnline_cmd_x1
sub  i,15
sub  i,eline_initx
mov  eline_winlen,i
div  eline_winlen,terminal_chardx
mov  eline_maxlen,eline_winlen
ret
Микроверсии :
 addfroms('DIVMMI', 'ii');  // div mem <-mem                   135*fz
 addfroms('DIVMII', 'ii');  // div mem <-immediate             140
 addfroms('DIVRII', 'ri');  // div reg <-immediate             143*fz
 addfroms('DIVRMD', 'ri');  // div regd <- memory              147*fo

*fz вдига флаг v1fl_izero, тоест if_zero ще работи
*fo вдига флаг v1fl_iover, тоест if_over ще работи

Коментар :

_________________________________________________________________

abs абсолютна стойност

Синтаксис: abs o1,o2

Действие : Ако o1 е отрицателно, връща o2=1 и сменя знака на o1. В противен случай връща o2=0.

Пример :

abs x,xsign

Микроверсии :
 addfroms('ABSMMI', 'ii');  // abs/sign mem / mem              151


Коментар :

Valid HTML 4.01!