Login

Subversion Repositories NedoOS

Rev

Rev 2037 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

//// imported
#include "../_sdk/str.h"
#include "../_sdk/io.h"
#include "../_sdk/emit.h"

PROC asmorgword FORWARD(LONG addr);
PROC fsm FORWARD();
PROC initmemmodel FORWARD();

FUNC UINT findlabel FORWARD(PBYTE labeltext);

////
///////яхЁхьхээ√х, ёюїЁрэ хь√х т post (ёюёЄю эшх рёёхьсыхЁр т ёхЁхфшэх ёЄЁюъш):

EXTERN UINT _curlnbeg; //эюьхЁ ёЄЁюъш эр ьюьхэЄ эрўрыр Єюъхэр //фы  read, emit

VAR BYTE _token; //Єхъє∙шщ ёўшЄрээ√щ Єюъхэ
VAR BYTE _curdir; //Єюъхэ Єхъє∙хщ юсЁрсрЄ√трхьющ фшЁхъЄшт√ рёёхьсыхЁр (эєцэю фы  яЁртшы№эющ юсЁрсюЄъш ЇюЁьрЄр)

VAR BYTE _reg; //яюёыхфэшщ ЁхушёЄЁ
VAR BYTE _oldreg; //яЁхф√фє∙шщ ЁхушёЄЁ
VAR BYTE _base; //срчр ъюфр ъюьрэф√
VAR BYTE _base2; //срчр2 ъюфр ъюьрэф√ (фы  єёыютэ√ї яхЁхїюфют)

VAR BYTE _nvalues; //ўшёыю чэрўхэшщ т ёЄхъх

VAR UINT _curaddr; //рфЁхё, ъєфр яш°хь
VAR UINT _curshift; //$=(_curaddr+curshift), curshift=(disp-_curaddr)
VAR UINT _curbegin; //эрўры№э√щ рфЁхё сыюър, ъєфр яш°хь
//VAR BYTE _curpage0;
//VAR BYTE _curpage1;
//VAR BYTE _curpage2;
//VAR BYTE _curpage3;

VAR UINT _plabel_index; //яюёых findlabel ёюфхЁцшЄ єърчрЄхы№ эр эрўрыю фрээ√ї ьхЄъш
VAR UINT _curplabel_index; //тЁхьхээюх їЁрэшыш∙х _plabel_index яЁш юяЁхфхыхэшш ьхЄюъ
VAR UINT _hash;
VAR UINT _curhash; //тЁхьхээюх їЁрэшыш∙х яЁш юяЁхфхыхэшш ьхЄюъ

VAR BYTE _isaddr; //ьрёър "т т√Ёрцхэшш шёяюы№чютрыё  рфЁхё" (юсэєы хЄё  т эрўрых ъюьрэф, ъюЄюЁ√х ухэхЁ Єё  ё чряшё№■ ёыютр шыш яш°єЄ ьхЄъє (label, =, dw, jp, call, ld))
//todo яюър эхы№ч  $-label!!! эю ьюцэю 1*($-label)

////////яхЁхьхээ√х, эх ёюїЁрэ хь√х т post:

VAR PBYTE _labelN; //єърчрЄхы№ эр Єхъє∙є■ ЄрсышЎє ьхЄюъ
VAR BOOL _labelchanged; //Їыру "шчьхэшыш ьхЄъє" - эєцэю фы  ю°шсъш яю LABEL (эю эх яю REEQU)
VAR UINT _passindex; //эюьхЁ яЁюїюфр
VAR BYTE _prefixedtoken; //Ёрё°шЇЁютрээ√щ Єюъхэ ё єў╕Єюь \n ш Є.я.

VAR BYTE _ninclfiles; //ўшёыю юЄъЁ√Є√ї Їрщыют

//////////////////////////////////////////////////////////////////////////////

VAR PBYTE _forg;
VAR PBYTE _fpost;
VAR PBYTE _fincb;
VAR PBYTE _fdecl;
VAR BOOL _asms;

#define _MAXVALS 0x10
VAR LONG _value[_MAXVALS];
#define _MAXINCLUDES 0x08
VAR PBYTE _inclfile[_MAXINCLUDES];

VAR UINT _nlabels;
VAR UINT _lenlabels;

CONST BYTE _LABELPAGEMASK = 0x00; //0x07
#ifdef BIGMEM
#define _LABELPAGESIZE 0xfffffe
#else
#define _LABELPAGESIZE 0x6500 /**0x7300*/
#endif
#define _LABELPAGEMAXSHIFT (UINT)(_LABELPAGESIZE-_STRLEN-10)
//CONST UINT _LABELPAGEFREESTART = 0x0200;
VAR UINT _labelpagefreestart; //[1];
//CONST UINT _LABELPAGEDATASHIFT = 0x0202;
#ifdef BIGMEM
CONST UINT _LABELPAGEEOF = 0xffffffff;
#else
CONST UINT _LABELPAGEEOF = 0xffff;
#endif

//todo фшэрьшўхёъш т√фхышЄ№
VAR BYTE _labels0[_LABELPAGESIZE]; //0x4000
//VAR BYTE _labels1[0xc000]/**_LABELPAGESIZE*/;
//VAR BYTE _labels2[0xc000]/**_LABELPAGESIZE*/;
//VAR BYTE _labels3[0xc000]/**_LABELPAGESIZE*/;
//VAR BYTE _labels4[0xc000]/**_LABELPAGESIZE*/;
//VAR BYTE _labels5[0xc000]/**_LABELPAGESIZE*/;
//VAR BYTE _labels6[0xc000]/**_LABELPAGESIZE*/;
//VAR BYTE _labels7[0xc000]/**_LABELPAGESIZE*/;
VAR UINT _labelshift[0x400]; //todo 8 pages
VAR PBYTE _labelpage[1]; //8

VAR BYTE _m_curlabeltext[_STRLEN]; //Єрь цх fn?
VAR BYTE _m_evallabeltext[_STRLEN];

VAR PBYTE _curlabeltext;
VAR PBYTE _evallabeltext;
VAR UINT _labellen; //фышэр ьхЄъш фы  findlabel //тъы■ўр  0

//0x0000..0x01ff - рфЁхёр эрўрыр Ўхяюўхъ
//0x0200..0x0201 - рфЁхё эрўрыр ётюсюфэюую ьхёЄр (freestart)
//фры№°х ёрьш Ўхяюўъш
//ЇюЁьрЄ Ўхяюўъш:
//2 срщЄр - рфЁхё ёыхфє■∙хщ ьхЄъш
//N срщЄ - ЄхъёЄ ьхЄъш
//1 срщЄ - '\0'
//1 срщЄ - Їыруш ьхЄъш (defined, accessed, macro)
//4 срщЄр - чэрўхэшх ьхЄъш

CONST BYTE _ASMLABEL_DEFINED = 0x01;
CONST BYTE _ASMLABEL_ACCESSED= 0x02;
CONST BYTE _ASMLABEL_MACRO   = 0x04;
CONST BYTE _ASMLABEL_ISADDR  = 0x08;

FUNC LONG getlabel FORWARD();

//ъръ ёюїЁрэ Є№ post labels?
//todo сєфхь ёюїЁрэ Є№ тё╕ ёюёЄю эшх рёёхьсыхЁр ш ёЄЁюъє фю ъюэЎр, р яюёЄ√ ъюьяшышЁютрЄ№ Єръ цх, ъръ юс√ўэ√щ ЄюъхэшчшЁютрээ√щ ЄхъёЄ
//р яюър яЁюёЄю фтр яЁюїюфр ё чрЄшЁрэшхь Ёхчєы№ЄрЄр яхЁтюую

PROC decltoken(BYTE bb)
{
  writebyte(_fdecl,bb);
}

PROC asmpushvalue(LONG value)
{
/**  IF ((value & 0xffffL) != value) {
    errstr("val>65536"); enderr();
  };*/

  IF (_nvalues != _MAXVALS) {
    _value[_nvalues] = value;
    INC _nvalues;
  }ELSE {errstr("maxvals"); enderr(); };
}

PROC asmpushbool(BOOL b)
{
  //IF (b) {asmpushvalue(1L);
  //}ELSE asmpushvalue(0L);
  asmpushvalue((LONG)(BYTE)b);
}

FUNC LONG asmpopvalue()
{
//VAR LONG tempvalue;
//  IF (_nvalues!=0x00) {
    DEC _nvalues;
    //tempvalue = _value[_nvalues];
//  }ELSE {
    //tempvalue = 0xDEADBEEFL;
//    errstr("no data"); enderr(); //debug (can't be error after tokenizer)
//  };
  RETURN _value[_nvalues]; //tempvalue;
}
/**
PROC asmwritestate()
{
  writebyte(_fpost, +_DIR_READSTATE);

  writebyte(_fpost, _token);
  writebyte(_fpost, _curdir);

  writebyte(_fpost, _reg);
  writebyte(_fpost, _oldreg);
  writebyte(_fpost, _base);
  writebyte(_fpost, _base2);

  writebyte(_fpost, _nvalues);
  WHILE (_nvalues!=0x00) {
    writelong(_fpost, asmpopvalue());
  };

  writeuint(_fpost, _curaddr);
  writeuint(_fpost, _curshift);
  writeuint(_fpost, _curbegin);

  writebyte(_fpost, _curpage0); //ьюфхы№ ярь Єш
  writebyte(_fpost, _curpage1);
  writebyte(_fpost, _curpage2);
  writebyte(_fpost, _curpage3);

  //writepointer(_fpost, _labelN);
  //writeuint(_fpost, plabelqueuestart_index);
  writeuint(_fpost, _plabel_index);
  writeuint(_fpost, _curplabel_index);
  writeuint(_fpost, _hash);
  writeuint(_fpost, _curhash);

  writeuint(_fpost, _curlnbeg);

  writebyte(_fpost, _isaddr);
}
*/

/**
PROC asmreadstate()
{
VAR BYTE i;
  _token = readfin();
  _curdir = readfin();

  _reg = readfin();
  _oldreg = readfin();
  _base = readfin();
  _base2 = readfin();

  i = readfinbyte();
  WHILE (_nvalues!=i) {
    asmpushvalue(readfinlong());
  };

  _curaddr = readfinuint();
  _curshift = readfinuint();
  _curbegin = readfinuint();

  _curpage0 = readfin(); //ьюфхы№ ярь Єш
  _curpage1 = readfin();
  _curpage2 = readfin();
  _curpage3 = readfin();

  //_labelN = readfinpointer();
  //plabelqueuestart_index = readfinuint();
  _curplabel_index = readfinuint();
  _plabel_index = readfinuint();
  _hash = readfinuint();
  _curhash = readfinuint();

  _curlnbeg = readfinuint();

  _isaddr = readfinbyte();
}
*/


//0x0000..0x01ff - рфЁхёр эрўрыр Ўхяюўхъ
//фры№°х ёрьш Ўхяюўъш
//ЇюЁьрЄ Ўхяюўъш:
//2 срщЄр - рфЁхё ёыхфє■∙хщ ьхЄъш
//N срщЄ - ЄхъёЄ ьхЄъш
//1 срщЄ - '\0'
//1 срщЄ - Їыруш ьхЄъш (defined, accessed, macro)
//4 срщЄр - чэрўхэшх ьхЄъш

PROC clearlabels(UINT labelblock, PBYTE labelpointer)
{
  _labelpage[labelblock] = labelpointer;
  _hash = 0x0400;
  REPEAT {
    DEC _hash;
    _labelshift[_hash] = _LABELPAGEEOF;
  }UNTIL (_hash == 0);
  _labelpagefreestart = 0;
}

PROC readlabel()
{
VAR PBYTE pevalstr; //ьхЄър т ёЄЁюъх чрърэўштрхЄё  TOK_ENDTEXT
VAR BYTE cstr; //ёшьтюы шч ёЄЁюъш
VAR UINT labellen;
  _token = readfin(); //TOK_TEXT
  labellen = 0;
  REPEAT {
    cstr = readfin();
    IF ((CHAR)cstr == '#') { //evallabelname=123:labelname#evallabelname фюыцэю фртрЄ№ labelname123
      //ё яюёЄрьш ЁрсюЄрЄ№ эх сєфхЄ!!!
      //яЁюўшЄрЄ№ evallabel т _evallabeltext - TODO fgets
      pevalstr = (PBYTE)_evallabeltext;
      REPEAT {
        cstr = readfin();
        POKE *(PBYTE)(pevalstr) = cstr; //ьхЄър т ёЄЁюъх чрърэўштрхЄё  TOK_ENDTEXT
        INC pevalstr;
      }UNTIL (cstr == +_TOKENDTEXT);
      ;;_labellen = (UINT)(pevalstr - _evallabeltext); //тъы■ўр  0
      //т√ўшёышЄ№ evallabel
      //errstr("readevallabel "); errstr(_evallabeltext); enderr();
      _plabel_index = findlabel(_evallabeltext);
      emitn((UINT)getlabel());
      labellen = strjoin((PCHAR)_curlabeltext, labellen, _nbuf); //уыюсры№эр 
      //cstr == +_TOKENDTEXT
    };
    _curlabeltext[labellen] = cstr;
    INC labellen; //TODO яЁютхЁ Є№ яхЁхяюыэхэшх фышэ√
  }UNTIL (cstr == +_TOKENDTEXT);
  _labellen = labellen; //тъы■ўр  +_TOKENDTEXT
  //errstr("readlabel "); errstr(_curlabeltext); enderr();
}
/**
FUNC UINT findlabel(PBYTE labeltext)
{
//VAR PBYTE _labelN; //єърчрЄхы№ эр Єхъє∙є■ ЄрсышЎє ьхЄюъ
VAR PBYTE plabel; //ьхЄър т ЄрсышЎх чрърэўштрхЄё  эєы╕ь
//VAR PBYTE pstr; //ьхЄър т ёЄЁюъх чрърэўштрхЄё  TOK_ENDTEXT
//VAR BYTE cstr; //ёшьтюы шч ёЄЁюъш
//VAR BYTE clabel; //ёшьтюы шч ЄрсышЎ√ ьхЄюъ
//VAR UINT pnext_index; //рфЁхё ёыхфє■∙хщ ьхЄъш т ЄрсышЎх
//VAR UINT plabelqueuestart_index; //т (_labelN+plabelqueuestart_index) їЁрэшЄё  рфЁхё эрўрыр Ўхяюўъш фы  ьхЄъш
  _hash = hash(labeltext)&0x3ff;

  _labelN = _labels0; //_labelpage[(UINT)(_hashhigh&_LABELPAGEMASK)]; //set page (todo ъръ юяЁхфхышЄ№? ёшёЄхьэ√щ ьръЁюё?)
  //plabelqueuestart_index = ((UINT)(_hash))<<1; //todo Ёрчэр  ЁрчЁ фэюёЄ№ UINT
  _plabel_index = _labelshift[_hash];
  //todo ъръ ёфхырЄ№ эрсюЁ ьрёёштют т Ёрчэ√ї ёЄЁрэшўърї? ёфтшу шэфхъёр т юфэюь ьрёёштх тэшчє?
  //_labelflag = 0x00; //"label not found"
  WHILE (_plabel_index != _LABELPAGEEOF) { //яюър Ўхяюўър ьхЄюъ эх чръюэўшырё№
    plabel = &_labelN[_plabel_index]; //(PBYTE)((POINTER)_labelN + (POINTER)_plabel_index);
    _plabel_index = *(PUINT)(plabel);
    plabel = &plabel[+sizeof(UINT)]; //(PBYTE)((POINTER)plabel + (POINTER)2);
    IF (strcp((PCHAR)labeltext, (PCHAR)plabel)) { //ьхЄър эрщфхэр
      //plabel = (PBYTE)((POINTER)plabel + (POINTER)_labellen); //тъы■ўр  0
        //errstr("found label "); errstr(labeltext); enderr();
      _plabel_index = (UINT)(plabel - _labelN) + _labellen; //тъы■ўр  0 //єърчрЄхы№ эр эрўрыю фрээ√ї ёючфртрхьющ ьхЄъш (эрфю юс чрЄхы№эю чряюьэшЄ№!)
      //_labelflag = *(PBYTE)(plabel);
      //_labelvalue = *(PLONG)((POINTER)plabel + (POINTER)1);
      BREAK; //яюьэшЄ _plabel_index эрўрыр фрээ√ї эрщфхээющ ьхЄъш
    };
    //_plabel_index = pnext_index;
  }; //хёыш эх эрщфхэю, Єю _plabel_index==_LABELPAGEEOF
RETURN _plabel_index;
}
*/

PROC addlabel(LONG labelvalue) //т√ч√трЄ№ эхяюёЁхфёЄтхээю яюёых findlabel!!!
{
//VAR PBYTE _labelN; //єърчрЄхы№ эр Єхъє∙є■ ЄрсышЎє ьхЄюъ
VAR PBYTE plabel;
//VAR PBYTE pstr; //ьхЄър т ёЄЁюъх чрърэўштрхЄё  TOK_ENDTEXT
//VAR BYTE cstr;
//VAR UINT plabelqueuestart_index; //т (_labelN+plabelqueuestart_index) їЁрэшЄё  рфЁхё эрўрыр Ўхяюўъш фы  ьхЄъш
//VAR UINT oldqueuestart_index; //ёЄрЁ√щ єърчрЄхы№ эр эрўрыю Ўхяюўъш
VAR UINT freestart_index;
VAR BYTE labelflag;
//VAR LONG oldlabelvalue;
  _labelchanged = +FALSE;
  _labelN = _labels0; //_labelpage[(UINT)(_hashhigh&_LABELPAGEMASK)]; //set page (todo ъръ юяЁхфхышЄ№? ёшёЄхьэ√щ ьръЁюё?)
  //IF (_labelflag!=0x00) { //ьхЄър хёЄ№
  IF (_plabel_index!=_LABELPAGEEOF) { //ьхЄър хёЄ№
    plabel = &_labelN[_plabel_index]; //(PBYTE)((POINTER)_labelN + (POINTER)_plabel_index); //єърчрЄхы№ эр эрўрыю фрээ√ї ьхЄъш
    labelflag = *(PBYTE)(plabel); //findlabel();
    IF ((labelflag&_ASMLABEL_MACRO)!=0x00) {
      errstr("redefmacro"); /**errstr((PCHAR)_curlabeltext);*/ enderr();
    }ELSE IF ((labelflag&_ASMLABEL_DEFINED)!=0x00) {
      IF (*(PLONG)&plabel[1] != labelvalue) { //хёыш ьхЄър юяЁхфхыхэр ш чэрўхэшх эх ёююЄтхЄёЄтєхЄ
        _labelchanged = +TRUE;
        //;;errstr("old "); erruint(*(PUINT)&plabel[1]); enderr();
        //;;errstr("new "); erruint((UINT)labelvalue); enderr();
      };
    }ELSE { //шэрўх (эх юяЁхфхыхэр) юяЁхфхы хь
      POKE *(PBYTE)(plabel) = labelflag|_isaddr|_ASMLABEL_DEFINED;
      POKE *(PLONG)(&plabel[1]) = labelvalue;
    };
  }ELSE {//ьхЄъш эхЄ: яш°хь т эрўрыю Ўхяюўъш рфЁхё ъюэЎр ёЄЁрэшЎ√ ш ёючфр╕ь ьхЄъє Єрь ёю ёё√ыъющ эр ёЄрЁюх эрўрыю Ўхяюўъш
    //plabelqueuestart_index = (UINT)_hash + (UINT)_hash; //todo Ёрчэр  ЁрчЁ фэюёЄ№ UINT
    //oldqueuestart_index = *(PUINT)((POINTER)_labelN + (POINTER)plabelqueuestart_index); //ёЄрЁ√щ єърчрЄхы№ эр эрўрыю Ўхяюўъш
    freestart_index = _labelpagefreestart; //[0] //эрўрыю ётюсюфэюую ьхёЄр
    _plabel_index = freestart_index; //єърчрЄхы№ эр эрўрыю фрээ√ї ёючфртрхьющ ьхЄъш (эрфю юс чрЄхы№эю чряюьэшЄ№!)
    IF (freestart_index < _LABELPAGEMAXSHIFT) { //хёЄ№ ьхёЄю яюф ьхЄъє
      plabel = &_labelN[_plabel_index]; //єърчрЄхы№ эр эрўрыю ёючфртрхьющ ьхЄъш
      //яш°хь ьхЄъє
      POKE *(PUINT)(plabel) = _labelshift[_hash]; //oldqueuestart_index; //ёЄрЁ√щ єърчрЄхы№ эр эрўрыю Ўхяюўъш
      plabel = &plabel[+sizeof(UINT)];
      strcopy((PCHAR)_curlabeltext, _labellen /**-1*/, (PCHAR)plabel); //_labellen тъы■ўр  0
      plabel = &plabel[_labellen]; //тъы■ўр  0
      POKE *(PBYTE)(plabel) = _ASMLABEL_DEFINED;
      _plabel_index = (UINT)(plabel - _labelN); //єърчрЄхы№ эр эрўрыю фрээ√ї ёючфртрхьющ ьхЄъш
      INC plabel;
      POKE *(PLONG)(plabel) = labelvalue;
      plabel = &plabel[+sizeof(LONG)];
      _labelshift[_hash] = freestart_index; //эют√щ єърчрЄхы№ эр эрўрыю Ўхяюўъш
      _labelpagefreestart = (UINT)(plabel - _labelN); //єърчрЄхы№ эр ъюэхЎ ёючфртрхьющ ьхЄъш
      _lenlabels = _lenlabels + _labelpagefreestart - freestart_index;
      INC _nlabels;
      //_plabel_index фюыцхэ єърч√трЄ№ эр эрўрыю фрээ√ї ьхЄъш!
    }ELSE {errstr("mem"); enderr();
    };
  };
}

PROC changelabel(LONG labelvalue) //т√ч√трхЄё  яю фрээ√ь ёЄрЁюую findlabel (Єюы№ъю т reequ - TODO тэхфЁшЄ№)
{ //_plabel_index єърч√трхЄ эр эрўрыю фрээ√ї ьхЄъш
//VAR PBYTE _labelN; //єърчрЄхы№ эр Єхъє∙є■ ЄрсышЎє ьхЄюъ
VAR PBYTE plabel;
//VAR BYTE labelflag;
  _labelN = _labels0; //_labelpage[(UINT)(_hashhigh&_LABELPAGEMASK)]; //set page (todo ъръ юяЁхфхышЄ№? ёшёЄхьэ√щ ьръЁюё?)
  plabel = &_labelN[_plabel_index];
  //labelflag = *(PBYTE)(plabel);
  POKE *(PBYTE)(plabel) = (*(PBYTE)(plabel)&~_ASMLABEL_ISADDR)|_isaddr|_ASMLABEL_DEFINED;
  POKE *(PLONG)(&plabel[1]) = labelvalue;
}

FUNC LONG getlabel() //т√ч√трЄ№ эхяюёЁхфёЄтхээю яюёых findlabel!!!
{ //_plabel_index єърч√трхЄ эр эрўрыю фрээ√ї ьхЄъш
//VAR PBYTE _labelN; //єърчрЄхы№ эр Єхъє∙є■ ЄрсышЎє ьхЄюъ
VAR PBYTE plabel;
VAR BYTE labelflag;
VAR LONG labelvalue; //=0L; //= 0xDEADBEEFL;
  _labelN = _labels0; //_labelpage[(UINT)(_hashhigh&_LABELPAGEMASK)]; //set page (todo ъръ юяЁхфхышЄ№? ёшёЄхьэ√щ ьръЁюё?)
  IF (_plabel_index!=_LABELPAGEEOF) { //ьхЄър хёЄ№
    plabel = &_labelN[_plabel_index];
    labelflag = *(PBYTE)(plabel);
//    IF ((labelflag&_ASMLABEL_MACRO)!=0x00) {
//      errstr("label=macro"); enderr();
//    }ELSE {
      POKE *(PBYTE)(plabel) = labelflag|_ASMLABEL_ACCESSED;
      labelvalue = *(PLONG)(&plabel[1]);
      _isaddr = labelflag&_ASMLABEL_ISADDR;
//    };
  }ELSE {//ьхЄъш эхЄ: ю°шсър //todo post
    //asmwritestate();
    //todo чряшёрЄ№ т яюёЄ тхё№ ЄхъёЄ фю ъюэЎр ъюьрэф√

    //todo яю ЇюЁьрЄє ъюьрэф√ юяЁхфхышЄ№, ёъюы№ъю срщЄ яЁюяєёЄшЄ№

    errstr("nolbl "); errstr((PCHAR)_curlabeltext); enderr();
  };
  RETURN labelvalue;
}

PROC asmdir_label() //эхшчтхёЄэю, яЁюёЄю ьхЄър шыш reequ
{
  readlabel();
  _plabel_index = findlabel(_curlabeltext);
  //эхы№ч  ёхщўрё яхЁхюяЁхфхы Є№! шэрўх эхы№ч  label=label+1
  addlabel((LONG)(_curaddr+_curshift)); //■чрхЄ _plabel_index //єёЄрэютшЄ _labelchanged, хёыш шчьхэшыш
  _curplabel_index = _plabel_index; //чряюьэшЄ№ єърчрЄхы№ фрээ√ї ьхЄъш фы  REEQU
  _curhash = _hash;
}

PROC asmfmt_reequ()
{
  _plabel_index = _curplabel_index; //фюёЄрЄюўэю юфэющ тыюцхээюёЄш эр ўЄхэшх ьхЄюъ т т√Ёрцхэшш
  _hash = _curhash;
  IF (_plabel_index!=_LABELPAGEEOF) { //ьхЄър хёЄ№
    changelabel(asmpopvalue()); /**тёяюьэшЄ№ єърчрЄхы№ ьхЄъш ш яЁшётюшЄ№/яхЁхяЁшётюшЄ№ хщ value*/
  };
}
/**
PROC asmfmt_dir_label()
{
  //_plabel_index=_curplabel_index; //фюёЄрЄюўэю юфэющ тыюцхээюёЄш эр ўЄхэшх ьхЄюъ т т√Ёрцхэшш
  //_hash=_curhash;
  //addlabel((_curaddr+curshift)); //эхы№ч  схч findlabel эхяюёЁхфёЄтхээю фю!!!

  IF (_labelchanged) {
    errstr("redef "); errstr((PCHAR)_curlabeltext); enderr();
  };
}
*/

//////////////

PROC errwrongreg()
{
  errstr("badreg"); enderr();
}

PROC errwrongpar()
{
  errstr("badpar"); enderr();
}

PROC asmerrtext()
{
  loop:
  {
    _token = readfin();
    IF ((_token == +_TOKENDERR)||_waseof) goto end; //BREAK;
    //IF (_waseof) goto end; //BREAK; //эр тё ъшщ ёыєўрщ
    IF (_token == +_TOKTEXT) {
      txtloop:
      {
        _token = readfin();
        IF ((_token == +_TOKENDTEXT)||_waseof) goto loop; //BREAK;
        //IF (_waseof) goto loop; //BREAK; //эр тё ъшщ ёыєўрщ
        err((CHAR)_token);
        goto txtloop;
      };
    }ELSE err(' ');
    goto loop;
  };
  end:
  err('\"'); enderr();
}

PROC asmbyte(BYTE token)
{
  IF (_asms) writefout(token);
  INC _curaddr;
}

PROC asmemitblock() //чряшёрЄ№ рфЁхёр сыюър org
{
  IF (_curaddr != _curbegin) {
    asmorgword((LONG)_curbegin);
    asmorgword((LONG)(_curaddr-_curbegin));
  };
}

PROC asmreadprefixed()
{
  _token=readfin();
  IF ((CHAR)_token=='\\') { //todo тёЄртшЄ№ TOK_TEXT...TOK_ENDTEXT
    _token=readfin();
    IF       ((CHAR)_token=='n') {_prefixedtoken=0x0a;
    }ELSE IF ((CHAR)_token=='r') {_prefixedtoken=0x0d;
    }ELSE IF ((CHAR)_token=='t') {_prefixedtoken=0x09;
    }ELSE IF ((CHAR)_token=='0') {_prefixedtoken=0x00;
    }ELSE _prefixedtoken=_token; //юёЄры№э√х яЁхЇшъёэ√х ёшьтюы√ юёЄрты хь ъръ хёЄ№
  }ELSE _prefixedtoken=_token;
}

PROC asmpass(PCHAR fn)
{
  initmemmodel();
  _curbegin = _curaddr;
  _curshift = 0;

  _nvalues = 0x00;
  _ninclfiles = 0x00;

  //;;errstr("pass "); erruint(_passindex); enderr();
  //setfin("tok.f");
  _fin = nfopen(fn, "rb");
  IF (_fin != (PBYTE)0) {
    _waseof = +FALSE;
    _curlnbeg = 1; //todo яЁш include ш яюЄюь тюёёЄрэртыштрЄ№

    fsm();

    fclose(_fin); //closefin();
  }ELSE {
    errstr("no "); errstr(fn); enderr();
  };
  asmemitblock(); //чряшёрЄ№ рфЁхёр сыюър org
  INC _passindex;
}

FUNC UINT findlast(PCHAR s, CHAR eol)
{
VAR UINT len;
VAR UINT last;
VAR CHAR c;
  len = 0;
  last = 0; //яюёых яюёыхфэхую ЄхЁьшэрЄюЁр
  loop: //REPEAT {
    c = *(PCHAR)s;
    IF (c == '\0') goto endloop; //BREAK; //ЄхЁьшэрЄюЁ эх ъюяшЁєхЄё 
    IF (c == eol) last = len;
    INC s;
    INC len;
  goto loop; //}UNTIL ( (c==eol) || (len>=_STRMAX) ); //ЄхЁьшэрЄюЁ эх ъюяшЁєхЄё 
  endloop:
RETURN last; //яюёых яюёыхфэхую ЄхЁьшэрЄюЁр
}

FUNC PBYTE openext(PCHAR ext)
{
  _lenfn = findlast(_fn, '.');
  _lenfn = strjoin(_fn, _lenfn, ext);
  _fn[_lenfn] = '\0'; //strclose
RETURN openwrite(_fn);
}

PROC asmcompile(PCHAR fn)
{
  _curlabeltext = (PBYTE)_m_curlabeltext;
  _evallabeltext = (PBYTE)_m_evallabeltext;

  _fn = _m_fn;
  _lenfn = 0;

  _nlabels = 0;
  _lenlabels = 0;
  clearlabels(0, (PBYTE)_labels0);
  //clearlabels(1, (PBYTE)_labels1);
  //clearlabels(2, (PBYTE)_labels2);
  //clearlabels(3, (PBYTE)_labels3);
  //clearlabels(4, (PBYTE)_labels4);
  //clearlabels(5, (PBYTE)_labels5);
  //clearlabels(6, (PBYTE)_labels6);
  //clearlabels(7, (PBYTE)_labels7);

  _passindex = 1;

  _errs = +FALSE;
  _asms = +FALSE;
  asmpass(fn);

  _lenfn = strjoineol(_fn, 0, fn, '\0'); //фышэр схч ЄхЁьшэрЄюЁр!
  _fn[_lenfn] = '\0'; //strclose
  _fout = openext(".bin");
  _forg = openext(".org");
  //_fpost = openext(".pst");
  _fdecl = openext(".D_");
  //_fout = openwrite( "bin.f" );
  //_forg = openwrite( "org.f" );
  //_fpost = openwrite( "post.f" );
  //_fdecl = openwrite( "decl.f" );
  //setferr("asmerr.f");
  _errs = +TRUE;
  _asms = +TRUE;
  asmpass(fn);
  errstr("lbls "); erruint(_nlabels); errstr(" buf "); erruint(_lenlabels); enderr();
  //closeferr();
  decltoken(+_TOKEOF);
  fclose(_fdecl);
  //fclose(_fpost);
  fclose(_forg);
  fclose(_fout);
}