added: build asap codec inline. needs attention on osx/win32. note: needs gdc and...
authorspiff_ <spiff_@svn>
Sun, 13 Dec 2009 04:41:36 +0000 (04:41 +0000)
committerspiff_ <spiff_@svn>
Sun, 13 Dec 2009 04:41:36 +0000 (04:41 +0000)
git-svn-id: https://xbmc.svn.sourceforge.net/svnroot/xbmc/trunk@25625 568bbfeb-2a22-0410-94d2-cc84cf5bfa90

12 files changed:
Makefile.in
README.ubuntu
system/players/paplayer/xbmc_asap-i486-linux.so [deleted file]
xbmc/Settings.cpp
xbmc/cores/paplayer/ASAPCodec.cpp
xbmc/cores/paplayer/asap/Makefile
xbmc/cores/paplayer/asap/mads/Makefile [new file with mode: 0644]
xbmc/cores/paplayer/asap/mads/mads.pas [new file with mode: 0644]
xbmc/cores/paplayer/asap/players/Makefile
xbmc/cores/paplayer/asap/xasm/Makefile [new file with mode: 0644]
xbmc/cores/paplayer/asap/xasm/xasm.1.txt [new file with mode: 0644]
xbmc/cores/paplayer/asap/xasm/xasm.d [new file with mode: 0644]

index 1fa6143..6e577fe 100644 (file)
@@ -75,7 +75,8 @@ PAPCODECS_DIRS= \
        xbmc/cores/paplayer/ModuleCodec \
        xbmc/cores/paplayer/SPCCodec/SNES/SNESAPU \
        xbmc/cores/paplayer/vgmstream \
-       xbmc/cores/paplayer/MACDll
+       xbmc/cores/paplayer/MACDll \
+       xbmc/cores/paplayer/asap \
 
 ifeq ($(findstring osx,$(ARCH)),osx)
 PAPCODEC_DIRS+= \
@@ -299,6 +300,7 @@ endif
        $(MAKE) -C xbmc/cores/paplayer/NSFCodec
        $(MAKE) -C xbmc/cores/paplayer/SIDCodec
        $(MAKE) -C xbmc/cores/paplayer/ModuleCodec
+       $(MAKE) -C xbmc/cores/paplayer/asap asap-xbmc
 ifneq (@USE_EXTERNAL_LIBWAVPACK@,1)
        $(MAKE) -C xbmc/cores/paplayer/WavPackCodec
 endif
index c26c3c5..ebf6b4c 100644 (file)
@@ -41,7 +41,7 @@ Two methods exist to install the required Ubuntu packages :
 
 For Ubuntu (all versions >= 7.04):
 
-   # sudo aptitude install subversion make g++ gcc gawk pmount libtool nasm automake cmake gperf unzip bison libsdl-dev libsdl-image1.2-dev libsdl-gfx1.2-dev libsdl-mixer1.2-dev libfribidi-dev liblzo2-dev libfreetype6-dev libsqlite3-dev libogg-dev libasound-dev python-sqlite libglew-dev libcurl3 libcurl4-openssl-dev x11proto-xinerama-dev libxinerama-dev libxrandr-dev libxrender-dev libmad0-dev libogg-dev libvorbis-dev libsmbclient-dev libmysqlclient-dev libpcre3-dev libdbus-1-dev libhal-dev libhal-storage-dev libjasper-dev libfontconfig-dev libbz2-dev libboost-dev libfaac-dev libenca-dev libxt-dev libxtst-dev libxmu-dev libpng-dev libjpeg-dev libpulse-dev mesa-utils libcdio-dev libsamplerate-dev libmms-dev libmpeg3-dev libfaad-dev libflac-dev libiso9660-dev libass-dev libssl-dev
+   # sudo aptitude install subversion make g++ gcc gawk pmount libtool nasm automake cmake gperf unzip bison libsdl-dev libsdl-image1.2-dev libsdl-gfx1.2-dev libsdl-mixer1.2-dev libfribidi-dev liblzo2-dev libfreetype6-dev libsqlite3-dev libogg-dev libasound-dev python-sqlite libglew-dev libcurl3 libcurl4-openssl-dev x11proto-xinerama-dev libxinerama-dev libxrandr-dev libxrender-dev libmad0-dev libogg-dev libvorbis-dev libsmbclient-dev libmysqlclient-dev libpcre3-dev libdbus-1-dev libhal-dev libhal-storage-dev libjasper-dev libfontconfig-dev libbz2-dev libboost-dev libfaac-dev libenca-dev libxt-dev libxtst-dev libxmu-dev libpng-dev libjpeg-dev libpulse-dev mesa-utils libcdio-dev libsamplerate-dev libmms-dev libmpeg3-dev libfaad-dev libflac-dev libiso9660-dev libass-dev libssl-dev fp-compiler gdc
 
 On 8.04 and older versions, libmms is outdated and thus XBMC will not compile properly.
 In this case you will have to manually compile the latest version.
diff --git a/system/players/paplayer/xbmc_asap-i486-linux.so b/system/players/paplayer/xbmc_asap-i486-linux.so
deleted file mode 100755 (executable)
index 559570b..0000000
Binary files a/system/players/paplayer/xbmc_asap-i486-linux.so and /dev/null differ
index e0bb182..78c726e 100644 (file)
@@ -104,7 +104,7 @@ void CSettings::Initialize()
   m_stSettings.m_fPixelRatio = 1.0f;
 
   m_stSettings.m_pictureExtensions = ".png|.jpg|.jpeg|.bmp|.gif|.ico|.tif|.tiff|.tga|.pcx|.cbz|.zip|.cbr|.rar|.m3u|.dng|.nef|.cr2|.crw|.orf|.arw|.erf|.3fr|.dcr|.x3f|.mef|.raf|.mrw|.pef|.sr2|.rss";
-  m_stSettings.m_musicExtensions = ".nsv|.m4a|.flac|.aac|.strm|.pls|.rm|.rma|.mpa|.wav|.wma|.ogg|.mp3|.mp2|.m3u|.mod|.amf|.669|.dmf|.dsm|.far|.gdm|.imf|.it|.m15|.med|.okt|.s3m|.stm|.sfx|.ult|.uni|.xm|.sid|.ac3|.dts|.cue|.aif|.aiff|.wpl|.ape|.mac|.mpc|.mp+|.mpp|.shn|.zip|.rar|.wv|.nsf|.spc|.gym.adx|.dsp|.adp|.ymf|.ast|.afc|.hps|.xsp|.xwav|.waa|.wvs|.wam|.gcm|.idsp|.mpdsp|.mss|.spt|.rsd|.mid|.kar|.sap|.cmc|.cmr|.dmc|.mpt|.mpd|.rmt|.tmc|.tm8|.tm2|.oga|.url|.pxml|.tta|.rss";
+  m_stSettings.m_musicExtensions = ".nsv|.m4a|.flac|.aac|.strm|.pls|.rm|.rma|.mpa|.wav|.wma|.ogg|.mp3|.mp2|.m3u|.mod|.amf|.669|.dmf|.dsm|.far|.gdm|.imf|.it|.m15|.med|.okt|.s3m|.stm|.sfx|.ult|.uni|.xm|.sid|.ac3|.dts|.cue|.aif|.aiff|.wpl|.ape|.mac|.mpc|.mp+|.mpp|.shn|.zip|.rar|.wv|.nsf|.spc|.gym.adx|.dsp|.adp|.ymf|.ast|.afc|.hps|.xsp|.xwav|.waa|.wvs|.wam|.gcm|.idsp|.mpdsp|.mss|.spt|.rsd|.mid|.kar|.sap|.cmc|.cmr|.dmc|.mpt|.mpd|.rmt|.tmc|.tm8|.tm2|.oga|.url|.pxml|.tta|.rss|.cm3|.cms|.dlt";
   m_stSettings.m_videoExtensions = ".m4v|.3g2|.3gp|.nsv|.tp|.ts|.ty|.strm|.pls|.rm|.rmvb|.m3u|.ifo|.mov|.qt|.divx|.xvid|.bivx|.vob|.nrg|.img|.iso|.pva|.wmv|.asf|.asx|.ogm|.m2v|.avi|.bin|.dat|.mpg|.mpeg|.mp4|.mkv|.avc|.vp3|.svq3|.nuv|.viv|.dv|.fli|.flv|.rar|.001|.wpl|.zip|.vdr|.dvr-ms|.xsp|.mts|.m2t|.m2ts|.evo|.ogv|.sdp|.avs|.rec|.url|.pxml|.vc1|.h264|.rcv|.rss";
   // internal music extensions
   m_stSettings.m_musicExtensions += "|.sidstream|.oggstream|.nsfstream|.asapstream|.cdda";
index a60e8b2..0f70c7b 100644 (file)
@@ -92,5 +92,6 @@ bool ASAPCodec::IsSupportedFormat(const CStdString &strExt)
   return ext == "sap"
     || ext == "cmc" || ext == "cmr" || ext == "dmc"
     || ext == "mpt" || ext == "mpd" || ext == "rmt"
-    || ext == "tmc" || ext == "tm8" || ext == "tm2";
+    || ext == "tmc" || ext == "tm8" || ext == "tm2"
+    || ext == "cms" || ext == "cm3" || ext == "dlt";
 }
index 8472d1e..e499d15 100644 (file)
@@ -3,8 +3,8 @@ PREFIX = /usr/local
 CC = gcc -s -O2 -Wall
 AR = ar rc
 PERL = perl
-XASM = xasm -q
-MADS = mads -s
+XASM = xasm/xasm -q
+MADS = mads/mads -s
 RM = rm -f
 MKDIRS = mkdir -p
 INSTALL = install
@@ -19,12 +19,15 @@ XMMS_INPUT_PLUGIN_DIR = `xmms-config --input-plugin-dir`
 XMMS_USER_PLUGIN_DIR = $(HOME)/.xmms/Plugins
 MOC_INCLUDE = ../moc-2.4.4
 MOC_PLUGIN_DIR = /usr/local/lib/moc/decoder_plugins
-XBMC_DLL_LOADER_EXPORTS = ../XBMC/xbmc/cores/DllLoader/exports
+XBMC_DLL_LOADER_EXPORTS = ../../DllLoader/exports
 
 COMMON_C = asap.c acpu.c apokeysnd.c
 COMMON_H = asap.h asap_internal.h anylang.h players.h
+COMMON_O = asap.o acpu.o apokeysnd.o
 PLAYERS_OBX = players/cmc.obx players/cm3.obx players/cms.obx players/dlt.obx players/mpt.obx players/rmt4.obx players/rmt8.obx players/tmc.obx players/tm2.obx
 
+.PHONY: force
+
 all: asap2wav libasap.a
 
 asap2wav: asap2wav.c $(COMMON_C) $(COMMON_H)
@@ -46,15 +49,33 @@ asap-moc: libasap_decoder.so
 libasap_decoder.so: moc/libasap_decoder.c $(COMMON_C) $(COMMON_H)
        $(CC) -shared -fPIC -o $@ -I. -I$(MOC_INCLUDE) moc/libasap_decoder.c $(COMMON_C)
 
-asap-xbmc: xbmc_asap-i486-linux.so
+asap-xbmc: mads/mads xasm/xasm ../../../../system/players/paplayer/xbmc_asap-i486-linux.so
+
+xbmc/xbmc_asap.o: xbmc/xbmc_asap.c
+       $(CC) -I. -O2 -o $@ -c xbmc/xbmc_asap.c
+
+asap.o: asap.c $(COMMON_H)
+       $(CC) -I. -O2 -o $@ -c asap.c
+
+acpu.o: acpu.c $(COMMON_H)
+       $(CC) -I. -O2 -o $@ -c acpu.c
+
+apokeysnd.o: apokeysnd.c
+       $(CC) -I. -O2 -o $@ -c apokeysnd.c
 
-xbmc_asap-i486-linux.so: xbmc/xbmc_asap.c $(COMMON_C) $(COMMON_H)
-       $(CC) -shared -fPIC -o $@ -I. xbmc/xbmc_asap.c `cat $(XBMC_DLL_LOADER_EXPORTS)/wrapper.def` $(XBMC_DLL_LOADER_EXPORTS)/wrapper.o $(COMMON_C)
+../../../../system/players/paplayer/xbmc_asap-i486-linux.so: xbmc/xbmc_asap.o $(COMMON_O) $(COMMON_H)
+       $(CC) -shared -fPIC -o $@ -I. xbmc/xbmc_asap.o `cat $(XBMC_DLL_LOADER_EXPORTS)/wrapper.def` $(XBMC_DLL_LOADER_EXPORTS)/wrapper.o $(COMMON_O)
 
-players.h: files2anylang.pl $(PLAYERS_OBX)
+players.h: mads/mads xasm/xasm files2anylang.pl $(PLAYERS_OBX)
        $(PERL) files2anylang.pl $(PLAYERS_OBX) >$@
 
-players/cmc.obx: players/cmc.asx
+mads/mads: force
+       make -C mads
+
+xasm/xasm: force
+       make -C xasm
+
+players/cmc.obx: players/cmc.asx 
        $(XASM) -d CM3=0 -o $@ players/cmc.asx
 
 players/cm3.obx: players/cmc.asx
@@ -120,8 +141,15 @@ install-moc: libasap_decoder.so
 uninstall-moc:
        $(RM) $(MOC_PLUGIN_DIR)/libasap_decoder.so
 
-clean:
-       $(RM) asap2wav libasap.a asap.o acpu.o apokeysnd.o libasap-xmms.so libasap_decoder.so xbmc_asap-i486-linux.so players.h
+players-clean:
+       make -C players clean
+       make -C mads clean
+       make -C xasm clean
+
+distclean: clean
+
+clean: players-clean
+       $(RM) asap2wav libasap.a asap.o acpu.o apokeysnd.o libasap-xmms.so libasap_decoder.so ../../../../system/players/paplayer/xbmc_asap-i486-linux.so players.h xbmc/xbmc_asap.o
 
 README.html: README INSTALL NEWS CREDITS
        $(ASCIIDOC) -o $@ -a asapsrc -a asapports README
diff --git a/xbmc/cores/paplayer/asap/mads/Makefile b/xbmc/cores/paplayer/asap/mads/Makefile
new file mode 100644 (file)
index 0000000..1ed5d5e
--- /dev/null
@@ -0,0 +1,11 @@
+ARCH=i486-linux
+
+OBJS=mads.o
+
+all: mads.o
+
+mads.o: mads.pas
+       fpc -Mdelphi -vh -O3 mads.pas
+
+include ../../../../../Makefile.include
+
diff --git a/xbmc/cores/paplayer/asap/mads/mads.pas b/xbmc/cores/paplayer/asap/mads/mads.pas
new file mode 100644 (file)
index 0000000..ee0f317
--- /dev/null
@@ -0,0 +1,13537 @@
+(*----------------------------------------------------------------------------*)\r
+(*  Mad-Assembler v1.9.0 by Tomasz Biela (aka Tebe/Madteam)                   *)\r
+(*                                                                            *)\r
+(*  support 6502, 65816, Sparta DOS X, virtual banks                          *)\r
+(*  .LOCAL, .MACRO, .PROC, .STRUCT, .ARRAY, .REPT, .PAGES, .ENUM              *)\r
+(*  #WHILE, #IF, #ELSE                                                        *)\r
+(*                                                                            *)\r
+(*  last changes: 04.08.2009                                                  *)\r
+(*----------------------------------------------------------------------------*)\r
+\r
+// Free Pascal Compiler, http://www.freepascal.org/\r
+// Compile: fpc -Mdelphi -vh -O3 mads.pas\r
+\r
+program MADS;\r
+\r
+{$APPTYPE CONSOLE}\r
+{$I-}\r
+\r
+//uses SysUtils;\r
+\r
+type\r
+\r
+    _typStrREG = string [4];\r
+    _typStrSMB = string [8];\r
+    _typStrINT = string [32];\r
+\r
+    _argArray  = array [0..31] of byte;\r
+\r
+    _strArray  = array of string;\r
+    _intArray  = array of integer;\r
+    _carArray  = array of cardinal;\r
+    _bolArray  = array of Boolean;\r
+\r
+    labels  = record\r
+                nam: cardinal;    // identyfikator etykiety (CRC32)\r
+                adr: cardinal;    // wartosc etykiety\r
+                ofs: integer;     // wartosc etykiety przed zmiana adresu asemblacji\r
+                len: integer;     // dlugosc etykiety w bajtach <1..65535>\r
+                blk: integer;     // blok przypisany etykiecie\r
+                lln: integer;     // dlugosc bloku .LOCAL\r
+                lid: Boolean;     // identyfikator etykiety .LOCAL\r
+                bnk: integer;     // licznik wirtualnych bankow przypisany do etykiety <0..$FF>, na potrzeby MADS-a jest on typu WORD\r
+                sts: Boolean;     // czy definicja etykiety powiodla sie\r
+                rel: Boolean;     // czy relokowac\r
+                pas: byte;        // numer przebiegu dla danej etykiety\r
+                typ: char;        // typ etykiety (V-ARIABLE, P-ROCEDURE, C-ONSTANT)\r
+                use: Boolean;     // czy etykieta jest u¿ywana\r
+              end;\r
+\r
+    wywolyw = record\r
+                 zm: string;      // wiersz listingu\r
+                 pl: string;      // nazwa pliku ktorego zawartosc asemblujemy\r
+                 nr: integer;     // numer linii listingu\r
+              end;\r
+\r
+    stosife = record\r
+               _if_test: Boolean; // stan IF_TEST\r
+                  _else: Boolean; // czy wystapilo .ELSE\r
+                _okelse: integer; // numer aktualnego poziomu .IF\r
+             old_iftest: Boolean; // stan IF_TEST przed wykonaniem nowego .IF\r
+              end;\r
+\r
+   relocLab = record\r
+                adr: integer;     // adres relokowalny\r
+                idx: integer;     // indeks do T_SMB lub T_SIZ\r
+                blk: integer;     // numer segmentu\r
+                blo: integer;     // numer bloku\r
+                bnk: integer;     // bank\r
+              end;\r
+\r
+   relocSmb = record\r
+                smb: _typStrSMB;  // 8 znakowy symbol SMB dla systemu SDX\r
+                use: Boolean;     // czy w programie nastapilo odwolanie do symbolu\r
+              end;\r
+\r
+   extLabel = record\r
+               adr: cardinal;     // adres pod ktorym wystapila etykieta external\r
+               bnk: integer;      // bank w ktorym wystapila etykieta external\r
+               idx: integer;      // index do T_EXT\r
+               typ: char;         // typ operacji ' ', '<', '>', '^'\r
+               lsb: byte;\r
+              end;\r
+\r
+   usingLab = record\r
+               lok: integer;      // numer obszaru lokalnego\r
+               nam: string;       // nazwa obszaru w ktorym wystapilo .USING\r
+               lab: string;       // etykieta\r
+              end;\r
+\r
+   pubTab   = record\r
+               nam: string;       // nazwa etykiety publicznej\r
+               typ: Boolean;      // aktualny adres asemblacji\r
+              end;\r
+\r
+   mesTab   = record\r
+               pas: byte;         // numer przebiegu\r
+               mes: string;       // tresc komunikatu bledu\r
+              end;\r
+\r
+   locTab   = record\r
+               nam: string;       // nazwa bloku .LOCAL\r
+               adr: integer;      // aktualny adres asemblacji\r
+               idx: integer;      // indeks do tablicy T_LAB\r
+               ofs: integer;      // poprzedni adres asemblacji\r
+              end;\r
+\r
+   arrayTab = record\r
+                adr: cardinal;    // adres tablicy\r
+                bnk: integer;     // bank przypisany tablicy\r
+                idx: integer;     // okreslony indeks tablicy [0..IDX]\r
+                def: Boolean;     // czy zostal okreslony indeks tablicy\r
+                siz: byte;        // wielkosc pola tablicy B-YTE, W-ORD, L-ONG, D-WORD\r
+                len: integer;     // dlugosc tablicy w bajtach\r
+                ofs: integer;\r
+              end;\r
+\r
+   varTab   = record\r
+               lok: integer;      // nr poziomu lokalnego\r
+               nam: string;       // nazwa zmiennej\r
+               siz: integer;      // rozmiar zmiennej\r
+               cnt: integer;      // wielokrotnosc rozmiaru zmiennej\r
+               war: cardinal;     // wartosc poczatkowa zmiennej\r
+               adr: integer;      // adres zmiennych jesli zostal okreslony\r
+               typ: char;         // typ zmiennej V-AR, S-TRUCT, E-NUM\r
+               idx: integer;      // indeks do struktury tworzacej zmienna\r
+               str: string;       // nazwa struktury tworzacej zmienna\r
+                id: integer;      // identyfikator grupy etykiet deklarowanych przez .VAR w tym samym bloku\r
+               zpv: Boolean;      // ZPV = TRUE dla zmiennych deklarowanych przez .ZPVAR  \r
+              end;\r
+\r
+   stctTab  = record\r
+                 id: integer;     // numer struktury (identyfikator)\r
+                 no: integer;     // numer pozycji w strukturze (-1 gdy nie sa to pola struktury)\r
+                adr: cardinal;    // adres struktury\r
+                bnk: integer;     // bank przypisany strukturze\r
+                idx: integer;     // index do dodatkowej struktury\r
+                ofs: integer;     // ofset od poczatku struktury\r
+                siz: integer;     // rozmiar danych definiowanych przez pole struktury 1..4 (B-YTE..D-WORD)\r
+                                  // lub calkowita dlugosc danych definiowanych przez strukture\r
+                rpt: integer;     // liczba powtorzen typu SIZ (SIZ*RPT = rozmiar calkowity pola)\r
+                lab: string;      // etykieta wystepujaca w .STRUCT\r
+              end;\r
+\r
+    procTab = record\r
+                nam: string;      // nazwa procedury .PROC\r
+                str: integer;     // indeks do T_MAC z nazwami parametrow\r
+                adr: cardinal;    // adres procedury\r
+                ofs: integer;\r
+                bnk: integer;     // bank przypisany procedurze\r
+                par: integer;     // liczba parametrow procedury\r
+                ile: integer;     // liczba bajtow zajmowana przez parametry procedury\r
+                typ: char;        // typ procedury __pDef, __pReg, __pVar\r
+                reg: byte;        // kolejnosc rejestrow CPU\r
+                use: Boolean;     // czy procedura zostala uzyta w programie, czy pominac ja podczas asemblacji\r
+                len: cardinal;    // dlugosc procedury w bajtach\r
+                pnr: integer;     // proc_nr\r
+                prc: Boolean;     // proc = [TRUE, FALSE]\r
+                oof: integer;     // org_ofset\r
+                pnm: string;      // proc_name\r
+              end;\r
+\r
+    pageTab = record\r
+                adr: integer;     // poczatkowa strona pamieci\r
+                cnt: integer;     // liczba stron pamieci\r
+              end;\r
+\r
+    rSizTab = record\r
+               siz: char;\r
+               lsb: byte;\r
+              end;\r
+\r
+    endTab  = record\r
+               kod: byte;         // kod konca bloku .END??\r
+               adr: integer;\r
+               old: integer;\r
+               sem: Boolean;      // czy wystapil znak {\r
+              end;\r
+\r
+   extName  = record\r
+                nam: string;      // nazwa etykiety external\r
+                siz: char;        // zadeklarowany rozmiar etykiety od 1..4 bajtow\r
+                prc: Boolean;     // czy etykieta external jest deklaracja procedury\r
+              end;\r
+\r
+    heaMad  = record\r
+               nam: string;       // nazwa etykiety\r
+               adr: cardinal;     // adres przypisany etykiecie\r
+               bnk: byte;         // bank przypissany etykiecie\r
+               typ: char;         // typ etykiety (P-procedure, V-ariable, C-onstans)\r
+               idx: integer;      // index do tablicy T_PRC gdy etykiecie external przypisano procedure\r
+              end;\r
+\r
+    int5    = record              // nowy typ dla OBLICZ_MNEMONIK\r
+                 l: byte;         // liczba bajtow skladajaca sie na rozkaz CPU\r
+                 h: _argArray;    // argumenty rozkazu\r
+                 i: integer;      // ofset do tablic\r
+               tmp: byte;         // bajt pomocniczy\r
+              end;\r
+\r
+    relVal  = record\r
+               use: Boolean;\r
+               cnt: integer;\r
+              end;\r
+\r
+              \r
+    _bckAdr = array [0..1] of integer;\r
+\r
+    c64kb   = array [0..$FFFF] of cardinal;\r
+    m64kb   = array [0..$FFFF] of byte;\r
+    m4kb    = array [0..4095] of byte;\r
+    t256i   = array [0..255] of integer;\r
+    t256c   = array [0..255] of cardinal;\r
+    t256b   = array [0..255] of Boolean;\r
+\r
+var lst, lab, hhh, mmm: textfile;\r
+    dst: file;\r
+\r
+    label_type: char = 'V';\r
+\r
+    pass, status, memType, optDefault: byte;\r
+    opt : byte = 3;         // OPT default value\r
+\r
+    bank: integer;\r
+\r
+    __link_stack_pointer_old, __link_stack_address_old, __link_proc_vars_adr_old: cardinal;\r
+    __link_stack_pointer, __link_stack_address, __link_proc_vars_adr: cardinal;\r
+\r
+    blok, proc_lokal, fill, proc_idx: integer;\r
+    whi_idx, while_nr, ora_nr, test_nr, test_idx, sym_idx, org_ofset: integer;\r
+    hea_i, rel_ofs, wyw_idx, array_idx, buf_i: integer;\r
+    proc_nr, lc_nr, lokal_nr, rel_idx, smb_idx, var_id, usi_idx: integer;\r
+    line, line_err, line_all, line_add, ___rept_ile, ext_idx, extn_idx: integer;\r
+    pag_idx, end_idx, pub_idx, var_idx, ifelse, ds_empty: integer;\r
+    siz_idx    : integer = 1;\r
+    adres      : integer = -$FFFF;\r
+    zpvar      : integer = $80;\r
+\r
+    nul : int5;\r
+\r
+    while_name, test_name: string;\r
+    path, name, t, global_name, proc_name, def_label, str_blad: string;\r
+    end_string, plik_h, plik_hm, plik_lst, plik_obj, warning_mes: string;\r
+    plik_lab, plik_mac, plik_asm, macro_nr, lokal_name, warning_old: string;\r
+\r
+   \r
+    regOpty     : record\r
+                   blk: Boolean;\r
+                   use: Boolean;\r
+                   reg: array [0..2] of integer;\r
+                  end;\r
+\r
+    struct      : record\r
+                   use, drelocUSE, drelocSDX: Boolean;\r
+                   idx, id, adres, cnt: integer;\r
+                  end = (use: false; drelocUSE: false; drelocSDX: false; idx: 0; id: 0; adres: 0; cnt: -1);\r
+\r
+    struct_used : record\r
+                   use: Boolean;     // czy powstala struktura danych\r
+                   idx: integer;     // index do struktury zalozyciela\r
+                   cnt: integer;     // licznik pozycji struktury\r
+                  end;\r
+\r
+    array_used  : record\r
+                   idx: integer;\r
+                   max: integer;     // maksylany indeks na podstawie wprowadzonych danych\r
+                   typ: char;\r
+                  end;\r
+\r
+    ext_used    : record\r
+                   use: Boolean;\r
+                   idx: integer;\r
+                   siz: char;\r
+                  end;\r
+\r
+    dreloc      : record\r
+                   use: Boolean;     // czy wystapila dyrektywa .RELOC\r
+                   sdx: Boolean;     // czy wystapil pseudo rozkaz BLK SPARTA\r
+                   siz: char;        // rozmiar etykiety\r
+                  end;\r
+\r
+    dlink       : record\r
+                   use: Boolean;     // czy linkujemy blok z adresem ladowania $0000\r
+                   stc: Boolean;     // czy sprawdzalismy adresy stosu\r
+                   len: integer;     // dlugosc bloku linkowanego\r
+                   emp: integer;     // dlugosc pustego bloku\r
+                  end;\r
+\r
+    skip        : record\r
+                   use: Boolean;     // czy zostal wywolany pseudorozkaz skoku\r
+                   xsm: Boolean;     // czy wystapilo laczenie mnemonikow w stylu XASM-a\r
+                   hlt: Boolean;     // blokada TEST_SKIPA jesli przetwarzamy makra rozdzielone znakiem ':'\r
+                   idx: integer;     // indeks do tablicy T_SKP\r
+                   cnt: byte;        // liczba odlozonych adresow w przod\r
+                  end;\r
+\r
+    blkupd      : record\r
+                   adr: Boolean;     // czy wystapilo BLK UPDATE ADDRESS\r
+                   ext: Boolean;     // czy wystapilo BLK UPDATE EXTERNAL\r
+                   pub: Boolean;     // czy wystapilo BLK UPDATE PUBLIC\r
+                   sym: Boolean;     // czy wystapilo BLK UPDATE SYMBOL\r
+                   new: Boolean;     // czy wystapilo BLK UPDATE NEW SYMBOL\r
+                  end;\r
+\r
+    binary_file : record\r
+                   use: Boolean;\r
+                   adr: integer;\r
+                  end;\r
+\r
+    raw          : record\r
+                    use: Boolean;\r
+                    old: integer;\r
+                   end;\r
+\r
+    hea_ofs      : record\r
+                    adr: integer;\r
+                    old: integer;\r
+                   end;\r
+\r
+    enum         : record\r
+                    use, drelocUSE, drelocSDX: Boolean;\r
+                    val, max: integer;\r
+                   end;\r
+\r
+\r
+    VerifyProc  : Boolean = false;\r
+    exProcTest  : Boolean = false;      // wymagany w celu wyeliminowania 'Unreferenced procedures'\r
+    new_local   : Boolean = false;\r
+    NoAllocVar  : Boolean = false;      // wstrzymaj siê z alokacj¹ zmiennych .VAR\r
+    code6502    : Boolean = false;\r
+    unused_label: Boolean = false;\r
+    regAXY_opty : Boolean = false;      // OPT R+- registry optymisation MW?,MV?\r
+    mae_labels  : Boolean = false;      // OPT ?+- MAE ?labels\r
+    undeclared  : Boolean = false;\r
+    variable    : Boolean = false;\r
+    klamra_used : Boolean = false;\r
+    noWarning   : Boolean = false;\r
+    lst_off     : Boolean = false;\r
+    macro       : Boolean = false;\r
+    labFirstCol : Boolean = false;\r
+    test_symbols: Boolean = false;\r
+    overflow    : Boolean = false;\r
+    blokuj_zapis: Boolean = false;\r
+    FOX_ripit   : Boolean = false;\r
+    blocked     : Boolean = false;\r
+    rel_used    : Boolean = false;\r
+    put_used    : Boolean = false;\r
+    exclude_proc: Boolean = false;\r
+    mne_used    : Boolean = false;\r
+    data_out    : Boolean = false;\r
+    aray        : Boolean = false;\r
+    dta_used    : Boolean = false;\r
+    pisz        : Boolean = false;\r
+    rept        : Boolean = false;\r
+    rept_run    : Boolean = false;\r
+    empty       : Boolean = false;\r
+    reloc       : Boolean = false;\r
+    branch      : Boolean = false;\r
+    vector      : Boolean = false;\r
+    silent      : Boolean = false;\r
+    bez_lst     : Boolean = false;\r
+    icl_used    : Boolean = false;\r
+    komentarz   : Boolean = false;\r
+    case_used   : Boolean = false;\r
+    full_name   : Boolean = false;\r
+    proc        : Boolean = false;\r
+    run_macro   : Boolean = false;\r
+    loop_used   : Boolean = false;\r
+    org         : Boolean = false;\r
+    over        : Boolean = false;\r
+    open_ok     : Boolean = false;\r
+    list_lab    : Boolean = false;\r
+    list_hhh    : Boolean = false;\r
+    list_mmm    : Boolean = false;\r
+    list_mac    : Boolean = false;\r
+    next_pass   : Boolean = false;\r
+\r
+    regA        : Boolean = true; // rozmiar rejestrow dla OPT T+ (track sep rep)\r
+    regX        : Boolean = true; // true = 8bit, false = 16bit\r
+    regY        : Boolean = true;\r
+\r
+    first_org   : Boolean = true;\r
+    if_test     : Boolean = true;\r
+    hea         : Boolean = true;\r
+\r
+    TestWhileOpt: Boolean = true;\r
+\r
+\r
+    ___search_comment_block : procedure (var i:integer; var zm,txt:string);\r
+\r
+    analizuj_plik__   : procedure (var a:string; var old_str:string);\r
+    analizuj_mem__    : procedure (const start,koniec:integer; var old,a,old_str:string; licz:integer; const p_max:integer; const rp:Boolean);\r
+\r
+    oblicz_mnemonik__ : function (var i:integer; var a,old:string): int5;\r
+    ___wartosc_noSPC  : function (var zm,old:string; var i:integer; const sep,typ:Char): Int64;\r
+\r
+\r
+    imes:      t256i;\r
+    tCRC16:    t256i;\r
+    tCRC32:    t256c;\r
+\r
+\r
+    reptPar: _strArray;   // globalna tablica dla parametrów przekazywanych do .REPT\r
+\r
+    \r
+    // zmienna przechowujaca 2 adresy wstecz\r
+    t_bck: _bckAdr;\r
+\r
+    // hashowane mnemoniki i tryby adresowania\r
+    hash: m64kb;\r
+\r
+    // bufor dla dyrektywy .GET i .PUT\r
+    t_get: m64kb;\r
+\r
+    // bufor dla dyrektywy .LINK\r
+    t_lnk: m64kb;\r
+\r
+    // bufor dla wpisywanych danych do .ARRAY\r
+    t_tmp: c64kb;\r
+\r
+    // bufor dla odczytu plikow przez INS, maksymalna dlugosc pliku to 64KB\r
+    t_ins: m64kb;\r
+\r
+    // bufor pamieci dla zapisu\r
+    t_buf: m4kb;\r
+\r
+    // 256 znaczników dla zmiennych odkladanych na stronie zerowej\r
+    t_zpv: t256b;\r
+\r
+    // T_HEA zapamieta dlugosc bloku\r
+    t_hea: _intArray;\r
+\r
+    // tablica przechowujaca adres naprzod\r
+    t_skp: _intArray;\r
+\r
+    // T_LIN przechowuje polaczone znakiem '\' linie listingu (rozbite na wiersze)\r
+    t_lin: _strArray;\r
+\r
+    // T_MAC zapamieta linie z makrami, procedurami, petlami .REPT\r
+    t_mac: _strArray;\r
+\r
+    // T_PAR zapamieta nazwy parametrow procedur .PROC\r
+    t_par: _strArray;\r
+\r
+    // T_PTH zapamieta sciezki poszukiwan dla INS i ICL\r
+    t_pth: _strArray;\r
+\r
+    // T_SYM zapamieta nowe symbole dla SDX (blk update new i_settd 'i_settd')\r
+    t_sym: _strArray;\r
+\r
+    // T_ELS zapamieta wystapienia #ELSE w blokach #IF\r
+    t_els: _bolArray;\r
+\r
+    // T_LOC zapamieta nazwy obszarow .LOCAL\r
+    t_loc: array of locTab;\r
+\r
+    // MESSAGES - komunikaty o bledach i ostrzezeniach\r
+    messages: array of mesTab;\r
+\r
+    // T_PUB zapamieta nazwy etykiet .PUBLIC\r
+    t_pub: array of pubTab;\r
+\r
+    // T_VAR zapamieta nazwy etykiet .VAR\r
+    t_var: array of varTab;\r
+\r
+    // T_END zapamieta kolejnosci wywolywania dyrektyw .MACRO, .PROC, .LOCAL, .STRUCT, .ARRAY itd.\r
+    t_end: array of endTab;\r
+\r
+    // T_SIZ zapamieta rozmiary argumentow\r
+    t_siz: array of rSizTab;\r
+\r
+    // T_MAD zapamieta etykiety dla pliku naglowkowego *.HEA (-hm)\r
+    t_mad: array of heaMad;\r
+\r
+    // T_PAG zapamieta paremetry dla dyrektywy .PAGE\r
+    t_pag: array of pageTab;\r
+\r
+    // T_USI zapamieta paremetry dla dyrektywy .USE [.USING]\r
+    t_usi: array of usingLab;\r
+\r
+    // T_EXT  zapamieta adresy wystapienia etykiet external\r
+    // T_EXTN zapamieta deklaracje etykiet external\r
+    t_ext: array of extLabel;\r
+    t_extn: array of extName;\r
+\r
+    // T_ARR zapamieta parametry tablic .ARRAY\r
+    t_arr: array of arrayTab;\r
+\r
+    // T_REL zapamieta relokowalne adresy etykiet SDX\r
+    t_rel: array of relocLab;\r
+\r
+    // T_SMB zapamieta relokowalne adresy symboli SDX\r
+    t_smb: array of relocSmb;\r
+\r
+    // T_PRC zapamieta parametry procedury .PROC\r
+    t_prc: array of procTab;\r
+\r
+    // T_LAB zapamieta etykiety\r
+    t_lab: array of labels;\r
+\r
+    // T_WYW zapamieta linie z wywolywanymi makrami, pomocne przy wyswietlaniu linii z bledem\r
+    t_wyw: array of wywolyw;\r
+\r
+    // T_STR zapamieta nazwy struktur .STRUCT\r
+    t_str: array of stctTab;\r
+\r
+    // stos dla operacji .IF .ELSE .ENDIF\r
+    if_stos: array of stosife;\r
+                     \r
+\r
+    pass_end : byte = 2;       // pass = <0..2>\r
+\r
+\r
+// komunikaty\r
+ mes: array [0..2911] of char=(\r
+{0}  chr(ord('V') + $80),'a','l','u','e',' ','o','u','t',' ','o','f',' ','r','a','n','g','e',\r
+{1}  chr(ord('M') + $80),'i','s','s','i','n','g',' ','.','E','N','D','I','F',\r
+{2}  chr(ord(' ') + $80),'d','e','c','l','a','r','e','d',' ','t','w','i','c','e',\r
+{3}  chr(ord('S') + $80),'t','r','i','n','g',' ','e','r','r','o','r',\r
+{4}  chr(ord('E') + $80),'x','t','r','a',' ','c','h','a','r','a','c','t','e','r','s',' ','o','n',' ','l','i','n','e',\r
+{5}  chr(ord('U') + $80),'n','d','e','c','l','a','r','e','d',' ','l','a','b','e','l',' ',\r
+{6}  chr(ord('N') + $80),'o',' ','m','a','t','c','h','i','n','g',' ','b','r','a','c','k','e','t',\r
+{7}  chr(ord('N') + $80),'e','e','d',' ','p','a','r','e','n','t','h','e','s','i','s',\r
+{8}  chr(ord('I') + $80),'l','l','e','g','a','l',' ','c','h','a','r','a','c','t','e','r',':',' ',\r
+{9}  chr(ord('R') + $80),'e','s','e','r','v','e','d',' ','w','o','r','d',' ',\r
+{10} chr(ord('N') + $80),'o',' ','O','R','G',' ','s','p','e','c','i','f','i','e','d',\r
+{11} chr(ord('C') + $80),'P','U',' ','d','o','e','s','n','''','t',' ','h','a','v','e',' ','s','o',' ','m','a','n','y',' ','r','e','g','i','s','t','e','r','s',\r
+{12} chr(ord('I') + $80),'l','l','e','g','a','l',' ','i','n','s','t','r','u','c','t','i','o','n',' ',\r
+{13} chr(ord('V') + $80),'a','l','u','e',' ','o','u','t',' ','o','f',' ','r','a','n','g','e',\r
+{14} chr(ord('I') + $80),'l','l','e','g','a','l',' ','a','d','d','r','e','s','s','i','n','g',' ','m','o','d','e',' ','(','C','P','U',' ','6','5',\r
+{15} chr(ord('L') + $80),'a','b','e','l',' ','n','a','m','e',' ','r','e','q','u','i','r','e','d',\r
+{16} chr(ord('I') + $80),'n','v','a','l','i','d',' ','o','p','t','i','o','n',\r
+{17} chr(ord('M') + $80),'i','s','s','i','n','g',' ','.','E','N','D',\r
+{18} chr(ord('C') + $80),'a','n','n','o','t',' ','o','p','e','n',' ','o','r',' ','c','r','e','a','t','e',' ','f','i','l','e',\r
+{19} chr(ord('N') + $80),'e','s','t','e','d',' ','o','p','-','c','o','d','e','s',' ','n','o','t',' ','s','u','p','p','o','r','t','e','d',\r
+{20} chr(ord('M') + $80),'i','s','s','i','n','g',' ','''','}','''',\r
+{21} chr(ord('B') + $80),'r','a','n','c','h',' ','o','u','t',' ','o','f',' ','r','a','n','g','e',' ','b','y',' ','$',\r
+{22} chr(ord(' ') + $80),'b','y','t','e','s',\r
+{23} chr(ord('U') + $80),'n','e','x','p','e','c','t','e','d',' ','e','n','d',' ','o','f',' ','l','i','n','e',\r
+{24} chr(ord('F') + $80),'i','l','e',' ','i','s',' ','t','o','o',' ','s','h','o','r','t',\r
+{25} chr(ord('F') + $80),'i','l','e',' ','i','s',' ','t','o','o',' ','l','o','n','g',\r
+{26} chr(ord('D') + $80),'i','v','i','d','e',' ','b','y',' ','z','e','r','o',\r
+{27} chr(ord('^') + $80),' ','n','o','t',' ','r','e','l','o','c','a','t','a','b','l','e',\r
+{28} chr(ord('M') + $80),'i','s','s','i','n','g',' ','.','L','O','C','A','L',\r
+{29} chr(ord('M') + $80),'i','s','s','i','n','g',' ','.','E','N','D','L',\r
+{30} chr(ord('U') + $80),'s','e','r',' ','e','r','r','o','r',\r
+{31} chr(ord('O') + $80),'p','e','r','a','n','d',' ','o','v','e','r','f','l','o','w',\r
+{32} chr(ord('B') + $80),'a','d',' ','s','i','z','e',' ','s','p','e','c','i','f','i','e','r',\r
+{33} chr(ord('S') + $80),'i','z','e',' ','s','p','e','c','i','f','i','e','r',' ','n','o','t',' ','r','e','q','u','i','r','e','d',\r
+{34} chr(ord(' ') + $80),         // !!! zarezerwowane !!!  USER ERROR\r
+{35} chr(ord('U') + $80),'n','d','e','c','l','a','r','e','d',' ','m','a','c','r','o',' ',\r
+{36} chr(ord('C') + $80),'a','n','''','t',' ','r','e','p','e','a','t',' ','t','h','i','s',' ','d','i','r','e','c','t','i','v','e',\r
+{37} chr(ord('M') + $80),'i','s','s','i','n','g',' ','.','I','F',\r
+{38} chr(ord('L') + $80),'a','b','e','l',' ','n','o','t',' ','r','e','q','u','i','r','e','d',\r
+{39} chr(ord('M') + $80),'i','s','s','i','n','g',' ','.','P','R','O','C',\r
+{40} chr(ord('I') + $80),'m','p','r','o','p','e','r',' ','n','u','m','b','e','r',' ','o','f',' ','a','c','t','u','a','l',' ','p','a','r','a','m','e','t','e','r','s',\r
+{41} chr(ord('I') + $80),'n','c','o','m','p','a','t','i','b','l','e',' ','t','y','p','e','s',' ',\r
+{42} chr(ord('.') + $80),'E','N','D','I','F',' ','e','x','p','e','c','t','e','d',\r
+{43} chr(ord('M') + $80),'i','s','s','i','n','g',' ','.','E','N','D','R',\r
+{44} chr(ord('S') + $80),'M','B',' ','l','a','b','e','l',' ','t','o','o',' ','l','o','n','g',\r
+{45} chr(ord('T') + $80),'o','o',' ','m','a','n','y',' ','b','l','o','c','k','s',\r
+{46} chr(ord('B') + $80),'a','d',' ','p','a','r','a','m','e','t','e','r',' ','t','y','p','e',' ',\r
+{47} chr(ord('B') + $80),'a','d',' ','p','a','r','a','m','e','t','e','r',' ','n','u','m','b','e','r',\r
+{48} chr(ord(' ') + $80),'l','i','n','e','s',' ','o','f',' ','s','o','u','r','c','e',' ','a','s','s','e','m','b','l','e','d',\r
+{49} chr(ord(' ') + $80),'b','y','t','e','s',' ','w','r','i','t','t','e','n',' ','t','o',' ','t','h','e',' ','o','b','j','e','c','t',' ','f','i','l','e',\r
+{50} chr(ord('M') + $80),'i','s','s','i','n','g',' ','t','y','p','e',' ','l','a','b','e','l',\r
+{51} chr(ord('M') + $80),'i','s','s','i','n','g',' ','.','R','E','P','T',\r
+{52} chr(ord('B') + $80),'a','d',' ','o','r',' ','m','i','s','s','i','n','g',' ','s','i','n','u','s',' ','p','a','r','a','m','e','t','e','r',\r
+{53} chr(ord('O') + $80),'n','l','y',' ','R','E','L','O','C',' ','b','l','o','c','k',\r
+{54} chr(ord('L') + $80),'a','b','e','l',' ','t','a','b','l','e',':',\r
+{55} chr(ord('M') + $80),'i','s','s','i','n','g',' ','.','S','T','R','U','C','T',\r
+{56} chr(ord('M') + $80),'i','s','s','i','n','g',' ','.','E','N','D','S',\r
+{57} chr(ord('C') + $80),'a','n',' ','n','o','t',' ','u','s','e',' ','r','e','c','u','r','s','i','v','e',' ','s','t','r','u','c','t','u','r','e','s',\r
+{58} chr(ord('I') + $80),'m','p','r','o','p','e','r',' ','s','y','n','t','a','x',\r
+{59} chr(ord('M') + $80),'i','s','s','i','n','g',' ','.','A','R','R','A','Y',\r
+{60} chr(ord('M') + $80),'i','s','s','i','n','g',' ','.','E','N','D','A',\r
+{61} chr(ord('C') + $80),'P','U',' ','d','o','e','s','n','''','t',' ','h','a','v','e',' ','r','e','g','i','s','t','e','r',' ',\r
+{62} chr(ord('C') + $80),'o','n','s','t','a','n','t',' ','e','x','p','r','e','s','s','i','o','n',' ','v','i','o','l','a','t','e','s',' ','s','u','b','r','a','n','g','e',' ','b','o','u','n','d','s',\r
+{63} chr(ord('B') + $80),'a','d',' ','r','e','g','i','s','t','e','r',' ','s','i','z','e',\r
+{64} chr(ord('M') + $80),'i','s','s','i','n','g',' ','.','P','A','G','E','S',\r
+{65} chr(ord('M') + $80),'i','s','s','i','n','g',' ','.','E','N','D','P','G',\r
+{66} chr(ord('I') + $80),'n','f','i','n','i','t','e',' ','r','e','c','u','r','s','i','o','n',\r
+{67} chr(ord('D') + $80),'e','f','a','u','l','t',' ','a','d','d','r','e','s','s','i','n','g',' ','m','o','d','e',\r
+{68} chr(ord('U') + $80),'n','k','n','o','w','n',' ','d','i','r','e','c','t','i','v','e',' ',\r
+{69} chr(ord('U') + $80),'n','r','e','f','e','r','e','n','c','e','d',' ','p','r','o','c','e','d','u','r','e',' ',\r
+{70} chr(ord('P') + $80),'a','g','e',' ','e','r','r','o','r',' ','a','t',' ',\r
+{71} chr(ord('I') + $80),'l','l','e','g','a','l',' ','i','n','s','t','r','u','c','t','i','o','n',' ','a','t',' ','R','E','L','O','C',' ','b','l','o','c','k',\r
+{72} chr(ord('U') + $80),'n','r','e','f','e','r','e','n','c','e','d',' ','d','i','r','e','c','t','i','v','e',' ','.','E','N','D',\r
+{73} chr(ord('U') + $80),'n','d','e','f','i','n','e','d',' ','s','y','m','b','o','l',' ',\r
+{74} chr(ord('I') + $80),'n','c','o','r','r','e','c','t',' ','h','e','a','d','e','r',' ','f','o','r',' ','t','h','i','s',' ','f','i','l','e',' ','t','y','p','e',\r
+{75} chr(ord('I') + $80),'n','c','o','m','p','a','t','i','b','l','e',' ','s','t','a','c','k',' ','p','a','r','a','m','e','t','e','r','s',\r
+{76} chr(ord('Z') + $80),'e','r','o',' ','p','a','g','e',' ','R','E','L','O','C',' ','b','l','o','c','k',\r
+{77} chr(ord(' ') + $80),'(','B','A','N','K','=',        // od 77 kolejnosc wystapienia istotna\r
+{78} chr(ord(' ') + $80),'(','B','L','O','K','=',\r
+{79} chr(ord('L') + $80),'a','b','e','l',' ',\r
+{80} chr(ord(')') + $80),' ','E','R','R','O','R',':',' ',\r
+{81} chr(ord('0') + $80),'2',')',\r
+{82} chr(ord('8') + $80),'1','6',')',\r
+{83} chr(ord('O') + $80),'R','G',' ','s','p','e','c','i','f','i','e','d',' ','a','t',' ','R','E','L','O','C',' ','b','l','o','c','k',\r
+{84} chr(ord('C') + $80),'a','n','''','t',' ','s','k','i','p',' ','o','v','e','r',' ','t','h','i','s',\r
+{85} chr(ord('A') + $80),'d','d','r','e','s','s',' ','r','e','l','o','c','a','t','i','o','n',' ','o','v','e','r','l','o','a','d',\r
+{86} chr(ord('N') + $80),'o','t',' ','r','e','l','o','c','a','t','a','b','l','e',\r
+{87} chr(ord('V') + $80),'a','r','i','a','b','l','e',' ','a','d','d','r','e','s','s',' ','o','u','t',' ','o','f',' ','r','a','n','g','e',\r
+{88} chr(ord('M') + $80),'i','s','s','i','n','g',' ','#','W','H','I','L','E',\r
+{89} chr(ord('M') + $80),'i','s','s','i','n','g',' ','.','E','N','D','W',\r
+{90} chr(ord('B') + $80),'L','K',' ','U','P','D','A','T','E',' ',\r
+{91} chr(ord('A') + $80),'D','D','R','E','S','S',\r
+{92} chr(ord('E') + $80),'X','T','E','R','N','A','L',\r
+{93} chr(ord('P') + $80),'U','B','L','I','C',\r
+{94} chr(ord('S') + $80),'Y','M','B','O','L',\r
+{95} chr(ord('M') + $80),'i','s','s','i','n','g',' ','#','I','F',\r
+{96} chr(ord('M') + $80),'i','s','s','i','n','g',' ','.','E','N','D','T',\r
+{97} chr(ord('M') + $80),'i','s','s','i','n','g',' ','.','M','A','C','R','O',\r
+{98} chr(ord('S') + $80),'k','i','p','p','i','n','g',' ','o','n','l','y',' ','t','h','e',' ','f','i','r','s','t',' ','i','n','s','t','r','u','c','t','i','o','n',\r
+{99} chr(ord('R') + $80),'e','p','e','a','t','i','n','g',' ','o','n','l','y',' ','t','h','e',' ','l','a','s','t',' ','i','n','s','t','r','u','c','t','i','o','n',\r
+{100} chr(ord('O') + $80),'n','l','y',' ','S','D','X',' ','R','E','L','O','C',' ','b','l','o','c','k',\r
+{101} chr(ord('L') + $80),'i','n','e',' ','t','o','o',' ','l','o','n','g',\r
+{102} chr(ord('C') + $80),'o','n','s','t','a','n','t',' ','e','x','p','r','e','s','s','i','o','n',' ','e','x','p','e','c','t','e','d',\r
+{103} chr(ord('C') + $80),'a','n',' ','n','o','t',' ','d','e','c','l','a','r','e',' ','l','a','b','e','l',' ',\r
+{104} chr(ord(' ') + $80),'a','s',' ','p','u','b','l','i','c',\r
+{105} chr(ord('W') + $80),'r','i','t','i','n','g',' ','l','i','s','t','i','n','g',' ','f','i','l','e','.','.','.',\r
+{106} chr(ord('W') + $80),'r','i','t','i','n','g',' ','o','b','j','e','c','t',' ','f','i','l','e','.','.','.',\r
+{107} chr(ord('U') + $80),'s','e',' ','s','q','u','a','r','e',' ','b','r','a','c','k','e','t','s',' ','i','n','s','t','e','a','d',\r
+{108} chr(ord('C') + $80),'a','n','''','t',' ','f','i','l','l',' ','f','r','o','m',' ','h','i','g','h','e','r',' ','t','o',' ','l','o','w','e','r',' ','m','e','m','o','r','y',' ','l','o','c','a','t','i','o','n',\r
+{109} chr(ord('A') + $80),'c','c','e','s','s',' ','v','i','o','l','a','t','i','o','n','s',' ','a','t',' ','a','d','d','r','e','s','s',' ',\r
+{110} chr(ord('N') + $80),'o',' ','i','n','s','t','r','u','c','t','i','o','n',' ','t','o',' ','r','e','p','e','a','t',\r
+{111} chr(ord('I') + $80),'l','l','e','g','a','l',' ','w','h','e','n',' ','A','t','a','r','i',' ','f','i','l','e',' ','h','e','a','d','e','r','s',' ','d','i','s','a','b','l','e','d',\r
+{112} chr(ord('T') + $80),'h','e',' ','r','e','f','e','r','e','n','c','e','d',' ','l','a','b','e','l',' ',\r
+{113} chr(ord(' ') + $80),'h','a','s',' ','n','o','t',' ','p','r','e','v','i','o','u','s','l','y',' ','b','e','e','n',' ','d','e','f','i','n','e','d',' ','p','r','o','p','e','r','l','y',\r
+{114} chr(ord('U') + $80),'n','i','n','i','t','i','a','l','i','z','e','d',' ','v','a','r','i','a','b','l','e',\r
+{115} chr(ord('U') + $80),'n','u','s','e','d',' ','l','a','b','e','l',' ',\r
+{116} chr(ord('''') + $80),'#','''',' ','i','s',' ','a','l','l','o','w','e','d',' ','o','n','l','y',' ','i','n',' ','r','e','p','e','a','t','e','d',' ','l','i','n','e','s',\r
+\r
+{117} chr(ord('S') + $80),\r
+     'y','n','t','a','x',':',' ','m','a','d','s',' ','s','o','u','r','c','e',' ','[','s','w','i','t','c','h','e','s',']',#13,#10,\r
+     '-','b',':','a','d','d','r','e','s','s',#9,'G','e','n','e','r','a','t','e',' ','b','i','n','a','r','y',' ','f','i','l','e',' ','a','t',' ','s','p','e','c','i','f','i','c',' ','a','d','d','r','e','s','s',#13,#10,\r
+     '-','c',#9,#9,'L','a','b','e','l',' ','c','a','s','e',' ','s','e','n','s','i','t','i','v','i','t','y',#13,#10,\r
+     '-','d',':','l','a','b','e','l','=','v','a','l','u','e',#9,'D','e','f','i','n','e',' ','a',' ','l','a','b','e','l',#13,#10,\r
+     '-','f',#9,#9,'C','P','U',' ','c','o','m','m','a','n','d',' ','a','t',' ','f','i','r','s','t',' ','c','o','l','u','m','n',#13,#10,\r
+     '-','h','c','[',':','f','i','l','e','n','a','m','e',']',#9,'H','e','a','d','e','r',' ','f','i','l','e',' ','f','o','r',' ','C','C','6','5',#13,#10,\r
+     '-','h','m','[',':','f','i','l','e','n','a','m','e',']',#9,'H','e','a','d','e','r',' ','f','i','l','e',' ','f','o','r',' ','M','A','D','S',#13,#10,\r
+     '-','i',':','p','a','t','h',#9,#9,'A','d','d','i','t','i','o','n','a','l',' ','i','n','c','l','u','d','e',' ','d','i','r','e','c','t','o','r','i','e','s',#13,#10,\r
+     '-','l','[',':','f','i','l','e','n','a','m','e',']',#9,'G','e','n','e','r','a','t','e',' ','l','i','s','t','i','n','g',#13,#10,\r
+     '-','m',':','f','i','l','e','n','a','m','e',#9,'F','i','l','e',' ','w','i','t','h',' ','m','a','c','r','o',' ','d','e','f','i','n','i','t','i','o','n',#13,#10,\r
+     '-','o',':','f','i','l','e','n','a','m','e',#9,'S','e','t',' ','o','b','j','e','c','t',' ','f','i','l','e',' ','n','a','m','e',#13,#10,\r
+     '-','p',#9,#9,'P','r','i','n','t',' ','f','u','l','l','y',' ','q','u','a','l','i','f','i','e','d',' ','f','i','l','e',' ','n','a','m','e','s',' ','i','n',' ','l','i','s','t','i','n','g',' ','a','n','d',' ','e','r','r','o','r',' ','m','e','s','s','a','g','e','s',#13,#10,\r
+     '-','s',#9,#9,'S','i','l','e','n','t',' ','m','o','d','e',#13,#10,\r
+     '-','t','[',':','f','i','l','e','n','a','m','e',']',#9,'L','i','s','t',' ','l','a','b','e','l',' ','t','a','b','l','e',#13,#10,\r
+     '-','x',#9,#9,'E','x','c','l','u','d','e',' ','u','n','r','e','f','e','r','e','n','c','e','d',' ','p','r','o','c','e','d','u','r','e','s',#13,#10,\r
+     '-','v','u',#9,#9,'V','e','r','i','f','y',' ','c','o','d','e',' ','i','n','s','i','d','e',' ','u','n','r','e','f','e','r','e','n','c','e','d',' ','p','r','o','c','e','d','u','r','e','s',#13,#10,\r
+      '-','u',#9,#9,'W','a','r','n',' ','o','f',' ','u','n','u','s','e','d',' ','l','a','b','e','l','s',\r
+\r
+     chr($80),\r
+\r
+// version\r
+\r
+{118} chr(ord('m') + $80),'a','d','s',' ','1','.','9','.','0',chr($80),' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',\r
+\r
+     chr($80));\r
+\r
+\r
+const\r
+  pass_max = 16;        // maksymalna mozliwa liczba przebiegow asemblacji\r
+\r
+  __equ    = $80;       // kody pseudo rozkazow\r
+  __opt    = $81;\r
+  __org    = $82;\r
+  __ins    = $83;\r
+  __end    = $84;\r
+  __dta    = $85;\r
+  __icl    = $86;\r
+  __run    = $87;       // RUN\r
+  __nmb    = $88;\r
+  __ini    = $89;       // INI-RUN = 2  !!! koniecznie !!!\r
+//  __bot    = $8a;       // BOT aktualnie nie oprogramowany\r
+  __rmb    = $8b;\r
+  __lmb    = $8c;\r
+  __ert    = $8d;\r
+//  __ift    = $8e;       // -> .IF\r
+//  __els    = $8f;       // -> .ELSE\r
+//  __eif    = $90;       // -> .ENDIF\r
+//  __eli    = $91;       // -> .ELSEIF\r
+  __smb    = $92;\r
+  __blk    = $93;\r
+  __ext    = $94;\r
+\r
+  __cpbcpd = $97;       // kody makro rozkazow __cpbcpd..__jskip\r
+  __adbsbb = $98;\r
+  __phrplr = $99;\r
+  __adwsbw = $9A;\r
+  __BckSkp = $9B;\r
+  __inwdew = $9C;\r
+  __addsub = $9D;\r
+  __movaxy = $9E;\r
+  __jskip  = $9F;       // koniec kodów makro rozkazów\r
+\r
+  __macro  = $A0;       // kody dyrektyw, kolejnosc wg tablicy 'MAC' + $A0\r
+  __if     = $A1;\r
+  __endif  = $A2;\r
+  __endm   = $A3;\r
+  __exit   = $A4;\r
+  __error  = $A5;\r
+  __else   = $A6;\r
+  __print  = $A7;       // = __echo\r
+  __proc   = $A8;\r
+  __endp   = $A9;\r
+  __elseif = $AA;\r
+  __local  = $AB;\r
+  __endl   = $AC;\r
+  __rept   = $AD;\r
+  __endr   = $AE;\r
+\r
+  __byte   = $AF;       // kody dla .BYTE, .WORD, .LONG, .DWORD\r
+//  __word   = $B0;      // nastepuja po sobie, !!! koniecznie !!!\r
+//  __long   = $B1;\r
+  __dword  = $B2;\r
+\r
+  __byteValue = __byte-1;     // zastapi operacje (...-__byte+1)\r
+\r
+  __struct = $B3;\r
+  __ends   = $B4;\r
+  __ds     = $B5;\r
+  __symbol = $B6;\r
+  __fl     = $B7;\r
+  __array  = $B8;\r
+  __enda   = $B9;\r
+  __get    = $BA;\r
+  __put    = $BB;\r
+  __sav    = $BC;\r
+  __pages  = $BD;\r
+  __endpg  = $BE;\r
+  __reloc  = $BF;\r
+  __dend   = $C0;       // zastepuje dyrektywy .ENDL, .ENDP, .ENDS, .ENDM itd.\r
+  __link   = $C1;\r
+  __extrn  = $C2;       // odpowiednik pseudo rozkazu EXT\r
+  __public = $C3;       // odpowiednik dla .GLOBAL, .GLOBL\r
+\r
+  __reg    = $C4;       // __REG, __VAR koniecznie w tej kolejnosci\r
+  __var    = $C5;\r
+\r
+  __or     = $C6;\r
+  __by     = $C7;\r
+  __he     = $C8;\r
+  __wo     = $C9;\r
+  __en     = $CA;\r
+  __sb     = $CB;\r
+  __while  = $CC;\r
+  __endw   = $CD;\r
+  __test   = $CE;\r
+  __endt   = $CF;\r
+  __using  = $D0;\r
+  __ifndef = $D1;\r
+  __nowarn = $D2;\r
+  __def    = $D3;\r
+  __ifdef  = $D4;\r
+  __align  = $D5;\r
+  __zpvar  = $D6;\r
+  __enum   = $D7;\r
+  __ende   = $D8;\r
+\r
+  __over   = __ende;    // koniec kodow dyrektyw\r
+\r
+\r
+//  __switch = $E0;     // nie oprogramowane\r
+//  __case   = $E1;\r
+  __telse  = $E2;\r
+\r
+\r
+  __nill   = $F0;\r
+  __addEqu = $F1;\r
+  __xasm   = $F2;\r
+\r
+  __blkSpa = $F3;\r
+  __blkRel = $F4;\r
+  __blkEmp = $F5;\r
+\r
+  __struct_run_noLabel = $F6;          // ostatni wolny tutaj kod to $F7\r
+\r
+\r
+  __rel    = $0000;                    // wartosc dla etykiet relokowalnych\r
+\r
+  __relASM = $0100;                    // adres asemblacji dla bloku .RELOC\r
+\r
+  __relHea = ord('M')+ord('R') shl 8;  // naglowek 'MR' dla bloku .RELOC\r
+\r
+\r
+  __id_param   = $FFF7;   // !!! zaczynamy koniecznie od __ID_PARAM !!!\r
+  __id_array   = $FFF8;\r
+  __dta_struct = $FFF9;\r
+  __id_ext     = $FFFA;\r
+  __id_smb     = $FFFB;\r
+  __id_macro   = $FFFC;\r
+  __id_enum    = $FFFD;\r
+  __id_struct  = $FFFE;\r
+  __id_proc    = $FFFF;\r
+\r
+  __array_run  = byte(__id_array);\r
+  __macro_run  = byte(__id_macro);\r
+  __enum_run   = byte(__id_enum);\r
+  __struct_run = byte(__id_struct);\r
+  __proc_run   = byte(__id_proc);\r
+\r
+  __hea_dos      = $FFFF;  // naglowek dla bloku DOS\r
+  __hea_reloc    = $0000;  // naglowek dla bloku .RELOC\r
+  __hea_public   = $FFED;  // naglowek dla bloku aktualizacji symboli public\r
+  __hea_external = $FFEE;  // naglowek dla bloku aktualizacji symboli external\r
+  __hea_address  = $FFEF;  // naglowek dla bloku aktualizacji adresow relokowalnych\r
+\r
+  __pDef = 'D';            // Default\r
+  __pReg = 'R';            // Registry\r
+  __pVar = 'V';            // Variable\r
+\r
+\r
+ __test_label  = '##TB';          // etykieta dla poczatku bloku #IF\r
+ __telse_label = '@?@?@ML?ET';    // etykieta dla poczatku bloku #ELSE\r
+ __endt_label  = '@?@?@ML?TE';    // etykieta dla konca bloku #IF (#END)\r
+\r
+ __while_label = '##B';           // etykieta dla poczatku bloku #WHILE\r
+ __endw_label  = '@?@?@ML?E';     // etykieta dla konca bloku #WHILE (#END)\r
\r
+\r
+ mads_stack: array [0..2] of string[14] =\r
+ ('@STACK_POINTER', '@STACK_ADDRESS', '@PROC_VARS_ADR');\r
+\r
+ tType: array [1..4] of char =\r
+ ('B','A','T','F');                   // typy uzywane wewnetrznie przez MADS\r
+\r
+ relType: array [1..7] of char =\r
+ ('B','W','L','D','<','>','^');       // typy zapisywane w relokowalnych plikach\r
+\r
+ mads_param: array [1..4] of string [7] =\r
+ ('.BYTE ', '.WORD ', '.LONG ', '.DWORD ');\r
+\r
+ PathDelim: char = '/';\r
+\r
+\r
+function _pth(const a: char): Boolean;\r
+(*----------------------------------------------------------------------------*)\r
+(*  test dla roznych znakow PathDelim                                         *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+ _pth := (a in ['/','\'])\r
+end;\r
+\r
+\r
+{procedure czytaj_komentarz(var i: integer; var a, txt: string);\r
+(*----------------------------------------------------------------------------*)\r
+(* czytamy komentarz ograniczony znakami /* */                                *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+               txt:=txt+'/*'; inc(i,2);\r
+               komentarz:=true;\r
+\r
+               while komentarz and (i<=length(a)) do begin\r
+\r
+                txt:=txt+a[i];\r
+\r
+                if a[i]='*' then\r
+                 if a[i+1]='/' then begin txt:=txt+'/'; inc(i); komentarz:=false end;\r
+\r
+                inc(i);\r
+               end;\r
+end;     }\r
+\r
+\r
+procedure omin_spacje (var i:integer; var a:string);\r
+(*----------------------------------------------------------------------------*)\r
+(*  omijamy tzw. "biale spacje" czyli spacje, tabulatory, komentarze /* */    *)\r
+(*----------------------------------------------------------------------------*)\r
+var txt: string;\r
+begin\r
+\r
+ if a<>'' then begin\r
+  while a[i] in [' ',#9] do inc(i);\r
+\r
+  if (a[i]='/') and (a[i+1]='*') then begin\r
+   txt:=''; ___search_comment_block(i,a, txt);\r
+\r
+   if not(komentarz) then omin_spacje(i,a);\r
+  end;\r
+\r
+ end;\r
+\r
+end;\r
+\r
+\r
+procedure __inc(var i:integer; var a:string);\r
+begin\r
+\r
+ if i>length(a) then exit;\r
+\r
+ inc(i);\r
+ omin_spacje(i,a);\r
\r
+end;\r
+\r
+\r
+function UpCas_(const a: char): char;\r
+begin\r
+\r
+ if not(case_used) then\r
+  Result:=UpCase(a)\r
+ else\r
+  Result:=a;\r
+\r
+end;\r
+\r
+\r
+function ata2int(const a: byte): byte;\r
+(*----------------------------------------------------------------------------*)\r
+(*  zamiana znakow ATASCII na INTERNAL                                        *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+ Result:=a;\r
+\r
+ case (a and $7f) of\r
+    0..31: inc(Result,64);\r
+   32..95: dec(Result,32);\r
+ end;\r
+\r
+end;\r
+\r
+\r
+function IntToStr(const a: Int64): string;\r
+var tmp: _typStrINT;\r
+begin\r
+ str(a, tmp);\r
+\r
+ Result := tmp;\r
+end;\r
+\r
+\r
+function StrToInt(var a: string): Int64;\r
+var i: integer;\r
+begin\r
+ val(a,Result, i);\r
+end;\r
+\r
+\r
+procedure flush_dst;\r
+(*----------------------------------------------------------------------------*)\r
+(*  oproznienie bufora zapisu                                                 *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+ if buf_i>0 then blockwrite(dst,t_buf,buf_i);\r
+ buf_i:=0;\r
+end;\r
+\r
+\r
+procedure put_dst(const a: byte);\r
+(*----------------------------------------------------------------------------*)\r
+(*  zapisz do bufora zapisu                                                   *)\r
+(*----------------------------------------------------------------------------*)\r
+var v: byte;\r
+begin\r
+\r
+  if fill>0 then begin\r
+\r
+   flush_dst;\r
+\r
+   v:=$ff;\r
+\r
+   while fill>0 do begin\r
+    blockwrite(dst,v,1);\r
+    dec(fill);\r
+   end;\r
+\r
+  end;  \r
+  \r
+  t_buf[buf_i]:=a; inc(buf_i);\r
+  if buf_i>=sizeof(t_buf) then flush_dst;\r
+end;\r
+\r
+\r
+function Hex(a:cardinal; b:shortint): string;\r
+(*----------------------------------------------------------------------------*)\r
+(*  zamiana na zapis hexadecymalny                                            *)\r
+(*  'B' okresla maksymalna liczbe nibbli do zamiany                           *)\r
+(*  jesli sa jeszcze jakies wartosci to kontynuuje zamiane                    *)\r
+(*----------------------------------------------------------------------------*)\r
+var v: byte;\r
+\r
+const\r
+    tHex: array [0..15] of char =\r
+    ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');\r
+\r
+begin\r
+ Result:='';\r
+\r
+ while (b>0) or (a<>0) do begin\r
+\r
+  v := byte(a);\r
+  Result:=tHex[v shr 4] + tHex[v and $0f] + Result;\r
+\r
+  a:=a shr 8;\r
+\r
+  dec(b,2);\r
+ end;\r
+\r
+end;\r
+\r
+\r
+function load_mes(const b: integer): string;\r
+(*----------------------------------------------------------------------------*)\r
+(*  tworzymy STRING z komunikatem nr w 'B'                                    *)\r
+(*----------------------------------------------------------------------------*)\r
+var i: integer;\r
+begin\r
+\r
+ i:=imes[b]-imes[b-1];\r
+\r
+ SetLength(Result, i);\r
+ move(mes[imes[b-1]], Result[1], i);\r
+end;\r
+\r
+\r
+function GetFilePath(var a: string): string;\r
+(*----------------------------------------------------------------------------*)\r
+(*  z pelnej nazwy pliku wycinamy sciezke (ExtractFilePath)                   *)\r
+(*----------------------------------------------------------------------------*)\r
+var i: integer;\r
+begin\r
+ Result:='';\r
+\r
+ if a<>'' then begin\r
+  i:=length(a);\r
+  while not(_pth(a[i])) and (i>=1) do dec(i);\r
+\r
+  Result:=a;\r
+  SetLength(Result,i);\r
+ end;\r
\r
+end;\r
+\r
+\r
+function GetFileName(var a: string): string;\r
+(*----------------------------------------------------------------------------*)\r
+(*  z pelnej nazwy pliku wycinamy nazwe pliku (ExtractFileName)               *)\r
+(*----------------------------------------------------------------------------*)\r
+var i: integer;\r
+begin\r
+ Result:='';\r
+\r
+ if a<>'' then begin\r
+  i:=length(a);\r
+  while not(_pth(a[i])) and (i>=1) do dec(i);\r
+\r
+  Result:=copy(a,i+1,length(a));\r
+ end;    \r
+\r
+end;\r
+\r
+\r
+function show_full_name(var a:string; const b,c:Boolean): string;\r
+var pth: string;\r
+begin\r
+ pth:=GetFilePath(a);\r
+\r
+ Result:=a;\r
+\r
+ if b then begin\r
+\r
+  if pth='' then Result:=path+Result;\r
+\r
+ end else\r
+  Result:=GetFileName(Result);\r
+\r
+ if c then Result:='Source: '+Result;\r
+end;\r
+\r
+\r
+procedure warning(const a: byte);\r
+(*----------------------------------------------------------------------------*)\r
+(*  wyswietla ostrzezenie, nie przerywa asemblacji                            *)\r
+(*----------------------------------------------------------------------------*)\r
+var txt: string;\r
+begin\r
+\r
+ if not(noWarning) then begin\r
+\r
+  txt:=load_mes(a+1);\r
+\r
+  case a of\r
+        8: txt:=txt+'?';\r
+      109: txt:=txt+'$'+HEX(zpvar,4);\r
+   69,115: txt:=txt+str_blad;\r
+       70: txt:=txt+'$'+HEX(adres,4);\r
+  end;\r
+\r
+  warning_mes:=show_full_name(global_name,full_name,false)+' ('+IntToStr(line)+') WARNING: '+txt;\r
+\r
+  if warning_mes<>warning_old then begin\r
+   writeln(warning_mes);\r
+   warning_old:=warning_mes;\r
+  end;\r
+\r
+ end;\r
+\r
+end;\r
+\r
+\r
+procedure madH_save(var b:integer; var s:string);\r
+(*----------------------------------------------------------------------------*)\r
+(*  zapisujemy plik naglowkowy MADS'a                                         *)\r
+(*----------------------------------------------------------------------------*)\r
+var okej: Boolean;\r
+    tst: char;\r
+    i: integer;\r
+begin\r
+\r
+ tst:=s[1];\r
+\r
+ okej:=false;\r
+\r
+ for i:=High(t_mad)-1 downto 0 do\r
+  if t_mad[i].bnk=b then\r
+   if t_mad[i].typ=tst then begin okej:=true; Break end;\r
+\r
+ if okej then begin\r
+  writeln(mmm,#13#10,'; ',s);\r
+  for i:=High(t_mad)-1 downto 0 do\r
+   if t_mad[i].bnk=b then\r
+    if t_mad[i].typ=tst then writeln(mmm,t_mad[i].nam,#9,'=',#9,'$',Hex(t_mad[i].adr,4));\r
+ end;\r
+\r
+end;\r
+\r
+\r
+procedure new_message(var a: string);\r
+var i: integer;\r
+begin\r
+\r
+ if a='' then exit;\r
+\r
+ i:=High(messages);\r
+\r
+ messages[i].pas:=pass;\r
+ messages[i].mes:=a;\r
+\r
+ SetLength(messages,i+2);\r
+\r
+ a:='';\r
+end;\r
+\r
+\r
+procedure koniec(const err: byte);\r
+(*----------------------------------------------------------------------------*)\r
+(*  ERR = 0  bez bledow                                                       *)\r
+(*  ERR = 1  tylko komunikaty WARNING                                         *)\r
+(*  ERR = 2  blad i zatrzymanie asemblacji                                    *)\r
+(*  ERR = 3  bledne parametry dla MADS'a                                      *)\r
+(*----------------------------------------------------------------------------*)\r
+var a, b: integer;\r
+    ok: Boolean;\r
+    txt: string;\r
+    f: textfile;\r
+begin\r
+\r
+ if open_ok then begin\r
+\r
+  Flush(lst);\r
+  CloseFile(lst);\r
+\r
+  Flush_dst;\r
+\r
+  a:=integer( FileSize(dst) );\r
+  CloseFile(dst);\r
+\r
+\r
+  AssignFile(f, plik_lst); FileMode:=0; Reset(f);  // sprawdzamy liczbe wierszy w 'PLIK_LST'\r
+  b:=0;\r
+  while not(eof(f)) do begin\r
+   ReadLn(f, t); inc(b);\r
+   if b>2 then Break;\r
+  end;\r
+  CloseFile(f);\r
+\r
+\r
+  if list_lab then CloseFile(lab);\r
+\r
+\r
+  if (b<3) or (err>1) then begin\r
+   Erase(lst);                          // usuwamy plik LST\r
+   if list_lab then Erase(lab);\r
+  end else\r
+   if (opt and 4>0) then begin\r
+    txt:=load_mes(105+1);\r
+    if not(silent) then new_message(txt);\r
+   end;\r
+\r
+\r
+  if (a=0) or (err>1) then\r
+   Erase(dst)                           // usuwamy plik OBX (plik DST wczesniej musi zostac zamkniety) \r
+  else begin\r
+   txt:=load_mes(106+ord(raw.use)+1);\r
+   if not(silent) then new_message(txt);\r
+  end;\r
+\r
+\r
+  if over then\r
+   if end_string<>'' then write(end_string);\r
+\r
+\r
+  if over and not(silent) then begin\r
+\r
+   if err<>2 then begin\r
+     txt:=IntToStr(line_all)+load_mes(48+1)+' in '+IntToStr(pass_end)+' pass';\r
+     new_message(txt);\r
+\r
+     if a>0 then begin\r
+      txt:=IntToStr(a)+load_mes(49+1);\r
+      new_message(txt);\r
+     end;\r
+\r
+   end;\r
+\r
+  end;\r
+\r
+ end;\r
+\r
+\r
+ if list_mmm then begin\r
+\r
+  b:=0;\r
+  while b<256 do begin\r
+\r
+   ok:=false;\r
+   for a:=High(t_mad)-1 downto 0 do\r
+    if t_mad[a].bnk=b then begin ok:=true; Break end;\r
+\r
+   if ok then begin\r
+\r
+    if b>0 then writeln(mmm,#13#10,' lmb #',b,#9#9,'; BANK #',b);\r
+\r
+    txt:='CONSTANS';   madH_save(b,txt);   // constans\r
+    txt:='VARIABLES';  madH_save(b,txt);   // variables\r
+    txt:='PROCEDURES'; madH_save(b,txt);   // procedures\r
+\r
+   end;\r
+\r
+   inc(b);\r
+  end;\r
+\r
+  CloseFile(mmm);\r
+ end;\r
+\r
+ if list_hhh then begin\r
+  writeln(hhh,#13#10+'#endif');\r
+  CloseFile(hhh);\r
+ end;\r
+\r
+\r
+ for a:=0 to High(messages)-1 do\r
+  if messages[a].pas < 16 then begin\r
+\r
+   if a<>High(messages)-1 then\r
+    writeln(messages[a].mes)\r
+   else\r
+    write(messages[a].mes);\r
+             \r
+   for b:=High(messages)-1 downto 0 do    // usuwamy powtarzajace sie komunikaty\r
+//    if messages[b].pas=messages[a].pas then\r
+     if messages[b].mes=messages[a].mes then messages[b].pas:=$ff;\r
+\r
+  end;\r
+\r
+ if not(silent) then writeln;\r
+\r
+ Halt(err);\r
+end;\r
+\r
+\r
+function TestFile(var a: string): Boolean;\r
+(*----------------------------------------------------------------------------*)\r
+(*  sprawdzamy istnienie pliku na dysku bez udzialu 'SysUtils',               *)\r
+(*  jest to odpowiednik funkcji 'FileExists'                                  *)\r
+(*----------------------------------------------------------------------------*)\r
+var f: textfile;            // !!! koniecznie plik tekstowy !!!\r
+begin\r
+\r
+ AssignFile(f, a);\r
+// {$I-}\r
+ FileMode:=0;\r
+ Reset(f);\r
+// {$I+}\r
+\r
+ if IOResult = 0 then begin\r
+  Result:=true;\r
+  CloseFile(f);\r
+ end else\r
+  Result:=false;\r
+\r
+end;\r
+\r
+\r
+procedure just_t(const a:cardinal);\r
+var len: integer;\r
+begin\r
+\r
+ len:=length(t);\r
+\r
+ if not(len>31) then\r
+  if len+3>29 then begin\r
+   t:=t+' +';\r
+   while length(t)<32 do t:=t+' ';\r
+  end else\r
+   t:=t+' '+Hex(a,2);\r
+\r
+end;\r
+\r
+\r
+procedure bank_adres(a: integer);\r
+begin\r
+ if (dreloc.use) and (a-rel_ofs>=0) then dec(a, rel_ofs);\r
+\r
+ if bank>0 then t:=t+Hex(bank,2)+',';\r
+\r
+ {if a>=0 then} t:=t+Hex(a,4);           // inaczej nie wyswietli wartosci 64bit\r
+end;\r
+\r
+\r
+procedure save_dst(const a: byte);\r
+var x, y, ex, ey: integer;\r
+    znk: char;\r
+begin\r
+\r
+ if (pass=pass_end) and (opt and 2>0) then begin\r
+\r
+  if org then begin\r
+\r
+   SetLength(t,7);\r
+\r
+   if hea and (opt and 1>0) and not(dreloc.sdx) then t:=t+'FFFF> ';\r
+\r
+   x:=adres;\r
+   y:=t_hea[hea_i];\r
+\r
+   if dreloc.use then begin\r
+    dec(x,rel_ofs);\r
+    dec(y,rel_ofs);\r
+   end;\r
+\r
+   if hea_ofs.adr>=0 then begin\r
+    y:=hea_ofs.adr+(y-x); x:=hea_ofs.adr;\r
+   end;\r
+\r
+   if x<=y then begin\r
+    ex:=x; ey:=y\r
+   end else begin\r
+    ey:=x; ex:=y\r
+   end;\r
+\r
+   if blok>0 then begin       // dlugosc bloku relokowalnego\r
+    y:=y-x+1;\r
+    znk:=',';\r
+   end else\r
+    znk:='-';\r
+\r
+   if adres>=0 then begin\r
+    if ex>ey then bank_adres(t_hea[hea_i-1]+1) else bank_adres(x);\r
+    if (ex<=ey) and (opt and 1>0) then t:=t+znk+Hex(y,4)+'>';\r
+   end;\r
+\r
+   if hea and (opt and 1>0) and not(dreloc.sdx) then begin\r
+    put_dst($FF); put_dst($FF);\r
+   end;\r
+\r
+   if (opt and 1>0) then begin\r
+    put_dst( byte(x) ); put_dst( byte(x shr 8) );\r
+    put_dst( byte(y) ); put_dst( byte(y shr 8) );\r
+   end;\r
+\r
+   org:=false; hea:=false;\r
+  end;\r
+\r
+  just_t(a);\r
+\r
+  if not(blokuj_zapis) then put_dst(a);\r
+\r
+ end else begin\r
+\r
+  fill:=0;        // istotne dla zapisu pliku RAW\r
+\r
+  if org and raw.use then begin\r
+   hea:=false;    // istotne dla zapisu pliku RAW\r
+   org:=false;    // istotne dla zapisu pliku RAW\r
+  end;\r
+\r
+ end;\r
+\r
+end;\r
+\r
+\r
+procedure save_dstW(const a: integer);\r
+begin\r
+ save_dst( byte(a) );         // lo\r
+ save_dst( byte(a shr 8) );   // hi\r
+end;\r
+\r
+\r
+procedure save_dstS(var a: string);\r
+var i, len: integer;\r
+begin\r
+ len:=length(a);\r
+\r
+ save_dstW( len );\r
+\r
+ for i:=1 to len do save_dst( ord(a[i]) );\r
+end;\r
+\r
+\r
+procedure blad(var a: string; const b: integer);\r
+(*----------------------------------------------------------------------------*)\r
+(*  wyswietla komunikat bledu nr w 'B'                                        *)\r
+(*  wyjatek stanowi b<0 wtedy wyswietli komunikat 'Branch...'                 *)\r
+(*  dla komunikatu nr 14 wyswietli nazwe wybranego trybu pracy CPU 8-16bit    *)\r
+(*----------------------------------------------------------------------------*)\r
+var add, prv, con: string;\r
+begin\r
+\r
+ if b=0 then begin\r
+\r
+  overflow := true;\r
+\r
+  if pass<>pass_end then exit;\r
+ end;\r
+\r
+                              \r
+ add:=''; prv:=''; con:='';\r
+\r
+ line_err := line;\r
+                     \r
+ if run_macro then begin\r
+  con := t_wyw[1].zm;  new_message(con);\r
+  global_name:=t_wyw[wyw_idx].pl;\r
+  inc(line_err,t_wyw[wyw_idx].nr);\r
+\r
+ end else\r
+  if not(rept_run) and not(FOX_ripit) and not(loop_used) and not(code6502) then\r
+   if line_add>0 then inc(line_err,line_add);\r
+\r
+{\r
+ if str_blad<>'' then\r
+  while (length(str_blad)>0) and (str_blad[1]='#') do str_blad:=copy(str_blad,2,length(str_blad));\r
+}\r
+\r
+\r
+// usuwamy znaki #0 bo to pewnie jakies krzaki-dziwaki\r
+ while (length(a)>0) and (pos(#0,a)>0) do SetLength(a,pos(#0,a)-1);  \r
+\r
+\r
+ if (a<>'') and not(b in [18,34]) then begin con := a; new_message(con) end;\r
+\r
+ con := con+show_full_name(global_name,full_name,false)+' ('+IntToStr(Int64(line_err)+ord(line_err=0))+load_mes(81);\r
+\r
+ if b=18 then add:=' '''+a+'''';\r
+\r
+ if b=2 then prv:=load_mes(80);\r
+\r
+ if b=113 then prv:=load_mes(112+1);\r
+\r
\r
+ if b in [2,113] then prv:=prv+str_blad;\r
+\r
\r
+ if b in [5,8,9,35,41,46,61,68,73,103] then add:=add+str_blad;\r
+\r
+ if b in [2,5,35] then add:=add+load_mes(77+1+ord(dreloc.use))+IntToStr(bank)+')';   // BLOK / BANK\r
+\r
+ if b=103 then add:=add+load_mes(104+1);       // ... as public\r
+\r
+ if b=14 then add:=load_mes( 82+ord( opt and 16>0 ) );    // if opt and 16>0 then add:='816)' else add:='02)';\r
+\r
+ if b=17 then\r
+   if proc then add:='P' else\r
+    if macro then add:='M';\r
+\r
+ if b<0 then\r
+  con := con+load_mes(22)+Hex(abs(b),4)+load_mes(23)\r
+ else\r
+  if b<>34 then\r
+   con := con+prv+load_mes(b+1)+add\r
+  else\r
+   con := con+a+add;\r
+\r
+\r
+ status := 2;\r
+\r
+ new_message(con);\r
+\r
+// pewne bledy wymagaja natychmiastowego zakonczenia asemblacji\r
+// jesli wystapi za duzo bledow (>512) to te¿ konczymy asemblacje\r
+ if (b in [3,8,10,12,13,15,17,18,23,24,25,28,30,34,40,41,46,57,58,62,66,73,74,76,87]) or (High(messages)>512) then begin over:=true; koniec(2) end;\r
+end;\r
+\r
+\r
+procedure justuj;\r
+var j: integer;\r
+begin\r
+\r
+ if (pass=pass_end) and (t<>'') and not(FOX_ripit) then begin\r
+\r
+  j:=length(t);\r
+\r
+  while j<32 do begin\r
+   t:=t+#9;\r
+   inc(j,8);\r
+  end;\r
+\r
+ end;\r
+\r
+end;\r
+\r
+\r
+procedure blad_und(var old: string; const b: string; const x: byte);\r
+(*----------------------------------------------------------------------------*)\r
+(*  wyswietla komunikat 'Undeclared label ????'                               *)\r
+(*  wyswietla komunikat 'Label ???? declared twice'                           *)\r
+(*  wyswietla komunikat 'Undeclared macro ????'                               *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+ str_blad:=b;\r
+\r
+ if x=69 then\r
+  warning(x)\r
+ else\r
+  blad(old,x);\r
+\r
+end;\r
+\r
+\r
+procedure WriteAccessFile(var a: string);\r
+(*----------------------------------------------------------------------------*)\r
+(*  sprawdzamy mozliwosc zapisu do pliku o podanej nazwie                     *)\r
+(*----------------------------------------------------------------------------*)\r
+var f: textfile;             // !!! koniecznie plik tekstowy !!!\r
+begin\r
+\r
+ AssignFile(f,a);\r
+// {$I-}\r
+ FileMode:=1;\r
+ Rewrite(f);\r
+// {$I+}\r
+\r
+ if IOResult = 0 then\r
+  CloseFile(f)\r
+ else\r
+  blad(a,18);\r
+\r
+end;\r
+\r
+\r
+function GetFile(a: string; var zm: string): string;\r
+(*----------------------------------------------------------------------------*)\r
+(*  szukamy pliku w zadeklarowanych sciezkach poszukiwan                      *)\r
+(*----------------------------------------------------------------------------*)\r
+var c, p: string;\r
+    i: integer;\r
+begin\r
+ if a='' then blad(zm,3);\r
+\r
+ p:=path+a;\r
+ if TestFile(p) then a:=path+a;\r
+\r
+ Result:=a;\r
+\r
+ if TestFile(a) then exit;\r
+\r
+ for i:=0 to High(t_pth)-1 do begin            // !!! kolejnosc przegladania T_PTH[0..] ma znaczenie !!!\r
+  p:=t_pth[i];\r
+\r
+  if p<>'' then\r
+    if not(_pth(p[length(p)])) then p:=p+PathDelim;\r
+\r
+  c:=p+a;\r
+  if TestFile(c) then begin Result:=c; Break end;\r
+ end;\r
+\r
+end;\r
+\r
+\r
+procedure blad_ill(var a:string; const c:char);\r
+(*----------------------------------------------------------------------------*)\r
+(*  wyswietla komunikat 'Illegal character ??'                                *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+ str_blad:=c;\r
+\r
+ blad(a,8);\r
+end;\r
+\r
+\r
+function fASC(var a: string): byte;\r
+(*----------------------------------------------------------------------------*)\r
+(*  !!! koniecznie obliczamy kod dla 3 pierwszych znakow !!!                  *)\r
+(*  obliczamy sume kontrolna dla 3 literowego ciagu znakowego 'A'..'Z'        *)\r
+(*  obliczona suma kontrolna jest indeksem do tablicy HASH                    *)\r
+(*----------------------------------------------------------------------------*)\r
+var i: cardinal;\r
+    j: integer;\r
+begin\r
+\r
+ Result:=0;\r
+\r
+ if length(a)>=3 then begin          // !!! koniecznie LENGTH(A)>=3 !!! aby obliczal LDA.W itp.\r
+\r
+  for j:=1 to 3 do\r
+   if not(a[j] in ['A'..'Z']) then exit;\r
+\r
+  i:= ord(a[1])-ord('@') + (ord(a[2])-ord('@')) shl 5 + (ord(a[3])-ord('@')) shl 10;\r
+\r
+  Result:=hash[i];\r
+\r
+ end;\r
+\r
+end;\r
+\r
+\r
+function fCRC16(var a: string): byte;\r
+(*----------------------------------------------------------------------------*)\r
+(*  obliczamy sume kontrolna CRC 16-bit dla krotkiego ciagu znakowego <3..6>  *)\r
+(*  obliczona 16-bitowa suma kontrolna jest indeksem do tablicy HASH          *)\r
+(*----------------------------------------------------------------------------*)\r
+var x, i: integer;\r
+begin\r
+ x:=$ffff;\r
+\r
+ i:=1;\r
+ while i<=length(a) do begin                     // WHILE jest krótsze od FOR\r
+  x:=tCRC16[byte(x shr 8) xor byte(a[i])] xor (x shl 8);\r
+  inc(i);\r
+ end;\r
+\r
+ Result:=hash[x and $ffff];\r
+end;\r
+\r
+\r
+function l_lab(var a: string): integer;\r
+(*----------------------------------------------------------------------------*)\r
+(*  szukamy etykiety i zwracamy jej indeks do tablicy 'T_LAB'                 *)\r
+(*  jesli nie ma takiej etykiety zwracamy wartosc -1                          *)\r
+(*----------------------------------------------------------------------------*)\r
+var x: cardinal;\r
+    i, len: integer;\r
+begin\r
+ Result:=-1;\r
+\r
+ len:=length(a);   \r
+\r
+ x:=$ffffffff;\r
+\r
+ i:=1;\r
+ while i<=len do begin                           // WHILE jest krótsze od FOR\r
+  x:=tCRC32[byte(x) xor byte(a[i])] xor (x shr 8);\r
+  inc(i);\r
+ end;\r
+\r
+// OK jesli znaleziona etykieta ma kod >=__id_param, lub aktualna wartosc BANK=0\r
+// OK jesli znaleziona etykieta jest z aktualnego banku lub banku zerowego (BNK=BANK | BNK=0)\r
+\r
+ for i:=High(t_lab)-1 downto 0 do\r
+  if (t_lab[i].len=len) and (t_lab[i].nam=x) then\r
+   if (bank=0) or (t_lab[i].bnk>=__id_param) then begin Result:=i; Break end else\r
+    if t_lab[i].bnk in [bank,0] then begin Result:=i; Break end;\r
+\r
+end;\r
+\r
+\r
+procedure obetnij_kropke(var b: string);\r
+(*----------------------------------------------------------------------------*)\r
+(*  usuwamy z ciagu ostatni ciag znakow po kropce, ciag konczy znak kropki    *)\r
+(*----------------------------------------------------------------------------*)\r
+var i: integer;\r
+begin\r
+\r
+  i:=length(b);\r
+  if (b<>'') and (i>1) then begin\r
+\r
+   dec(i);\r
+   while (b[i]<>'.') and (i>=1) do dec(i);\r
+\r
+   SetLength(b,i);\r
+  end;\r
+\r
+end;\r
+\r
+\r
+function search(var a,x: string): integer;\r
+(*----------------------------------------------------------------------------*)\r
+(*  szukamy nazwy etykiety w tablicy T_LAB, jesli w nazwie wystepuje kropka   *)\r
+(*  obcinamy nazwe i szukamy dalej                                            *)\r
+(*----------------------------------------------------------------------------*)\r
+var b, t: string;\r
+begin\r
+ b:=x+lokal_name;\r
+\r
+ t:=b+a;\r
+ Result:=l_lab(t);\r
+\r
+ while (Result<0) and (pos('.',b)>0) do begin\r
+\r
+  obetnij_kropke(b);\r
+\r
+  t:=b+a;\r
+  Result:=l_lab(t);\r
+ end;\r
+\r
+end;\r
+\r
+\r
+function load_lab(var a:string; const test:Boolean): integer;\r
+(*----------------------------------------------------------------------------*)\r
+(*  szukamy etykiety i zwracamy jej indeks do tablicy 'T_LAB'                 *)\r
+(*  jesli nie ma takiej etykiety zwracamy wartosc -1                          *)\r
+(*                                                                            *)\r
+(*  jesli jest uruchomione makro i nie znajdziemy etykiety to szukamy w proc  *)\r
+(*  jesli nie znajdziemy w proc to wtedy szukamy w glownym programie          *)\r
+(*----------------------------------------------------------------------------*)\r
+var txt: string;\r
+    i: integer;\r
+begin\r
+\r
+  if test then begin\r
+\r
+    if run_macro then begin\r
+     Result:=search(a,macro_nr);\r
+\r
+     if Result>=0 then exit;\r
+    end;\r
+\r
+\r
+    if proc then begin\r
+     Result:=search(a,proc_name);\r
+\r
+     if Result>=0 then exit;\r
+    end;\r
+\r
+    txt:='';\r
+    Result:=search(a,txt);\r
+    if Result>=0 then exit;\r
+\r
+  end;\r
+\r
+\r
+  txt:=lokal_name+a;\r
+  Result:=l_lab(txt);\r
+\r
+  if Result<0 then Result:=search(a,proc_name);  \r
+             \r
+  if Result<0 then                         // test dla .USE [.USING]\r
+   if usi_idx>0 then\r
+    for i:=0 to usi_idx-1 do {begin}\r
+     if ((pos(t_usi[i].nam,lokal_name)=1) or (pos(t_usi[i].nam,proc_name)=1)) or (lokal_name=t_usi[i].nam) or (proc_name=t_usi[i].nam) then begin\r
+\r
+      txt:=t_usi[i].lab+'.'+a;  \r
+\r
+      Result:=l_lab(txt);\r
+\r
+      if Result>=0 then\r
+       exit\r
+      else begin\r
+       txt:=lokal_name+txt;\r
+\r
+       Result:=l_lab(txt);\r
+\r
+       if Result>=0 then exit;\r
+      end;\r
+\r
+     end;\r
+\r
+\r
+end;\r
+\r
+\r
+procedure zapisz_etykiete(var a:string; const ad:cardinal; const ba:integer; const symbol:char);\r
+(*----------------------------------------------------------------------------*)\r
+(*  zapisujemy nazwe etykiety, jej adres itp w pliku .LAB                     *)\r
+(*  dodatkowo jesli jest to wymagane w pliku naglowkowym .C dla cc65          *)\r
+(*  nie zapisujemy etykiet tymczasowych, lokalnych w makrach                  *)\r
+(*----------------------------------------------------------------------------*)\r
+var i: integer;\r
+begin\r
+\r
+ if pass=pass_end then\r
+  if not(struct.use) and not(not(mae_labels) and (symbol='?')) and not(pos('::',a)>0) then begin\r
+\r
+   if list_lab then writeln(lab,Hex(ba,2),#9,Hex(ad,4),#9,a);\r
+\r
+   if not(proc) and (ba<256) then begin\r
+    if list_hhh and (ba=0) then writeln(hhh,'#define ',name,'_',a,' 0x',Hex(ad,4));\r
+    if list_mmm then begin\r
+     i:=High(t_mad);             // SAVE_MAD\r
+                                 //\r
+     t_mad[i].nam:=a;            //\r
+     t_mad[i].adr:=ad;           //\r
+     t_mad[i].bnk:=byte(ba);     //\r
+     t_mad[i].typ:=label_type;   //\r
+                                 //\r
+     SetLength(t_mad,i+2);       //\r
+    end;\r
+\r
+   end;\r
+\r
+  end;\r
+\r
+end;\r
+\r
+\r
+function loa_str(var a:string; var id:integer): integer;\r
+(*----------------------------------------------------------------------------*)\r
+(*  sprawdz czy wystepuje deklaracja pola struktury w T_STR                   *)\r
+(*----------------------------------------------------------------------------*)\r
+var i: integer;\r
+begin\r
+\r
+  Result:=-1;\r
+\r
+  for i:=High(t_str)-1 downto 0 do     // !!! koniecznie przegladamy od tylu !!!\r
+   if t_str[i].id=id then\r
+    if t_str[i].lab=a then begin Result:=i; Break end;\r
+\r
+// dzieki temu ze przegladamy od tylu nigdy nie trafimy na nazwe struktury,\r
+// nazwa struktury ma numer NO ten sam co pierwsze pole struktury\r
+end;\r
+\r
+\r
+function loa_str_no(var id:integer; const x:integer): integer;\r
+(*----------------------------------------------------------------------------*)\r
+(*  odczytaj indeks do pola struktury o konkretnym numerze X                  *)\r
+(*----------------------------------------------------------------------------*)\r
+var i: integer;\r
+begin\r
+\r
+  Result:=-1;\r
+\r
+  for i:=High(t_str)-1 downto 0 do     // !!! koniecznie przegladamy od tylu !!!\r
+   if t_str[i].id=id then\r
+    if t_str[i].no=x then begin Result:=i; Break end;\r
+\r
+end;\r
+\r
+\r
+procedure save_str(var a:string; const ofs,siz,rpt:integer; const ad:cardinal; const bn:integer);\r
+(*----------------------------------------------------------------------------*)\r
+(* zapisz informacje na temat pol struktury, jesli wczesniej nie wystapily    *)\r
+(*----------------------------------------------------------------------------*)\r
+var i: integer;\r
+begin\r
+          \r
+  i:=loa_str(a, struct.id);\r
+\r
+  if i<0 then begin\r
+   i:=High(t_str);\r
+   SetLength(t_str,i+2);\r
+  end;\r
+\r
+  t_str[i].id:=struct.id;\r
+\r
+  t_str[i].no:=struct.cnt;\r
+\r
+  t_str[i].adr := ad;\r
+  t_str[i].bnk := bn;\r
+\r
+  t_str[i].lab := a;\r
+  t_str[i].ofs := ofs;\r
+  t_str[i].siz := siz;\r
+\r
+  if rpt=0 then\r
+   t_str[i].rpt := 1\r
+  else\r
+   t_str[i].rpt := rpt;\r
+  \r
+end;\r
+\r
+\r
+procedure s_lab(var a:string; const ad:cardinal; var ba:integer; var old:string; const symbol:char);\r
+(*----------------------------------------------------------------------------*)\r
+(*  wlasciwa procedura realizujaca zapamietanie etykiety w tablicy 'T_LAB'    *)\r
+(*----------------------------------------------------------------------------*)\r
+var tmp: cardinal;\r
+    x, len, i: integer;\r
+begin\r
+// sprawdz czy nie ma juz takiej etykiety\r
+// bo jesli jest to nie dopisuj nowej pozycji tylko popraw stara\r
+ x:=l_lab(a);\r
+\r
+ if x<0 then begin\r
+  x:=High(t_lab);\r
+  SetLength(t_lab,x+2);\r
+ end else\r
+  if symbol<>'?' then\r
+   if (t_lab[x].bnk<>ba) and not(struct_used.use) and not(enum.use) then blad_und(old,a,2);\r
+\r
+ len:=length(a);\r
+\r
+ tmp:=$ffffffff;              // crc32\r
+\r
+ i:=1;\r
+ while i<=len do begin                           // WHILE jest krótsze od FOR\r
+  tmp:=tCRC32[byte(tmp) xor byte(a[i])] xor (tmp shr 8);\r
+  inc(i);\r
+ end;\r
+\r
+ if pass>0 then\r
+ if (symbol<>'?') or mae_labels then             // jesli to styl etykiet MAE to musimy je sprawdzic\r
+  if t_lab[x].nam=tmp then                       // normalnie sprawdzamy tylko etykiety z pierwszym znakiem <>'?'\r
+   if (t_lab[x].bnk<__id_param) and not(t_lab[x].lid) then begin\r
+\r
+    if t_lab[x].pas=pass then blad_und(old,a,2); // nie mozna sprawdzac dwa razy tej samej etykiety w aktualnym przebiegu\r
+\r
+    if not(next_pass) then                       // sprawdz czy potrzebny jest dodatkowy przebieg\r
+     if mne_used then                            // jakis mnemonik musial zostac wczesniej wykonany\r
+      next_pass := (t_lab[x].adr <> ad);\r
+\r
+   end;\r
+\r
+\r
+ if (pass=pass_end) and unused_label and (ba<__id_param) and not(struct.use) and not(run_macro) and not(t_lab[x].use) then begin\r
+   str_blad:=a;\r
+   warning(115);\r
+ end;\r
+\r
+\r
+ if t_lab[x].lid and not(new_local) then blad_und(old,a,2);\r
\r
+ t_lab[x].lid := new_local;\r
+\r
+ t_lab[x].typ := label_type;\r
+\r
+ t_lab[x].len := len;\r
+\r
+ t_lab[x].nam := tmp;\r
+\r
+ if new_local then begin\r
+  if t_lab[x].pas<>pass then t_lab[x].adr := ad;   // tylko pierwszy adres dla .LOCAL\r
+ end else\r
+  t_lab[x].adr := ad;\r
\r
+ t_lab[x].bnk := ba;\r
+ t_lab[x].blk := blok;\r
+\r
+ t_lab[x].pas := pass;\r
+\r
+ t_lab[x].ofs := org_ofset;\r
+\r
+ if (blok>0) or dreloc.use then t_lab[x].rel := true;\r
+\r
+ zapisz_etykiete(a,ad,ba,symbol);\r
+end;\r
+\r
+\r
+procedure save_lab(var a:string; const ad:cardinal; ba:integer; var old:string);\r
+(*----------------------------------------------------------------------------*)\r
+(*  zapamietujemy etykiete, adres, bank                                       *)\r
+(*----------------------------------------------------------------------------*)\r
+var tmp: string;\r
+begin\r
+\r
+ if a<>'' then begin                       // !!! konieczny test\r
+\r
+  if mae_labels and (a[1]<>'?') then begin\r
+\r
+   tmp:=a;\r
+   lokal_name:=a+'.';\r
+\r
+  end else\r
+   if run_macro then tmp:=macro_nr+lokal_name+a else   // !!! nie remowac LOKAL_NAME !!!\r
+    if proc then tmp:=proc_name+lokal_name+a else\r
+     tmp:=lokal_name+a;\r
+\r
+  s_lab( tmp, ad, ba, old, a[1] );\r
+\r
+ end;\r
+  \r
+end;\r
+\r
+\r
+procedure save_arr(const a:cardinal; var b:integer);\r
+begin\r
+\r
+ t_arr[array_idx].adr:=a;\r
+ t_arr[array_idx].bnk:=b;\r
+\r
+ t_arr[array_idx].ofs:=org_ofset;\r
+\r
+ inc(array_idx);\r
+\r
+ if array_idx>High(t_arr) then SetLength(t_arr, array_idx+1);\r
+\r
+end;\r
+\r
+\r
+procedure save_hea;\r
+begin\r
+ t_hea[hea_i]:=adres-1 - fill;\r
+\r
+ fill:=0;\r
\r
+ inc(hea_i);\r
\r
+ if hea_i>High(t_hea) then SetLength(t_hea,hea_i+1);\r
+end;\r
+\r
+\r
+procedure save_par(var a: string);\r
+var i: integer;\r
+begin\r
+ i:=High(t_par);\r
+\r
+ t_par[i]:=a;\r
+\r
+ SetLength(t_par,i+2);\r
+end;\r
+\r
+\r
+procedure save_mac(var a: string);\r
+var i: integer;\r
+begin\r
+ i:=High(t_mac);\r
+\r
+ t_mac[i]:=a;     \r
+\r
+ SetLength(t_mac,i+2);\r
+end;\r
+\r
+\r
+procedure save_end(const a: byte);\r
+begin\r
+ t_end[end_idx].kod := a;\r
+ t_end[end_idx].adr := adres;\r
+\r
+ t_end[end_idx].sem := false;           // semicolon {\r
+\r
+ inc(end_idx);\r
+\r
+ if end_idx>High(t_end) then SetLength(t_end, end_idx+1);\r
+end;\r
+\r
+\r
+procedure dec_end(var zm: string; const a: byte);\r
+begin\r
+ dec(end_idx);\r
+\r
+ if t_end[end_idx].kod <> a then\r
+  case a of\r
+   __endpg: blad(zm,64);  // Missing .PAGES\r
+   __ends: blad(zm,55);   // Missing .STRUCT\r
+   __endm: blad(zm,97);   // Missing .MACRO\r
+   __endw: blad(zm,88);   // Missing .WHILE\r
+   __endt: blad(zm,95);   // Missing .TEST\r
+   __enda: blad(zm,59);   // Missing .ARRAY\r
+   __endr: blad(zm,51);   // Missing .REPT\r
+  end;\r
+\r
+end;\r
+\r
+\r
+procedure save_pub(var a,zm: string);\r
+(*----------------------------------------------------------------------------*)\r
+(*  zapisujemy symbol .PUBLIC                                                 *)\r
+(*  jesli ADD = FALSE to w przypadku powtorzenia symbolu wystapi blad         *)\r
+(*----------------------------------------------------------------------------*)\r
+var i: integer;\r
+begin\r
+\r
+ for i:=pub_idx-1 downto 0 do           // symbole public nie moga sie powtarzac\r
+  if t_pub[i].nam=a then blad_und(zm,a,2);\r
+\r
+ t_pub[pub_idx].nam := a;\r
+\r
+ inc(pub_idx);\r
+\r
+ if pub_idx>High(t_pub) then SetLength(t_pub,pub_idx+1);\r
+end;\r
+\r
+\r
+procedure save_rel(var a:integer; const idx, b:integer; var reloc_value:relVal);\r
+begin\r
+\r
+if dreloc.use or dreloc.sdx then begin\r
+\r
+  if vector then t_rel[rel_idx].adr:=a-rel_ofs else t_rel[rel_idx].adr:=a-rel_ofs+1;\r
+\r
+  t_rel[rel_idx].blk:=b;\r
+  if not(empty) then t_rel[rel_idx].idx:=idx else t_rel[rel_idx].idx:=-100;\r
+  t_rel[rel_idx].blo:=blok;\r
+\r
+  if dreloc.use then begin\r
+   t_rel[rel_idx].idx:=siz_idx;\r
+   t_rel[rel_idx].bnk:=bank;\r
+\r
+   inc(siz_idx);\r
+\r
+   rel_used:=true;               // pozwalamy na zapis rozmiaru do T_SIZ\r
+\r
+   if siz_idx>High(t_siz) then SetLength(t_siz,siz_idx+1);\r
+  end;\r
+\r
+  inc(rel_idx);\r
+\r
+  if rel_idx>High(t_rel) then SetLength(t_rel,rel_idx+1);\r
+\r
+  reloc:=true;\r
+\r
+  reloc_value.use:=true;\r
+\r
+  inc(reloc_value.cnt);\r
+ end;\r
+\r
+end;\r
+\r
+\r
+procedure save_relAddress(const arg:integer; var reloc_value: relVal);\r
+begin\r
+\r
+  if not(branch) then\r
+   if t_lab[arg].rel then begin\r
+    save_rel(adres, -1, t_lab[arg].blk, reloc_value);\r
+   end;\r
+\r
+end;\r
+\r
+\r
+function wartosc(var a:string; var v:Int64; const o:char): cardinal;\r
+(*----------------------------------------------------------------------------*)\r
+(*  sprawdzamy zakres wartosci zmiennej 'V' na podstawie kodu w 'O'           *)\r
+(*----------------------------------------------------------------------------*)\r
+var x: Boolean;\r
+    i: int64;\r
+begin\r
+ Result:=cardinal( v );\r
+\r
+ i:=abs(v);                  // koniecznie ABS inaczej nie zadziala prawidlowo\r
+\r
+ case o of\r
+               'B' :  x := i > $FF;\r
+           'A','V' :  x := i > $FFFF;\r
+           'E','T' :  x := i > $FFFFFF;\r
+//   'F','G','L','H' :  x := i > $FFFFFFFF;   // !!! nie realne !!! zaremowac aby dzialalo odejmowanie\r
+ else\r
+  x:=false;\r
+ end;\r
+\r
+ if x then blad(a,0);\r
+                      \r
+end;\r
+\r
+\r
+function _ope(var a: char): Boolean;\r
+(*----------------------------------------------------------------------------*)\r
+(*  dopuszczalne operandy                                                     *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+ Result := (a in ['=','<','>','!'])\r
+end;\r
+\r
+\r
+function _eol(var a: char): Boolean;\r
+(*----------------------------------------------------------------------------*)\r
+(*  test konca linii                                                          *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+ Result := (a in [#0,#9,' '])\r
+end;\r
+\r
+\r
+function _dec(var a: char): Boolean;\r
+(*----------------------------------------------------------------------------*)\r
+(*  dopuszczalne znaki dla liczb decymalnych                                  *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+ Result := (a in ['0'..'9'])\r
+end;\r
+\r
+\r
+function _lab(var a: char): Boolean;\r
+(*----------------------------------------------------------------------------*)\r
+(*  dopuszczalne znaki dla etykiet                                            *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+ Result := (UpCase(a) in ['A'..'Z','0'..'9','_','?','@','.'])\r
+end;\r
+\r
+\r
+function _bin(var a: char): Boolean;\r
+(*----------------------------------------------------------------------------*)\r
+(*  dopuszczalne znaki dla liczb binarnych                                    *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+ Result := (a in ['0'..'1'])\r
+end;\r
+\r
+\r
+function _hex(var a: char): Boolean;\r
+(*----------------------------------------------------------------------------*)\r
+(*  dopuszczalne znaki dla liczb heksadecymalnych                             *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+ Result := (UpCase(a) in ['0'..'9','A'..'F'])\r
+end;\r
+\r
+\r
+function _first_char(var a: char): Boolean;\r
+(*----------------------------------------------------------------------------*)\r
+(*  pierwsze dopuszczalne znaki dla linii                                     *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+ Result := (UpCase(a) in ['A'..'Z','_','?','@','.','+','-','=','*',':'])\r
+end;\r
+\r
+\r
+function _dir_first(var a: char): Boolean;\r
+(*----------------------------------------------------------------------------*)\r
+(*  pierwsze dopuszczalne znaki dla dyrektyw                                  *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+ Result := (a in ['.','#'])\r
+end;\r
+\r
+\r
+function _lab_first(var a: char): Boolean;\r
+(*----------------------------------------------------------------------------*)\r
+(*  pierwsze dopuszczalne znaki dla etykiet                                   *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+ Result := (UpCase(a) in ['A'..'Z','_','?','@'])\r
+end;\r
+\r
+\r
+function _lab_firstEx(var a: char): Boolean;\r
+(*----------------------------------------------------------------------------*)\r
+(*  pierwsze dopuszczalne znaki dla etykiet w wyrazeniach                     *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+ Result := (UpCase(a) in ['A'..'Z','_','?','@',':'])\r
+end;\r
+\r
+\r
+function test_char(i:integer; var a:string; const sep,sep2:Char): Boolean;\r
+(*----------------------------------------------------------------------------*)\r
+(* test konca linii, linie moga konczyc znaki #0, #9, ' ', ';', '//','/*','\' *)\r
+(*----------------------------------------------------------------------------*)\r
+var txt: string;\r
+begin\r
+\r
+  if a='' then begin Result:=false; exit end;                 \r
+\r
+  if (a[i]='/') and (a[i+1]='*') then begin    // !!! omin_spacje !!! tutaj niemozliwe\r
+\r
+   txt:=''; ___search_comment_block(i,a, txt);\r
+   \r
+{   inc(i,2);\r
+   while i<=length(a) do begin\r
+\r
+    if a[i]='*' then\r
+     if a[i+1]='/' then begin\r
+\r
+      inc(i);\r
+      if i=length(a) then begin\r
+       Result:=true;\r
+       exit\r
+      end else begin\r
+       __inc(i,a);\r
+       Break\r
+      end;\r
+\r
+     end;\r
+\r
+    __inc(i,a);\r
+   end;}\r
+\r
+  end;\r
+\r
+ Result := (a[i] in [#0,#9,'\',';',sep,sep2]) or ((a[i]='/') and (a[i+1] in ['/'{,'*'}]));\r
+end;\r
+\r
+\r
+procedure test_eol(const i:integer; var a,old:string; const b:char);\r
+(*----------------------------------------------------------------------------*)\r
+(*  sprawdzamy czy nie ma niepoprawnych znakow na koncu linii                 *)\r
+(*  linia moze konczyc sie znakami #0,#9,';',' ','//' lub przecinkiem ','     *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+ if not(a[i] in [#0,#9,'\',';',' ',b]) and not((a[i]='/') and (a[i+1] in ['/','*'])) then blad(old,4)\r
+end;\r
+\r
+\r
+function get_directive(var i:integer; var a:string): string;\r
+(*----------------------------------------------------------------------------*)\r
+(*  pobierz dyrektywe zaczynajaca sie znakami '.', '#'                        *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+ Result:='';\r
+\r
+ if _dir_first(a[i]) then begin\r
+  Result:=a[i];\r
+  inc(i);\r
+\r
+  while _lab(a[i]) do begin Result:=Result+UpCase(a[i]); inc(i) end;\r
+\r
+ end;\r
+\r
+end;\r
+\r
+\r
+function get_lab(var i:integer; var a:string; const tst:Boolean): string;\r
+(*----------------------------------------------------------------------------*)\r
+(*  pobierz etykiete zaczynajaca sie znakami 'A'..'Z','_','?','@'             *)\r
+(*  jesli TST = TRUE to etykieta musi zawierac jakies znaki                   *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+ Result:='';\r
+\r
+ if a<>'' then begin\r
+\r
+  if tst then omin_spacje(i,a);\r
+\r
+  if _lab_first(a[i]) then\r
+   while _lab(a[i]) do begin Result:=Result+UpCas_(a[i]); inc(i) end;\r
+\r
+ end;\r
+\r
+ if tst then\r
+  if Result='' then blad(a,15);\r
+end;\r
+\r
+\r
+function get_string(var i:integer; var a,old:string; const test:Boolean): string;\r
+(*----------------------------------------------------------------------------*)\r
+(*  pobiera ciag znakow, ograniczony znakami '' lub ""                        *)\r
+(*  podwojny '' oznacza literalne '                                           *)\r
+(*  podwojny "" oznacza literalne "                                           *)\r
+(*  TEST = TRUE sprawdza czy ciag jest pusty                                  *)\r
+(*----------------------------------------------------------------------------*)\r
+var len: integer;\r
+    znak, gchr: char;\r
+begin\r
+ Result:='';\r
+\r
+ omin_spacje(i,a);\r
+ if not(a[i] in ['''','"']) then exit;\r
+\r
+ gchr:=a[i]; len:=length(a);\r
+\r
+ while i<=len do begin\r
+  inc(i);         // omijamy pierwszy znak ' lub "\r
+\r
+  znak:=a[i];\r
+\r
+  if znak=gchr then begin\r
+   inc(i);\r
+   if a[i]=gchr then znak:=gchr else begin\r
+    if test then if Result='' then blad(old,3);\r
+    exit;\r
+   end;\r
+  end;\r
+\r
+  Result:=Result+znak;\r
+ end;\r
+\r
+ if not(komentarz) then blad(a,3);       // nie napotkal znaku konczacego ciag ' lub "\r
+end;\r
+\r
+\r
+function get_datUp(var i:integer; var a:string; const sep:Char; const tst:Boolean): string;\r
+(*----------------------------------------------------------------------------*)\r
+(* pobieramy ciag znakow (dyrektywy), zmieniamy wielkosc liter na duze        *)\r
+(* jeli TST = TRUE to ciag musi byc niepusty                                  *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+ Result:='';\r
+\r
+ omin_spacje(i,a);\r
+\r
+ if a<>'' then\r
+  while (a[i]<>'=') and not(test_char(i,a,' ',sep)) do begin\r
+   Result := Result + UpCase(a[i]);\r
+   inc(i);\r
+  end;\r
+\r
+ if tst then\r
+  if Result='' then blad(a,23);\r
+\r
+end;\r
+\r
+\r
+function get_type(var i:integer; var zm,old: string; const tst:Boolean): byte;\r
+(*----------------------------------------------------------------------------*)\r
+(*  sprawdzamy czy odczytany ciag znakow oznacza dyrektywe typu danych        *)\r
+(*  akceptowane dyrektywy typu to .BYTE, .WORD, .LONG, .DWORD                 *)\r
+(*----------------------------------------------------------------------------*)\r
+var txt: string;\r
+begin\r
+ omin_spacje(i,zm);\r
+\r
+// txt:=get_datUp(i,zm,#0,false);\r
+ txt:=get_directive(i,zm);\r
+\r
+ if (txt='') and not(tst) then begin Result:=0; exit end;   // wyjatek dla .RELOC [.BYTE] [.WORD]\r
+\r
+ Result := fCRC16(txt);\r
+\r
+ if not(Result in [__byte..__dword]) then blad_und(old,txt,46);\r
+\r
+ dec(Result, __byteValue);\r
+end;\r
+\r
+\r
+function get_typeExt(var i:integer; var zm:string): byte;\r
+(*----------------------------------------------------------------------------*)\r
+(* sprawdzamy czy odczytany ciag znakow oznacza dyrektywe typu danych dla EXT *)\r
+(* akceptowane dyrektywy typu to .BYTE, .WORD, .LONG, .DWORD, .PROC           *)\r
+(*----------------------------------------------------------------------------*)\r
+var txt: string;\r
+begin\r
+ omin_spacje(i,zm);\r
+\r
+// txt:=get_datUp(i,zm,'(',false);\r
+ txt:=get_directive(i,zm);\r
+\r
+ Result := fCRC16(txt);\r
+\r
+ if not(Result in [__byte..__dword, __proc]) then blad_und(zm,txt,46);\r
+end;\r
+\r
+\r
+function ciag_ograniczony(var i:integer; var a:string; const cut:Boolean): string;\r
+(*----------------------------------------------------------------------------*)\r
+(*  pobiera ciag ograniczony dwoma znakami 'LEWA' i 'PRAWA'                   *)\r
+(*  znaki 'LEWA' i 'PRAWA' moga byc zagniezdzone                              *)\r
+(*  jesli CUT = TRUE to usuwamy poczatkowy i koncowy nawias                   *)\r
+(*----------------------------------------------------------------------------*)\r
+var nawias, len: integer;\r
+    znak, lewa, prawa: char;\r
+    petla: Boolean;\r
+begin\r
+ Result:='';\r
+\r
+ if not(a[i] in ['[','(','{']) then exit;\r
+\r
+ lewa:=a[i];\r
+ if lewa='(' then prawa:=')' else prawa:=chr(ord(lewa)+2);\r
+\r
+ nawias:=0; petla:=true; len:=length(a);\r
+\r
+ while petla and (i<=len) do begin\r
+\r
+  znak := a[i];\r
+\r
+  if znak=lewa then inc(nawias) else\r
+   if znak=prawa then dec(nawias);\r
+\r
+//  if not(zag) then\r
+//   if nawias>1 then test_nawias(a,lewa,0);\r
+\r
+//  if nawias=0 then petla:=false;\r
+  petla := not(nawias=0);\r
+\r
+  if znak='\' then begin\r
+   petla:=false;\r
+   Break;\r
+  end else\r
+  \r
+   if znak in ['''','"'] then begin\r
+    Result := Result + znak + get_string(i,a,a,false) + znak\r
+   end else begin\r
+    Result := Result + UpCas_(znak);\r
+    inc(i)\r
+   end;\r
+           \r
+ end;\r
+\r
+\r
+ if petla and not(komentarz) then\r
+  case lewa of\r
+   '[': blad(a,6);\r
+   '(': blad(a,7);\r
+   '{': blad(a,20);\r
+  end;\r
+\r
+ if cut then\r
+  if Result<>'' then Result:=copy(Result,2,length(Result)-2);\r
+end;\r
+\r
+\r
+function test_param(var i:integer; var a:string): Boolean;\r
+(*----------------------------------------------------------------------------*)\r
+(*  test na obecnosc parametrow makra, czyli ':0..9', '%%0..9'                *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+ Result := ((a[i]=':') and _dec(a[i+1])) or ((a[i]='%') and (a[i+1]='%') and _dec(a[i+2]))\r
+end;\r
+\r
+\r
+function get_dat(var i:integer; var a:string; const Sep:Char; const spacja:Boolean): string;\r
+(*----------------------------------------------------------------------------*)\r
+(*  wczytaj dowolne znaki, oprocz spacji, tabulatora i 'Sep'                  *)\r
+(*  jesli wystepuja znaki otwierajace ciag, czytaj taki ciag                  *)\r
+(*----------------------------------------------------------------------------*)\r
+var znak: char;\r
+    len: integer;\r
+begin\r
+ Result:='';\r
+\r
+ len:=length(a);\r
+\r
+ while i<=len do\r
+\r
+  if a[i]=Sep then\r
+   exit\r
+  else\r
+\r
+  case UpCase(a[i]) of\r
+   '[','(','{':\r
+     if not(komentarz) then\r
+      Result:=Result + ciag_ograniczony(i,a,false)\r
+     else begin\r
+      Result:=Result+a[i];\r
+      inc(i);\r
+     end;\r
+\r
+   'A'..'Z': Result:=Result + get_lab(i,a, false);\r
+\r
+   '''','"':\r
+     if not(komentarz) then begin\r
+      znak:=a[i];\r
+      Result:=Result + znak + get_string(i,a,a,false) + znak;\r
+     end else begin\r
+      Result:=Result+a[i];\r
+      inc(i);\r
+     end;\r
+\r
+   '/': case a[i+1] of\r
+         '/': exit;\r
+         '*': begin ___search_comment_block(i,a, Result); if komentarz then exit end;\r
+        else\r
+         begin\r
+          Result:=Result+'/';\r
+          inc(i);\r
+         end;\r
+        end;\r
+\r
+   ';','\': exit;\r
+\r
+   ' ',#9: if spacja then exit else begin Result:=Result+a[i]; inc(i) end;\r
+\r
+  else\r
+   begin\r
+//    if a[i]=Sep then exit;\r
+    Result := Result + UpCas_(a[i]);\r
+    inc(i);\r
+   end;\r
+  end;\r
+\r
+end;\r
+\r
+\r
+function get_dat_noSPC(var i:integer; var a:string; const sep,sep2:Char; var old:string): string;\r
+(*----------------------------------------------------------------------------*)\r
+(*  wczytujemy ciag znakow pomijajac znaki spacji                             *)\r
+(*----------------------------------------------------------------------------*)\r
+var len: integer;\r
+begin\r
+ Result:='';\r
+\r
+ omin_spacje(i,a);\r
+\r
+ len:=length(a);\r
+\r
+ while i<=len do begin\r
+\r
+  case a[i] of\r
+   ' ',#9:\r
+        if sep=' ' then exit else __inc(i,a);\r
+\r
+   '.','$','%':\r
+        if a[i]=sep then exit else begin\r
+         if (test_char(i+1,a,' ',#0)) and not(komentarz) then blad(old,4);\r
+         Result:=Result+a[i]; __inc(i,a);\r
+        end;\r
+\r
+   '/': case a[i+1] of\r
+         '/': exit;\r
+         '*': begin ___search_comment_block(i,a, Result); if komentarz then exit end;\r
+        else\r
+         begin\r
+          Result:=Result+'/';\r
+          __inc(i,a);\r
+         end;\r
+        end;\r
+\r
+   ';','\': exit;\r
+\r
+  else\r
+\r
+   if a[i] in [sep,sep2] then\r
+    exit\r
+   else\r
+    Result := Result + get_dat(i,a,sep,true);\r
+\r
+  end;\r
+\r
+ end;\r
+\r
+end;\r
+\r
+\r
+function OperExt(var i:integer; var old:string; const a,b:char; var value:Boolean): char;\r
+(*----------------------------------------------------------------------------*)\r
+(*  operatory zlozone zamieniamy na odpowiedni jednoliterowy kod              *)\r
+(*----------------------------------------------------------------------------*)\r
+var x: integer;\r
+begin\r
+ Result:=' ';\r
+\r
+ x:=ord(a) shl 8+ord(b);\r
+\r
+ case x of\r
+  15422,8509: Result := 'A';       // '<>', '!='\r
+       15421: Result := 'B';       // '<='\r
+       15933: Result := 'C';       // '>='\r
+       15420: Result := 'D';       // '<<'\r
+       15934: Result := 'E';       // '>>'\r
+       15677: Result := '=';       // '=='\r
+        9766: Result := 'F';       // '&&'\r
+       31868: Result := 'G';       // '||'\r
+ end;\r
+\r
+ if not(value) or (Result=' ') then begin\r
+  str_blad:=a+b;\r
+  blad(old,8);\r
+ end;\r
+\r
+ inc(i,2); value:=false;\r
+end;\r
+\r
+\r
+function OperNew(var i:integer; var old:string; const a:char; var value:Boolean; const b:Boolean): char;\r
+begin\r
+ if value<>b then blad_ill(old,a);\r
+\r
+ Result:=a;\r
+\r
+ inc(i); value:=false;\r
+end;\r
+\r
+\r
+function test_string(var i:integer; var a:string; const typ:Char): integer;\r
+(*----------------------------------------------------------------------------*)\r
+(*  obliczamy wartosc ktora zmodyfikuje ciag znakowy lub plikowy              *)\r
+(*  dla '*' jest to wartosc 128, czyli invers                                 *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+ Result:=0;          // wynik jest typem ze znakiem, koniecznie !!!\r
+\r
+ omin_spacje(i,a);\r
+\r
+ case a[i] of\r
+      '*': begin\r
+            Result := 128;\r
+            inc(i);\r
+           end;\r
+\r
+  '+','-': Result := integer( ___wartosc_noSPC(a,a,i,',',typ) );\r
+ end;\r
+\r
+ omin_spacje(i,a);\r
+end;\r
+\r
+\r
+procedure subrange_bounds(var a:string; const v,y:integer);\r
+begin\r
+  if (v<0) or (v>y) then blad(a,62);\r
+end;\r
+\r
+\r
+procedure save_dtaS(war:cardinal; ile:integer);\r
+begin\r
+\r
+ while ile>0 do begin\r
+\r
+  save_dst( byte(war) );\r
+\r
+  war:=war shr 8;\r
+\r
+  inc(adres);\r
+  dec(ile);\r
+ end;\r
+\r
+end;\r
+\r
+\r
+procedure save_dta(const war:cardinal; var tmp:string; const op_:char; const invers:byte);\r
+(*----------------------------------------------------------------------------*)\r
+(*  zapisujemy bajty danych do .ARRAY w zaleznosci od ustawionego typu danych *)\r
+(*----------------------------------------------------------------------------*)\r
+var k, i: integer;\r
+    v: byte;\r
+begin\r
+\r
+ if aray or put_used then\r
+  if array_used.idx>$FFFF then exit else begin\r
+\r
+   if op_ in ['C','D'] then begin\r
+    i:=length(tmp);\r
+\r
+    for k:=1 to i do begin\r
+     v:=byte( ord(tmp[k])+invers );\r
+     if op_='D' then v:=ata2int(v);\r
+\r
+     {if not(loop_used) and not(FOX_ripit) then} just_t(v);\r
+\r
+     if aray then\r
+      t_tmp[array_used.idx]:=v\r
+     else\r
+      t_get[array_used.idx]:=v;\r
+\r
+     inc(array_used.idx);\r
+\r
+     if array_used.idx>array_used.max then array_used.max:=array_used.idx;\r
+    end;\r
+\r
+    exit;\r
+   end;\r
+\r
+   {if not(loop_used) and not(FOX_ripit) then} just_t(war);\r
+\r
+   if aray then\r
+    t_tmp[array_used.idx]:=cardinal(war)\r
+   else\r
+    t_get[array_used.idx]:=byte(war);\r
+\r
+   inc(array_used.idx);\r
+\r
+   if array_used.idx>array_used.max then array_used.max:=array_used.idx;\r
+\r
+   exit;\r
+  end;\r
+\r
+\r
+  case op_ of\r
+    'L','B':\r
+         begin\r
+          save_dst( byte(war) );            inc(adres);\r
+         end;\r
+\r
+    'H': begin\r
+          save_dst( byte(war shr 8) );      inc(adres);\r
+         end;\r
+\r
+    'A','V':\r
+         begin\r
+          save_dst( byte(war) );\r
+          save_dst( byte(war shr 8) );      inc(adres,2);\r
+         end;\r
+\r
+    'T','E':\r
+         begin\r
+          save_dst( byte(war) );\r
+          save_dst( byte(war shr 8) );\r
+          save_dst( byte(war shr 16) );     inc(adres,3);\r
+         end;\r
+\r
+    'F': begin\r
+          save_dst( byte(war) );\r
+          save_dst( byte(war shr 8) );\r
+          save_dst( byte(war shr 16) );\r
+          save_dst( byte(war shr 24) );     inc(adres,4);\r
+         end;\r
+\r
+    'G': begin\r
+          save_dst( byte(war shr 24) );\r
+          save_dst( byte(war shr 16) );\r
+          save_dst( byte(war shr 8) );\r
+          save_dst( byte(war) );            inc(adres,4);\r
+         end;\r
+\r
+    'C','D':\r
+         begin\r
+          i:=length(tmp);\r
+\r
+          for k:=1 to i do begin\r
+           v:=byte( ord(tmp[k])+invers );\r
+           if op_='D' then v:=ata2int(v);\r
+           save_dst(v);\r
+          end;\r
+                                            inc(adres,i);\r
+         end;\r
+\r
+   end;\r
+\r
+end;\r
+\r
+\r
+function oblicz_wartosc_ogr(var zm,old:string; var i:integer): Int64;\r
+(*----------------------------------------------------------------------------*)\r
+(*  obliczamy wartosc ograniczona nawiasami '[' lub '('                       *)\r
+(*----------------------------------------------------------------------------*)\r
+var txt: string;\r
+    k: integer;\r
+begin\r
+ Result:=0;\r
+\r
+ omin_spacje(i,zm);\r
+\r
+ if zm[i] in ['[','('] then begin\r
+  txt:=ciag_ograniczony(i,zm,true);\r
+\r
+  k:=1;\r
+  Result:=___wartosc_noSPC(txt,old,k,#0,'F')\r
+ end;\r
+\r
+end;\r
+\r
+\r
+function get_labelEx(var i:integer; var a:string): string;\r
+begin\r
+ Result:='';\r
+\r
+ if _lab_firstEx(a[i]) then begin\r
+\r
+  Result:=Result+UpCas_(a[i]);\r
+  inc(i);\r
+\r
+  while _lab(a[i]) do begin Result:=Result+UpCas_(a[i]); inc(i) end;\r
+\r
+ end;\r
+\r
+ //if not( _eol(a[i]) ) then blad_ill(old,a[i]);   // z tym testem nie policzy ciagu  wyr|wyr \r
+end;\r
+\r
+\r
+function get_labEx(var i:integer; var a,old:string): string;\r
+(*----------------------------------------------------------------------------*)\r
+(*  pobierz etykiete zaczynajaca sie znakami 'A'..'Z','_','?','@',':'         *)\r
+(*  jesli wystepuja nawiasy '( )' lub '[ ]' to usuwamy je                     *)\r
+(*----------------------------------------------------------------------------*)\r
+var tmp: string;\r
+    k: integer;\r
+begin\r
+\r
+ omin_spacje(i,a);\r
+\r
+ if a[i] in ['(','['] then begin\r
+  tmp := ciag_ograniczony(i,a,true);\r
+\r
+  k:=1;\r
+  omin_spacje(k,tmp);\r
+\r
+  Result := get_labelEx(k, tmp);\r
+ end else\r
+  Result := get_labelEx(i, a);\r
+\r
+ if Result='' then blad(old,15);\r
+\r
+end;\r
+\r
+\r
+function load_label_ofset(a:string; var old:string; const test:Boolean): integer;\r
+(*----------------------------------------------------------------------------*)\r
+(*  znajdujemy indeks do tablicy T_LAB                                        *)\r
+(*----------------------------------------------------------------------------*)\r
+var b: integer;\r
+begin\r
+\r
+ if a='' then blad(old,23);\r
+\r
+ if a[1]=':' then begin\r
+  b     := bank;\r
+  bank  := 0;         // wymuszamy BANK=0 aby odczytac etykiete z najnizszego poziomu\r
+\r
+  a:=copy(a,2,length(a));\r
+  Result:=l_lab(a);\r
+\r
+  bank  := b;         // przywracamy poprzednia wartosc BANK\r
+ end else\r
+  Result:=load_lab(a,true);\r
+\r
+ if test then\r
+  if (Result<0) and (pass=pass_end) then blad_und(old,a,5);\r
+\r
+end;\r
+\r
+\r
+procedure testRange(var old:string; var i:integer; const b:byte);\r
+begin\r
+ if (i<0) or (i>$FFFF) then begin\r
+  blad(old,b);\r
+  i:=0;\r
+ end;\r
+end;\r
+\r
+\r
+function read_HEX(var i:integer; var a,old: string): string;\r
+begin\r
+         inc(i);     // omin pierwszy znak '$'\r
+\r
+         Result:='';\r
+         while _hex(a[i]) do begin Result:=Result+UpCase(a[i]); inc(i) end;\r
+\r
+         if not(test_param(i,a)) then\r
+          if Result='' then blad_ill(old,a[i]);\r
+\r
+         Result:='$'+Result;\r
+end;\r
+\r
+\r
+procedure save_lst(const c:char);\r
+(*----------------------------------------------------------------------------*)\r
+(*  formatowanie wierszy listingu przed zapisaniem ich do pliku .LST          *)\r
+(*----------------------------------------------------------------------------*)\r
+var i: byte;\r
+begin\r
+\r
+ if pass=pass_end then begin\r
+\r
+  if not(loop_used) and not(FOX_ripit) then begin\r
+   t:=IntToStr(line);\r
+   while length(t)<6 do t:=' '+t;\r
+   t:=t+' ';\r
+  end;\r
+\r
+\r
+  case c of\r
+\r
+   'l': if not(FOX_ripit) then begin t:=t+'= '; bank_adres(nul.i) end;\r
+\r
+   'i': bank_adres(adres);\r
+\r
+   'a': begin\r
+\r
+          if not(hea) and not(loop_used) and not(FOX_ripit) and\r
+             not(struct.use) and (adres>=0) then bank_adres(adres);\r
+\r
+          if nul.l>0 then begin\r
+           data_out:=true;\r
+           for i:=0 to nul.l-1 do save_dst(nul.h[i]);\r
+          end;\r
+\r
+        end;\r
+\r
+  end;   // end case\r
+\r
+ end;\r
+\r
+ inc(adres,nul.l);    // to zawsze musi sie wykonac niezaleznie od przebiegu\r
+end;\r
+\r
+\r
+procedure zapisz_lokal;\r
+begin\r
+ t_loc[lokal_nr].nam := lokal_name;\r
+\r
+ inc(lokal_nr);\r
+\r
+ if lokal_nr>High(t_loc) then SetLength(t_loc,lokal_nr+1);\r
+end;\r
+\r
+\r
+procedure oddaj_lokal(var a: string);\r
+begin\r
+ if lokal_nr=0 then blad(a,28);\r
+ dec(lokal_nr);\r
+\r
+ lokal_name := t_loc[lokal_nr].nam;\r
+end;\r
+\r
+\r
+procedure new_DOS_header;\r
+var old_opt: byte;\r
+begin\r
+       old_opt:=opt;\r
+\r
+       opt:=opt or 1;               // wymuszamy zapis naglowka DOS-a\r
+       save_hea;  org:=true;\r
+\r
+       opt:=old_opt;\r
+end;\r
+\r
+\r
+function oblicz_wartosc(var a:string; var old:string): Int64;\r
+(*----------------------------------------------------------------------------*)\r
+(*  obliczamy wartosc wyrazenia, uwzgledniajac operacje arytmetyczne          *)\r
+(*  w 'J' jest licznik dla STOS'u                                             *)\r
+(*  zamiast tablic dynamicznych wprowadzilem tablice statyczne i ograniczylem *)\r
+(*  maksymalna liczbe operacji i operatorow w wyrazeniu do 512                *)\r
+(*----------------------------------------------------------------------------*)\r
+type znak_wart = record\r
+                  znak: char;\r
+                  wart: Int64;\r
+                 end;\r
+\r
+     _typCash  = array [0..16] of char;  // taka sama liczba elementow jak PRIOR\r
+     _typOper  = array [0..511] of char;\r
+     _typStos  = array [0..511] of znak_wart;\r
+\r
+\r
+var i, j, b, x, k, v, pomoc, ofset, _hlp, len, op_idx, arg: integer;\r
+    old_reloc_value_cnt: integer;\r
+    tmp, txt: string;\r
+    iarg, war: Int64;\r
+    petla, value, old_reloc_value_use: Boolean;\r
+    oper, byt: char;\r
+\r
+    fsize: file;\r
+\r
+    reloc_value: relVal;\r
+\r
+    stos_: _carArray;\r
+    cash : _typCash;\r
+    stos : _typStos;\r
+    op   : _typOper;\r
+\r
+const\r
+ prior: array [0..16] of char=          // piorytet operatorow\r
+ ('D','E','&','|','^','/','*','%','+',{'-',}'=','A','B','<','C','>','F','G');\r
+\r
+begin\r
+\r
+ if a='' then blad(old,23);    \r
+                               \r
+ Result:=0;\r
+\r
+ // init tablicy dynamicznej OP\r
+// SetLength(op,2);\r
+ op[0]:='+'; oper:='+'; op_idx:=1;\r
+\r
+ i:=1; war:=0; b:=0;\r
+\r
+// fillchar(cash,sizeof(cash),' ');   // wypelniamy spacjami\r
+\r
+ cash[0]:=' ';\r
+ cash[1]:=' ';\r
+ cash[2]:=' ';\r
+ cash[3]:=' ';\r
+ cash[4]:=' ';\r
+ cash[5]:=' ';\r
+ cash[6]:=' ';\r
+ cash[7]:=' ';\r
+ cash[8]:=' ';\r
+ cash[9]:=' ';\r
+ cash[10]:=' ';\r
+ cash[11]:=' ';\r
+ cash[12]:=' ';\r
+ cash[13]:=' ';\r
+ cash[14]:=' ';\r
+ cash[15]:=' ';\r
+ cash[16]:=' ';    \r
+\r
+ value:=false;\r
+\r
+ reloc_value.use:=false;\r
+ reloc_value.cnt:=0;\r
+\r
+ j:=1;               // na pozycji zerowej (J=0) tablicy 'STOS' dopiszemy '+0'\r
+                     // !!! zmienne I,J uzywane sa przez petle WHILE !!!\r
+\r
+// SetLength(stos,3);\r
+\r
+ len:=length(a);\r
+\r
+ while (i<=len) and not(overflow) do begin\r
+\r
+  case UpCase(a[i]) of\r
+\r
+   '#': begin\r
+         if ___rept_ile<0 then blad(old,116); \r
+\r
+         war:=___rept_ile;\r
+         value:=true;\r
+         __inc(i,a);      \r
+        end;\r
+\r
+   // odczytaj operator '<'\r
+   '<': if a[i+1] in ['<','=','>'] then\r
+         oper:=OperExt(i,old,'<',a[i+1],value) else\r
+          if value then oper:=OperNew(i,old,'<',value,true) else\r
+           oper:=OperNew(i,old,'M',value,false);\r
+\r
+   // odczytaj operator '>'\r
+   '>': if a[i+1] in ['=','>'] then\r
+         oper:=OperExt(i,old,'>',a[i+1],value) else\r
+          if value then oper:=OperNew(i,old,'>',value,true) else\r
+           oper:=OperNew(i,old,'S',value,false);\r
+\r
+   // odczytaj operator '='\r
+   '=': if a[i+1]='=' then\r
+         oper:=OperExt(i,old,'=','=',value) else\r
+          if value then oper:=OperNew(i,old,'=',value,true) else\r
+           oper:=OperNew(i,old,'X',value,false);\r
+\r
+   // odczytaj operator '&'\r
+   '&': if a[i+1]='&' then\r
+         oper:=OperExt(i,old,'&','&',value) else\r
+          oper:=OperNew(i,old,'&',value,true);\r
+\r
+   // odczytaj operator '|'\r
+   '|': if a[i+1]='|' then\r
+         oper:=OperExt(i,old,'|','|',value) else\r
+          oper:=OperNew(i,old,'|',value,true);\r
+\r
+   // odczytaj operator '!'\r
+   '!': if a[i+1]='=' then\r
+         oper:=OperExt(i,old,'!','=',value) else\r
+          oper:=OperNew(i,old,'!',value,false);\r
+\r
+   // odczytaj operator '^'\r
+   '^': if not(value) then begin\r
+         oper:='H'; inc(i)\r
+        end else oper:=OperNew(i,old,'^',value,true);\r
+\r
+   // odczytaj operator '/'\r
+   '/': if a[i+1]='*' then begin\r
+         omin_spacje(i,a);\r
+         value:=false;\r
+        end else oper:=OperNew(i,old,'/',value,true);\r
+\r
+   // odczytaj operator '*'\r
+   '*': if not(value) then begin\r
+         b:=bank;\r
+         war:=adres; inc(i);\r
+         value:=true;\r
+\r
+         label_type:='V';\r
+\r
+         if not(branch) then begin\r
+          save_rel(adres, -1, bank, reloc_value);\r
+         end;\r
+\r
+        end else oper:=OperNew(i,old,'*',value,true);\r
+\r
+   // odczytaj operator '~'\r
+   '~': oper:=OperNew(i,old,'~',value,false);\r
+\r
+   // odczytaj operatory '+' '-'\r
+   '+','-':\r
+        oper:=OperNew(i,old,a[i],value,value);\r
+\r
+   // odczytaj wartosc decymalna lub wyjatkowo hex 0x...\r
+   '0'..'9':\r
+        begin\r
+         if value then blad(old,4);\r
+\r
+         if (UpCase(a[i+1])='X') and (a[i]='0') then begin  // 0x...\r
+\r
+          inc(i);\r
+          tmp:=read_HEX(i,a,old);\r
+\r
+         end else begin                                     // 0..9\r
+\r
+          tmp:='';\r
+          while _dec(a[i]) do begin tmp:=tmp+a[i]; __inc(i,a) end;\r
+\r
+         end;\r
+\r
+         war:=StrToInt(tmp);\r
+\r
+         value:=true;\r
+        end;\r
+\r
+   // odczytaj .R, .OR, .LO, .HI, .GET, .AND, .XOR, .NOT, .LEN, .ADR, .DEF\r
+   '.':\r
+    if a[i+1] in ['r','R'] then begin                    // .R\r
+     if ___rept_ile<0 then blad(old,116);\r
+     \r
+     war:=___rept_ile;\r
+     inc(i,2);\r
+     value:=true;\r
+     if not(loop_used) and not(FOX_ripit) then t:=t+' #'+Hex(cardinal(war),2);    // zapisz w pliku LST #numer\r
+\r
+    end else begin\r
+\r
+      tmp:='.'+UpCase(a[i+1])+UpCase(a[i+2]);\r
+      _hlp:=ord(tmp[2]) shl 16+ord(tmp[3]) shl 8;\r
+\r
+      case _hlp of\r
+       $4F5200: begin\r
+                 oper:=OperExt(i,old,'|','|',value);     // .OR\r
+                 inc(i);\r
+                end;\r
+\r
+       $4C4F00: begin                                    // .LO (expression)\r
+                 inc(i,3);\r
+\r
+                 old_reloc_value_cnt := reloc_value.cnt;\r
+                 old_reloc_value_use := reloc_value.use;\r
+\r
+                 war:=byte( oblicz_wartosc_ogr(a,old,i) );\r
+\r
+                 reloc_value.use := old_reloc_value_use;\r
+                 inc(reloc_value.cnt, old_reloc_value_cnt);\r
+\r
+                 value:=true;\r
+                end;\r
+\r
+       $484900: begin                                    // .HI (expression)\r
+                 inc(i,3);\r
+\r
+                 old_reloc_value_cnt := reloc_value.cnt;\r
+                 old_reloc_value_use := reloc_value.use;\r
+\r
+                 war:=byte( oblicz_wartosc_ogr(a,old,i) shr 8 );\r
+\r
+                 reloc_value.use := old_reloc_value_use;\r
+                 inc(reloc_value.cnt, old_reloc_value_cnt);\r
+                 \r
+                 value:=true;\r
+                end;\r
+\r
+       else begin\r
+\r
+        tmp:=tmp+UpCase(a[i+3]);\r
+        inc( _hlp , ord(tmp[4]) );\r
+\r
+        case _hlp of\r
+         $474554:\r
+             begin                                       // .GET\r
+              inc(i,4);\r
+              omin_spacje(i,a); arg:=0;\r
+\r
+              old_reloc_value_cnt := reloc_value.cnt;\r
+              old_reloc_value_use := reloc_value.use;\r
+\r
+              if a[i] in ['[','('] then arg:=integer( oblicz_wartosc_ogr(a,old,i) );\r
+\r
+              subrange_bounds(old,arg,$FFFF);            // !!! konieczny test\r
+\r
+              reloc_value.use := old_reloc_value_use;\r
+              inc(reloc_value.cnt, old_reloc_value_cnt);\r
+\r
+              war:=t_get[arg];\r
+              value:=true;\r
+             end;\r
+\r
+         $414E44:\r
+             begin\r
+              oper:=OperExt(i,old,'&','&',value);        // .AND\r
+              inc(i,2);\r
+             end;\r
+\r
+         $584F52:\r
+             begin\r
+              oper:=OperNew(i,old,'^',value,true);       // .XOR\r
+              inc(i,3);\r
+             end;\r
+\r
+         $4E4F54:\r
+             begin\r
+              oper:=OperNew(i,old,'!',value,false);      // .NOT\r
+              inc(i,3);\r
+             end;\r
+\r
+         $4C454E:                                        // .LEN label\r
+             begin\r
+            // omijamy 4 znaki dyrektywy '.LEN'\r
+            // i odczytujemy nazwe etykiety\r
+              inc(i,4);\r
+\r
+              if a[i] in ['''','"'] then begin           // file size\r
+\r
+               txt:=get_string(i,a,old,true);\r
+\r
+               txt:=GetFile(txt,a);  if not(TestFile(txt)) then blad(txt,18);\r
+\r
+               assignfile(fsize, txt); FileMode:=0; Reset(fsize, 1);\r
+               war:=FileSize(fsize);\r
+               CloseFile(fsize);\r
+\r
+              end else begin                             // var size\r
+\r
+               txt:=get_labEx(i,a, old);\r
+               arg:=load_label_ofset(txt, old, true);\r
+\r
+               if arg>=0 then\r
+                case t_lab[arg].bnk of\r
+                   __id_proc: war:=t_prc[t_lab[arg].adr].len; // dlugosc bloku .PROC\r
+                  __id_array: war:=t_arr[t_lab[arg].adr].len; // dlugosc bloku .ARRAY\r
+                 __id_struct: war:=t_str[t_lab[arg].adr].siz; // dlugosc bloku .STRUCT\r
+                else\r
+                 war:=t_lab[arg].lln;                         // dlugosc bloku .LOCAL\r
+                end;\r
+\r
+              end;\r
+\r
+              value:=true;\r
+             end;\r
+\r
+         $414452:\r
+             begin                                       // .ADR label\r
+            // omijamy 4 znaki dyrektywy '.ADR'\r
+            // i odczytujemy nazwe etykiety\r
+              inc(i,4);\r
+\r
+              txt:=get_labEx(i,a, old);\r
+\r
+              arg:=load_label_ofset(txt, old, true);\r
+\r
+              war:=0;\r
+\r
+              if arg>=0 then begin\r
+\r
+               old_reloc_value_cnt := reloc_value.cnt;\r
+               old_reloc_value_use := reloc_value.use;\r
+\r
+               war:= oblicz_wartosc(txt,old);\r
+\r
+               reloc_value.use := old_reloc_value_use;\r
+               inc(reloc_value.cnt, old_reloc_value_cnt);\r
+  \r
+               case t_lab[arg].bnk of\r
+                __id_proc: dec(war, t_prc[t_lab[arg].adr].ofs);\r
+               else\r
+                dec(war, t_lab[arg].ofs)\r
+               end;\r
+\r
+              end;\r
+              \r
+              value:=true;\r
+             end;\r
+\r
+         $444546:\r
+             begin                                    // .DEF label\r
+            // omijamy 4 znaki dyrektywy '.DEF'\r
+            // i odczytujemy nazwe etykiety\r
+              inc(i,4);\r
+\r
+              txt:=get_labEx(i,a, old);\r
+              arg:=load_label_ofset(txt, old, false);\r
+\r
+//              war:=ord(arg>=0);      // !!! nie dziala prawidlowo dla .IFNDEF z Exomizera !!!\r
+\r
+              if arg>=0 then           // !!! koniecznie ta wersja !!!\r
+               war := ord( t_lab[arg].pas>0 )\r
+              else\r
+               war:=0;\r
+\r
+              value:=true;\r
+             end;\r
+\r
+        else begin\r
+\r
+         tmp:=tmp+UpCase(a[i+4])+UpCase(a[i+5]);\r
+\r
+         if tmp<>'.ZPVAR' then\r
+          blad_und(old,tmp,68)\r
+         else begin\r
+          inc(i,6);\r
+          war:=zpvar;\r
+          value:=true;\r
+         end;\r
+\r
+        end; \r
+\r
+        end;\r
+\r
+       end;\r
+\r
+      end;\r
+\r
+    end;\r
+\r
+   // odczytaj etykiete i okresl jej wartosc\r
+   // znak ':' oznacza etykiete globalna lub parametr makra\r
+   'A'..'Z','_','?','@',':':\r
+     begin\r
+         petla:=false;  b:=0;  war:=0;  //pomoc:=0;\r
+\r
+         if a[i]=':' then\r
+\r
+          if _lab_first(a[i+1]) then begin\r
+           petla:=true; inc(i)\r
+          end else\r
+           if _dec(a[i+1]) then begin\r
+\r
+            if run_macro then begin\r
+             value:=false; oper:=' ';   Break; //i:=len+1\r
+            end else\r
+             blad_ill(old,':');\r
+\r
+           end else\r
+            blad(old,4);\r
+\r
+         if i<=len then begin\r
+\r
+          if value then blad(old,4);\r
+\r
+          tmp:=get_lab(i,a, false);  if petla then tmp:=':'+tmp;\r
+\r
+\r
+          arg:=load_label_ofset(tmp, old, true);\r
+\r
+\r
+{          if arg>=0 then                             // skladnia dla enum label1::label2\r
+           if t_lab[arg].bnk=__id_enum then           // usunieta w celu zachowania spojnosci\r
+            if (a[i]=':') and (a[i+1]=':') then begin // akceptowany jest znak '.' zamiast '::'\r
+             inc(i, 2);\r
+             tmp:=tmp+'.'+get_lab(i,a, false);\r
+\r
+             if petla then tmp:=':'+tmp;\r
+\r
+             arg:=load_label_ofset(tmp, old, true);\r
+            end;       }\r
+\r
+\r
+      // jesli przetwarzamy makro to nie musza byc zdefiniowane wartosci etykiet\r
+      // w pozostalych przypadkach wystapi blad 'Undeclared label ????'\r
+\r
+          if arg<0 then begin\r
+           undeclared:=true;               // wystapila niezdefiniowana etykieta\r
+           value:=false; oper:=' '; Break  // przerywamy obliczanie wyrazenia\r
+          end else\r
+           if (pass=pass_end) and (t_lab[arg].bnk<__id_param) and t_lab[arg].sts then blad_und(old,tmp,113);\r
+\r
+          undeclared:=t_lab[arg].sts;      // aktualny status etykiety\r
+\r
+          pomoc:=t_lab[arg].adr;\r
+\r
+          if (t_lab[arg].typ in ['P','V']) then variable:=true;\r
+\r
+          t_lab[arg].use:=true;\r
+\r
+\r
+   if arg>=0 then\r
+     case t_lab[arg].bnk of\r
+\r
+      __id_struct:  // zamiana struktur na dane DTA, na poczatku sprawdzimy czy 'DTA_USED = true'\r
+\r
+   if not(dta_used) then begin\r
+\r
+       b   := t_str[pomoc].bnk;\r
+       war := t_str[pomoc].siz;\r
+\r
+      end else\r
+      if pass=0 then begin              // teraz nie znamy wszystkich struktur, musimy koñczyc\r
+\r
+        if a[i]<>'[' then warning(102); // 'Constant expression expected', brakuje indeksu [idx]\r
+\r
+      end else begin     // w drugim przebiegu mamy pewnosc ze poznalismy wszystkie struktury\r
+\r
+      dta_used:=false;\r
+\r
+      struct_used.use:=true;\r
+\r
+      save_lst('i');\r
+\r
+    // odczytujemy ofset do tablicy 'T_STR'\r
+      ofset:=t_lab[arg].adr;\r
+\r
+      struct_used.idx:=ofset;     // w OFSET indeks do pierwszego pola struktury\r
+\r
+    // liczba pol struktury\r
+      b := t_str[ofset].ofs;\r
+\r
+      inc(ofset);  txt:='';\r
+\r
+    // odczytujemy zadeklarowana liczbe elementow danych strukturalnych  [?]\r
+      arg:=integer( oblicz_wartosc_ogr(a,old,i) );\r
+\r
+      testRange(old, arg, 62);\r
+\r
+      struct_used.cnt:=arg;\r
+\r
+      omin_spacje(i,a);\r
+\r
+    // odczytujemy wartosci elementow ograniczone nawiasami ( )\r
+      while a[i] ='(' do begin\r
+\r
+       tmp:=ciag_ograniczony(i,a,true);\r
+\r
+       k:=1; tmp:=get_dat_noSPC(k,tmp,#0,#0,old);\r
+       k:=1;\r
+\r
+       SetLength(stos_,1);\r
+\r
+     // wczytujemy elementy ograniczone nawiasami, w 'X' jest licznik\r
+       x:=0;\r
+       while k<=length(tmp) do begin\r
+\r
+        pomoc:=loa_str_no(t_str[ofset].id, x);  // zawsze musi odnalezc wlasciwe pole struktury\r
+\r
+        v:=t_str[pomoc].siz;   byt:=tType[v];\r
+\r
+        war:=___wartosc_noSPC(tmp,old,k,',',byt);\r
+\r
+        _hlp:=t_str[pomoc].rpt * v;\r
+\r
+        save_dtaS(cardinal(war), _hlp);\r
+\r
+        inc(x);\r
+//        if pass>0 then\r
+         if x>b then blad(old,40);   // jesli liczba podanych elementow jest wieksza niz w strukturze\r
+\r
+        pomoc:=High(stos_);\r
+        stos_[pomoc]:=cardinal( war );\r
+\r
+        SetLength(stos_,pomoc+2);\r
+\r
+        omin_spacje(k,tmp);\r
+        if tmp[k]=',' then __inc(k,tmp) else Break;\r
+       end;\r
+\r
+//       if pass>0 then\r
+        if x<>b then blad(old,40);\r
+\r
+     // zmniejszamy licznik elementow\r
+       dec(arg); if arg<-1 then blad(old,40);\r
+\r
+       omin_spacje(i,a);\r
+      end;\r
+\r
+      omin_spacje(i,a);\r
+\r
+      value:=( High(stos_) = b );   // jesli podalismy jakies wartosci poczatkowe to VALUE=TRUE\r
+\r
+      if not(value) then new_DOS_header;  // jesli nie podalismy wartosci to musimy wymusic ORG-a\r
+\r
+    // !!! nie mozna domyslnie zapisywac zer dla zmiennej strukturalnej !!!\r
+    // !!! bo nie zawsze mozna zapisywac pamiec pod aktualnym adresem !!!\r
+\r
+    // reszte elementow struktury wypelniamy ostatnimi wartosciami lub zerami\r
+      while arg>=0 do begin\r
+\r
+       for x:=0 to b-1 do begin\r
+\r
+        pomoc:=loa_str_no(t_str[ofset].id, x);\r
+\r
+        v:=t_str[pomoc].siz;   //byt:=tType[v];\r
+\r
+        _hlp:=t_str[pomoc].rpt * v;\r
+\r
+        if value then begin\r
+         war:=stos_[x];\r
+         save_dtaS(cardinal(war), _hlp); // nowy adres i zapisanie wartosci poczatkowej struktury\r
+        end else begin\r
+         war:=0;\r
+         inc(adres, _hlp);               // nowy adres bez zapisywania wartosci poczatkowej\r
+        end;\r
+\r
+       end;\r
+\r
+       dec(arg);\r
+      end;\r
+\r
+     b:=bank;\r
+     value:=false;\r
+     oper:=' ';\r
+   end;\r
+\r
+            __id_enum: begin\r
+                        omin_spacje(i,a);\r
+            \r
+                        if a[i] in ['(','['] then begin\r
+\r
+                         _hlp:=usi_idx;                 // dla enum_name(label1|label2|...)\r
+\r
+                         t_usi[usi_idx].lok:=end_idx;\r
+                         t_usi[usi_idx].lab:=tmp;\r
+\r
+                         if proc then\r
+                          t_usi[usi_idx].nam:=proc_name\r
+                         else           \r
+                          t_usi[usi_idx].nam:=lokal_name;\r
+\r
+                         inc(usi_idx);\r
+\r
+                         SetLength(t_usi, usi_idx+1);\r
+\r
+                         war:=oblicz_wartosc_ogr(a,old,i);\r
+\r
+                         usi_idx:=_hlp;\r
+                        end;\r
+\r
+                       end;\r
+\r
+\r
+            __id_proc: begin\r
+                        b:=t_prc[pomoc].bnk;\r
+                        war:=t_prc[pomoc].adr;\r
+\r
+                        if ExProcTest then\r
+                         t_prc[pomoc].use:=true;  // procedura .PROC musi byc asemblowana\r
+\r
+                        save_relAddress(arg, reloc_value);\r
+                       end;\r
+\r
+            __id_ext:  begin\r
+                        if blocked then blad_und(old,tmp,41);\r
+\r
+                        if not(branch) then begin\r
+\r
+                          if vector then\r
+                           _hlp:=adres\r
+                          else\r
+                           _hlp:=adres+1;\r
+\r
+                          if dreloc.use then dec(_hlp, rel_ofs);\r
+\r
+                          t_ext[ext_idx].adr := _hlp;\r
+                          t_ext[ext_idx].bnk := bank;\r
+                          t_ext[ext_idx].idx := pomoc;\r
+\r
+                          inc(ext_idx);\r
+\r
+                          if ext_idx>High(t_ext) then SetLength(t_ext,ext_idx+1);\r
+                        end;\r
+\r
+                        ext_used.use:=true;\r
+                        ext_used.idx:=pomoc;\r
+                        ext_used.siz:=t_extn[pomoc].siz;\r
+\r
+                        inc(reloc_value.cnt);\r
+                       end;\r
+\r
+            __id_smb:  begin\r
+                        if blocked then blad_und(old,tmp,41);\r
+\r
+                        if not(branch) then begin\r
+                         save_rel(adres,pomoc,0, reloc_value);\r
+                         t_smb[pomoc].use:=true;\r
+                         war:=__rel;\r
+                        end;\r
+\r
+                       end;\r
+\r
+           __id_array: begin\r
+                        b:=t_arr[pomoc].bnk;\r
+                        war:=t_arr[pomoc].adr;\r
+\r
+                        omin_spacje(i,a);\r
+                        if a[i]='[' then begin\r
+                         ofset:=integer( oblicz_wartosc_ogr(a,old,i) );\r
+                         subrange_bounds(old,ofset,t_arr[pomoc].idx);\r
+\r
+                         inc(war, Int64(ofset)*t_arr[pomoc].siz);\r
+                        end;\r
+\r
+                        save_relAddress(arg, reloc_value);\r
+                       end;\r
+\r
+         __dta_struct: begin\r
+\r
+                        save_relAddress(arg, reloc_value);\r
+\r
+                        b:=t_str[pomoc].bnk;\r
+                        war:=t_str[pomoc].adr;\r
+\r
+                        ofset:=integer( oblicz_wartosc_ogr(a,old,i) );\r
+\r
+                        subrange_bounds(old,ofset,t_str[pomoc].ofs);\r
+\r
+                        arg:=t_str[t_lab[arg].adr].idx;\r
+\r
+                        ofset:=ofset * t_str[arg].siz;   // indeks * dlugosc_struktury\r
+\r
+                        if a[i]='.' then begin\r
+                          inc(i);\r
+                          txt:=get_lab(i,a, false);\r
+\r
+                         // szukamy w T_STR\r
+                          pomoc:=loa_str(txt, t_str[arg].id);\r
+\r
+                          if pomoc>=0 then\r
+                           inc(ofset,t_str[pomoc].ofs)\r
+                          else\r
+                           if pass=pass_end then blad_und(old,txt,46);\r
+\r
+                        end;\r
+\r
+                        inc(war,ofset);\r
+                       end;\r
+           else\r
+            begin\r
+\r
+\r
+          // wystapi blad 'Address relocation overload'\r
+          // jesli dokonujemy operacji na wiecej niz jednej relokowalnej etykiecie\r
+\r
+             save_relAddress(arg, reloc_value);\r
+\r
+\r
+             if dreloc.use or dreloc.sdx then\r
+              if reloc_value.use and (reloc_value.cnt>1) then blad(old,85);\r
+\r
+\r
+             b:=t_lab[arg].bnk;\r
+             war:=t_lab[arg].adr;\r
+\r
+             while pos('.',tmp)>0 do begin\r
+\r
+              obetnij_kropke(tmp);\r
+\r
+              k:=length(tmp);            // usun ostatni znak kropki\r
+              SetLength(tmp,k-1);\r
+\r
+              arg:=l_lab(tmp);\r
+\r
+              pomoc:=t_lab[arg].adr;\r
+\r
+              if (arg>=0) and ExProcTest then\r
+               if t_lab[arg].bnk=__id_proc then begin\r
+                t_prc[pomoc].use:=true;  // procedura .PROC musi byc asemblowana\r
+                Break;\r
+               end;\r
+               \r
+             end;\r
+\r
+            end;\r
+\r
+           end;\r
+\r
+          value:=true;\r
+         end;\r
+\r
+\r
+      // wyjatkowo dla PASS=0 i prawdopodobnego odwolania do tablicy przyjmij wartosc =0\r
+         omin_spacje(i,a);\r
+         if a[i]='[' then\r
+          if pass<pass_end then\r
+           exit\r
+          else\r
+           blad_und(old,tmp,5);\r
+\r
+        end;\r
+\r
+   // odczytaj wartosc hexadecymalna\r
+   '$': begin\r
+\r
+         if value then blad(old,4);\r
+\r
+         tmp:=read_HEX(i,a,old);\r
+\r
+         war:=StrToInt(tmp);\r
+\r
+         value:=true;\r
+        end;\r
+\r
+   // odczytaj wartosc binarna lub potraktuj '%' jako operator\r
+   // lub jako numer parametru dla makra gdy wystapily znaki '%%'\r
+   '%': if a[i+1]='%' then begin\r
+\r
+         if not(_dec(a[i+2])) then blad(old,47);      // %%0..9\r
+\r
+//         b:=0; war:=0;\r
+         value:=false; oper:=' ';  Break; //i:=len+1\r
+        end else\r
+         if value then oper:=OperNew(i,old,'%',value,true) else\r
+          begin\r
+           inc(i);     // omin pierwszy znak '%'\r
+//           war:=get_value(i,a,'B',old);\r
+\r
+           tmp:='';\r
+           while _bin(a[i]) do begin tmp:=tmp+a[i]; __inc(i,a) end;\r
+\r
+           if not(test_param(i,a)) then\r
+            if tmp='' then blad_ill(old,a[i]);\r
+\r
+//           war:=BinToInt(tmp);\r
+           war:=0;\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  realizacja zamiany ciagu zero-jedynkowego na wartosc decymalna            *)\r
+(*----------------------------------------------------------------------------*)\r
+       if tmp<>'' then begin\r
+\r
+           k:=Length(tmp);\r
+\r
+          //remove leading zeros\r
+           pomoc:=1;\r
+           while tmp[pomoc]='0' do inc(pomoc);\r
+\r
+          //do the conversion\r
+           for ofset:=k downto pomoc do\r
+            if tmp[ofset]='1' then\r
+             war:=war+(1 shl (k-ofset));\r
+       end;\r
+       \r
+           value:=true;\r
+          end;\r
+\r
+   // odczytaj string ograniczony apostrofami ''\r
+   '''','"':\r
+        begin\r
+         if value then blad(old,4);\r
+\r
+         k:=ord(a[i]);\r
+         tmp:=get_string(i,a,old,true);\r
+\r
+         if length(tmp)>1 then blad(old,3);                // maksymalnie 1 znak\r
+         \r
+         if chr(k)='''' then\r
+          war:=ord(tmp[1])\r
+         else\r
+          war:=ata2int(ord(tmp[1]));\r
+\r
+         byt:=a[i+1];\r
+\r
+         if not(_lab_firstEx(byt) or _dec(byt) or (byt in ['$','%'])) then\r
+          inc(war,test_string(i,a,'F'));\r
+\r
+         value:=true;\r
+        end;\r
+\r
+   // odczytaj wartosc miedzy { }\r
+   '{': begin\r
+         if value then blad(old,4);\r
+\r
+         klamra_used := true;\r
+\r
+         petla:=dreloc.use;       // blokujemy relokowalnosc DRELOC.USE=FALSE\r
+         dreloc.use:=false;\r
+\r
+         tmp:=ciag_ograniczony(i,a,true);            // test na poprawnosc nawiasow\r
+         k:=1; nul:=oblicz_mnemonik__(k,tmp,old);\r
+\r
+         dreloc.use:=petla;       // przywracamy poprzednia wartosc DRELOC.USE\r
+\r
+         klamra_used := false;\r
+\r
+         war:=nul.h[0];\r
+\r
+         nul.l:=0;\r
+\r
+         value:=true;\r
+        end;\r
+\r
+   // odczytaj wartosc miedzy [ ] ( )\r
+   '[','(':\r
+        begin\r
+         if value then blad(old,4);\r
+\r
+         old_reloc_value_cnt := reloc_value.cnt;\r
+         old_reloc_value_use := reloc_value.use;\r
+\r
+         war:=oblicz_wartosc_ogr(a,old,i);\r
+\r
+         reloc_value.use := old_reloc_value_use;\r
+         inc(reloc_value.cnt, old_reloc_value_cnt);\r
+\r
+         value:=true;\r
+        end;\r
+\r
+   // jesli napotkasz spacje to zakoncz przetwarzanie\r
+   // do 'value' wpisz 'false' aby nie traktowal tego jako liczby\r
+   ' ',#9:\r
+        begin\r
+         value:=false; oper:=' ';  Break; //i:=len+1\r
+        end;\r
+\r
+  else\r
+   blad_ill(old,a[i]);\r
+  end;\r
+\r
+\r
+// jesli przetwarzamy wartosc numeryczna to zapisz na stosie\r
+// t¹ wartosc i operator\r
+  if value then begin\r
+\r
+   op[op_idx]:='+';\r
+\r
+  // przetworz operatory z 'OP' cofajac sie\r
+   for k:=op_idx downto 1 do\r
+    case op[k] of\r
+     '-': war := -war;\r
+     'M': war := byte(war);\r
+     'S': war := byte(war shr 8);\r
+     'H': war := byte(war shr 16);\r
+//     'I': war := byte(war shr 24);\r
+     '!': war := ord(war=0);\r
+     '~': war := not(war);\r
+     'X': war := b;\r
+    end;\r
+\r
+   if op[0]='-' then begin war:=-war; op[0]:='+' end;\r
+\r
+   stos[j].znak := op[0];\r
+   stos[j].wart := war;\r
+\r
+   cash[pos(op[0],prior)-1]:=op[0];\r
+\r
+  // zeruj indeks do tablicy dynamicznej OP\r
+   op_idx:=0; oper:=' ';\r
+\r
+   inc(j);\r
+//   if j>High(stos) then SetLength(stos,j+1);\r
+\r
+  end else begin\r
+\r
+   op[op_idx] := oper;\r
+\r
+   inc(op_idx);\r
+ //  if op_idx>High(op) then SetLength(op,op_idx+1);\r
+\r
+  end;\r
+\r
+ end;\r
+\r
+\r
+ if not(overflow) then\r
+  if oper<>' ' then blad(old,23);\r
+\r
+\r
+ if reloc_value.cnt>1 then blad(old,85);\r
+\r
+\r
+// obliczenie wartosci wg piorytetu obliczen\r
+// na koncu dodawaj tak dlugo az nie uzyskasz wyniku\r
+ len:=0; war:=0;\r
+\r
+ while cash[len]=' ' do inc(len);     // omijaj puste operatory\r
+ if len>=sizeof(cash) then exit;      // nie wystapil zaden operator\r
+\r
+ stos[0].znak:='+'; stos[0].wart:=0;\r
+ stos[j].znak:='+'; stos[j].wart:=0;\r
+ inc(j);\r
+\r
+// SetLength(stos,j+1);\r
+\r
+\r
+ while j>1 do begin\r
+ // 'petla=true' jesli nie wystapi zaden operator\r
+ // 'petla=false' jesli wystapi operator\r
+  i:=0; petla:=true;\r
+\r
+  while i<=j-2 do begin\r
+\r
+    war  := stos[i].wart;\r
+    oper := stos[i+1].znak;\r
+    iarg := stos[i+1].wart;\r
+\r
+ // obliczaj wg kolejnosci operatorow z 'prior'\r
+ // operatory '/','*','%' maja ten sam piorytet, stanowi¹ wyj¹tek\r
+\r
+     if (oper=cash[len]) or ((oper in ['/','*','%']) and (len in [5..7])) then begin\r
+        case oper of\r
+         '+': war := war + iarg;\r
+         '&': war := war and iarg;\r
+         '|': war := war or iarg;\r
+         '^': war := war xor iarg;\r
+         '*': war := war * iarg;\r
+\r
+         '/','%':\r
+              if iarg=0 then begin\r
+\r
+               overflow:=true;\r
+\r
+               if pass=pass_end then\r
+                blad(old,26)\r
+               else\r
+                war:=0;\r
+\r
+              end else\r
+               case oper of\r
+                '/': war := war div iarg;\r
+                '%': war := war mod iarg;\r
+               end;\r
+\r
+         '=': war := ord(war=iarg);\r
+         'A': war := ord(war<>iarg);\r
+         'B': war := ord(war<=iarg);\r
+         '<': war := ord(war<iarg);\r
+         'C': war := ord(war>=iarg);\r
+         '>': war := ord(war>iarg);\r
+         'D': war := war shl iarg;\r
+         'E': war := war shr iarg;\r
+         'F': war := ord(war<>0) and ord(iarg<>0);\r
+         'G': war := ord(war<>0) or ord(iarg<>0);\r
+        end;\r
+\r
+ // obliczyl nowa wartosc, skasuj znak\r
+\r
+      stos[i].wart   := war;\r
+      stos[i+1].znak := ' ';\r
+\r
+      inc(i); petla:=false;\r
+     end;\r
+\r
+  inc(i)\r
+  end;\r
+\r
+// przepisz elementy ktore maja niepusty znak na poczatek tablicy STOS\r
+  k:=0;\r
+\r
+  for i:=0 to j-1 do\r
+   if stos[i].znak<>' ' then begin\r
+    stos[k] := stos[i];\r
+    inc(k)\r
+   end;\r
+\r
+  j:=k;\r
+\r
+  if petla and (len<sizeof(prior)-1) then begin\r
+   inc(len);\r
+   while cash[len]=' ' do inc(len);\r
+  end;\r
+\r
+ end;\r
+\r
+\r
+ if overflow then          // konieczny warunek dla .MACRO\r
+  Result := 0\r
+ else\r
+  Result := war;\r
+\r
+end;\r
+\r
+\r
+function oblicz_wartosc_noSPC(var zm,old:string; var i:integer; const sep,typ:Char): Int64;\r
+(*----------------------------------------------------------------------------*)\r
+(*  pobieramy ciag pomijajac spacje, nastepnie obliczamy jego wartosc         *)\r
+(*----------------------------------------------------------------------------*)\r
+var txt: string;\r
+begin\r
+\r
+ txt:=get_dat_noSPC(i,zm,sep,#0,old);\r
+\r
+ Result:=oblicz_wartosc(txt,old);\r
+\r
+ omin_spacje(i,zm);\r
+\r
+ wartosc(old,Result,typ);\r
+\r
+end;\r
+\r
+\r
+function get_expres(var i:integer; var a,old:string; const tst:Boolean): Int64;\r
+(*----------------------------------------------------------------------------*)\r
+(*  pobierz ciag znakow ograniczony przecinkiem i oblicz jego wartosc         *)\r
+(*  nie wczytuj nawiasow zamykajacych ')'                                     *)\r
+(*  jesli TST = TRUE to sprawdzaj czy to koniec wyrazenia                     *)\r
+(*----------------------------------------------------------------------------*)\r
+var k: integer;\r
+    tmp: string;\r
+begin\r
+ k:=i;\r
+ tmp:=get_dat(k,a,')',false);\r
+\r
+ tmp:=a;\r
+ SetLength(tmp,k-1);  // tmp:=copy(a,1,k-1);\r
+\r
+ Result:=___wartosc_noSPC(tmp,old,i,',','F');\r
+\r
+ if tst then\r
+  if a[i]<>',' then blad(old,52) else inc(i);\r
+end;\r
+\r
+\r
+procedure put_lst(const a:string);\r
+(*----------------------------------------------------------------------------*)\r
+(*  zapisujemy wiersze listingu po asemblacji do pliku .LST                   *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+\r
+ if (pass=pass_end) and (a<>'') then begin\r
+\r
+   if run_macro then           // nie zapisuj zawartosci makra jesli bit5 OPT skasowany\r
+    if (opt and $20=0) and not(data_out) then exit;\r
+\r
+   if (opt and 4>0) and not(FOX_ripit) then writeln(lst,a);\r
+   if (opt and 8>0) and not(FOX_ripit) then writeln(a);\r
+\r
+   if not(FOX_ripit) then t:='';\r
+\r
+ end;\r
+\r
+end;\r
+\r
+\r
+procedure zapisz_lst(var a: string);\r
+(*----------------------------------------------------------------------------*)\r
+(*  wymuszenie zapisania wiersza listingu do pliku .LST                       *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+\r
+ if (pass=pass_end) then begin\r
+  justuj;  put_lst(t+a);  a:='';\r
+ end;\r
+\r
+end;\r
+\r
+\r
+procedure wymus_zapis_lst(var a: string);\r
+(*----------------------------------------------------------------------------*)\r
+(*  dodatkowe wymuszenie zapisania wiersza listingu do pliku .LST             *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+\r
+ if pass=pass_end then begin\r
+  save_lst(' ');\r
+  justuj;  put_lst(t+a);\r
+ end;\r
+\r
+end;\r
+\r
+\r
+procedure _siz(const t: Boolean);\r
+begin\r
+\r
+  if t then\r
+   t_siz[siz_idx-1].siz:=dreloc.siz\r
+  else\r
+   t_siz[siz_idx].siz:=dreloc.siz;\r
+\r
+end;\r
+\r
+\r
+procedure _sizm(const a: byte);\r
+begin\r
+\r
+ t_siz[siz_idx-1].lsb:=a;\r
+\r
+end;\r
+\r
+\r
+procedure oblicz_dane(var i:integer; var a,old:string; const typ: byte);\r
+(*----------------------------------------------------------------------------*)\r
+(*  zwracamy wartosci liczbowe dla ciagu DTA, .BYTE, .WORD, .LONG, .DWORD     *)\r
+(*----------------------------------------------------------------------------*)\r
+(*  B( -> BYTE, A( -> WORD, V( -> VECTOR (WORD)                               *)\r
+(*  L( -> BYTE, H( -> BYTE                                                    *)\r
+(*  T( -> 24bit, E( -> 24bit                                                  *)\r
+(*  F( -> DWORD                                                               *)\r
+(*  G( -> DWORD (odwrocona kolejnosc)                                         *)\r
+(*  C' -> ATASCII                                                             *)\r
+(*  D' -> INTERNAL                                                            *)\r
+(*  sin(centre,amp,size[,first,last])                                         *)\r
+(*----------------------------------------------------------------------------*)\r
+var op_, default: char;\r
+    sin_a, sin_b, sin_c, sin_d, sin_e, x, len, k: integer;\r
+    war: Int64;\r
+    invers: byte;\r
+    value, nawias, ciag: Boolean;\r
+    tmp: string;\r
+begin\r
+ omin_spacje(i,a);\r
+\r
+ if empty or enum.use then blad(old,58);\r
+\r
+ war:=0; invers:=0;\r
+\r
+ value:=false; nawias:=false; ciag:=false;\r
+\r
+ if not(pisz) then branch:=false;\r
+\r
+ reloc := false;\r
+\r
+ data_out := true;\r
+\r
+ tmp:=' ';\r
+\r
+\r
+// ------------------ okreslenie domyslnego typu wartosci ---------------------\r
+\r
+  default := tType[typ];\r
+  op_:=default;\r
+\r
+  dreloc.siz:=relType[typ];\r
+\r
+// ----------------------------------------------------------------------------\r
+\r
+\r
+ if not(pisz) and test_char(i,a,#0,#0) then begin // jesli brakuje danych to generuj domyslnie zera\r
+  save_dta(cardinal(war),tmp,op_,invers);\r
+  exit;\r
+ end;\r
+\r
+ if struct.use then blad(old,58);\r
+\r
+ vector:=true;\r
+\r
+ if not(pisz) then dta_used:=true;\r
+\r
+\r
+ len:=length(a);\r
+\r
+ while i<=len do begin\r
+\r
+// SIN, RND\r
+  if UpCase(a[i]) in ['S','R'] then begin\r
+   x:=ord(UpCase(a[i+1])) shl 16+ord(UpCase(a[i+2])) shl 8+ord(a[i+3]);\r
+\r
+  CASE x of\r
+ // IN(\r
+   $494E28: begin\r
+    inc(i,3);\r
+\r
+   // sprawdzamy poprawnosc nawiasow\r
+    k:=i;\r
+    tmp:=ciag_ograniczony(k,a,true);\r
+\r
+    value:=true; invers:=0; tmp:='';\r
+\r
+    inc(i);\r
+    sin_a:=integer( get_expres(i,a,old,true) );\r
+    sin_b:=integer( get_expres(i,a,old,true) );\r
+    sin_c:=integer( get_expres(i,a,old,false) );\r
+\r
+    if sin_c<=0 then blad(old,0);           \r
+\r
+    sin_d:=0;\r
+    sin_e:=sin_c-1;\r
+\r
+    if a[i]=',' then begin\r
+\r
+     inc(i);\r
+     sin_d:=integer( get_expres(i,a,old,true) );\r
+     sin_e:=integer( get_expres(i,a,old,false) );\r
+\r
+     inc(i);\r
+    end else inc(i);\r
+\r
+\r
+    while sin_d <= sin_e do begin\r
+     war:= sin_a + round(sin_b * sin(sin_d * 2 * pi / sin_c));\r
+\r
+     war:=wartosc(old,war,op_);\r
+     save_dta(cardinal(war),tmp,op_,invers);\r
+\r
+     inc(sin_d);\r
+    end;\r
+\r
+\r
+    omin_spacje(i,a);\r
+   end;\r
+\r
+ // ND(\r
+   $4E4428: begin\r
+    inc(i,3);\r
+\r
+   // sprawdzamy poprawnosc nawiasow\r
+    k:=i;\r
+    tmp:=ciag_ograniczony(k,a,true);\r
+\r
+    value:=true; invers:=0; tmp:='';\r
+\r
+    inc(i);\r
+    sin_a:=integer( get_expres(i,a,old,true) );\r
+    sin_b:=integer( get_expres(i,a,old,true) );\r
+    sin_c:=integer( get_expres(i,a,old,false) );\r
+    inc(i);\r
+\r
+    sin_d:=sin_b-sin_a;\r
+\r
+    randomize;\r
+    for x:=0 to sin_c-1 do begin\r
+\r
+     war:=sin_a+Int64(random(sin_d+1));\r
+\r
+     war:=wartosc(old,war,op_);\r
+     save_dta(cardinal(war),tmp,op_,invers)\r
+    end;\r
+\r
+    omin_spacje(i,a);\r
+   end;\r
+\r
+  END;    //end case\r
+\r
+  end;\r
+\r
+\r
+\r
+  case UpCase(a[i]) of\r
+   'A','B','E','F','G','H','L','T','V':\r
+\r
+          begin\r
+            k:=i;\r
+\r
+            if a[i+1] in [' ',#9] then begin\r
+             __inc(i,a);\r
+\r
+             if a[i]='(' then dec(i) else i:=k;\r
+            end;\r
+\r
+            if a[i+1]='(' then begin\r
+            // pobierz ciag ograniczony nawiasami ( )\r
+             if value then blad(old,4);\r
+\r
+             op_:=UpCase(a[k]);  inc(i);\r
+            // sprawdzamy poprawnosc\r
+             k:=i;\r
+             tmp:=ciag_ograniczony(k,a,true);\r
+             nawias:=true;\r
+\r
+            // dane inne niz 2 bajtowe nie sa relokowalne w przypadku SPARTA DOS X\r
+            // relokowalne sa wszystkie jesli uzylismy dyrektywy .RELOC\r
+             if dreloc.use then begin\r
+//              if op_='G' then branch:=true else branch:=false;\r
+              branch := (op_='G');\r
+\r
+              case op_ of\r
+               'E','T': dreloc.siz:=relType[3];\r
+               'A','V': dreloc.siz:=relType[2];\r
+                   'F': dreloc.siz:=relType[4];\r
+                   'L': dreloc.siz:='<';\r
+                   'H': dreloc.siz:='>';\r
+              else\r
+               dreloc.siz:=relType[1];\r
+              end;\r
+\r
+              _siz(false); \r
+\r
+             end else\r
+//              if op_ in ['E','F','G','T'] then branch:=true else branch:=false;\r
+              branch := (op_ in ['E','F','G','T']);\r
+\r
+             inc(i);             // omin nawias otwierajacy\r
+\r
+            end else begin\r
+\r
+             if dreloc.use then _siz(false);\r
+\r
+             if value then blad(old,4);\r
+             war:=get_expres(i,a,old, false);\r
+             value:=true;\r
+\r
+            { if reloc and not(nawias) then             ????????????????????????\r
+              if pass=pass_end then warning(116);  }\r
+\r
+             if pisz then end_string := end_string + '$' + hex(cardinal(war),4);\r
+            end;\r
+\r
+          end;\r
+\r
+\r
+   'C','D':\r
+          begin\r
+            k:=i;\r
+\r
+            if a[i+1] in [' ',#9] then begin\r
+             __inc(i,a);\r
+\r
+             if a[i] in ['''','"'] then dec(i) else i:=k;\r
+            end;\r
+\r
+            if a[i+1] in ['''','"'] then begin\r
+           // pobierz ciag ograniczony apostrofami '' lub ""\r
+             op_:=UpCase(a[k]);  inc(i);\r
+\r
+            end else begin\r
+\r
+             if dreloc.use then _siz(false);\r
+\r
+             if value then blad(old,4);\r
+             war:=get_expres(i,a,old, false);\r
+             value:=true;\r
+\r
+            { if reloc and not(nawias) then             ????????????????????????\r
+              if pass=pass_end then warning(116);    }\r
+\r
+             if pisz then end_string := end_string + '$' + hex(cardinal(war),4);\r
+            end;\r
+\r
+          end;\r
+\r
+   '''','"': begin\r
+              if value then blad(old,4);\r
+\r
+//              if aray then\r
+              if not(op_ in ['C','D']) then\r
+               if a[i]='"' then op_:='D' else op_:='C';\r
+\r
+              tmp:=get_string(i,a,old,true);\r
+              war:=0; ciag:=true;\r
+              invers:=byte( test_string(i,a,'B') );\r
+              value:=true;\r
+\r
+              if pisz then end_string := end_string + tmp;\r
+             end;\r
+\r
+\r
+   '(': begin nawias:=true; inc(i) end;\r
+\r
+\r
+   ')': if nawias and value then begin\r
+         value:=false; nawias:=false; inc(i);\r
+\r
+         omin_spacje(i,a);\r
+\r
+         if not(test_char(i,a,#0,#0)) then    // jesli nie ma konca linii to jedynym\r
+          if a[i]<>',' then blad(old,107);    // akceptowanym znakiem jest znak ','\r
+\r
+        end else blad(old,4);\r
+\r
+\r
+   ',': begin\r
+         inc(i); invers:=0; value:=false;\r
+\r
+         omin_spacje(i,a);\r
+         if test_char(i,a,#0,#0) then blad(old,23);  // jesli koniec linii to blad 'Unexpected end of line'\r
+\r
+         if not(nawias) then op_:=default;\r
+        end;\r
+\r
+\r
+   ' ',#9: omin_spacje(i,a); \r
+\r
+\r
+   '/': case a[i+1] of\r
+         '/': Break;\r
+         '*': begin tmp:=''; ___search_comment_block(i,a, tmp); if komentarz then Break end;\r
+        else\r
+         blad(old,4);   // value:=false; i:=length(a)+1\r
+        end;\r
+\r
+   ';','\': Break;                                   // value:=false; i:=length(a)+1\r
+\r
+  else\r
+       begin\r
+         if _eol(a[i]) then Break;\r
+\r
+         if dreloc.use then _siz(false);\r
+\r
+         if value then blad(old,4);\r
+\r
+         war:=get_expres(i,a,old, false);\r
+         value:=true;\r
+\r
+         if pisz then end_string := end_string + '$' + hex(cardinal(war),4);\r
+\r
+       end;\r
+  end;\r
+\r
+\r
+  if dta_used then\r
+   if value then begin\r
+\r
+    if not(ciag) then\r
+     if op_ in ['C','D'] then op_:='B';\r
+\r
+\r
+    if reloc and dreloc.use then begin\r
+     dec(war,rel_ofs); reloc:=false;\r
+\r
+     _sizm(byte(war));   \r
+    end;\r
+\r
+    if not(pisz) then begin\r
+\r
+     if ext_used.use and (op_ in ['L','H']) then\r
+      case op_ of\r
+       'L': t_ext[ext_idx-1].typ:='<';\r
+       'H': begin t_ext[ext_idx-1].typ:='>'; t_ext[ext_idx-1].lsb:=byte(war) end;\r
+      end;\r
+\r
+     war:=wartosc(old,war,op_);\r
+     save_dta(cardinal(war),tmp,op_,invers);\r
+    end else\r
+     branch:=true;           // jesli PISZ=TRUE to nie ma relokowalnosci\r
+\r
+    ciag:=false;\r
+   end;\r
+\r
+  omin_spacje(i,a);\r
+ end;\r
+\r
+ vector:=false; dta_used:=false;\r
+end;\r
+\r
+\r
+function value_code(var a: Int64; var old: string; const test:Boolean): char;\r
+(*----------------------------------------------------------------------------*)\r
+(*  przedstawiamy wartosc w postaci kodu literowego 'Z', 'Q', 'T' , 'D'       *)\r
+(*  kody literowe symbolizuja typ wartosci BYTE, WORD, LONG, DWORD            *)\r
+(*----------------------------------------------------------------------------*)\r
+var x: cardinal;\r
+begin\r
+ Result:='D';\r
+\r
+ x:=cardinal( abs(a) );\r
+\r
+ case x of\r
+              0..$FF: Result:='Z';\r
+         $100..$FFFF: Result:='Q';\r
+     $10000..$FFFFFF: if test then Result:='T' else blad(old,14);\r
+// $1000000..$FFFFFFFF: Result:='D';\r
+ else\r
+  if not(test) then blad(old,0);\r
+ end;\r
+\r
+end;\r
+\r
+\r
+procedure reg_size(const i:byte; const a:Boolean);\r
+(*----------------------------------------------------------------------------*)\r
+(*  nowe rozmiary rejestrow dla operacji sledzenia SEP, REP                   *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+\r
+ if i in [$10,$30] then begin regX:=a; regY:=a end;\r
+ if i in [$20,$30] then regA:=a;\r
+\r
+end;\r
+\r
+\r
+procedure test_reg_size(var a:string; const b:Boolean; const i:byte);\r
+(*----------------------------------------------------------------------------*)\r
+(*  sprawdzamy rozmiar rejestrow dla wlaczonej opcji sledzenia SEP, REP       *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+\r
+ if b then begin\r
+  if i>2 then blad(a,63);\r
+ end else\r
+  if i<3 then blad(a,63);\r
+\r
+end;\r
+\r
+\r
+function macro_rept_if_test: Boolean;\r
+begin\r
+ Result := (not(rept) and if_test)\r
+end;\r
+\r
+\r
+procedure test_siz(var a:string; var siz:Char; const x:Char; var pomin:Boolean);\r
+(*----------------------------------------------------------------------------*)\r
+(*  sprawdzamy identyfikator rozmiaru                                         *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+ if siz in [' ',x] then siz:=x else blad(a,14);\r
+\r
+ pomin:=true;\r
+end;\r
+\r
+\r
+function adr_label(const n: byte; const tst:Boolean): cardinal;\r
+(*----------------------------------------------------------------------------*)\r
+(*  szukamy wartosci dla etykiety o nazwie z MADS_STACK[N], jesli nie zostaly *)\r
+(*  zdefiniowane etykiety z MADS_STACK wowczas przypisujemy im wartosci       *)\r
+(*  z MADS_STACK_DEFAULT[N]                                                   *)\r
+(*----------------------------------------------------------------------------*)\r
+var i: integer;\r
+    txt: string;\r
+\r
+const\r
+    mads_stack_default: array [0..2] of cardinal = ($fe, $0500, $0600);\r
+\r
+begin\r
+ Result:=0;\r
+\r
+ txt:=mads_stack[n];  i:=load_lab(txt,false);\r
+\r
+ if tst then\r
+  if i<0 then begin\r
+   Result:=mads_stack_default[n];    // brak deklaracji dla etykiety z TXT\r
+\r
+   s_lab(txt,Result,bank,txt,'@');\r
+  end;\r
+\r
+ if i>=0 then Result:=t_lab[i].adr;  // odczytujemy wartosc etykiety\r
+end;\r
+\r
+\r
+procedure test_skipa;\r
+begin\r
+\r
+   if t_bck[1]=adres then exit;\r
+\r
+   t_bck[0] := t_bck[1];\r
+   t_bck[1] := adres;\r
+\r
+   if skip.use then begin\r
+\r
+    t_skp[skip.idx] := adres;\r
+\r
+    inc(skip.idx);\r
+\r
+    if skip.idx>High(t_skp) then SetLength(t_skp,skip.idx+1);\r
+\r
+    inc(skip.cnt);\r
+    if skip.cnt>1 then begin\r
+     skip.use := false;\r
+     skip.xsm := false;\r
+    end;\r
+\r
+   end;\r
+\r
+end;\r
+\r
+\r
+procedure addResult(var hlp, Res: int5);\r
+var i: integer;\r
+begin\r
+  for i:=0 to hlp.l-1 do Res.h[Res.l+i]:=hlp.h[i];\r
+  inc(Res.l, hlp.l);\r
+end;\r
+\r
+\r
+function asm_mnemo(var txt, old:string): int5;\r
+var i: integer;\r
+begin\r
+ i:=1; Result:=oblicz_mnemonik__(i,txt, old);\r
+\r
+ inc(adres, Result.l);\r
+end;\r
+\r
+\r
+function moveAXY(var mnemo,zm,zm2, old: string): int5;\r
+var tmp: string;\r
+    hlp: int5;\r
+    r: byte;\r
+    v: integer;\r
+begin\r
+\r
+   mnemo[1]:='L'; mnemo[2]:='D';                  // LD?\r
+   tmp:=mnemo + #32 + zm;\r
+   Result:=asm_mnemo(tmp,old);\r
+\r
+   if regAXY_opty and not(dreloc.use) and not(dreloc.sdx) then\r
+   if zm[1] in ['#','<','>'] then begin\r
+\r
+    v:=Result.h[1];\r
+\r
+    case mnemo[3] of\r
+     'A': r := 0;\r
+     'X': r := 1;\r
+//     'Y': r := 2;\r
+    else\r
+     r:=2;\r
+    end;\r
+\r
+    if regOpty.use then\r
+     if regOpty.reg[r]=v then Result.l:=0;\r
+\r
+    regOpty.reg[r]:=v;\r
+   end;\r
+\r
+\r
+   mnemo[1]:='S'; mnemo[2]:='T';                  // ST?\r
+   tmp:=mnemo + #32 + zm2;\r
+   hlp:=asm_mnemo(tmp,old);\r
+\r
+   addResult(hlp, Result);\r
+\r
+   Result.tmp:=hlp.h[0];\r
+end;\r
+\r
+\r
+function adrMode(var a: string): byte;\r
+begin\r
+\r
+ Result:=fCRC16(a);\r
+\r
+ if Result in [$60..$7e] then\r
+  dec(Result,$60)\r
+ else\r
+  Result:=0;\r
+\r
+end;\r
+\r
+\r
+procedure save_fake_label(var ety,old:string; const tst:cardinal);\r
+var war: integer;\r
+begin\r
+\r
+   war:=load_lab(ety,false);        // uaktualniamy wartosc etykiety\r
+\r
+   if war<0 then\r
+    s_lab(ety,tst,bank,old,ety[1])\r
+   else\r
+    t_lab[war].adr:=tst;\r
+\r
+end;\r
+\r
+\r
+procedure __next(var i:integer; var zm:string);\r
+begin\r
+ omin_spacje(i,zm);\r
+ if zm[i]=',' then __inc(i,zm);\r
+ omin_spacje(i,zm);\r
+end;\r
+\r
+\r
+procedure get_parameters(var j:integer; var str:string; var par:_strArray; const mae:Boolean; const sep1,sep2: char);\r
+(*----------------------------------------------------------------------------*)\r
+(*  jesli wystepuje znak '=' to omijamy spacje sprzed i zza znaku '='         *)\r
+(*  zapamietamy wszystkie etykiety (parametry) w tablicy dynamicznej          *)\r
+(*----------------------------------------------------------------------------*)\r
+var txt: string;\r
+    i: integer;\r
+begin\r
+\r
+    SetLength(par,1);\r
+\r
+    if str='' then exit;\r
+\r
+    omin_spacje(j,str);\r
+\r
+    while not(test_char(j,str, sep1,sep2)) do begin\r
+\r
+      txt:=get_dat(j,str,',',true);   // TRUE - konczy gdy napotka biala spacje\r
+\r
+      i:=length(txt);                 // wyjatek jesli odczytal ciag znakow zakonczony\r
+                                      // znakiem '=', np. 'label='\r
+      if i>0 then\r
+       if txt[i]='=' then begin\r
+        SetLength(txt, i-1);\r
+        dec(j);\r
+       end;\r
+\r
+\r
+      i := j;\r
+\r
+      omin_spacje(j,str);\r
+\r
+      if str[j]='=' then begin        // '=' nowa wartosc dla etykiety\r
+       __inc(j,str);\r
+       txt:=txt+'=';\r
+       txt:=txt+get_dat(j,str,',',true);\r
+      end else\r
+       j := i;                        // jesli nie odczytal znaku '='\r
+\r
+\r
+   //   if txt<>'' then begin        // !!! inaczej nie bedzie pomijal parametrow PROC !!!\r
+                                     // np. proc_label ,1\r
+       i:=High(par);\r
+\r
+       par[i]:=txt;\r
+\r
+       SetLength(par,i+2);\r
+\r
+  //    end;\r
+\r
+\r
+      if str[j] in [',',' ',#9] then\r
+       __next(j,str)\r
+      else\r
+       if mae and test_char(j,str,#0,#0) then Break;\r
+\r
+    end;\r
+\r
+end;\r
+\r
+\r
+function TypeToByte(const a: char): byte;\r
+begin\r
+\r
+ case a of\r
+  'B': Result := 1;\r
+  'W': Result := 2;\r
+  'L': Result := 3;\r
+  'D': Result := 4;\r
+ else\r
+   Result := 0;\r
+ end;\r
+\r
+end;\r
+\r
+\r
+function ValueToType(const a: Int64): byte;\r
+begin\r
+\r
+ case abs(a) of\r
+           0..$FF: Result:=1;\r
+      $100..$FFFF: Result:=2;\r
+  $10000..$FFFFFF: Result:=3;\r
+ else\r
+  Result:=4\r
+ end;\r
+\r
+end;\r
+\r
+\r
+function getByte(var pom: string; const ile: byte; const ch: Char): string;\r
+begin\r
+\r
+ Result:='';\r
+\r
+      case ch of\r
+       'W': case ile of\r
+             2: pom[1]:='>';\r
+             1: pom[1]:='<';\r
+            end;\r
+\r
+       'L': case ile of\r
+             3: pom[1]:='^';\r
+             2: pom[1]:='>';\r
+             1: pom[1]:='<';\r
+            end;\r
+\r
+       'D': case ile of\r
+             4: Result:='>>24';\r
+             3: pom[1]:='^';\r
+             2: pom[1]:='>';\r
+             1: pom[1]:='<';\r
+            end;\r
+       end;\r
+       \r
+end;\r
+\r
+\r
+function oblicz_mnemonik(var i:integer; var a,old:string): int5;\r
+(*----------------------------------------------------------------------------*)\r
+(*  funkcja zwraca wartosc typu INT5                                          *)\r
+(*  INT5.L  -> liczba bajtow                                                  *)\r
+(*  INT5.H  -> kod maszynowy mnemonika, ARGUMENTY                             *)\r
+(*----------------------------------------------------------------------------*)\r
+var j, m, idx, len: integer;\r
+    op_, mnemo, mnemo_tmp, zm, tmp, str, pom, add: string;\r
+    war, war_roz, help: Int64;\r
+    code, ile, k, byt: byte;\r
+    op, siz: char;\r
+    test, zwieksz, incdec, mvnmvp, mSEP, mREP, pomin, opty, isvar: Boolean;\r
+    branch_run: Boolean;\r
+    tryb: cardinal;\r
+    hlp: int5;\r
+    par: _strArray;\r
+\r
+const\r
+ maska: array [1..23] of cardinal=(\r
+ $01,$02,$04,$08,$10,$20,$40,$80,$100,$200,$400,$800,$1000,$2000,\r
+ $4000,$8000,$10000,$20000,$40000,$80000,$100000,$200000,$400000);\r
+\r
+ addycja: array [1..24] of byte=(\r
+ 0,0,4,8,8,12,16,20,20,24,28,44,0,0,8,4,8,16,20,24,24,32,32,32);\r
+\r
+ addycja_16: array [1..207] of byte=(\r
+ 0,0,0,2,2,4,6,8,8,12,14,16,17,18,20,20,22,24,28,30,32,34,48,\r
+ 0,0,0,2,2,8,6,4,8,16,14,16,17,18,24,24,22,32,32,30,32,34,48,\r
+ 0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,220,\r
+ 0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,32,144,48,\r
+ 0,0,0,0,0,0,0,101,0,8,0,0,0,0,16,0,0,0,24,0,0,0,0,\r
+ 0,0,0,0,0,0,0,0,0,56,0,0,0,0,16,0,0,0,58,0,0,0,0,\r
+ 0,0,0,0,0,0,0,146,0,0,0,0,114,0,0,0,0,0,0,0,0,0,0,\r
+ 0,0,0,0,0,140,0,0,0,148,0,0,0,0,156,0,0,0,164,0,0,0,0,\r
+ 0,0,0,0,0,204,0,0,0,212,0,0,0,0,220,0,0,0,228,0,0,0,0);\r
+\r
+ // kod maszynowy mnemonika w pierwszej adresacji (CPU 6502)\r
+ kod: array [0..55] of byte=(\r
+ $A1,$9E,$9C,$81,$82,$80,$61,$21,\r
+ $02,$E1,$14,$40,$42,$01,$C1,$BC,\r
+ $DC,$C2,$E2,$41,$22,$62,$00,$18,\r
+ $58,$B8,$D8,$08,$28,$48,$68,$40,\r
+ $60,$38,$78,$F8,$C8,$E8,$88,$CA,\r
+ $8A,$98,$9A,$A8,$AA,$BA,$EA,$10,\r
+ $30,$D0,$90,$B0,$F0,$50,$70,$20);\r
+\r
+ // kod maszynowy mnemonika w pierwszej adresacji (CPU 65816)\r
+ kod_16: array [0..91] of byte=(\r
+ $A1,$9E,$9C,$81,$82,$80,$61,$21,\r
+ $02,$E1,$20,$4C,$42,$01,$C1,$BC,\r
+ $DC,$3A,$1A,$41,$22,$62,$00,$18,\r
+ $58,$B8,$D8,$08,$28,$48,$68,$40,\r
+ $60,$38,$78,$F8,$C8,$E8,$88,$CA,\r
+ $8A,$98,$9A,$A8,$AA,$BA,$EA,$10,\r
+ $30,$D0,$90,$B0,$F0,$50,$70,$24,\r
+ $64,$DE,$BE,$10,$00,$80,$FE,$54,\r
+ $44,$62,$8B,$0B,$4B,$DA,$5A,$AB,\r
+ $2B,$FA,$7A,$6B,$DB,$5B,$1B,$7B,\r
+ $3B,$9B,$BB,$CB,$42,$EB,$FB,$3A,\r
+ $1A,$14,$4E,$80);\r
+\r
+ // mozliwe adresacje rozkazu (10 bitow) CPU6502\r
+ // bity w najstarszym bajcie oznaczaja przesuniecie w tablicy 'ADDYCJA'\r
+ ads: array [0..55] of cardinal=(\r
+ $000006ED,$8000032C,$800004AC,$000006E5,$00000124,$000000A4,$000006ED,$000006ED,\r
+ $000004B4,$000006ED,$00000020,$00000820,$000004B4,$000006ED,$000006ED,$8000002C,\r
+ $8000002C,$000004A4,$000004A4,$000006ED,$000004B4,$000004B4,$00000000,$00000000,\r
+ $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,\r
+ $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,\r
+ $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000002,\r
+ $00000002,$00000002,$00000002,$00000002,$00000002,$00000002,$00000002,$00000024);\r
+\r
+ // mozliwe adresacje rozkazu (32 bity) CPU65816\r
+ // bity w najstarszym bajcie oznaczaja przesuniecie w tablicy 'ADDYCJA_16'\r
+ ads_16: array [0..91] of cardinal=(\r
+ $000F7EE9,$800282A0,$800442A0,$000F7E69,$00008220,$00004220,$000F7EE9,$000F7EE9,\r
+ $00044320,$000F7EE9,$40400600,$20700600,$00044320,$000F7EE9,$000F7EE9,$800002A0,\r
+ $800002A0,$02044320,$01044320,$000F7EE9,$00044320,$00044320,$00000000,$00000000,\r
+ $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,\r
+ $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,\r
+ $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000002,\r
+ $00000002,$00000002,$00000002,$00000002,$00000002,$00000002,$00000002,$100442A0,\r
+ $08044220,$80000080,$80000080,$00000220,$00000220,$00000012,$80000080,$00000004,\r
+ $00000004,$04001090,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,\r
+ $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,\r
+ $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,\r
+ $00000000,$00000400,$00000400,$00000010);\r
+\r
+begin\r
+ Result.l:=0;\r
+                          \r
+ if a='' then blad(old,12);\r
+\r
+ op_:=''; siz:=' '; op:=' ';\r
+\r
+ war_roz:=0;\r
+\r
+ mvnmvp:=true; mSEP:=false; mREP:=false; pomin:=false; ext_used.use:=false;\r
+\r
+ zwieksz:=false; incdec:=false; reloc:=false; branch:=false;   mne_used:=false;\r
+\r
+ omin_spacje(i,a);\r
+\r
+ m:=i;                  // zapamietaj pozycje\r
+\r
+// pobierz nazwe rozkazu, oblicz jego CRC16\r
+ mnemo:='';  mnemo_tmp:='';\r
+\r
+ if _lab_first(a[i]) then\r
+  while _lab(a[i]) or (a[i] in [':','%']) do begin\r
+   mnemo:=mnemo+UpCase(a[i]);\r
+   mnemo_tmp:=mnemo_tmp+UpCas_(a[i]);\r
+   inc(i);\r
+  end;\r
+\r
+\r
+ // asemblujemy procedury .PROC do ktorych wystapilo odwolanie w programie\r
+ // przelacznik -x 'Exclude unreferenced procedures' musi byc uaktywniony\r
+ if exclude_proc then\r
+  if proc and (pass>0) then\r
+   if not(t_prc[proc_nr-1].use) then begin\r
+\r
+    if VerifyProc then begin\r
+\r
+     exProcTest  := false;\r
+     exclude_proc:= false;\r
+\r
+     Result:=oblicz_mnemonik(m,a,old);     // dodatkowy test linii gdy EXCLUDE_PROC:=FALSE\r
+\r
+     if Result.l<__equ then Result.l:=0;\r
+\r
+     exProcTest  := true;\r
+     exclude_proc:= true;\r
+\r
+     i:=m;\r
+    end;\r
+\r
+    exit;\r
+   end;\r
+\r
+\r
+ // jesli czytamy tablice ARRAY to linia zaczyna sie znakiem '(' lub '['\r
+ // jesli innym niz znaki konca linii to blad 'Improper syntax'\r
+  if aray then begin\r
+   Result.l:=__array_run; i:=1; exit\r
+  end;\r
+\r
+\r
+ // jesli brakuje mnemonika to sprawdz czy nie jest to cyfra (blad 'Illegal instruction')\r
+ // w innym przypadku nie przetwarzamy tego i wychodzimy\r
+  if mnemo='' then\r
+   if _dec(a[i]) or (a[i] in ['$','%']) then\r
+    blad(old,12)\r
+   else\r
+    exit;\r
+\r
+\r
+ // wyjatek znak '=' jest rownowazny 'EQU'\r
+ // dla etykiety zaczynajacej sie od pierwszego znaku w wierszu\r
+ if mnemo='=' then begin Result.l:=__equ; exit end;\r
+\r
+\r
+ // jesli wystepuje znak ':' tzn ze laczymy mnemoniki w stylu XASM'a\r
+ j:=pos(':',mnemo);\r
+ if j>0 then begin\r
+   Result.i:=i;\r
+   i:=m;                      // modyfikujemy wartosc spod adresu 'i'\r
+   Result.l:=__xasm;\r
+   exit;\r
+ end;\r
+\r
+\r
+// sprawdz czy to operacja przypisania '=' , 'EQU' , '+=' , '-=' , '++' , '--'\r
+// dla etykiety poprzedzonej minimum jedna spacja lub tabulatorem\r
+\r
+ j:=i;\r
+\r
+ omin_spacje(i,a);\r
+\r
+ tmp:='';\r
+\r
+ if UpCase(a[i])='E' then begin\r
+  tmp:=get_datUp(i,a,#0,false);\r
+  k:=fASC(tmp);\r
+ end else begin\r
+\r
+  while a[i] in ['=','+','-'] do begin\r
+   tmp:=tmp+a[i];\r
+   if a[i]='=' then Break;\r
+   __inc(i,a);\r
+  end;\r
+\r
+  k:=fCRC16(tmp);\r
+\r
+ end;\r
+\r
+//  if (tmp='EQU') or (tmp='=') or (tmp='+=') or (tmp='-=') or (tmp='++') or (tmp='--') then begin\r
+ if k in [__equ+1, __nill] then begin\r
+   i:=m;                      // modyfikujemy wartosc spod adresu 'i'\r
+   Result.l:=__addEqu;\r
+   exit;\r
+ end;\r
+\r
+\r
+ i:=j;\r
+\r
+\r
+ len:=length(mnemo);\r
+\r
+\r
+// sprawdz czy wystapilo rozszerzenie mnemonika\r
+ if len=5 then\r
+  if a[i-2]='.' then\r
+                    case UpCase(a[i-1]) of\r
+                     'A','W','Q': siz:='Q';\r
+                         'B','Z': siz:='Z';\r
+                         'L','T': siz:='T';\r
+                    end;\r
+\r
+\r
+// poszukaj mnemonika w tablicy HASH\r
+ k:=0;\r
+\r
+ if len=3 then\r
+  k:=fASC(mnemo)\r
+ else\r
+  if siz<>' ' then begin     // jesli SIZ<>' ' tzn ze jest to 3-literowy mnemonik z rozszerzeniem\r
+\r
+    k:=fASC(mnemo);\r
+\r
+    if k>0 then SetLength(mnemo,3); // jesli taki mnemonik istnieje to OK,\r
+                                    // !!! w przeciwnym wypadku zapewne jest to jakies makro !!!\r
+  end;\r
+\r
+\r
+ if not(opt and 16>0) then\r
+  if k in [57..92] then k:=0;    // symbole mnemonikow maja kody <1..91>\r
+                                 // symbole mnemonikow 6502      <1..56>\r
+                                 // symbole mnemonikow 65816     <57..92>\r
+\r
+// w IDX przechowujemy aktualny adres asemblacji, tej zmiennej nie uzyjemy w innym celu\r
+\r
+if k in [__cpbcpd..__jskip] then begin\r
+\r
+ if adres<0 then\r
+  if pass=pass_end then blad(old,10);\r
+\r
+ if siz<>' ' then blad(old,33);\r
+\r
+ if not(k in [__BckSkp, __phrplr]) then begin     // __BckSkp i __phrplr nie potrzebuja parametrow\r
+\r
+  omin_spacje(i,a);\r
+\r
+  SetLength(par, 1);\r
+  \r
+  while not(test_char(i,a,#0,#0)) do begin\r
+\r
+   idx:=High(par);\r
+\r
+   par[idx]:=get_dat(i,a,' ',true);\r
+\r
+   //if par[idx][1] in ['<','>'] then insert('#',par[idx],1);   // !!! zaremowac !!! bo zle liczy "mva >$e000+3 $80" \r
+\r
+   SetLength(par, idx+2);\r
+\r
+   omin_spacje(i,a);\r
+  end;\r
+\r
+  tmp:=par[0];\r
+ end;\r
+\r
+ idx := adres;\r
+\r
+ Result.l:=0;\r
+\r
+\r
+ case k of\r
+\r
+// obsluga PHR, PLR\r
+ __phrplr:\r
+ begin\r
+\r
+  Result.l:=5;\r
+\r
+  if mnemo[2]='H' then begin\r
+   Result.h[0]:=$48;\r
+   Result.h[1]:=$8a;\r
+   Result.h[2]:=$48;\r
+   Result.h[3]:=$98;\r
+   Result.h[4]:=$48;\r
+  end else begin\r
+   Result.h[0]:=$68;\r
+   Result.h[1]:=$a8;\r
+   Result.h[2]:=$68;\r
+   Result.h[3]:=$aa;\r
+   Result.h[4]:=$68;\r
+  end;\r
+\r
+ end;\r
+\r
+\r
+// obsluga INW, INL, IND, DEW, DEL, DED\r
+ __inwdew:\r
+ begin\r
+\r
+  if High(par)<1 then blad(old,23);\r
+\r
+  Result.l:=0;\r
+\r
+  ile:=TypeToByte(mnemo[3]);\r
+\r
+  mnemo[3]:='C';\r
+\r
+\r
+  if mnemo[1]='I' then begin         // INW, INL, IND\r
+\r
+   str:='##INC#DEC'+IntToStr(ora_nr);\r
+\r
+   j:=load_lab(str,false);        // odczytujemy wartosc etykiety\r
+\r
+   if j>=0 then\r
+    tryb:=t_lab[j].adr\r
+   else\r
+    tryb:=0;\r
+\r
+   j:=0;\r
+\r
+   while ile>0 do begin\r
+     zm:=mnemo + #32 + tmp + '+' + IntToStr(j);\r
+     hlp:=asm_mnemo(zm,old);\r
+     addResult(hlp, Result);\r
+\r
+     if ile>1 then begin\r
+      zm:='BNE '+IntToStr(tryb);\r
+      hlp:=asm_mnemo(zm,old);\r
+      addResult(hlp, Result);\r
+     end;\r
+\r
+     inc(j);\r
+     dec(ile);\r
+   end;\r
+\r
+   save_fake_label(str,old, adres);\r
+\r
+   inc(ora_nr);\r
+\r
+  end else begin                     // DEW, DEL, DED\r
+\r
+   byt:=0;\r
+\r
+   while byt<ile-1 do begin\r
+\r
+     zm:='LDA ' + tmp + '+' + IntToStr(byt);\r
+     hlp:=asm_mnemo(zm,old);\r
+     addResult(hlp, Result);\r
+\r
+     str:='##INC#DEC'+IntToStr(Int64(ora_nr)+byt);\r
+\r
+     j:=load_lab(str,false);         // odczytujemy wartosc etykiety\r
+\r
+     if j>=0 then\r
+      tryb:=t_lab[j].adr\r
+     else\r
+      tryb:=0;\r
+\r
+     zm:='BNE '+IntToStr(tryb);\r
+     hlp:=asm_mnemo(zm,old);\r
+     addResult(hlp, Result);\r
+\r
+     inc(byt);\r
+   end;\r
+\r
+   inc(byt);\r
+\r
+   while byt<>0 do begin\r
+\r
+     if byt<>ile then begin\r
+      str:='##INC#DEC'+IntToStr(Int64(ora_nr)+byt-1);\r
+      save_fake_label(str,old, adres);\r
+     end;\r
+\r
+     zm:='DEC ' + tmp + '+' + IntToStr(Int64(byt)-1);\r
+     hlp:=asm_mnemo(zm,old);\r
+     addResult(hlp, Result);\r
+\r
+     dec(byt);\r
+   end;\r
+\r
+   inc(ora_nr, ile-1);\r
+  end;\r
+\r
+ end;\r
+\r
+\r
+// obsluga ADW, SBW\r
+ __adwsbw:\r
+ begin\r
+    if High(par)<2 then blad(old,23);\r
+\r
+    str:=par[1];\r
+    pom:=par[2];\r
+\r
+    test:=false;\r
+    if pom='' then\r
+     pom:=tmp                        // w POM wynik operacji\r
+    else\r
+     test:=true;\r
+\r
+    if tmp[1]='#' then blad(old,14);\r
+\r
+    mnemo[3] := 'C';                 // ADC, SBC\r
+\r
+    if mnemo[1]='S' then\r
+     zm:='SEC'\r
+    else\r
+     zm:='CLC';\r
+\r
+    Result:=asm_mnemo(zm,old);\r
+\r
+    zm:='LDA ' + tmp;\r
+\r
+    hlp:=asm_mnemo(zm,old);\r
+    addResult(hlp, Result);\r
+\r
+    ile:=hlp.h[0];\r
+\r
+    opty:=false;\r
+    if ile=$B1 then opty:=true;      // wystepuje LDA(),Y\r
+\r
+\r
+    if not(ile in [$A5,$AD,$B5,$BD]) then\r
+     test:=true;                     // nie przejdzie krotsza wersja z SCC, SCS\r
+\r
+\r
+    if str[1]='#' then begin\r
+     str[1]:='+';\r
+     branch:=true;                   // nie relokujemy, testujemy tylko wartosc\r
+     war:=oblicz_wartosc(str,old);\r
+     wartosc(old,war,'A');\r
+\r
+     str[1]:='<';\r
+     zm:=mnemo + #32 + str;\r
+     hlp:=asm_mnemo(zm,old);\r
+     addResult(hlp, Result);\r
+\r
+     zm:='STA '+pom;\r
+     hlp:=asm_mnemo(zm,old);\r
+     addResult(hlp, Result);\r
+\r
+     if not(test) and (war<256) then begin\r
+\r
+      if mnemo[1]='S' then\r
+       zm:='SCS'\r
+      else\r
+       zm:='SCC';\r
+\r
+      hlp:=asm_mnemo(zm,old);\r
+      addResult(hlp, Result);\r
+\r
+      test_skipa;\r
+\r
+      if mnemo[1]='S' then\r
+       zm:='DEC ' + tmp + '+1'\r
+      else\r
+       zm:='INC ' + tmp + '+1';\r
+\r
+      hlp:=asm_mnemo(zm,old);\r
+      addResult(hlp, Result);\r
+\r
+     end else begin\r
+\r
+      if opty then begin\r
+\r
+       zm:='iny';                     // tylko w ten sposob przez ASM_MNEMO\r
+       hlp:=asm_mnemo(zm, old);       // inaczej nie bedzie relokowalnosci\r
+       addResult(hlp,Result);\r
+\r
+{       hlp.l:=1;\r
+       hlp.h[0]:=$c8;               // $C8 = INY\r
+       addResult(hlp,Result);}\r
+\r
+       add:='';\r
+      end else\r
+       add:='+1';\r
+\r
+      zm:='LDA ' + tmp + add;\r
+      hlp:=asm_mnemo(zm,old);\r
+      addResult(hlp, Result);\r
+\r
+      str[1]:='>';\r
+      zm:=mnemo + #32 + str;\r
+      hlp:=asm_mnemo(zm,old);\r
+      addResult(hlp, Result);\r
+\r
+      zm:='STA ' + pom + add;\r
+      hlp:=asm_mnemo(zm,old);\r
+      addResult(hlp, Result);\r
+     end;\r
+\r
+    end else begin\r
+     zm:=mnemo + #32 + str;\r
+     hlp:=asm_mnemo(zm,old);\r
+     addResult(hlp, Result);\r
+\r
+     byt:=hlp.h[0];\r
+\r
+     zm:='STA ' + pom;\r
+     hlp:=asm_mnemo(zm,old);\r
+     addResult(hlp, Result);\r
+\r
+     if opty then begin\r
+\r
+      zm:='iny';\r
+      hlp:=asm_mnemo(zm, old);\r
+      addResult(hlp,Result);\r
+     \r
+{      hlp.l:=1;\r
+      hlp.h[0]:=$c8;               // $C8 = INY\r
+      addResult(hlp,Result);}\r
+\r
+      add:='';\r
+     end else\r
+      add:='+1';\r
+\r
+      \r
+     if byt in [$71,$F1] then begin         // $71 = ADC(),Y ; $F1 = SBC(),Y\r
+\r
+      if not(opty) then begin\r
+\r
+       zm:='iny';\r
+       hlp:=asm_mnemo(zm, old);\r
+       addResult(hlp,Result);\r
+\r
+{       hlp.l:=1;\r
+       hlp.h[0]:=$c8;              // $C8 = INY\r
+       addResult(hlp,Result);}\r
+\r
+       if (ile in [$b6,$b9,$be]) then add:='';\r
+      end;\r
+\r
+     end else\r
+      if not(opty and (byt=$79)) then str:=str+'+1';\r
+\r
+     zm:='LDA ' + tmp + add;\r
+     hlp:=asm_mnemo(zm,old);\r
+     addResult(hlp, Result);\r
+\r
+     zm:=mnemo + #32 + str;\r
+     hlp:=asm_mnemo(zm,old);\r
+     addResult(hlp, Result);\r
+\r
+     zm:='STA ' + pom + add;\r
+     hlp:=asm_mnemo(zm,old);\r
+     addResult(hlp, Result);\r
+    end;\r
+\r
+\r
+    case pom[length(pom)] of\r
+     '+': zm:='iny';\r
+     '-': zm:='dey';\r
+    else\r
+     zm:='';\r
+    end;\r
+\r
+    if zm<>'' then begin\r
+     hlp:=asm_mnemo(zm, old);\r
+     addResult(hlp,Result);\r
+    end;\r
+\r
+ end;\r
+\r
+\r
+// obsluga ADB, SBB\r
+ __adbsbb:\r
+ begin\r
+    if High(par)<2 then blad(old,23);\r
+\r
+    str:=par[1];\r
+    pom:=par[2];\r
+\r
+    Result.l:=0;\r
+\r
+    if pom='' then begin\r
+     pom:=tmp;\r
+\r
+     if tmp[1]='#' then\r
+      if str[1]<>'#' then pom:=str;\r
+\r
+    end;\r
+\r
+    if tmp<>'@' then begin\r
+     zm:='LDA ' + tmp;\r
+     Result:=asm_mnemo(zm,old);\r
+    end;\r
\r
+    if mnemo[1]='S' then\r
+     zm:='SUB '\r
+    else\r
+     zm:='ADD ';\r
+\r
+    zm:=zm + str;\r
+    hlp:=asm_mnemo(zm,old);\r
+    addResult(hlp, Result);\r
+\r
+    if pom<>'@' then begin\r
+     zm:='STA ' + pom;\r
+     hlp:=asm_mnemo(zm,old);\r
+     addResult(hlp, Result);\r
+    end;\r
+ end;\r
+\r
\r
+// obsluga ADD, SUB\r
+ __addsub:\r
+ begin\r
+\r
+  if High(par)<1 then blad(old,23);\r
+\r
+  inc(adres);\r
+\r
+  mnemo[2]:=mnemo[3];\r
+  mnemo[3]:='C';\r
+  Result.l:=1;\r
+\r
+  if mnemo[1]='A' then\r
+   Result.h[0]:=$18               // kod dla CLC\r
+  else\r
+   Result.h[0]:=$38;              // kod dla SEC\r
+\r
+  zm:=mnemo + #32 + tmp;\r
+  hlp:=asm_mnemo(zm,old);\r
+  addResult(hlp, Result);\r
+ end;\r
+\r
+\r
+// obsluga MVA, MVX, MVY, MWA, MWX, MWY\r
+ __movaxy:\r
+ begin\r
+\r
+  if High(par)<2 then blad(old,23);\r
+              \r
+  zm:=par[1];\r
+\r
+  op:=tmp[1];\r
+  Result.l:=0;\r
+\r
+  opty:=false;\r
+\r
+  if op='#' then regOpty.blk:=true;   // wlaczamy przetwarzanie makro-rozkazow MW?#, MV?#\r
+\r
+  \r
+  if mnemo[2]='W' then begin          // MW?\r
+\r
+    if op='#' then begin\r
+\r
+     variable:=false;                 // domyslnie VARIABLE=FALSE, czyli nie jest to zmienna\r
+\r
+     tmp[1]:='+';\r
+     branch:=true;                    // nie relokujemy, testujemy tylko wartosc\r
+     war:=oblicz_wartosc(tmp,old);\r
+     wartosc(old,war,'A');\r
+\r
+//     if not(dreloc.use) and not(dreloc.sdx) then\r
+      if not(variable) then           // jesli nie jest to zmienna to testujemy dalej\r
+       if byte(war)=byte(war shr 8) then opty:=true;\r
+\r
+     tmp[1]:='<';\r
+    end;\r
+\r
+    Result:=moveAXY(mnemo,tmp,zm,old);\r
+                   \r
+    test:=false;\r
+\r
+\r
+    if not(opty) then\r
+    if op='#' then\r
+     tmp[1]:='>'\r
+    else                                     // wyj¹tek MWA (ZP),Y ADR\r
+     if Result.h[0]<>$B1 then begin          // $B1 = LDA(ZP),Y\r
+\r
+      if Result.tmp=$91 then begin\r
+       if not(Result.h[0] in [$b6,$b9,$be]) then tmp:=tmp+'+1';\r
+      end else\r
+       tmp:=tmp+'+1';\r
+\r
+     end else begin                    // $C8 = INY\r
+\r
+      if Result.h[Result.l-1]<>$c8 then begin\r
+       pom:='iny';                     // tylko w ten sposob przez ASM_MNEMO\r
+       hlp:=asm_mnemo(pom, old);       // inaczej nie bedzie relokowalnosci\r
+       addResult(hlp,Result);\r
+      end;\r
+\r
+      test:=true;\r
+     end;\r
+\r
+    if Result.tmp=$91 then begin      // $91 = STA(ZP),Y\r
+\r
+     if (Result.h[0]<>$B1) and (Result.h[Result.l-1]<>$c8) then begin\r
+      pom:='iny';\r
+      hlp:=asm_mnemo(pom, old);\r
+      addResult(hlp,Result);\r
+     end;\r
+\r
+    end else\r
+     if test then begin                                     // $96 = STX Z,Y\r
+      if not(Result.tmp in [$96,$99]) then zm:=zm+'+1';     // $99 = STA Q,Y\r
+     end else\r
+      zm:=zm+'+1';\r
+\r
+  end;\r
+\r
+\r
+  if opty then begin\r
+\r
+   tmp:=mnemo + #32 + zm;\r
+   hlp:=asm_mnemo(tmp, old);\r
+\r
+  end else\r
+   hlp:=moveAXY(mnemo,tmp,zm,old);    // MV?\r
+\r
+\r
+  addResult(hlp,Result);\r
+\r
+  regOpty.blk:=false;                 // wylaczamy przetwarzanie makro-rozkazow MWA, MVA itp.\r
+ end;\r
+\r
+\r
+// obsluga JEQ, JNE, JPL, JMI, JCC, JCS, JVC, JVS\r
+ __jskip:\r
+ begin\r
+\r
+  mnemo[1]:='B';              // zamieniamy pseudo rozkaz na mnemonik\r
+  k:=fASC(mnemo);             // wyliczamy kod dla mnemonika\r
+\r
+  branch:=true;      // nie relokujemy\r
+  war:=oblicz_wartosc(tmp,old);\r
+\r
+  test:=false; war:=war-2-adres;\r
+\r
+  if (war<0) and (abs(war)-128>0) then test:=true;\r
+  if (war>0) and (war-127>0) then test:=true;\r
+\r
+\r
+  if not(test) then begin\r
+\r
+   Result.l:=2;\r
+   Result.h[0]:=kod[k-1] {xor $20};     // kod maszynowy mnemonika w pierwszej adresacji 6502\r
+   Result.h[1]:=byte(war);\r
+\r
+  end else begin\r
+\r
+   inc(adres,2);\r
+\r
+   Result.l:=2;\r
+   Result.h[0]:=kod[k-1] xor $20;     // kod maszynowy mnemonika w pierwszej adresacji 6502\r
+   Result.h[1]:=3;\r
+\r
+   zm:='JMP ' + tmp;\r
+   hlp:=asm_mnemo(zm,old);\r
+   addResult(hlp,Result);\r
+  end;\r
+\r
+ end;\r
+\r
+\r
+// sprawdzamy czy nie sa to pseudo rozkazy skoku\r
+// req, rne, rpl, rmi, rcc, rcs, rvc, rvs  -> b??  skok do tylu\r
+// seq, sne, spl, smi, scc, scs, svc, svs  -> b??  skok do przodu\r
+\r
+ __BckSkp:\r
+   begin\r
+\r
+    if mnemo[1]='R' then begin\r
+\r
+     if (pass=pass_end) and skip.xsm then warning(99);  // Repeating only the last instruction\r
+\r
+     if t_bck[0]<0 then begin\r
+      if pass=pass_end then blad(old,110);              // No instruction to repeat\r
+      war:=0;\r
+     end else\r
+      war:=t_bck[0];\r
+\r
+    end else begin\r
+     if skip.idx+1<=High(t_skp) then war:=t_skp[skip.idx+1] else war:=adres;\r
+\r
+     skip.use:=true;\r
+     skip.cnt:=0;\r
+    end;\r
+\r
+     war:=war-2-adres;\r
+\r
+     if (war<0) and (abs(war)-128>0) then war:=abs(war)-128;\r
+     if (war>0) and (war-127>0) then dec(war, 127); //war:=war-127;\r
+\r
+     mnemo[1]:='B';              // zamieniamy pseudo rozkaz na mnemonik\r
+     k:=fASC(mnemo);             // wyliczamy kod dla mnemonika\r
+\r
+     code:=kod[k-1];             // kod maszynowy mnemonika w pierwszej adresacji 6502\r
+\r
+     Result.l := 2;\r
+     Result.h[0] := code;\r
+     Result.h[1] := byte(war);\r
+     inc(adres,2);\r
+   end;\r
+\r
+// CPB, CPW, CPL, CPD   \r
+ __cpbcpd:\r
+   begin\r
+\r
+    if High(par)<2 then blad(old,23);\r
+\r
+    pom:=par[1];\r
+\r
+    ile:=TypeToByte(mnemo[3]);\r
+\r
+    Result.l:=0;\r
+\r
+\r
+    str:='##CMP#'+IntToStr(ora_nr);\r
+\r
+    j:=load_lab(str,false);        // odczytujemy wartosc etykiety\r
+\r
+    if j>=0 then\r
+     tryb:=t_lab[j].adr\r
+    else\r
+     tryb:=0;\r
+\r
+    test := (tmp[1]='#');\r
+    opty := (pom[1]='#');\r
+\r
+\r
+    if (tmp='@') and (ile<>1) then blad(old,58);\r
+\r
+    \r
+    variable:=false;               // domyslnie VARIABLE=FALSE, czyli nie jest to zmienna\r
+\r
+    if opty then begin\r
+     pom[1]:='+';\r
+     branch:=true;                 // nie relokujemy, testujemy tylko wartosc\r
+     war:=oblicz_wartosc(pom,old);\r
+\r
+     pom[1]:='#';     \r
+    end;\r
+\r
+    isvar:=variable or TestWhileOpt;\r
+\r
+\r
+    while ile>0 do begin\r
+\r
+     if test then\r
+      add:=getByte(tmp, ile, mnemo[3])\r
+     else\r
+      add:='+'+IntToStr(Int64(ile)-1);\r
+                           \r
+     if tmp<>'@' then begin\r
+      zm:='LDA '+tmp + add;\r
+      hlp:=asm_mnemo(zm,old);\r
+      addResult(hlp, Result);\r
+     end;\r
+\r
+\r
+     if opty then\r
+      add:=getByte(pom, ile, mnemo[3])\r
+     else\r
+      add:='+'+IntToStr(Int64(ile)-1);\r
+\r
+\r
+     zm:='CMP '+pom + add;\r
+     hlp:=asm_mnemo(zm,old);\r
+\r
+     if not(isvar) and (hlp.l=2) and (hlp.h[0]=$c9) and (hlp.h[1]=0) then\r
+      dec(adres, 2)                                    // jesli CMP #0 to anuluj\r
+     else\r
+      addResult(hlp, Result);\r
+\r
+\r
+     if ile>1 then begin\r
+      zm:='BNE '+IntToStr(tryb);\r
+      hlp:=asm_mnemo(zm,old);\r
+      addResult(hlp, Result);\r
+     end;\r
+\r
+     dec(ile);\r
+    end;\r
+\r
+    str:='##CMP#'+IntToStr(ora_nr);\r
+    save_fake_label(str,old, adres);\r
+\r
+    TestWhileOpt:=true;\r
+\r
+    inc(ora_nr);\r
+   end;\r
+\r
+ end;\r
+\r
+ adres := idx;\r
+\r
+ regOpty.use := ( k = __movaxy );\r
+\r
+ mne_used := true;           // zostal odczytany jakis mnemonik\r
+ exit;                       // !!! KONIEC !!! zostal odczytany i zdekodowany makro-rozkaz\r
+end;\r
+\r
+\r
+// sprawdz czy to nazwa makra\r
+ if k=0 then begin\r
+\r
+    idx:=load_lab(mnemo_tmp,false);     // poszukaj w etykietach\r
+\r
+    if idx<0 then begin\r
+     if pass=pass_end then blad_und(old,mnemo,35);\r
+     exit;\r
+    end;\r
+\r
+    if t_lab[idx].bnk=__id_ext then             // symbol external\r
+     if t_extn[t_lab[idx].adr].prc then begin\r
+\r
+      tmp:='##'+t_extn[t_lab[idx].adr].nam;\r
+\r
+      Result.i:=t_lab[l_lab(tmp)].adr;\r
+      Result.l:=__proc_run;\r
+\r
+      exit;\r
+     end;\r
+\r
+\r
+//    if (t_lab[idx].bnk=__id_macro) then begin Result.l:=__nill; exit end;\r
+\r
+    if t_lab[idx].bnk>=__id_macro then begin\r
+     Result.l:=byte(t_lab[idx].bnk);\r
+     Result.i:=t_lab[idx].adr;\r
+    end else\r
+     blad_und(old,mnemo,35);\r
+\r
+    exit;\r
+ end;\r
+\r
+\r
+ dec(k);                   // !!! koniecznie\r
+\r
+\r
+// znalazl pseudo rozkaz\r
+ if k>=__equ then\r
+  if siz<>' ' then\r
+   blad(old,33)\r
+  else begin\r
+   Result.l:=k; exit\r
+  end;\r
+\r
+\r
+ if first_org and (opt and 1>0) then blad(old,10);\r
+\r
+\r
+// jesli nie przetwarzamy makro-rozkazow MWA, MVA itp. to blokujemy optymalizacje rejestrow\r
+ if not(regOpty.blk) then begin\r
+  regOpty.use:=false;\r
+\r
+  regOpty.reg[0]:=-1;\r
+  regOpty.reg[1]:=-1;\r
+  regOpty.reg[2]:=-1;\r
+ end;\r
+\r
+\r
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//\r
+// na podstawie kodu maszynowego CODE mozna juz okreslic jaki to rozkaz       //\r
+// nie trzeba porownywac stringow, czy zamieniac mnemonik na wartosc cyfrowa  //\r
+// w celu pozniejszego porownania                                             //\r
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//\r
+\r
+ if (opt and 16>0) then begin\r
+  code:=kod_16[k];                // kody maszynowe 65816 sa z przedzialu <0..91>\r
+  tryb:=ads_16[k];                // kod maszynowy mnemonika w pierwszej adresacji 65816\r
+ end else begin\r
+//  if k>55 then blad(a,14);        // kody maszynowe 6502 sa z przedzialu <0..55>\r
+  code:=kod[k];                   // kod maszynowy mnemonika w pierwszej adresacji 6502\r
+  tryb:=ads[k];\r
+ end;\r
+\r
+\r
+// w .STRUCT i .ARRAY nie ma mozliwosci uzywania rozkazow CPU\r
+// podobnie w bloku EMPTY (.ds) nie moga wystepowac rozkazy CPU\r
+ if struct.use or aray or enum.use or empty then blad(old,58);\r
+\r
+\r
+// jesli mnemonik nie wymaga argumentu to skoncz\r
+ if tryb=0 then begin\r
+\r
+  if siz<>' ' then blad(old,33);\r
+\r
+  test_eol(i,a,a,#0);\r
+\r
+  Result.l:=1; Result.h[0]:=code;\r
+\r
+  mne_used := true;          // zostal odczytany jakis mnemonik\r
+\r
+  exit;\r
+ end;\r
+\r
+\r
+// omin spacje i przejdz do argumentu\r
+ omin_spacje(i,a);\r
+\r
+// jesli wystepuja operatory #<, #> to omin pierwszy znak i pozostaw <,>\r
+{ if a[i]='#' then begin                           // jesli odremowac to zle liczy !!! lda #>dl1^>dl2 !!!\r
+  idx:=i;                                          // !!! tak musi zostac !!!\r
+  __inc(i,a);                                      // lda #>   nie moze byc tym samym co\r
+  if not(a[i] in ['<','>','^']) then i:=idx;       // lda >    ta operacja\r
+ end;   }\r
+\r
+\r
+ // pobierz operator argumentu do 'OP'\r
+ // nie dotyczy to rozkazow MVN i MVP (65816)\r
+\r
+// tst:=ord(mnemo[1]) shl 16+ord(mnemo[2]) shl 8+ord(mnemo[3]);\r
+\r
+\r
+// if (mnemo<>'MVN') and (mnemo<>'MVP') then begin\r
+// if (tst<>$4D564E) and (tst<>$4D5650) then begin\r
+\r
+ if not(code in [68,84]) then begin\r
+\r
+  mvnmvp:=false;\r
+  if a[i] in ['#','<','>','^'] then begin\r
+   if not(dreloc.use) then branch:=true;             // nie relokuj tego rozkazu\r
+   op:=a[i]; inc(i)\r
+  end else op:=' ';\r
+\r
+  if (a[i]='@') and (_eol(a[i+1])) then begin op:='@'; inc(i) end;\r
+\r
+  if (op='@') then\r
+   if (siz<>' ') then blad(old,33) else test_eol(i,a,a,#0);\r
+ end;\r
+\r
+ omin_spacje(i,a);\r
+\r
+ // wyjatki dla ktorych rozmiar rejestru jest staly\r
+ if (opt and 16>0) and (op='#') then\r
+  case code of\r
+    98: test_siz(a,siz,'Q',pomin);                       // PEA #Q\r
+   254: test_siz(a,siz,'Z',pomin);                       // COP #Z\r
+   190: begin test_siz(a,siz,'Z',pomin); mREP:=true end; // REP #Z\r
+   222: begin test_siz(a,siz,'Z',pomin); mSEP:=true end; // SEP #Z\r
+  end;\r
+\r
+\r
+ zm:=get_dat_noSPC(i,a,';',#0,old);\r
+\r
+ tmp:='';\r
+            \r
+ // jesli brak argumentu przyjmij domyslnie aktualny adres '*'\r
+ // lub operator '@' gdy ASL , ROL , LSR , ROR\r
+ // lub operator '@' dla INC, DEC gdy CPU=65816\r
+  if (zm='') and (op=' ') then begin\r
+\r
+   if (code in [2,34,66,98]) or ((opt and 16>0) and (code in [26,58])) then\r
+    op:='@'\r
+   else begin\r
+    zm:='*';\r
+    if not(klamra_used) then\r
+     if pass=0 then blad(old,23);            // 'Default addressing mode' -67- wycofany\r
+   end;\r
+\r
+  end;\r
+\r
+\r
+// jesli jest nawias otwierajacy '(' lub '[' to sprawdz poprawnosc\r
+// i czy nie ma miedzy nimi spacji\r
+ if zm<>'' then begin\r
+  j:=1;\r
+\r
+ if (op=' ') and (zm[1] in ['[','(']) then begin\r
+\r
+ tmp:=get_dat_noSPC(j,zm,',',#0,a);\r
+  \r
+\r
+ if length(tmp)=2 then blad(old,14);      // nie bylo argumentu pomiedzy nawiasami\r
+\r
+ // jesli po nawiasie wystapi znak inny niz ',',' ',#0 to BLAD\r
+\r
+  omin_spacje(j,zm);\r
+\r
+  test_eol(j,zm,a,',');\r
+\r
+ // przepisz znak nastepujacy po ',' do 'OP_'\r
+ if zm[j]=',' then begin\r
+\r
+  __inc(j,zm);\r
+\r
+  if test_param(j,zm) then begin Result.l:=__nill; exit end else\r
+  if UpCase(zm[j]) in ['X','Y','S'] then begin\r
+   op_:=op_+UpCase(zm[j]); //zm[j]:=' ';\r
+\r
+    if zm[j+1] in ['+','-'] then begin\r
+\r
+     if UpCase(zm[j])='S' then blad(old,4);       // + - nie moze byc dla 'S'\r
+\r
+     incdec:=true;\r
+\r
+      case zm[j+1] of\r
+       '-': //war_roz:=oblicz_wartosc('{de'+zm[j]+'}',a);\r
+            if UpCase(zm[j])='X' then war_roz:=$CA else war_roz:=$88;   // dex, dey\r
+       '+': //war_roz:=oblicz_wartosc('{in'+zm[j]+'}',a);\r
+            if UpCase(zm[j])='X' then war_roz:=$E8 else war_roz:=$C8;   // inx, iny\r
+      end;\r
+\r
+     test_eol(j+2,zm,a,#0);\r
+    end else test_eol(j+1,zm,a,#0);\r
+\r
+  end else blad(old,14);\r
+ end;\r
+\r
+ // usun z ciagu znaki '()' lub '[]' i przepisz do 'OP_'\r
+  op_:=op_+zm[1];\r
+  zm:=copy(tmp,2,length(tmp)-2);\r
+  j:=1;\r
+ end;\r
+\r
+\r
+ tmp:=get_dat_noSPC(j,zm,',',#0,a);\r
+\r
+\r
+// teraz jesli wystapi znak inny niz ',' to BLAD\r
+ case op of\r
+  '#','<','>','@','^': test_eol(j,zm,a,#0);\r
+ else\r
+  test_eol(j,zm,a,',');\r
+ end;\r
+\r
+\r
+// przepisz znak nastepujacy po ',' do 'OP_', jesli jest to 'XYS'\r
+// w przeciwnym wypadku wylicz wartosc po przecinku\r
+ if zm[j]=',' then\r
+\r
+  if mvnmvp then begin\r
+//   inc(j);\r
+   __inc(j,zm);\r
+   str:=get_dat(j,zm,' ',true);\r
+   war_roz:=oblicz_wartosc(str,a);\r
+   op_:=op_+value_code(war_roz,a,true);\r
+\r
+  end else begin\r
+\r
+  __inc(j,zm);\r
+\r
+   if test_param(j,zm) then begin Result.l:=__nill; exit end else\r
+   if UpCase(zm[j]) in ['X','Y','S'] then begin\r
+    op_:=op_+UpCase(zm[j]);\r
+\r
+    if zm[j+1] in ['+','-'] then begin\r
+     if _eol(zm[j+2]) then begin\r
+\r
+      if UpCase(zm[j])='S' then blad(old,4);      // + - nie moze byc dla 'S'\r
+\r
+      incdec:=true;\r
+\r
+       case zm[j+1] of\r
+        '-': //war_roz:=oblicz_wartosc('{de'+zm[j]+'}',a);\r
+             if UpCase(zm[j])='X' then war_roz:=$CA else war_roz:=$88;   // dex, dey\r
+        '+': //war_roz:=oblicz_wartosc('{in'+zm[j]+'}',a);\r
+             if UpCase(zm[j])='X' then war_roz:=$E8 else war_roz:=$C8;   // inx, iny\r
+       end;\r
+\r
+      inc(j,2);\r
+     end else begin\r
+      zwieksz:=true; inc(j);\r
+      war_roz:=___wartosc_noSPC(zm,a,j,#0,'F');\r
+     end;\r
+\r
+    end else inc(j);\r
+\r
+   end else blad(old,14);\r
+  end;\r
+\r
+//  end;\r
+  test_eol(j,zm,a,#0);\r
+ end;\r
+\r
+\r
+ // jesli to rozkaz skoku lub PEA to nie relokujemy (BRANCH=TRUE)\r
+\r
+ if ((mnemo[1]='B') and (mnemo[2]<>'I')) or ((mnemo[1]='P') and (mnemo[2]='E') and (mnemo[3]='A') and (op_='') and (op=' ')) then begin\r
+  branch:=true;\r
+\r
+  branch_run:=true;\r
+ end else\r
+  branch_run:=false;\r
+\r
+\r
+ if adres<0 then\r
+  if pass=pass_end then blad(old,10);        // adres<0 na pewno nie bylo ORG'a\r
+\r
+\r
+// oblicz wartosc argumentu mnemonika, jesli brak argumentu to 'WAR=0'\r
+ war:=0;\r
+ if not((tmp='') and (op='#')) then\r
+  if op<>'@' then war:=oblicz_wartosc(tmp,old);\r
+\r
+\r
+ if zwieksz then inc(war, war_roz); //war:=war+war_roz;\r
+\r
+ op_:=op_+value_code(war,a,true);\r
+\r
+ if mvnmvp then war:=war_roz + byte(war) shl 8;\r
+\r
+          \r
+(*----------------------------------------------------------------------------*)\r
+(* wyjatki dotycza skokow warunkowych B?? (6502) ; BRA, BRL, PEA (65816)      *)\r
+(*----------------------------------------------------------------------------*)\r
+\r
+ if branch_run then begin\r
+\r
+   op_:='B';\r
+\r
+   if siz<>' ' then\r
+    if siz='Q' then op_:='W' else\r
+     if siz<>'Z' then blad(old,31);\r
+\r
+   j:=adrMode(op_);                  // dowiemy sie ktory to tryb adresowania\r
+\r
+   war:=war-2-adres;\r
+\r
+\r
+   if tryb and maska[j]=2 then\r
+\r
+     idx:=128\r
+\r
+   else begin\r
+\r
+     op_:='W';\r
+\r
+     if siz<>' ' then\r
+      if siz<>'Q' then blad(old,31);\r
+\r
+     dec(war);\r
+\r
+     idx:=65536;\r
+\r
+   end;\r
+\r
+\r
+   test:=false;\r
+\r
+   if (war<0) and (abs(war)-idx>0) then begin war:=abs(war)-idx; test:=true end;\r
+\r
+   if (war>0) and (war-idx+1>0) then begin war:=war-idx+1; test:=true end;\r
+\r
+\r
+   if (pass=pass_end) and test then blad(old,integer(-war));\r
+ end;\r
+\r
+\r
+ // na podstawie 'OP' okresl adresacje 'OP_'\r
+ case op of\r
+  '#','<','>','^': op_:='#';\r
+              '@': op_:='@';\r
+ end;\r
+\r
+\r
+// znajdz obliczona adresacje w tablicy 'adresacja'\r
+// oraz sprawdz czy dla tego mnemonika jest mozliwa ta adresacja\r
+//\r
+// jesli nie znalazl to zmien rodzaj argumentu Z->Q\r
+\r
+ // jesli 65816 to wstaw znak '~'\r
+ if (opt and 16>0) then op_:='~'+op_;\r
+\r
+ len:=length(op_);\r
+   \r
+\r
+// jesli rozkaz relokowalny (RELOC=TRUE) wymus rozmiar 'Q'\r
+ if reloc and not(dreloc.use) then\r
+  if siz='T' then blad(old,12) else\r
+   if not(op in ['<','>','^']) then siz:='Q';\r
+\r
+\r
+// jesli wystapila etykieta external (EXT_USED.USE=TRUE) wymus rozmiar EXT_USED.SIZ\r
+ if ext_used.use and (ext_used.siz in ['B','W','L']) then begin\r
+\r
+  if op='^' then blad(old,85);\r
+\r
+  if op in ['<','>'] then begin\r
+   t_ext[ext_idx-1].typ:=op;\r
+   ext_used.siz:='B';\r
+\r
+   if op='>' then t_ext[ext_idx-1].lsb:=byte(war);\r
+  end;                                   \r
+\r
+\r
+  case ext_used.siz of\r
+   'B': siz:='Z';\r
+   'W': siz:='Q';\r
+   'L': siz:='T';\r
+  end;\r
+\r
+ end;\r
+\r
+\r
+// sprawdz czy wystapilo rozszerzenie mnemonika\r
+// zmodyfikuj wielkosc operandu na podstawie 'SIZ'\r
+ if siz<>' ' then\r
+  case op_[len] of\r
+   'Q': if siz<>'Z' then\r
+         op_[len]:=siz\r
+        else\r
+         if pass=pass_end then blad(old,31);\r
+\r
+   'T': if not(siz='T') then\r
+         if pass=pass_end then blad(old,31);\r
+\r
+   '#': if siz='T' then\r
+         blad(old,14)\r
+        else\r
+         if (siz='Z') and (abs(war)>$FF) then blad(old,31);\r
+\r
+   'Z': op_[len]:=siz;\r
+  end;\r
+\r
+\r
+ j:=adrMode(op_);\r
+\r
+ while (j=0) or (tryb and maska[j]=0) do begin\r
+\r
+  case op_[len] of         // zmien rozmiar operandu\r
+   'Z': op_[len]:='Q';\r
+   'Q': op_[len]:='T';\r
+  else\r
+\r
+   if pass=pass_end then\r
+    blad(old,14)\r
+   else\r
+    Break;\r
+\r
+  end;\r
+                           // sprawdz czy nowy operand nie kloci sie z zadeklarowanym rozmiarem\r
+  if (siz<>' ') and (pass=pass_end) then\r
+   if not(siz=op_[len]) then blad(old,31);\r
+\r
+  j:=adrMode(op_);         // sprawdz czy dla nowego rozmiaru operandu istnieje tryb adresowania\r
+ end;\r
+\r
+\r
+\r
+ if opt and 16>0 then begin\r
+  ile:=0;\r
+  for k:=8 downto 1 do\r
+   if ((tryb shr 24) and maska[k]>0) then ile:=byte( (9-k)*23 );\r
+\r
+{  if tryb and $80000000>0 then ile:=23;\r
+  if tryb and $40000000>0 then ile:=2*23;\r
+  if tryb and $20000000>0 then ile:=3*23;\r
+  if tryb and $10000000>0 then ile:=4*23;\r
+  if tryb and $08000000>0 then ile:=5*23;\r
+  if tryb and $04000000>0 then ile:=6*23;\r
+  if tryb and $02000000>0 then ile:=7*23;\r
+  if tryb and $01000000>0 then ile:=8*23;}\r
+\r
+  inc(code, addycja_16[j+ile])       //code:=byte( code+addycja_16[j+ile] )\r
+\r
+ end else\r
+  if (tryb and $80000000>0) then\r
+   inc(code, addycja[j+12])          //code:=code+addycja[j+12]\r
+  else\r
+   inc(code, addycja[j]);            //code:=code+addycja[j];\r
+\r
+\r
+// obliczenie wartosci 'WAR' na podstawie 'OP'\r
+// WAR moze byc dowolna wartoscia typu D-WORD\r
+\r
+ help:=war;\r
+ if dreloc.use and rel_used then dec(help,rel_ofs);\r
+\r
+ case op of\r
+  '<': war := byte( wartosc(a,help,'D') );\r
+  '>': begin war := byte( wartosc(a,help,'D') shr 8 );  _sizm( byte(help) ) end;\r
+  '^': begin war := byte( wartosc(a,help,'D') shr 16 ); _sizm( byte(help) ) end;\r
+ end;\r
+\r
+// policz z ilu bajtow sklada sie rozkaz wraz z argumentem\r
+ ile:=1;\r
+\r
+ if not(mvnmvp) then\r
+  if incdec then begin\r
+   inc(ile);\r
+   case op_[len] of\r
+    'Z': war := war + byte(war_roz) shl 8;\r
+    'Q': war := war + byte(war_roz) shl 16;\r
+    'T': war := war + byte(war_roz) shl 24;\r
+   end;\r
+  end;\r
+\r
+ if op_='~ZZ' then inc(ile,2)\r
+ else\r
+  case op_[len] of\r
+   '#': begin\r
+         if siz=' ' then siz:=value_code(war,a,false);\r
+\r
+         case siz of\r
+          'Z': begin\r
+                war:=wartosc(a,war,'B');\r
+                inc(ile)\r
+               end;\r
+\r
+          'Q': if (opt and 16=0) then\r
+                blad(old,0)\r
+               else begin\r
+                war:=wartosc(a,war,'A');\r
+                inc(ile,2)\r
+               end;\r
+         end;\r
+\r
+        end;\r
+   'Z','B': inc(ile);\r
+   'Q','W': inc(ile,2);\r
+   'T': inc(ile,3);\r
+  end;\r
+\r
+\r
+// okreslamy rozmiar relokowalnego argumentu B,W,L,<,>  \r
+ if dreloc.use and rel_used then begin\r
+\r
+  case op_[len] of\r
+       '#': if (op in ['<','>','^']) then dreloc.siz:=op;\r
+   'Z','B': dreloc.siz:=relType[1];\r
+   'Q','W': dreloc.siz:=relType[2];\r
+       'T': dreloc.siz:=relType[3];\r
+   end;\r
+\r
+  if not(ext_used.use) then dec(war,rel_ofs);  // nie wolno modyfikowac argumentu symbolu EXTERNAL\r
+\r
+  _siz(true);\r
+\r
+  rel_used:=false;\r
+ end;\r
+\r
+\r
+ // tutaj przeprowadzamy operacje sledzenia rozmiaru rejestrow A,X,Y\r
+ // modyfikowanych przez rozkazy REP, SEP\r
+  if (opt and $40>0) and (pass=pass_end) and macro_rept_if_test then begin  // wlaczona opcja sledzenia rozkazow SEP, REP\r
+\r
+   if mSEP then reg_size( byte(war),true ) else\r
+    if mREP then reg_size( byte(war),false );\r
+\r
+  // sprawdzamy rozmiar rejestrow dla trybu adresowania natychmiastowego '#'\r
+   if not(pomin) then\r
+    if op_[len]='#' then\r
+     case mnemo[3] of\r
+      'A','C','D','P','R','T': test_reg_size(a,regA,ile);  // lda, adc, sbc, and, cmp, ror, bit\r
+                          'X': test_reg_size(a,regX,ile);  // ldx\r
+                          'Y': test_reg_size(a,regY,ile);  // ldy\r
+     end;\r
+\r
+  end;\r
+\r
+ // preparujemy wynik, rozkaz CPU + argumenty\r
+\r
+ Result.l := ile;\r
+\r
+ Result.h[0] := code;\r
+ Result.h[1] := byte(war);\r
+ Result.h[2] := byte(war shr 8);\r
+ Result.h[3] := byte(war shr 16);\r
+ Result.h[4] := byte(war shr 24);\r
+\r
+ mne_used := true;           // zostal odczytany jakis mnemonik\r
+\r
+end;\r
+\r
+\r
+function reserved(var ety: string): Boolean;\r
+var v: byte;\r
+begin\r
+  v:=fASC(ety);\r
+\r
+  Result := (v in [$80..$9f]);     // PSEUDO\r
+  if Result then exit;\r
+\r
+  if opt and 16>0 then\r
+   Result := (v in [1..92])        // 65816\r
+  else\r
+   Result := (v in [1..56]);       // 6502\r
+\r
+end;\r
+\r
+\r
+procedure reserved_word(var ety, zm: string{; const skip: Boolean});\r
+(*----------------------------------------------------------------------------*)\r
+(*  testuj czy nie zostala uzyta zarezerwowana nazwa, np. nazwa pseudorozkazu *)\r
+(*  lub czy nazwa zostala juz wczesniej uzyta                                 *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+\r
+  if ety[1]='?' then warning(8);\r
+\r
+  if length(ety)=3 then\r
+   if reserved(ety) then blad_und(zm,ety,9);\r
+\r
+  if rept then blad(zm,51);\r
+  //if skip and proc then blad(zm,17);\r
+  if load_lab(ety,true)>=0 then blad_und(zm,ety,2);        // nazwa w uzyciu\r
+\r
+end;\r
+\r
+\r
+procedure create_struct_variable(var zm,ety: string; var mne: int5; const head: Boolean; var adres: integer);\r
+(*----------------------------------------------------------------------------*)\r
+(*  wykonaj .STRUCT (np. deklaracja pola struktury za pomoca innej struktury) *)\r
+(*  mo¿liwe jest przypisanie pol zdefiniowanych przez strukture nowej zmiennej*)\r
+(*----------------------------------------------------------------------------*)\r
+var indeks, _doo, j, k, idx: integer;\r
+    txt, str: string;\r
+begin\r
+\r
+    indeks:=mne.i;\r
+\r
+    if mne.l=__enum_run then begin\r
+\r
+     save_lst('a');\r
+\r
+     for k:=0 to indeks-1 do save_dst(0);\r
+     inc(adres, indeks);\r
+\r
+     exit;\r
+    end;\r
+\r
+  // sprawdzamy czy struktura nie wywoluje sama siebie\r
+    if t_str[indeks].lab+'.'=lokal_name then blad(zm,57);\r
+\r
+     _doo := adres-struct.adres;\r
+\r
+     if mne.l=__struct_run then\r
+      if struct.use then\r
+       save_lab(ety, _doo, bank, zm)     // nowe pole w strukturze\r
+      else\r
+       save_lab(ety, adres, bank, zm);   // definicja zmiennej typu strukturalnego\r
+\r
+     save_lst('a');\r
+\r
+   // odczytujemy liczbe pol struktury\r
+     k:=t_str[indeks].ofs;\r
+     inc(indeks);\r
+\r
+     for idx:=indeks to indeks+k-1 do begin\r
+\r
+      txt:=t_str[idx].lab;\r
+\r
+      if mne.l=__struct_run_noLabel then\r
+       str:=txt\r
+      else begin\r
+\r
+       //_odd:=pos('.',txt);                                //???\r
+       //if _odd>0 then txt:=copy(txt,_odd,length(txt));    //???\r
+\r
+       if txt[1]<>'.' then txt:='.'+txt;\r
+\r
+       str:=ety+txt;\r
+      end;\r
+\r
+      j:=t_str[idx].siz;\r
+\r
+      if struct.use then begin\r
+       k:=t_str[idx].ofs+_doo; // konieczna operacja, bo STRUCT.ADRES nie zostal zwiekszony\r
+\r
+       save_str(str,k,j,1,adres,bank);           // tutaj zwiekszony zostaje STRUCT.ADRES\r
+\r
+       save_lab(str,adres-struct.adres,bank,zm); // tutaj operujemy na nowej wartosci STRUCT.ADRES\r
+\r
+       inc(struct.cnt);        // zwiekszamy licznik pol w strukturze\r
+      end else begin\r
+\r
+       save_lab(str,adres,bank,zm);\r
+\r
+       if dreloc.use or dreloc.sdx then\r
+        for k:=0 to j-1 do save_dst(0)\r
+       else\r
+        if head then new_DOS_header;  // wymuszamy zapis naglowka DOS-a\r
+\r
+      end;\r
+\r
+      inc(adres, j);\r
+     end;\r
+end;\r
+\r
+\r
+procedure create_struct_data(var i: integer; var zm, ety: string; v: byte);\r
+(*----------------------------------------------------------------------------*)\r
+(* dla   DTA STRUCT_NAME [EXPRESSION]   tworzymy dane typu strukturalnego     *)\r
+(*----------------------------------------------------------------------------*)\r
+var _doo, _odd, k, idx: integer;\r
+    war: Int64;\r
+    tmp: string;\r
+begin\r
+           struct_used.use:=false;\r
+\r
+           _odd:=adres; war:=adres;\r
+           _doo:=bank; k:=bank;\r
+\r
+           save_lst('a');\r
+\r
+           if v>=__byte then\r
+            dec(v, __byteValue)\r
+           else\r
+            v:=1;\r
+\r
+           test_skipa;\r
+\r
+           oblicz_dane(i,zm,zm,v);\r
+\r
+       // jesli stworzylismy strukture to odpowiednio zapamietaj\r
+       // jej dane, adres, stworzyciela itp.\r
+           if struct_used.use then begin\r
+\r
+            if ety='' then blad(zm,15);\r
+            if (pass<2) and (ety[1]='?') then warning(8);\r
+\r
+\r
+            idx:=load_lab(ety,true);  \r
+\r
+\r
+       // jesli etykieta byla juz zadeklarowana i to jest PASS=0\r
+       // tzn ze mamy blad LABEL DECLARED TWICE\r
+            if (pass=0) and (idx>=0) then blad_und(zm,ety,2);\r
+\r
+\r
+            _doo:=__dta_struct;\r
+\r
+            if t_lab[idx].bnk=__dta_struct then begin\r
+         // wystapila juz ta deklaracja danych strukturalnych\r
+             _odd:=t_lab[idx].adr;\r
+\r
+             t_str[_odd].adr := cardinal( war );\r
+             t_str[_odd].bnk := integer( k );\r
+\r
+            end else begin\r
+\r
+         // w TMP tworzymy nazwe uwzgledniaj¹c¹ lokalnosc 'TMP:= ??? + ETY'\r
+             if run_macro then tmp:=macro_nr+{lokal_name+}ety else\r
+              if proc then tmp:=proc_name+lokal_name+ety else\r
+               tmp:=lokal_name+ety;\r
+\r
+         // nie wystapila jeszcze ta deklaracja danych strukturalnych\r
+             save_str(tmp,struct_used.cnt,0,1, integer(war), integer(k));\r
+\r
+             _odd:=loa_str(tmp, struct.id);\r
+\r
+             t_str[_odd].idx:=struct_used.idx;\r
+            end;\r
+\r
+           end;\r
+\r
+           save_lab(ety,cardinal(_odd),integer(_doo),zm);     // zapisujemy etykiete normalnie poza struktur¹\r
+end;\r
+\r
+\r
+procedure oddaj_var;\r
+var i, y, x: integer;\r
+    txt, tmp: string;\r
+    old_run_macro: Boolean;\r
+    mne: int5;\r
+begin\r
+\r
+if var_idx>0 then begin\r
+\r
+ old_run_macro := run_macro;\r
+ run_macro     := false;\r
+\r
+ tmp:='';\r
+\r
+ for i:=0 to var_idx-1 do\r
+  if t_var[i].lok = end_idx then begin   // zmienne odkladamy w odpowiednim obszarze lokalnym\r
+\r
+   txt := t_var[i].nam;                  // nazwa zmiennej .VAR\r
+\r
+   if t_var[i].adr>=0 then               // zmienne .VAR z okreslonym adresem umiejscowienia\r
+    nul.i:=t_var[i].adr\r
+   else\r
+    nul.i:=adres;                        // zmienne .VAR alokowane dynamicznie\r
+\r
+   if nul.i<0 then blad(global_name,87); // Undefined variable address\r
+\r
+   save_lst('l');\r
+\r
+   case t_var[i].typ of\r
+    'V': begin\r
+          save_lab(txt,nul.i,bank,txt);\r
+\r
+          if t_var[i].adr<0 then         // T_VAR[I].ADR<0 oznacza brak okreslonej wartosci\r
+           for y:=t_var[i].cnt-1 downto 0 do save_dta(t_var[i].war , tmp , tType[t_var[i].siz] , 0);\r
+         end;\r
+\r
+    'S': begin\r
+          y:=load_lab(t_var[i].str, false);\r
+\r
+          mne.i:=t_lab[y].adr;           // znajdz indeks do struktury\r
+          mne.l:=byte(__struct_run);\r
+\r
+          if t_var[i].zpv or (t_var[i].adr>=0) then begin  // jesli .ZPVAR lub okreslony adres\r
+           x:=t_var[i].adr;\r
+           create_struct_variable(txt, txt, mne, false, x);\r
+          end else\r
+           create_struct_variable(txt, txt, mne, true, adres);\r
+\r
+         end;\r
+   end;\r
+\r
+   tmp:=txt; zapisz_lst(txt);\r
+\r
+   t_var[i].lok:=-1;\r
+\r
+  end;\r
+\r
+ nul.i:=0;\r
+ save_lst(' ');                          // koniecznie musi to tutaj byc\r
+\r
+ run_macro := old_run_macro;\r
\r
+end;\r
+\r
+end;\r
+\r
+\r
+procedure add_blok(var a: string);\r
+begin\r
+ inc(blok);\r
+ if blok>$FF then blad(a,45);\r
+end;\r
+\r
+\r
+procedure save_blk(const kod:integer; var a:string; const h:Boolean);\r
+(*----------------------------------------------------------------------------*)\r
+(*  BLK UPDATE ADDRESS                                                        *)\r
+(*----------------------------------------------------------------------------*)\r
+var x, y, i, j, k: integer;\r
+    hea_fd, hea_fe, ok, tst: Boolean;\r
+    txt: string;\r
+begin\r
+ txt:=a;\r
+\r
+ for k:=blok downto 0 do begin\r
+\r
+  hea_fd:=false; ok:=false;\r
+\r
+// szukaj w glownym bloku\r
+\r
+  for y:=0 to rel_idx-1 do\r
+  if t_rel[y].idx=kod then\r
+   if t_rel[y].blo=0 then\r
+    if t_rel[y].blk=k then begin\r
+\r
+     if not(hea_fd) then begin\r
+      if h then begin\r
+       save_lst('a');\r
+\r
+       save_dstW( $fffd );\r
+       save_dst( byte(K) );\r
+       save_dstW( $0000 );\r
+\r
+       zapisz_lst(txt);\r
+      end;\r
+\r
+      hea_fd:=true; ok:=true;\r
+     end;\r
+\r
+     save_lst('a');\r
+\r
+     save_dst($fd);\r
+     save_dstW( t_rel[y].adr );   // save_dst(byte(t_rel[y].adr shr 8));\r
+\r
+     zapisz_lst(txt);\r
+\r
+     t_rel[y].idx:=-100;      // wylacz z poszukiwan\r
+    end;\r
+\r
+// szukaj w blokach relokowalnych\r
+  for x:=1 to blok do begin\r
+\r
+  hea_fe:=false; j:=0; tst:=false;\r
+\r
+  for y:=0 to rel_idx-1 do\r
+  if t_rel[y].idx=kod then\r
+   if t_rel[y].blo=x then\r
+    if t_rel[y].blk=k then begin\r
+\r
+     if not(tst) then begin\r
+      save_lst('a');\r
+      tst:=true;\r
+     end;\r
+\r
+     if not(hea_fe) then begin\r
+      if not(hea_fd) and h then begin\r
+       save_dstW( $fffd );\r
+       save_dst( byte(K) );\r
+       save_dstW( $0000 );\r
+\r
+       hea_fd:=true;\r
+      end;\r
+\r
+      save_dst($fe);\r
+      save_dst(byte(x));\r
+\r
+      hea_fe:=true; ok:=true;\r
+     end;\r
+\r
+     j:=t_rel[y].adr-j;\r
+     if j>=$fa then\r
+      for i:=0 to (j div $fa)-1 do begin\r
+       save_dst($ff);\r
+       dec(j,$fa);\r
+      end;\r
+\r
+     save_dst(byte(j));\r
+     j:=t_rel[y].adr;\r
+\r
+     t_rel[y].idx:=-100;      // wylacz z poszukiwan\r
+    end;\r
+\r
+   if tst then zapisz_lst(txt);\r
+  end;\r
+\r
+  if ok then begin\r
+   save_lst('a');\r
+\r
+   save_dst($fc);\r
+\r
+   zapisz_lst(txt);\r
+  end;\r
+\r
+ end;\r
+\r
+end;\r
+\r
+\r
+function get_pubType(var txt,zm:string; var _odd:integer): byte;\r
+(*----------------------------------------------------------------------------*)\r
+(* odczytujemy typ etykiety public, _ODD = indeks do etykiety w tablicy T_LAB *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+\r
+  Result:=0;\r
+\r
+  _odd:=load_lab(txt,false);\r
+\r
+  if _odd<0 then blad_und(zm,txt,73);\r
+\r
+// symbolami publicznymi nie moga byc etykiety przypisane do\r
+// SMB, STRUCT, PARAM, EXT, MACRO\r
+\r
+  if t_lab[_odd].bnk>=__id_param then begin\r
+   Result := byte( t_lab[_odd].bnk );\r
+   if not( Result in [__proc_run, __array_run, __struct_run]) then blad_und(zm,txt,103);\r
+  end;\r
+\r
+end;\r
+\r
+\r
+function get_smb(var i:integer; var zm:string): string;\r
+(*----------------------------------------------------------------------------*)\r
+(*  pobieramy 8 znakowy symbol SMB                                            *)\r
+(*----------------------------------------------------------------------------*)\r
+var txt: string;\r
+    x: integer;\r
+begin\r
+ txt:=get_string(i,zm,zm,true);\r
+\r
+ if length(txt)>8 then blad(zm,44);        // za dluga nazwa etykiety\r
+\r
+ while length(txt)<8 do txt:=txt+' ';      // wyrownaj do 8 znakow\r
+\r
+ for x:=1 to 8 do txt[x]:=UpCase(txt[x]);\r
+\r
+ Result:=txt;\r
+end;\r
+\r
+\r
+procedure blk_update_new(var i:integer; var zm:string);\r
+var txt, str: string;\r
+    war, k: integer;\r
+begin\r
+            txt:=zm; zapisz_lst(txt); str:='';\r
+\r
+            omin_spacje(i,zm);\r
+            txt:=get_dat(i,zm,' ',true); if txt='' then blad(zm,23);\r
+\r
+\r
+            if test_symbols then\r
+             for war:=High(t_sym)-1 downto 0 do\r
+              if txt=t_sym[war] then begin blad_und(zm,txt,2); exit end;\r
+\r
+\r
+            war:=l_lab(txt); if war<0 then blad_und(zm,txt,5);\r
+            k:=t_lab[war].blk; if k=0 then blad(zm,53);\r
+\r
+            save_lst('a');\r
+\r
+          // dta a($fffc),b(blk_num),a(smb_off)\r
+          // dta c'SMB_NAME'\r
+            save_dstW( $fffc );\r
+            save_dst(byte(k));\r
+            save_dstW( t_lab[war].adr );  // save_dst(byte(t_lab[war].adr shr 8));\r
+\r
+            zapisz_lst(str);\r
+            save_lst('a');\r
+\r
+            txt:=get_smb(i,zm);\r
+            for k:=1 to 8 do save_dst( ord(txt[k]) );\r
+\r
+            zapisz_lst(txt);\r
+            bez_lst:=true;\r
+end;\r
+\r
+\r
+procedure oddaj_sym;\r
+var txt: string;\r
+    i, k: integer;\r
+begin\r
+\r
+if sym_idx>0 then begin\r
+\r
+ if adres<0 then blad(global_name,10);\r
+\r
+ test_symbols := false;\r
+\r
+ for i:=sym_idx-1 downto 0 do begin\r
+ // preparujemy linie dla NEW SYMBOL\r
+  txt:='BLK UPDATE NEW ' + t_sym[i] + ' ' + '''' + t_sym[i] + '''';\r
+\r
+  save_lst('a');\r
+\r
+  k:=16;  blk_update_new(k,txt);\r
+ end;\r
+\r
+end;\r
+\r
+end;\r
+\r
+\r
+procedure blk_empty(const idx: integer; var zm: string);\r
+var indeks, tst: cardinal;\r
+    _doo: integer;\r
+    txt: string;\r
+begin\r
+\r
+ txt:=zm;\r
+ save_lst('a');\r
+\r
+                add_blok(zm);\r
+\r
+              // a($fffe),b(blk_num),b(blk_id)\r
+              // a(blk_off),a(blk_len)\r
+                save_dstW( $fffe );\r
+                save_dst(byte(blok));\r
+                save_dst(memType or $80);\r
+\r
+                save_dstW( adres ); //save_dst(byte(adres shr 8));\r
+                save_dstW( idx );   //save_dst(byte(idx shr 8));\r
+\r
+               // jesli deklaracja etykiet wystapila przed blokiem EMPTY\r
+               // znajdz je i popraw im numer bloku\r
+                indeks:=adres; tst:=adres+idx;\r
+\r
+                for _doo:=0 to High(t_lab)-1 do\r
+                 if (t_lab[_doo].adr>=indeks) and (t_lab[_doo].adr<=tst) then\r
+                  t_lab[_doo].blk:=blok;\r
+\r
+ zapisz_lst(txt);\r
+end;\r
+\r
+\r
+procedure oddaj_ds;\r
+var zm, txt: string;\r
+begin\r
+ if ds_empty>0 then begin\r
+  dec(adres, ds_empty);\r
+  zm:='BLK EMPTY';\r
+\r
+  if dreloc.sdx then begin        // dreloc.sdx BLOK EMPTY\r
+   blk_empty(ds_empty, zm);  \r
+  end else begin                  // dreloc.use BLOK EMPTY\r
+   save_lst('a');\r
+\r
+   save_dstW( __hea_address );\r
+   save_dst( byte('E') );\r
+   save_dstW( 1 );                // word(adres - rel_ofs) );\r
+   save_dstW( ds_empty );\r
+\r
+   txt:=zm; zapisz_lst(txt);\r
+  end;\r
+\r
+  ds_empty:=0;\r
+ end;\r
+end;\r
+\r
+\r
+procedure blk_update_symbol(var zm:string);\r
+var txt: string;\r
+    k: byte;\r
+    _doo: integer;\r
+begin\r
+\r
+ if smb_idx>0 then begin\r
+\r
+             txt:=zm; zapisz_lst(txt);\r
+\r
+             for _doo:=0 to smb_idx-1 do\r
+              if t_smb[_doo].use then begin\r
+\r
+              save_lst('a');\r
+\r
+            // a($fffb),c'SMB_NAME',a(blk_len)\r
+              save_dstW( $fffb );\r
+\r
+              txt:=t_smb[_doo].smb;\r
+              for k:=1 to 8 do save_dst( ord(txt[k]) );\r
+\r
+              save_dstW( $0000 );\r
+\r
+              zapisz_lst(txt);\r
+\r
+              save_blk(_doo,txt,false);\r
+             end;\r
+\r
+             bez_lst:=true;\r
+//             smb_idx:=0;\r
+ end;\r
+              \r
+end;\r
+\r
+\r
+procedure blk_update_address(var zm:string);\r
+var txt: string;\r
+    idx, i, _odd: integer;\r
+    v: byte;\r
+    ch: Boolean;\r
+    tst: cardinal;\r
+begin\r
+            if not(dreloc.use) then\r
+\r
+             save_blk(-1,zm,true)      // dla bloku Sparta DOS X\r
+\r
+            else begin\r
+\r
+             txt:=zm; zapisz_lst(txt);\r
+\r
+            // naglowek $FFEF, typ, liczba adresow, adresy\r
+\r
+{\r
+  if rel_idx>0 then begin\r
+   Writeln(rel_idx);\r
+   for i:=0 to rel_idx-1 do\r
+    Writeln(hex(t_rel[i].adr,4),',',t_rel[i].bnk,',',t_siz[t_rel[i].idx].siz,',',t_rel[i].idx,',',hex(t_siz[t_rel[i].idx].lsb,2));\r
+  end;  }\r
+\r
+  \r
+             for i:=1 to sizeof(relType) do begin       // dostepne typy B,W,L,D,<,>,^\r
+\r
+              ch:=false;\r
+              for idx:=0 to rel_idx-1 do\r
+               if t_siz[t_rel[idx].idx].siz=relType[i] then begin ch:=true; Break end;\r
+\r
+              if ch then begin\r
+\r
+              save_lst('a');\r
+\r
+            // A(HEADER = $FFEF)\r
+              save_dstW( __hea_address );\r
+\r
+            // najpierw zapiszemy do bufora aby dowiedziec sie ile ich jest\r
+            // maksymalnie mozemy zapisac $FFFF adresow\r
+              _odd:=0;\r
+//              old_case:=false;                           // jesli bank=0 to FALSE\r
+              for idx:=0 to rel_idx-1 do\r
+               if t_siz[t_rel[idx].idx].siz=relType[i] then begin\r
+\r
+//                if t_rel[idx].bnk>0 then old_case:=true; // jesli bank>0 to TRUE\r
+\r
+                tst:= (t_rel[idx].adr and $FFFF) or (t_siz[t_rel[idx].idx].lsb shl 16);\r
+                t_tmp[_odd] := tst;\r
+\r
+                inc(_odd);\r
+                testRange(zm, _odd, 13);    // koniecznie blad 13 aby natychmiast zatrzymac\r
+               end;\r
+\r
+              v:=ord(relType[i]);  //if old_case then v:=v or $80;\r
+\r
+              save_dst(v);                 // TYPE //+ MODE\r
+\r
+              zapisz_lst(txt);\r
+              save_lst('a');\r
+\r
+             // zapisujemy informacje o liczbie adresow  DATA_LENGTH\r
+              save_dstW( _odd );\r
+\r
+            // teraz zapisujemy informacje o adresach\r
+\r
+              for idx:=0 to _odd-1 do begin\r
+              // bank etykiety external jesli MODE=1\r
+//               if old_case then save_dst( byte(t_tmp[idx] shr 16) );\r
+\r
+              // adres do relokacji\r
+               save_dstW( t_tmp[idx] );\r
+\r
+\r
+               case relType[i] of\r
+                '>': save_dst( byte(t_tmp[idx] shr 16) );\r
+                '^': blad(zm,27);\r
+               end;\r
+\r
+              end;\r
+\r
+              zapisz_lst(txt);\r
+\r
+              end; //if ch then begin\r
+\r
+             end;\r
+\r
+            end;\r
+\r
+            bez_lst:=true;\r
+            first_org:=true;\r
+end;\r
+\r
+\r
+procedure blk_update_external(var zm:string);\r
+var txt: string;\r
+    idx, _doo, _odd, i: integer;\r
+    v: byte;\r
+    ch: Boolean;\r
+    tst: cardinal;\r
+\r
+const\r
+    typExt: array [0..2] of char = (#0,'<','>');\r
+\r
+begin\r
+\r
+ if dreloc.sdx then exit;\r
+\r
+ if not(dreloc.use) then blad(zm,53);\r
+\r
+\r
+ if extn_idx>0 then begin\r
+\r
+             txt:=zm; zapisz_lst(txt);\r
+             save_lst('a');\r
+\r
+{\r
+   Writeln(ext_idx);\r
+   for i:=0 to ext_idx-1 do\r
+    Writeln(hex(t_ext[i].adr,4),',',t_extn[t_ext[i].idx].nam);\r
+}\r
+\r
+             for _doo:=0 to extn_idx-1 do begin\r
+\r
+              for i:=0 to 2 do begin\r
+\r
+              ch:=false;\r
+              for idx:=0 to ext_idx-1 do\r
+               if (t_ext[idx].idx=_doo) and (t_ext[idx].typ=typExt[i]) then begin ch:=true; Break end;\r
+\r
+              if ch then begin     // czy wystapily w programie odwolania do etykiet external\r
+\r
+              save_lst('a');\r
+\r
+            // A(HEADER = $FFEE),b(TYPE)\r
+              save_dstW( __hea_external );\r
+\r
+            // najpierw zapiszemy do bufora aby dowiedziec sie ile ich jest\r
+            // maksymalnie mozemy zapisac $FFFF adresow i ich numerow bankow\r
+              _odd:=0;\r
+//              old_case:=false;                          // jesli bank=0 to FALSE\r
+\r
+              for idx:=0 to ext_idx-1 do\r
+               if (t_ext[idx].idx=_doo) and (t_ext[idx].typ=typExt[i]) then begin\r
+\r
+//                if t_ext[idx].bnk>0 then old_case:=true; // jesli bank>0 to TRUE\r
+\r
+                tst:= (t_ext[idx].adr and $FFFF) or (t_ext[idx].lsb shl 16) {(t_ext[idx].bnk shl 16)};\r
+                t_tmp[_odd] := tst;\r
+\r
+                inc(_odd);\r
+                testRange(zm, _odd, 13);    // koniecznie blad 13 aby natychmiast zatrzymac\r
+               end;\r
+\r
+              if typExt[i]=#0 then\r
+               v:=ord(t_extn[_doo].siz)  //if old_case then v:=v or $80;\r
+              else\r
+               v:=ord(typExt[i]);\r
+\r
+              save_dst(v);                    // ext_label TYPE //+ MODE\r
+\r
+              zapisz_lst(txt);\r
+              save_lst('a');\r
+\r
+             // zapisujemy informacje o liczbie adresow\r
+              save_dstW( _odd );\r
+\r
+           // A(EXT_LABEL_LENGTH) , C'EXT_LABEL'\r
+              txt:=t_extn[_doo].nam;\r
+\r
+              save_dstS(txt);                           // ext_label length, string\r
+\r
+\r
+            // teraz zapisujemy informacje o adresach\r
+\r
+              for idx:=0 to _odd-1 do begin\r
+              // bank etykiety external\r
+//               if old_case then save_dst( byte(t_tmp[idx] shr 16) );\r
+\r
+              // adres etykiety external\r
+               save_dstW( t_tmp[idx] );\r
+\r
+               if typExt[i]='>' then save_dst( byte(t_tmp[idx] shr 24) );\r
+              end;\r
+\r
+              zapisz_lst(txt);\r
+\r
+              end; //for i:=0 to 3 do begin\r
+\r
+              end; //if ch then begin\r
+\r
+             end;\r
+\r
+//             extn_idx:=0;\r
+             bez_lst:=true;\r
+ end;\r
+end;\r
+\r
+\r
+procedure blk_update_public(var zm:string);\r
+var txt, ety, str, tmp: string;\r
+    x, idx, j, k, indeks, _odd, _doo, i, len, old_rel_idx, old_siz_idx: integer;\r
+    sid, sno, six: integer;\r
+    v, sv: byte;\r
+    ch, tp: char;\r
+    test: Boolean;\r
+    war: Int64;\r
+    old_sizm0, old_sizm1: rSizTab;\r
+begin\r
+\r
+ if dreloc.sdx then exit;\r
+\r
+ if pub_idx>0 then begin\r
+\r
+             txt:=zm; zapisz_lst(txt);\r
+             save_lst('a');\r
+\r
+             _odd:=0;\r
+\r
+             _doo:=-1;\r
+\r
+           // test obecnosci etykiet publicznych oraz test parametrow procedur __pVar\r
+\r
+             for idx:=pub_idx-1 downto 0 do begin\r
+              txt:=t_pub[idx].nam;\r
+\r
+              v := get_pubType(txt,zm, _odd);\r
+\r
+           // dodajemy do upublicznienia parametry procedury __pVar\r
+           // pod warunkiem ze ich wczesniej jeszcze nie upublicznialismy\r
+              if v = __proc_run then\r
+               if t_prc[t_lab[_odd].adr].typ = __pVar then begin\r
+\r
+                k:=t_prc[t_lab[_odd].adr].par;        // liczba parametrow\r
+                indeks:=t_prc[t_lab[_odd].adr].str;\r
+\r
+                if k>0 then\r
+                 for j:=0 to k-1 do begin\r
+                  ety:=t_par[j+indeks];\r
+\r
+                // omijamy pierwszy znak okreslajacy typ parametru\r
+                // i czytamy az nie napotkamy znakow nie nalezacych do nazwy etykiety\r
+\r
+                  str:='';\r
+                  i:=2;\r
+                  len:=length(ety);\r
+\r
+                  while i<=len do begin\r
+                   if _lab(ety[i]) then str:=str+ety[i] else Break;\r
+                   inc(i);\r
+                  end;\r
+\r
+//                  str:=copy(ety,2,length(ety));    // poprawiamy nazwe parametru\r
+\r
+                  _doo:=l_lab(str);\r
+\r
+                  test:=false;\r
+                  for x:=pub_idx-1 downto 0 do\r
+                   if t_pub[x].nam=str then begin test:=true; Break end;\r
+\r
+                  if (_doo>=0) and not(test) then  // dopisujemy do T_PUB jesli nie zostala wczesniej upubliczniona\r
+                   if (t_lab[_doo].bnk<>__id_ext) {and not(test)} then save_pub(str,zm);\r
+\r
+                  end;\r
+\r
+                  if _doo<0 then blad_und(zm,str,5);\r
+\r
+                 end;\r
+\r
+               end;\r
+\r
+\r
+          // okreslamy typ etykiety PUBLIC, czy jest relokowalna\r
+\r
+             branch:=false;       // umo¿liwiamy relokowalnosc\r
+\r
+             old_rel_idx      := rel_idx;\r
+             old_siz_idx      := siz_idx;\r
+             old_sizm0        := t_siz[siz_idx];\r
+             old_sizm1        := t_siz[siz_idx-1];\r
+\r
+             for _odd:=pub_idx-1 downto 0 do begin\r
+              txt:=t_pub[_odd].nam;\r
+\r
+              reloc:=false;\r
+\r
+              oblicz_wartosc(txt,zm);\r
+              t_pub[_odd].typ := reloc;\r
+             end;\r
+\r
+             branch:=true;        // blokujemy relokowalnosc\r
+\r
+             rel_idx          := old_rel_idx;\r
+             siz_idx          := old_siz_idx;\r
+             t_siz[siz_idx]   := old_sizm0;\r
+             t_siz[siz_idx-1] := old_sizm1;\r
+\r
+{\r
+   Writeln(pub_idx);\r
+   for x:=0 to pub_idx-1 do Writeln(t_pub[x].nam,',',t_pub[x].typ);\r
+}\r
+\r
+\r
+          // A(HEADER = $FFED) , a(LENGTH)\r
+             save_dstW( __hea_public );\r
+             save_dstW( pub_idx );\r
+\r
+             for idx:=0 to pub_idx-1 do begin\r
+\r
+              txt:=t_pub[idx].nam;\r
+\r
+              ety:=txt;\r
+              save_lst('a');\r
+\r
+              v := get_pubType(txt,zm, _odd);  // V to typ, _ODD to indeks do T_LAB\r
+\r
+              case v of\r
+                 __proc_run: ch:='P';        // P-ROCEDURE\r
+                __array_run: ch:='A';        // A-RRAY\r
+               __struct_run: ch:='S';        // S-TRUCT\r
+              else\r
+\r
+               if t_pub[idx].typ then\r
+                ch := 'V'                    // V-ARIABLE\r
+               else\r
+                ch := 'C';                   // C-ONSTANT\r
+\r
+              end;\r
+\r
+              tp:='W';\r
+\r
+              if ch='C' then begin           // type B-YTE, W-ORD, L-ONG, D-WORD\r
+               war:=t_lab[_odd].adr;\r
+\r
+               tp:=relType [ ValueToType(war) ];\r
+\r
+               save_dst(ord(tp));     // type\r
+\r
+              end else\r
+               save_dst( byte('W') ); // type W-ORD dla V-ARIABLE, P-ROCEDURE, A-RRAY, S-TRUCT\r
+\r
+\r
+              save_dst(ord(ch));      // label_type V-ARIABLE, C-ONSTANT, P-ROCEDURE, A-RRAY, S-TRUCT\r
+\r
+              save_dstS(txt);         // label_name     [length + atascii]\r
+\r
+              case v of\r
+                  __proc_run: k:=t_prc[t_lab[_odd].adr].adr;    // PROC address\r
+                 __array_run: k:=t_arr[t_lab[_odd].adr].adr;    // ARRAY address\r
+                __struct_run: k:=t_str[t_lab[_odd].adr].ofs;    // liczba pol STRUCT\r
+              else\r
+               k:=t_lab[_odd].adr;              // variable address\r
+              end;\r
+\r
+              if not(ch in ['C','S']) then dec(k,rel_ofs);   // wartosci C-ONSTANT i S-TRUCT nie modyfikujemy\r
+\r
+\r
+              for sv:=1 to TypeToByte(tp) do begin\r
+                                                // wartosc zmiennej, stalej lub procedury\r
+               save_dst( byte(k) );             // o rozmiarze TP (B-YTE, W-ORD, L-ONG, D-WORD)\r
+               k := k shr 8;\r
+              end;\r
+\r
+\r
+      // S-TRUCT\r
+              if v = __struct_run then begin\r
+\r
+               sid:=t_str[t_lab[_odd].adr].id;\r
+               sno:=t_str[t_lab[_odd].adr].ofs;\r
+\r
+               for j:=0 to sno-1 do begin\r
+                six:=loa_str_no(sid, j);\r
+\r
+                txt:=t_str[six].lab;\r
+\r
+                save_dst ( byte( relType[t_str[six].siz] ) );\r
+\r
+                save_dstS ( txt );\r
+\r
+                save_dstW ( word(t_str[six].rpt) );\r
+\r
+               { write(t_str[six].lab);       // nazwa struktury\r
+                write(',',t_str[six].ofs);   // ofset lub liczba pol struktury\r
+                write(',',t_str[six].siz);   // dlugosc calkowita w bajtach\r
+\r
+                write(',',hex(t_str[six].rpt,4));\r
+\r
+                writeln(',',t_str[six].no); }\r
+               end;\r
+\r
+              end else\r
+\r
+      // A-RRAY\r
+              if v = __array_run then begin\r
+\r
+               save_dstW( t_arr[t_lab[_odd].adr].idx );  // maksymalny indeks tablicy\r
+\r
+               save_dst( ord ( relType[t_arr[t_lab[_odd].adr].siz] ) );   // rozmiar pol\r
+\r
+              end else\r
+\r
+      // P-ROCEDURE\r
+              if v = __proc_run then begin\r
+               k:=t_prc[t_lab[_odd].adr].reg;\r
+               save_dst( byte(k) );             // kolejnosc rejestrow\r
+\r
+               ch:=t_prc[t_lab[_odd].adr].typ;\r
+               save_dst( ord(ch) );             // typ procedury ' '__pDef, 'R'__pReg, 'V'__pVar\r
+\r
+\r
+               k:=t_prc[t_lab[_odd].adr].par;   // liczba parametrow\r
+\r
+               indeks:=t_prc[t_lab[_odd].adr].str;\r
+\r
+\r
+               if (k>0) and (ch=__pVar) then    // jesli __pVar to wliczamy tez dlugosc\r
+                for j:=0 to k-1 do begin        // nazw pametrow\r
+                 tmp:=t_par[j+indeks];\r
+                 inc(k,length(tmp)+2-1);\r
+                end;\r
+\r
+               save_dstW( k );                  // liczba danych na temat parametrow\r
+\r
+\r
+               k:=t_prc[t_lab[_odd].adr].par;   // liczba parametrow jeszcze raz\r
+\r
+\r
+               if k>0 then                      // jesli sa parametry to je zapiszemy\r
+                for j:=0 to k-1 do begin\r
+                 tmp:=t_par[j+indeks];\r
+                 save_dst(ord(tmp[1]));\r
+\r
+                 if ch=__pVar then begin        // dodatkowo dlugosc i nazwe etykiety jesli to __pVar\r
+                  txt:=copy(tmp,2,length(tmp)); // omijamy pierwszy znak typu\r
+\r
+                  save_dstS( txt );\r
+                 end;\r
+\r
+                end;\r
+\r
+              end;\r
+\r
+              zapisz_lst(ety);\r
+             end;\r
+\r
+             bez_lst:=true;\r
+ end;\r
+end;\r
+\r
+\r
+procedure operator_zlozony(var i:integer; var zm,ety:string; const glob:Boolean);\r
+var txt: string;\r
+begin\r
+\r
+ if ety[1]<>'?' then blad(zm,58); // te operacje dotycza etykiet tymczasowych\r
+\r
+ if glob then\r
+  txt:=':'\r
+ else\r
+  txt:='';\r
+\r
+ txt:=txt+ety+zm[i];\r
+\r
+ if if_test then\r
+  if zm[i+1]='=' then begin\r
+    insert(txt,zm,i+2);      // modyfikujemy linie np. ?tmp+=3 -> ?tmp=?tmp+3\r
+    delete(zm,i,1)\r
+  end else begin\r
+   zm:=ety+'='+txt+'1';     // modyfikujemy linie  ?tmp++ -> ?tmp=?tmp+1\r
+   i:=length(ety)+1         // modyfikujemy linie  ?tmp-- -> ?tmp=?tmp-1\r
+  end;\r
+\r
+end;\r
+\r
+\r
+procedure get_data_array(var i:integer; var zm:string; const max:integer; const typ:byte);\r
+var ety, str: string;\r
+    k, j: integer;\r
+    _odd: integer;\r
+begin\r
+\r
+ save_lst(' ');\r
+\r
+ omin_spacje(i,zm);\r
+\r
+ if not(zm[i] in ['[','(']) then begin\r
+\r
+  ety:='['+IntToStr(array_used.max)+']';\r
+\r
+  if zm[i]='=' then __inc(i,zm);\r
+\r
+ end else begin\r
+\r
+  ety:=get_dat_noSPC(i,zm,'=',#0,zm);\r
+  if ety='' then ety:='[0]';\r
+\r
+  if zm[i]<>'=' then\r
+   blad(zm,58)\r
+  else\r
+   __inc(i,zm);\r
+\r
+ end;\r
+                           \r
+ str:=get_dat_noSPC(i,zm,'\',#0,zm);\r
+                                    \r
+ k:=1;\r
+\r
+ while true do begin\r
+  _odd:=integer( oblicz_wartosc_ogr(ety,zm,k) ); //  ___wartosc_noSPC(txt,zm,k,#0,'F');\r
+\r
+  subrange_bounds(zm,_odd,max);\r
+\r
+  array_used.idx:=_odd;\r
+  array_used.typ:=tType[ typ ];\r
+\r
+  if not(loop_used) and not(FOX_ripit) and (length(t)+7<32) then t:=t+' ['+hex(cardinal(_odd),4)+']';\r
+\r
+  j:=1; oblicz_dane(j,str,zm,typ);\r
+\r
+  omin_spacje(k,ety);\r
+  if ety[k]<>':' then Break else __inc(k,ety);\r
+\r
+ end;\r
+          \r
+ if k<=length(ety) then blad_ill(zm,ety[k]);\r
+\r
+end;\r
+\r
+\r
+procedure add_proc_nr;\r
+(*----------------------------------------------------------------------------*)\r
+(*  zwiekszamy licznik PROC_IDX a przez to i PROC_NR                          *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+ inc(proc_idx);\r
+\r
+ proc_nr:=proc_idx;     // PROC_IDX to pierwszy wolny wpis do T_PRC\r
+                        // kazdy nowy blok .PROC musi otrzymac nowy niepowtarzalny numer\r
+\r
+ if proc_idx>High(t_prc) then SetLength(t_prc, proc_idx+1);\r
+end;\r
+\r
+\r
+procedure upd_procedure(var ety,zm:string; const a:integer);\r
+(*----------------------------------------------------------------------------*)\r
+(*  uaktualniamy wartosc BANK, ADRES i parametry procedury typu ' '           *)\r
+(*----------------------------------------------------------------------------*)\r
+var str, txt, b, tmp, add: string;\r
+    _doo, _odd, idx, i, len: integer;\r
+    tst: cardinal;\r
+    old_bool, old_macro: Boolean;\r
+begin\r
+\r
+   t_prc[proc_nr].bnk:=bank;\r
+   t_prc[proc_nr].adr:=a;\r
+\r
+   t_prc[proc_nr].ofs:=org_ofset;\r
+\r
+   str:=lokal_name+ety;\r
+   zapisz_etykiete(str,a,bank,ety[1]);\r
+\r
+   old_macro  := run_macro;\r
+   run_macro  := false;\r
+\r
+   old_bool   := dreloc.use;   // aby parametry procedury nie byly relokowalne\r
+   dreloc.use := false;\r
+\r
+   _doo:=t_prc[proc_nr].par;    // liczba zadeklarowanych parametrow w aktualnej procedurze\r
+\r
+   if _doo>0 then\r
+    case t_prc[proc_nr].typ of\r
+\r
+   __pDef: begin\r
+\r
+          // jesli procedura miala zadeklarowane parametry to\r
+          // odczytamy adres dla parametrow zawarty w @PROC_VARS_ADR\r
+          // i zaktualizujemy adresy parametrow procedury\r
+\r
+            tst:=adr_label(2,true);   // @proc_vars_adr\r
+\r
+            proc:=true;                  // PROC=TRUE i PROC_NAME\r
+            proc_name:=ety+'.';          // umozliwia uaktualnienie adresow etykiet\r
+\r
+          // wymus wykonanie makr @PULL 'I'\r
+\r
+//             wymus_zapis_lst(zm);\r
+\r
+             zm:=' @PULL ''I'','+IntToStr(t_prc[proc_nr].ile);\r
+\r
+             idx:=t_prc[proc_nr].str;\r
+\r
+             for _odd:=0 to _doo-1 do begin   // !!! koniecznie taka kolejnosc petli FOR !!!\r
+              txt:=t_par[idx+_odd];\r
+              str:=copy(txt,2,length(txt));\r
+\r
+          // uaktualnimy adresy etykiet parametrow procedury\r
+              save_lab(str , tst , __id_param , zm);\r
+\r
+              inc( tst , TypeToByte(txt[1]) );\r
+             end;\r
+\r
+           end;\r
+\r
+   __pVar: begin\r
+\r
+             idx:=t_prc[proc_nr].str;\r
+\r
+             for _odd:=_doo-1 downto 0 do begin\r
+              txt:=t_par[idx+_odd];\r
+\r
+\r
+            // wczytamy nazwe parametru, usuwamy pierwszy znak okreslajacy typ\r
+            // oraz znaki ktore nie naleza do nazwy etykiety\r
+\r
+              str:='';\r
+              add:='';\r
+              i:=2;\r
+              len:=length(txt);\r
+\r
+              while i<=len do begin\r
+               if _lab(txt[i]) then str:=str+txt[i] else Break;\r
+               inc(i);\r
+              end;\r
+\r
+              while i<=len do begin\r
+               add:=add+txt[i];\r
+               inc(i);\r
+              end;\r
\r
+              b:=lokal_name+ety+'.';\r
+\r
+              tmp:=b+str;\r
+              i:=l_lab(tmp);\r
+\r
+            // szukamy najblizszej sciezki dla parametru \r
+\r
+              while (i<0) and (pos('.',b)>0) do begin\r
+               obetnij_kropke(b);\r
+\r
+               tmp:=b+str;\r
+               i:=l_lab(tmp);\r
+              end;\r
+\r
+              t_par[idx+_odd] := txt[1]+tmp+add;\r
+             end;\r
+\r
+           end;\r
+           \r
+    end;\r
+\r
+\r
+ dreloc.use := old_bool;\r
+\r
+ run_macro  := old_macro;\r
+\r
+ save_lst(' ');\r
+\r
+end;\r
+\r
+\r
+function ByteToReg(var a: byte): char;\r
+begin\r
+\r
+ case (a and $c0) of\r
+  $40: Result := 'X';\r
+  $80: Result := 'Y';\r
+ else\r
+  Result := 'A';\r
+ end;\r
+\r
+ a:=byte( a shl 2 );\r
+end;\r
+\r
+\r
+function RegToByte(const a: char): byte;\r
+begin\r
+\r
+ case a of\r
+  'A': Result := $00;\r
+  'X': Result := $55;\r
+  'Y': Result := $aa;\r
+ else\r
+  Result := $ff;\r
+ end;\r
+\r
+end;\r
+\r
+\r
+procedure get_procedure(var ety,nam,zm: string; var i:integer);\r
+(*----------------------------------------------------------------------------*)\r
+(*  odczytujemy i zapamietujemy typy i nazwy parametrow w deklaracji .PROC    *)\r
+(*  w zaleznosci od sposobu przekazywania parametrow zwiekszana jest liczba   *)\r
+(*  przebiegow asemblacji PASS_END                                            *)\r
+(*----------------------------------------------------------------------------*)\r
+type _typBool = array [0..2] of Boolean;\r
+\r
+var k, l, nr_param, j: integer;\r
+    txt, str: string;\r
+    ch, ptype: char;\r
+    v: byte;\r
+    old_bool: Boolean;\r
+    \r
+    treg: _typBool;\r
+    all : _typStrREG;\r
+\r
+begin\r
+           reserved_word(ety,zm{, true});       // sprawdz czy nazwa .PROC jest dozwolona\r
+\r
+           old_bool  := run_macro;\r
+           run_macro := false;\r
+\r
+           save_lab(ety,proc_nr,__id_proc,zm);  // aktualny indeks do T_PRC = PROC_NR\r
+\r
+           run_macro := old_bool;\r
+\r
+           old_bool   := dreloc.use;            // koniecznie aby parametry procedury\r
+           dreloc.use := false;                 // nie byly relokowalne\r
+\r
+           t_prc[proc_nr].nam := nam;           // wlasciwa nazwa procedury\r
+           t_prc[proc_nr].bnk := bank;          // zapisanie banku procedury\r
+           t_prc[proc_nr].adr := adres;         // zapisanie adresu procedury\r
+\r
+           t_prc[proc_nr].typ := __pDef;        // domyslny typ procedury 'D'\r
+\r
+           t_prc[proc_nr].str := High(t_par);   // indeks do T_PAR, beda tam parametry procedury\r
+\r
+\r
+           omin_spacje(i,zm);\r
+\r
+           k:=0;  nr_param:=0;\r
+\r
+\r
+           str:=zm[i];\r
+           \r
+           if not(test_char(i,zm,'(',#0)) then blad_und(zm,str,8);\r
+\r
+          // odczytujemy deklaracje parametrow ograniczonych nawiasami ( )\r
+           if zm[i] = '(' then begin\r
+\r
+            all:='';                 // tutaj zapiszemy kombinacje rejestrow CPU\r
+//            fillchar(treg,sizeof(treg),false);\r
+\r
+            treg[0]:=false;\r
+            treg[1]:=false;\r
+            treg[2]:=false;\r
+\r
+            proc:=true;\r
+            proc_name:=ety+'.';\r
+\r
+          // sprawdzamy poprawnosc nawiasow, usuwamy poczatkowy i koncowy nawias\r
+\r
+            txt:=ciag_ograniczony(i,zm,true);\r
+\r
+            omin_spacje(i,zm);\r
+\r
+            ptype := __pDef;          // domyslny typ procedury __pDef\r
+\r
+         // sprawdzamy czy jest okreslony typ procedury .REG\r
+            if zm[i]='.' then begin\r
+             //str:=get_datUp(i,zm,#0,false);\r
+             str:=get_directive(i,zm);\r
+             \r
+             v := fCRC16(str);\r
+\r
+             if not(v in [__reg, __var]) then blad_und(zm,str,68);\r
+\r
+             ptype := str[2];\r
+             t_prc[proc_nr].typ := ptype;\r
+            end;\r
+\r
+            if ptype=__pVar then\r
+             if pass_end<3 then pass_end:=3;     // jesli sa parametry .VAR to musza byc conajmniej 3 przebiegi\r
+\r
+          // sprawdzamy obecnosc deklaracji dla programowego stosu MADS'a\r
+                             \r
+            if ptype=__pDef then begin\r
+             adr_label(0,true);   // @stack_pointer, test obecnosci deklaracji etykiety\r
+             adr_label(1,true);   // @stack_address, test obecnosci deklaracji etykiety\r
+             adr_label(2,true);   // @proc_vars_adr, test obecnosci deklaracji etykiety\r
+            end;\r
+\r
+\r
+            j:=1;\r
+            ch:=' ';                  // jesli ch=' ' to odczytuj typ parametru\r
+\r
+            while j<=length(txt) do begin\r
+\r
+             if ch=' ' then begin\r
+              v:=get_type(j,txt,zm,true);\r
+              ch:=relType[ v ];       // typ parametru 'B', 'W', 'L', 'D' z relType\r
+             end;\r
+\r
+\r
+           // odczytujemy nazwe parametru lub !!! wyrazenie !!! (np. label+1)\r
+           // parametry mo¿emy rozdzielac znakiem przecinka\r
+           // spacja sluzy do okreslenia nowego typu parametru\r
+\r
+             omin_spacje(j,txt);\r
+             str:=get_dat(j,txt,',',true);    // parametr lub wyrazenie\r
+             if str='' then blad(zm,15);\r
+\r
+\r
+           // jesli .REG to nazwy parametrow sa 1-literowe A,X,Y lub 2-literowe AX, AY itp.\r
+           // nazwy parametrow moga powtorzyc sie tylko raz\r
+           // dla .REG dopuszczalne sa tylko parametry typu .BYTE, .WORD, .LONG\r
+             if ptype=__pReg then begin\r
+\r
+               if not(TypeToByte(ch)=length(str)) then blad_und(zm,str,41);\r
+\r
+               for l:=1 to length(str) do begin\r
+\r
+                 v:=RegToByte(UpCase(str[l])) and 3;\r
+\r
+                 if v=3 then\r
+                  blad_und(zm,str[l],61)   // CPU doesn't have register ?\r
+                 else\r
+                  if treg[v] then\r
+                   blad(zm,11)             // CPU doesn't have so many registers\r
+                  else\r
+                   treg[v]:=true;\r
+\r
+               end;\r
+\r
+             end;\r
+\r
+             omin_spacje(j,txt);\r
+\r
+           // wstepnie zapamietujemy etykiety parametrow jako wartosc NR_PARAM dla __pDef\r
+\r
+             case ptype of\r
+              __pDef: save_lab(str , nr_param , __id_param , zm);\r
+              __pReg: all:=all+str;\r
+//              __pVar: str:=proc_name+lokal_name+str;   // potem poszukamy "sciezki" do nazwy parametru\r
+             end;\r
+\r
+             str:=ch+str;  save_par(str);\r
+\r
+             inc(k);              // zwiekszamy licznik odczytanych parametrow procedury\r
+\r
+             inc( nr_param , TypeToByte(ch) );   // zwiekszamy NR_PARAM o dlugosc danych\r
+\r
+             if txt[j]<>',' then\r
+              ch:=' '\r
+             else\r
+              inc(j);\r
+\r
+            end;    // while\r
+\r
+           end;     // if zm[i] = '('\r
+\r
+\r
+           if t_prc[proc_nr].typ = __pReg then begin\r
+          // maksymalnie 3 bajty mozna przekazac za pomoca rejestrow\r
+            if nr_param>3 then blad(zm,11);\r
+\r
+          // zapisujemy kolejnosc rejestrow\r
+            t_prc[proc_nr].reg := (RegToByte(all[1]) and $c0) or (RegToByte(all[2]) and $30) or (RegToByte(all[3]) and $0c);\r
+           end;\r
+\r
+           t_prc[proc_nr].par := k;\r
+           t_prc[proc_nr].ile := nr_param;\r
+\r
+           dreloc.use := old_bool;\r
+end;\r
+\r
+\r
+procedure test_wyjscia(var zm:string; const wyjscie:Boolean);\r
+(*----------------------------------------------------------------------------*)\r
+(*  testowanie zakonczenia asemblacji pliku                                   *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+\r
+ if not(wyjscie) then \r
+  if not(run_macro) and not(icl_used) then\r
+   if ifelse<>0 then blad(zm,1) else\r
+    if proc or macro then blad(zm,17) else  // !!! koniecznie !!! ... or macro\r
+     if struct.use then blad(zm,56) else\r
+      if aray then blad(zm,60) else\r
+       if rept then blad(zm,43) else\r
+        if lokal_nr>0 then blad(zm,29) else\r
+         if pag_idx>0 then blad(zm,65) else\r
+          if whi_idx>0 then blad(zm,89) else\r
+           if test_idx>0 then blad(zm,96);\r
+end;\r
+\r
+\r
+function fgetB(var i:integer): byte;\r
+begin\r
+ Result := t_lnk[i];\r
+ inc(i);\r
+end;\r
+\r
+function fgetW(var i:integer): integer;\r
+begin\r
+ Result := t_lnk[i] + t_lnk[i+1] shl 8;\r
+ inc(i,2);\r
+end;\r
+\r
+function fgetL(var i:integer): cardinal;\r
+begin\r
+ Result := t_lnk[i] + t_lnk[i+1] shl 8 + t_lnk[i+2] shl 16;\r
+ inc(i,3);\r
+end;    \r
+\r
+function fgetD(var i:integer): cardinal;\r
+begin\r
+ Result := t_lnk[i] + t_lnk[i+1] shl 8 + t_lnk[i+2] shl 16 + t_lnk[i+3] shl 24;\r
+ inc(i,4);\r
+end;\r
+\r
+function fgetS(var i:integer): string;\r
+var x, y: integer;\r
+begin\r
+ Result:='';\r
+\r
+ x:=fgetW(i);\r
+\r
+ for y:=x-1 downto 0 do Result:=Result+chr( fgetB(i) );\r
+end;\r
+\r
+\r
+procedure flush_link;\r
+var j, k: integer;\r
+begin\r
+ k:=dlink.len;\r
+\r
+ save_lst('a');\r
+\r
+ if k>0 then\r
+  for j:=0 to k-1 do save_dst(t_ins[j]);\r
+\r
+ inc(adres,k);\r
+\r
+ if dlink.emp>0 then begin\r
+  save_hea;  org:=true;\r
+  inc(adres,dlink.emp);\r
+  dlink.emp:=0;\r
+ end;\r
\r
+end;\r
+\r
+\r
+procedure get_address(var i:integer; var zm:string);\r
+// nowy adres asemblacji dla .PROC lub .LOCAL\r
+var txt: string;\r
+begin\r
+      t_end[end_idx].old:=adres;\r
+\r
+      // sprawdzamy czy jest nowy adres asemblacji dla .PROC lub .LOCAL\r
+\r
+      omin_spacje(i,zm);\r
+\r
+      if zm[i]=',' then begin\r
+        __inc(i,zm);\r
+        txt:=get_dat(i,zm,'(',true);\r
+\r
+        blokuj_zapis:=true;  // wymuszamy zapis ORG-a jesli wystapil wczesniej\r
+        save_dst(0);\r
+        blokuj_zapis:=false;\r
+\r
+        org_ofset := adres;\r
+\r
+        adres := integer( oblicz_wartosc(txt,zm) );\r
+\r
+        org_ofset := adres - org_ofset;\r
+\r
+        omin_spacje(i,zm);\r
+      end;\r
+end;\r
+\r
+\r
+procedure get_address_update;\r
+begin\r
+\r
+ dec(adres, t_end[end_idx-1].adr);\r
+ inc(adres, t_end[end_idx-1].old);\r
+\r
+ dec(end_idx);\r
+end;\r
+\r
+\r
+procedure save_extLabel(k:integer; var ety,zm:string; v:byte);\r
+var txt: string;\r
+    len: byte;\r
+    isProc: Boolean;\r
+begin\r
+\r
+  omin_spacje(k,zm);\r
+\r
+  if v=__proc then begin                  // etykieta external deklaruje procedure\r
+\r
+   proc_nr:=proc_idx;                     // koniecznie przez ADD_PROC_NR\r
+\r
+   if pass=0 then begin\r
+     txt:='##'+ety;                       // zapisujemy etykiete ze znakami ##\r
+     get_procedure(txt,ety,zm,k);         // odczytujemy parametry\r
+\r
+     proc:=false;                         // koniecznie wylaczamy PROC\r
+     proc_name:='';                       // i koniecznie PROC_NAME:=''\r
+   end;\r
+\r
+   add_proc_nr;                           // zwiekszamy numer koniecznie\r
+\r
+   save_lab(ety,extn_idx,__id_ext,zm);\r
+\r
+   len:=2;                                // typu .WORD\r
+   isProc:=true;\r
+\r
+  end else begin\r
+\r
+   dec(v, __byteValue);                   // normalna etykieta external\r
+\r
+   save_lab(ety, extn_idx, __id_ext, zm);\r
+\r
+   len:=v;\r
+   isProc:=false;\r
+\r
+  end;\r
+\r
+  t_extn[extn_idx].nam:=ety;              // SAVE_EXTN\r
+  t_extn[extn_idx].siz:=relType[len];     //\r
+  t_extn[extn_idx].prc:=isProc;           //\r
+\r
+  inc(extn_idx);\r
+\r
+  if extn_idx>High(t_extn) then SetLength(t_extn,extn_idx+1);\r
+end;\r
+\r
+\r
+procedure get_maeData(var zm:string; var i:integer; const typ:char);\r
+var _odd, _doo, idx, j, tmp: integer;\r
+    txt, hlp: string;\r
+    v, war: byte;\r
+\r
+    par: _strArray;\r
+begin\r
+\r
+   save_lst('a');\r
+\r
+   get_parameters(i,zm,par,true, '.',':');\r
+\r
+   _doo:=High(par);\r
+\r
+   if _doo>0 then begin\r
+\r
+    _odd:=0;\r
+    war:=0;\r
+\r
+    if (typ in ['B','S']) and (_doo>1) then begin\r
+\r
+     txt:=par[0];     // mozliwa wartosc, ktora bedziemy dodawac do reszty ciagu\r
+                      // pod warunkiem ze ciag liczy wiecej niz 1 element\r
+\r
+     if txt[1] in ['+','-'] then begin\r
+      j:=1; war:=byte( ___wartosc_noSPC(txt,zm,j,#0,'B') );\r
+      inc(_odd);\r
+     end;\r
+\r
+    end;\r
+\r
+\r
+    for idx:=_odd to _doo-1 do begin               // wlasciwe dekodowanie ciagu\r
+     txt:=par[idx];\r
+\r
+     if txt[1] in ['''','"'] then begin\r
+\r
+      j:=1; hlp:=get_string(j,txt,zm,true);\r
+\r
+      omin_spacje(j,txt);\r
+\r
+      if length(txt)>=j then\r
+       if not(txt[j] in ['*','+','-']) then blad_ill(zm,txt[j]);\r
+\r
+      v:=war;\r
+       \r
+      inc(v, test_string(j,txt,'F'));\r
+\r
+      if typ='S' then\r
+       save_dta(0,hlp,'D', v)\r
+      else\r
+       save_dta(0,hlp,'C', v);\r
+\r
+     end else\r
+\r
+      case typ of\r
+       'B', 'H', 'S':\r
+            begin\r
+             if typ='H' then txt:='$'+txt;\r
+\r
+             j:=1;  v := byte( ___wartosc_noSPC(txt,zm,j,#0,'B') );\r
+\r
+             if typ='S' then v:=ata2int(v);\r
+\r
+             inc(v, war); //v:=v + war;\r
+\r
+             save_dst(v);\r
+             inc(adres);\r
+            end;\r
+\r
+       'W': begin\r
+             j:=1;  tmp := integer( ___wartosc_noSPC(txt,zm,j,#0,'A') );\r
+             save_dstW( tmp );\r
+             inc(adres,2);\r
+            end;\r
+\r
+      end;\r
+\r
+    end;\r
+\r
+   end;\r
+\r
+end;\r
+\r
+\r
+function asm_test(var lar,rar,old, jump:string; const typ,op:byte): int5;\r
+(*----------------------------------------------------------------------------*)\r
+(* generujemy kod testujacy warunek dla .WHILE, .TEST                         *)\r
+(*----------------------------------------------------------------------------*)\r
+var hlp: int5;\r
+    txt: string;\r
+    adr: integer;\r
+begin\r
+\r
+ adr:=adres;\r
+\r
+ if lar[1]='#' then blad(old,58);   // argument nierealny :)\r
+\r
+ case typ of\r
+  1: txt:='CPB';\r
+  2: txt:='CPW';\r
+  3: txt:='CPL';\r
+ else\r
+  txt:='CPD';\r
+ end;\r
+\r
+ TestWhileOpt:=not(op in [0,4]);    // krótszy kod jesli operator '=', '<>'\r
+\r
+ txt:=txt+#32+lar+#32+rar;\r
+ Result:=asm_mnemo(txt, old);\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  0 <>      4 =           xor 4                                             *)\r
+(*  1 >=      5 <                                                             *)\r
+(*  2 <=      6 >                                                             *)\r
+(*----------------------------------------------------------------------------*)\r
+\r
+ case op of\r
+   0: txt:='JNE';                   // <>\r
+   1: txt:='JCS';                   // >=\r
+   2: txt:='JCC '+jump;             // <=\r
+   4: txt:='JEQ';                   // =\r
+   5: txt:='JCC';                   // <\r
+   6: txt:='SEQ';                   // >\r
+ end;\r
+\r
+\r
+ if op in [2,6] then begin\r
+\r
+   hlp:=asm_mnemo(txt,old);\r
+   addResult(hlp,Result);\r
+\r
+   if op=2 then\r
+    txt:='JEQ'\r
+   else begin\r
+    test_skipa;\r
+    txt:='JCS';\r
+   end;\r
+\r
+ end;\r
+\r
+\r
+ txt:=txt+#32+jump;\r
+ hlp:=asm_mnemo(txt,old);\r
+ addResult(hlp,Result);\r
+\r
+ adres := adr;                      // przywracamy poczatkowa wartosc ADRES\r
+end;\r
+\r
+\r
+procedure create_long_test(const _v, _r:byte; var long_test, _lft, _rgt:string);\r
+var txt: string;\r
+begin\r
+\r
+   case _v xor 4 of\r
+    0: txt:='<>';\r
+    1: txt:='>=';\r
+    2: txt:='<=';\r
+    4: txt:='=';\r
+    5: txt:='<';\r
+    6: txt:='>';\r
+   end;\r
+\r
+   if long_test<>'' then long_test:=long_test+'\';\r
+\r
+   long_test:=long_test+'.TEST '+mads_param[_r]+_lft+txt+_rgt+'\ LDA:SNE#1\.ENDT\ LDA#0';\r
+\r
+   long_test:=long_test+'\.IF .GET[?I-1]=41\ AND EX+?J-2+1\ STA EX+?J-2+1\ ?I--\ ELS\ STA EX+?J+1\ ?J+=2\ EIF\';\r
+\r
+end;\r
+\r
+\r
+procedure wyrazenie_warunkowe(var i:integer; var long_test, zm,left,right:string; var v,r:byte; const strend: string);\r
+(*----------------------------------------------------------------------------*)\r
+(* generowanie kodu dla warunku .WHILE, .TEST                                 *)\r
+(*----------------------------------------------------------------------------*)\r
+var str, txt, _lft, _rgt, kod: string;\r
+    k, j : integer;\r
+    _v, _r: byte;\r
+begin\r
+\r
+   if zm='' then blad(zm,23);\r
+\r
+   r:=get_type(i,zm,zm,true);\r
+\r
+   omin_spacje(i,zm);\r
+\r
+   str:=get_dat(i,zm,#0, false);\r
+\r
+   k:=1;\r
+\r
+   right:='';\r
+   left:='';        // czytamy do LEFT dopóki nie napotkamy operatorów '=', '<', '>', '!'\r
+\r
+   if str<>'' then\r
+    while not(_ope(str[k])) and not(test_char(k,str,#0,#0)) do begin\r
+\r
+       if str[k] in ['[','(','{'] then\r
+         left:=left + ciag_ograniczony(k,str,false)\r
+       else begin\r
+        if str[k]<>' ' then left:=left + str[k];\r
+        inc(k);\r
+       end;\r
+\r
+   end;\r
+\r
+\r
+   omin_spacje(k,str);\r
+\r
+\r
+   v:=$ff;\r
+\r
+   if left<>'' then begin\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  0 <>      4 =           xor 4                                             *)\r
+(*  1 >=      5 <                                                             *)\r
+(*  2 <=      6 >                                                             *)\r
+(*----------------------------------------------------------------------------*)\r
+        \r
+   case str[k] of            // szukamy znanej kombinacji operatorów\r
+\r
+      #0: v:=$80;             // koniec ci¹gu\r
+\r
+     '=': case str[k+1] of\r
+           '=': begin\r
+                 v:=4;       // ==\r
+                 inc(k);\r
+                end;\r
+          else\r
+           v:=4;             // =\r
+          end;\r
+\r
+     '!': case str[k+1] of\r
+           '=': v:=0;        // !=\r
+          end;\r
+\r
+     '<': case str[k+1] of\r
+           '>': v:=0;        // <>\r
+           '=': v:=2;        // <=\r
+          else\r
+           v:=5;             // <\r
+          end;\r
+\r
+     '>': case str[k+1] of\r
+           '=': v:=1;        // >=\r
+          else\r
+           v:=6;             // >\r
+          end;\r
+\r
+   end;\r
+\r
+\r
+\r
+     if v<$80 then begin\r
+\r
+       if v<4 then\r
+        inc(k,2)\r
+       else\r
+        inc(k);\r
+\r
+       if _ope(str[k]) then blad_ill(zm, str[k]);\r
+\r
+       v:=v xor 4;\r
+\r
+       omin_spacje(k,str);\r
+\r
+       right:=get_dat(k,str,#0,true);      //get_dat_noSPC(k,str,#0,#0,zm);\r
+\r
+     end else\r
+        if v=$80 then begin      // dla pustego ciagu domyslna operacja '<>0'\r
+           v:=4;\r
+           right:='#0';\r
+        end;\r
+\r
+   end;\r
+\r
+\r
+ // V = $FF oznacza brak operatora\r
+\r
+   if (left='') or (right='') or (v=$ff) then begin\r
+      blad(zm,58); koniec(2);\r
+   end;\r
+\r
+\r
+ // jesli wystêpuj¹ operatory .OR, .AND to generujemy specjalny kod\r
+\r
+  omin_spacje(k,str);\r
+\r
+  kod:='';\r
+\r
+  if not(test_char(k,str,#0,#0)) then begin\r
+\r
+   txt:=get_dat(k,str,#0,true);\r
+\r
+   if txt='.OR' then\r
+    kod:='9'\r
+   else\r
+    if txt='.AND' then\r
+     kod:='41';\r
+{    else\r
+     blad(zm,58);}\r
+\r
+  end;\r
+\r
+\r
+  if kod<>'' then begin\r
+\r
+   if long_test='' then long_test:=long_test+'.LOCAL\.PUT[0]=0\?I=1\?J=0';\r
+\r
+   omin_spacje(k,str);\r
+   txt:=get_dat(k,str,#0,false);\r
+\r
+   j:=1; wyrazenie_warunkowe(j, long_test, txt,_lft,_rgt, _v, _r, '.PUT[?I]='+kod+'\ ?I++');\r
+  end;\r
+\r
+\r
+  if (long_test<>'') then begin\r
+   create_long_test(v, r, long_test, left, right);\r
+   long_test:=long_test+strend;\r
+  end;\r
+\r
+end;\r
+\r
+\r
+function BCD(const l,r:char): byte;\r
+begin\r
+ Result:=byte( (ord(l)-ord('0')) shl 4 + (ord(r)-ord('0')) );\r
+end;\r
+\r
+\r
+procedure save_fl(var a,old:string);\r
+(*----------------------------------------------------------------------------*)\r
+(*  zapisujemy liczbe real w formacie FP Atari                                *)\r
+(*----------------------------------------------------------------------------*)\r
+var i, c, e: integer;\r
+    fl, tmp: string;\r
+    x: real;\r
+    v: byte;\r
+begin\r
+\r
+ val(a, x,i);\r
+ if i>0 then blad_ill(old,a[i]);\r
+\r
+ str(x, fl);\r
+\r
+ tmp:=copy(fl,pos('E',fl)+1,length(fl));  // odczytujemy wartosc E\r
+ e:=integer( StrToInt(tmp) );\r
+\r
+ c:=pos('.',fl);       // pozycja znaku '.'\r
+\r
+ if e and 1<>0 then    // jesli E jest nieparzyste to modyfikujemy\r
+  while c<>4 do begin\r
+\r
+   if c<4 then begin\r
+    fl[c]:=fl[c+1];    // przesuwamy w prawo\r
+    fl[c+1]:='.';\r
+    dec(e);\r
+    inc(c);\r
+   end else begin\r
+    fl[c]:=fl[c-1];    // przesuwamy w lewo\r
+    fl[c-1]:='.';\r
+    inc(e);\r
+    dec(c);\r
+   end;\r
+\r
+  end;\r
+\r
+ e:=e div 2;\r
+\r
+ if (c>4) or (abs(e)>64) then blad(old,0);   // przekroczony zakres FP Atari\r
+\r
+ v:=byte(64+e);\r
+ if fl[1]='-' then v:=v or $80;\r
+\r
+ save_dst(v);\r
+\r
+ if c=4 then               // dwie cyfry\r
+  v:=BCD(fl[2],fl[3])\r
+ else                      // jedna cyfra\r
+  v:=BCD('0',fl[2]);\r
+\r
+ save_dst(v);\r
+\r
+ i:=c+1;\r
+\r
+ v:=BCD(fl[i], fl[i+1]); inc(i,2);  save_dst(v);\r
+ v:=BCD(fl[i], fl[i+1]); inc(i,2);  save_dst(v);\r
+ v:=BCD(fl[i], fl[i+1]); inc(i,2);  save_dst(v);\r
+ v:=BCD(fl[i], fl[i+1]);            save_dst(v);\r
+\r
+ inc(adres,6);             // zapisalismy 6 bajtow\r
+\r
+end;\r
+\r
+\r
+function getMemType(var i: integer; var zm: string): byte;\r
+begin\r
+\r
+ omin_spacje(i,zm);\r
+\r
+ Result := 0;\r
+               case UpCase(zm[i]) of\r
+                'M': Result:=0;         // M[ain]\r
+                'E': Result:=2;         // E[xtended]\r
+               else\r
+                blad(zm,23);\r
+               end;\r
+\r
+ memType := Result;\r
+end;\r
+\r
+\r
+\r
+function directive(var zm:string; const kod:byte): byte;\r
+(*----------------------------------------------------------------------------*)\r
+(*  odczyt dyrektywy lub innego ciagu znakowego i obliczenie kodu             *)\r
+(*----------------------------------------------------------------------------*)\r
+var i: integer;\r
+    z: string;\r
+    old_case, space: Boolean;\r
+    label LOOP;\r
+begin\r
+ Result:=0;\r
+\r
+LOOP:\r
\r
+ if zm<>'' then begin\r
+\r
+  i:=1;\r
+  omin_spacje(i,zm);\r
+\r
+  space:=i<>1;               // sprawdzamy czy wystepuja spacje ("biale znaki")\r
+\r
+  old_case  := case_used;    // zapamietujemy poprzednia wartosc CASE_USED\r
+  case_used := false;        // wymuszamy duze litery CASE_USED = FALSE\r
+\r
+  z:=get_lab(i,zm,false);\r
+\r
+  case_used  := old_case;\r
+\r
+\r
+  if space or labFirstCol then begin\r
+   Result:=fASC(z);\r
+   if Result<>0 then exit;\r
+  end;\r
+\r
+\r
+  omin_spacje(i,zm);\r
+\r
+  if zm[i]='{' then begin\r
+\r
+    if end_idx>0 then begin\r
+      if t_end[end_idx-1].sem then blad(zm,58);\r
+      t_end[end_idx-1].sem:=true;\r
+\r
+      wymus_zapis_lst(zm);\r
+\r
+      zm:=copy(zm, i+1, length(zm));\r
+\r
+      goto LOOP;\r
+    end else\r
+     blad(zm,58);\r
+\r
+  end else\r
+\r
+  if zm[i]='}' then begin\r
+\r
+   if end_idx>0 then\r
+    if t_end[end_idx-1].sem then begin\r
+      __inc(i,zm);\r
+      if not(test_char(i,zm,#0,#0)) then blad(zm,58);\r
+      Result:=__dend;\r
+    end else\r
+     blad(zm,58);\r
+    \r
+  end else\r
+\r
+  if i<length(zm) then\r
+   if _dir_first(zm[i]) then begin\r
+    z:=get_directive(i,zm);\r
+    Result:=fCRC16(z);\r
+   end else begin\r
+    z:=get_datUp(i,zm,#0,false);\r
+    Result:=fASC(z);\r
+   end;\r
+\r
+\r
+  if (Result=__dend) and (end_idx>0) then begin\r
+    if t_end[end_idx-1].kod = kod then Result:=kod;\r
+  end;\r
+\r
+ end;\r
+\r
+end;\r
+\r
+\r
+function dirMACRO(var zm:string): byte;\r
+(*----------------------------------------------------------------------------*)\r
+(*  odczyt makra zdefiniowanego przez dyrektywy .MACRO, .ENDM [.MEND]         *)\r
+(*  !!! wyjatkowo dyrektywa .END nie mo¿e koñczyc definicji makra !!!         *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+   save_lst(' ');                               // .MACRO\r
+\r
+   Result:=directive(zm, __endm);\r
+\r
+   if (Result=__macro) and macro then blad(zm,17);\r
+\r
+   if Result=__endm then macro := false;\r
+\r
+   if (pass=0) and if_test then save_mac(zm);   // !!! makra zapisujemy tylko w 1 przebiegu !!!\r
+\r
+   zapisz_lst(zm);\r
+end;\r
+\r
+\r
+procedure dirENDR(var zm,a,old_str:string; var rept_nr,rept_ile:integer);\r
+(*----------------------------------------------------------------------------*)\r
+(*  .ENDR  -  wykonanie petli .REPT                                           *)\r
+(*----------------------------------------------------------------------------*)\r
+var tmp, lntmp: integer;\r
+    txt: string;\r
+    old_if_test: Boolean;\r
+begin\r
+\r
+      if if_test then\r
+       if not(rept) then blad(zm,51) else begin\r
+\r
+         wymus_zapis_lst(zm);\r
+\r
+         rept     := false;\r
+         rept_run := true;\r
+\r
+         tmp      := ___rept_ile;\r
+\r
+         lntmp    := line_add;\r
+\r
+\r
+         ___rept_ile := StrToInt(t_mac[rept_nr]);\r
+\r
+         line_add    := StrToInt(t_mac[rept_nr+1]);\r
+\r
+         old_if_test := if_test;\r
+\r
+\r
+         if not(run_macro) then begin\r
+          txt := 'REPT';\r
+          put_lst(show_full_name(txt,false,true));\r
+         end;\r
+\r
+\r
+         analizuj_mem__(rept_nr+2,High(t_mac), zm,a,old_str, 0,rept_ile, true);\r
+\r
+\r
+         rept_run  := false;\r
+\r
+         if not(run_macro) and not(rept) then put_lst(show_full_name(a,full_name,true));\r
+\r
+\r
+         line_add    := lntmp;\r
+\r
+         if_test     := old_if_test;\r
+\r
+         ___rept_ile := tmp;\r
+\r
+         SetLength(t_mac, rept_nr+1);\r
+\r
+         dec_end(zm, __endr);\r
+\r
+       end;\r
+\r
+end;\r
+\r
+\r
+procedure reptLine(var txt: string);\r
+(*----------------------------------------------------------------------------*)\r
+(*  podstawianie parametrow w bloku .REPT                                     *)\r
+(*----------------------------------------------------------------------------*)\r
+var ety, tmp: string;\r
+    j, k, war: integer;\r
+begin\r
+           j:=1;\r
+           while j<=length(txt) do\r
+            if test_param(j,txt) then begin\r
+\r
+             k:=j;\r
+             if txt[j]=':' then inc(j) else inc(j,2);\r
+\r
+             ety:='';\r
+             while _dec(txt[j]) do begin ety:=ety+txt[j]; inc(j) end;\r
+\r
+             war:=StrToInt(ety);\r
+\r
+             \r
+             if war<High(reptPar) then begin\r
+\r
+              delete(txt,k,j-k);  dec(j,j-k);\r
+\r
+              tmp:=reptPar[war];\r
+\r
+              war:=oblicz_wartosc(tmp, txt);\r
+\r
+              tmp:=IntToStr(war);\r
+\r
+{              if tmp[1]='#' then\r
+               tmp:=IntToStr(___rept_ile)\r
+              else\r
+               if (tmp[1]='"') and (tmp[length(tmp)]='"') then tmp:=copy(tmp,2,length(tmp)-2);\r
+}\r
+              insert(tmp,txt,k);\r
+              inc(j,length(tmp));\r
+             end;\r
+\r
+            end else inc(j);\r
+\r
+end;\r
+\r
+\r
+function dirREPT(var zm: string): byte; \r
+(*----------------------------------------------------------------------------*)\r
+(*  analiza linii gdy wystapilo .REPT                                         *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+   save_lst(' ');\r
+\r
+   Result:=directive(zm, __endr);\r
+\r
+   if (Result=__rept) and rept then blad(zm,43);\r
+\r
+   if Result<>__endr then begin\r
+    if if_test then save_mac(zm);\r
+    zapisz_lst(zm);\r
+   end;\r
+\r
+end;\r
+\r
+\r
+function get_vars_type(var i:integer; var zm:string; var typ:char; var i_str: integer; var n_str: string): integer;\r
+(*----------------------------------------------------------------------------*)\r
+(* odczytujemy typ dla zmiennych .BYTE, .WORD, .LONG, .DWORD, .STRUCT|.ENUM   *)\r
+(*----------------------------------------------------------------------------*)\r
+var txt: string;\r
+    k, x: integer;\r
+begin\r
+\r
+     omin_spacje(i,zm); \r
+\r
+     Result:=0;\r
+     k:=i;\r
+\r
+     if zm[i]='.' then begin\r
+\r
+       txt:=get_directive(i,zm);\r
+       Result:=fCRC16(txt);\r
+\r
+       if Result in [__byte..__dword] then\r
+         dec(Result, __byteValue)\r
+       else begin\r
+         Result:=0;     // to nie jest dyrektywa okreslajaca typ danych !!! V=0 !!!\r
+         i:=k;          // przywracamy poprzednie wartosci\r
+       end;\r
+\r
+     end else begin\r
+\r
+       txt:=get_lab(i,zm, true);    // zatrzyma sie jesli brak etykiety\r
+\r
+       x:=load_lab(txt, true);\r
+\r
+       if x<0 then\r
+        i:=k                        // etykieta nie zostala zdefiniowana\r
+       else\r
+        case t_lab[x].bnk of\r
+\r
+           __id_enum:\r
+           begin\r
+            Result:=t_lab[x].adr;\r
+\r
+            n_str := txt;\r
+\r
+//            typ:='E';\r
+           end;\r
+\r
+         __id_struct:\r
+           begin\r
+            Result:=t_str[t_lab[x].adr].siz;\r
+\r
+            i_str := t_lab[x].adr;\r
+            n_str := txt;\r
+\r
+            typ:='S';\r
+           end;\r
+\r
+        else\r
+         i:=k;\r
+        end;\r
+\r
+     end;\r
+\r
+end;\r
+\r
+\r
+procedure get_vars(var i:integer; var zm:string; var par:_strArray; const mne: byte);\r
+(*----------------------------------------------------------------------------*)\r
+(*  .VAR .TYPE v0 [=expression], v1 [=expression] .TYPE v3 [=expression] v4   *)\r
+(*  .VAR v0 [=expression] .TYPE v1 [=expression] v2 .TYPE [=address]          *)\r
+(*                                                                            *)\r
+(*  odczyt parametrow dla dyrektywy .VAR                                      *)\r
+(*----------------------------------------------------------------------------*)\r
+var idx, _doo, _odd, k, v, i_str: integer;\r
+    txt, str, n_str: string;\r
+    tst: Int64;\r
+    typ: char;\r
+begin\r
+\r
+     i_str:=0;\r
+     n_str:='';\r
+\r
+     typ:='V';\r
+\r
+     v:=get_vars_type(i,zm, typ, i_str, n_str);\r
+\r
+     get_parameters(i,zm,par,false, '.',':');\r
+\r
+     idx:=1;\r
+\r
+     if zm[i]=':' then begin                // liczba powtorzen\r
+      inc(i);\r
+      txt:=get_dat(i,zm,',',true);\r
+      idx:=integer( oblicz_wartosc(txt,zm) );\r
+      testRange(zm, idx, 0);\r
+     end;\r
+\r
+     _doo:=High(par);\r
+\r
+     if _doo=0 then blad(zm,23);            // brak zmiennych - Unexpected end of line\r
+\r
+     omin_spacje(i,zm);\r
+\r
+     if v=0 then\r
+      if zm[i]='.' then\r
+\r
+       v:=get_type(i,zm,zm,true)            // typ zmiennej\r
+\r
+      else begin\r
+       txt:=par[_doo-1];\r
+\r
+       k:=1;\r
+       v:=get_vars_type(k,txt,typ, i_str, n_str);\r
+\r
+       if v=0 then\r
+        blad_und(zm,txt,50)                 // nie zostal okreslony typ zmiennej "Missing type label"\r
+       else begin\r
+        par[_doo-1]:=copy(txt,k,length(txt));\r
+\r
+        dec(_doo);                          // udalo sie, ostatni element pomijamy\r
+       end;\r
+\r
+      end;\r
+\r
+\r
+     for _odd:=0 to _doo-1 do begin\r
+      txt:=par[_odd];\r
+\r
+      k:=1;  str:=get_lab(k, txt, true);    // sprawdzamy czy etykieta posiada poprawne znaki\r
+\r
+      //if str='' then blad_ill(zm,txt[1]);   // pierwszy znak etykiety jest niewlasciwy\r
+\r
+\r
+      tst:=0;\r
+\r
+      if txt[k]='=' then begin              // czy zmienna jest inicjowana ('=')\r
+\r
+        if (mne=__zpvar) and (pass=pass_end) then warning(114);\r
+\r
+        txt:=copy(txt,k+1,length(txt));\r
+\r
+        tst:=oblicz_wartosc(txt,zm);\r
+\r
+        if ValueToType(tst) > v then blad(zm,0);\r
+\r
+      end else\r
+       if not(test_char(k,txt,#0,#0)) then blad_ill(zm,txt[k]);  // wystapil niedozwolony znak\r
+\r
+\r
+        if proc then                           // SAVE_VAR\r
+         t_var[var_idx].lok := proc_lokal      //\r
+        else                                   //\r
+         t_var[var_idx].lok := end_idx;        //\r
+                                               //\r
+        if proc and (lokal_name<>'') then      //\r
+         t_var[var_idx].nam := lokal_name+str  //\r
+        else                                   //\r
+         t_var[var_idx].nam := str;            //\r
+                                               //\r
+        t_var[var_idx].siz := v;               //\r
+        t_var[var_idx].cnt := idx;             //\r
+        t_var[var_idx].war := cardinal (tst);  //\r
+                                               //\r
+        t_var[var_idx].adr := -1;              //\r
+                                               //\r
+        t_var[var_idx].id  := var_id;          //\r
+        t_var[var_idx].typ := typ;             //\r
+        t_var[var_idx].idx := i_str;           //\r
+        t_var[var_idx].str := n_str;           //\r
+\r
+        inc(var_idx);\r
+\r
+        if var_idx>High(t_var) then SetLength(t_var,var_idx+1);\r
+\r
+     end;\r
+\r
+end;\r
+\r
+\r
+procedure opt_h_minus;\r
+begin\r
+ opt:=opt and $fe;\r
+end;\r
+\r
+\r
+procedure upd_structure(var ety, zm: string);\r
+var idx: integer;\r
+    txt: string;\r
+begin\r
+           struct.cnt := 0;\r
+\r
+           txt:=lokal_name+ety;      // pelna nazwa struktury .STRUCT\r
+\r
+          // sprawdzamy czy mamy juz zapamietana ta strukture\r
+           idx:=loa_str(txt, struct.id);\r
+\r
+          // nie znalazl ofsetu do tablicy (idx = -1)\r
+           if idx<0 then begin\r
+\r
+            save_str(txt,adres,0,1,adres,bank);      // dopisz do tablicy T_STR nowa strukture\r
+\r
+            struct.idx:=loa_str(txt, struct.id);\r
+\r
+            save_lab(ety,struct.idx, __id_struct,zm);\r
+\r
+           end else begin\r
+          // znalazl ofset do tablicy\r
+            struct.idx:=idx;\r
+\r
+            save_lab(ety,struct.idx, __id_struct,zm);\r
+           end;\r
+\r
+           if pass_end<3 then pass_end:=3;     // jesli sa struktury to musza byc conajmniej 3 przebiegi\r
+\r
+end;\r
+\r
+\r
+\r
+procedure search_comment_block(var i:integer; var zm,txt:string);\r
+var k: integer;\r
+begin\r
+\r
+ if (zm<>'') and (i<length(zm)) then begin\r
+\r
+    k:=i;\r
+\r
+    if (zm[i]='/') and (zm[i+1]='*') then begin\r
+     komentarz:=true; inc(i,2);\r
+    end;\r
+\r
+    while komentarz and (i<=length(zm)) do\r
+      if (zm[i]='*') and (zm[i+1]='/') then begin\r
+       inc(i,2);\r
+       txt:=txt+copy(zm,k,i-k);\r
+\r
+       komentarz:=false; Break\r
+      end else\r
+       inc(i);\r
+\r
+ end;\r
+\r
+end;\r
+\r
+\r
+\r
+procedure wypisz(var i: integer; var zm: string);\r
+var txt: string;\r
+begin\r
+       //    save_lst(' ');\r
+\r
+       omin_spacje(i,zm);\r
+\r
+       if not(test_char(i,zm,#0,#0)) then begin\r
+\r
+           pisz   := true;\r
+           branch := true;             // dla .PRINT nie istnieje relokowalnosc\r
+\r
+           txt:=end_string;  end_string:='';\r
+\r
+           oblicz_dane(i,zm,zm,4);\r
+\r
+           pisz   := false;\r
+\r
+           save_lst(' ');\r
+           justuj;\r
+           put_lst(t+zm);\r
+\r
+           save_lst(' ');\r
+\r
+           zm:=end_string;             // !!! aby umiescil tekst w listingu !!!\r
+\r
+           end_string := txt + end_string + #13#10;\r
+\r
+       end;\r
+end;\r
+\r
+\r
+procedure analizuj_linie (var zm,a,old_str:string; var rept_nr,rept_ile,nr:integer; var end_file,wyjscie:Boolean);\r
+var g: file;\r
+    f: textfile;\r
+    v, r, opt_tmp: byte;\r
+    ch, rodzaj, typ: char;\r
+    i, k, j, m, _odd, _doo, idx, idx_get, rpt, old_ifelse, old_rept, indeks: integer;\r
+    old_loopused, old_icl_used, old_case, old_run_macro, old_komentarz: Boolean;\r
+    ety, txt, str, tmp, old_macro_nr, long_test, tmpZM: string;\r
+    war: Int64;\r
+    tst, vtmp: cardinal;\r
+\r
+    reloc_value: relVal;\r
+\r
+    mne: int5;\r
+    par: _strArray;\r
+\r
+    label JUMP, LOOP, JUMP_2;\r
+begin\r
+\r
+  i:=1;\r
+\r
+  if not(struct.use) and not(enum.use) then label_type:='V';\r
+                                    \r
+  overflow:=false;\r
+\r
+  mne.l:=0; rpt:=0;\r
+\r
+  data_out:=false;\r
+\r
+  reloc_value.use:=false; reloc_value.cnt:=0; rel_used:=false;\r
+\r
+  m:=i;                     // zapamietujemy poczatkowa wartosc 'i'\r
+\r
+\r
+  if zm='' then begin\r
+\r
+   mne_used := false;       // nie zostal odczytany mnemonik (!!! koniecznie w tym miejscu !!!)\r
+\r
+   save_lst(' ');\r
+   put_lst(t);\r
+\r
+   exit;\r
+  end;\r
+\r
+\r
+LOOP:\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  odczytujemy etykiete z lewej strony, od pierwszego znaku w linii          *)\r
+(*  jesli jest zakonczona dwukropkiem to pomijamy dwukropek                   *)\r
+(*----------------------------------------------------------------------------*)\r
+  ety:=get_lab(i,zm, false);\r
+  if (zm[i]=':') and (_eol(zm[i+1])) then inc(i);\r
+\r
+  omin_spacje(i,zm);\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  a moze jest jakas etykieta poprzedzona bialymi spacjami i zakonczona  ':' *)\r
+(*----------------------------------------------------------------------------*)\r
+  if ety='' then begin\r
+   k:=i;\r
+   txt:=get_lab(i,zm, false);\r
+\r
+   if txt<>'' then\r
+    if ((zm[i]=':') and (_eol(zm[i+1]))) or struct.use or enum.use then begin\r
+     ety:=txt;\r
+     __inc(i,zm);\r
+    end else\r
+     i:=k;\r
+\r
+  end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(* etykiety moga byc rozkazami CPU lub pseudo rozkazami jesli labFirstCol=true*)\r
+(* etykiet w stylu MAE to nie dotyczy, one sa rozpoznawane klasycznie         *)\r
+(* nie dotyczy to takze etykiet deklarowanych w .STRUCT                       *)\r
+(*----------------------------------------------------------------------------*)\r
+  if (length(ety)=3) and not(struct.use) and not(mae_labels) and labFirstCol then\r
+   if reserved(ety) then begin\r
+     i:=m;\r
+     ety:='';\r
+   end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  pierwszymi znakami moga byc tylko znaki poczatkujace nazwe etykiety,      *)\r
+(*  znaki konca linii oraz '.', ':', '*', '+', '-', '='                       *)\r
+(*  dopuszczalne sa instrukcje generujace kod 6502  #IF #WHILE #END           *)\r
+(*----------------------------------------------------------------------------*)\r
+//  if not(aray) and not(struct.use) and not(enum.use) then\r
+   if not(_first_char(zm[i])) and not(test_char(i,zm,#0,#0)) then\r
+\r
+    case zm[i] of\r
+\r
+     '#': begin\r
+           tmp:=get_directive(i,zm);\r
+\r
+           mne.l:=fCRC16(tmp);\r
+           if not(mne.l in [__test, __while, __dend, __telse]) then blad(zm,12);\r
+\r
+           goto JUMP_2;\r
+\r
+          end;\r
+\r
+     '{': if end_idx>0 then begin\r
+\r
+           if t_end[end_idx-1].sem then blad(zm,58);\r
+           \r
+           t_end[end_idx-1].sem:=true;\r
+           inc(i);\r
+\r
+           goto LOOP;\r
+           \r
+          end else\r
+           blad(zm,12);\r
+\r
+     '}': if end_idx>0 then\r
+           if t_end[end_idx-1].sem then begin\r
+            __inc(i,zm);\r
+\r
+            if not(test_char(i,zm,#0,#0)) then blad(zm,58);\r
+\r
+            mne.l:=t_end[end_idx-1].kod;\r
+           end else\r
+            blad(zm,12);\r
+\r
+    else\r
+     if (mne.l=0) and not(aray) and not(struct.use) and not(enum.use) then blad(zm,12);\r
+    end;\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  sprawdzamy czy wystapila deklaracja lokalna etykiety                      *)\r
+(*  znak '=' moze zastepowac EQU, nie musi byc poprzedzony "bialymi spacjami" *)\r
+(*  znaki '+=' , '-=' zastepuja dodawanie i odejmowanie wartosci od etykiety  *)\r
+(*  znaki '--' , '++' zastepuja zmniejszanie i zwiekszanie wartosci etykiety  *)\r
+(*----------------------------------------------------------------------------*)\r
+  tmpZM:=zm;\r
+\r
+  if zm[i] in ['+','-'] then\r
+   if (ety<>'') and (zm[i+1] in ['+','-','=']) then\r
+    operator_zlozony(i,zm,ety, false)\r
+   else\r
+    blad(zm,4);\r
+\r
+  if (zm[i]='=') and not(aray) and not(struct.use) and not(enum.use) then begin\r
+   mne.l:=__addEqu; __inc(i,zm);                // wymuszamy wykonanie __addEQU\r
+\r
+   save_lst(' ');\r
+\r
+   goto JUMP;\r
+  end;\r
+\r
+\r
+  if ifelse>0 then save_lst(' ');\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  znak okreslajacy liczbe powtorzen linii ':'                               *)\r
+(*----------------------------------------------------------------------------*)\r
+   if (zm[i]=':') then begin\r
+    save_lst('a');\r
+\r
+    inc(i);\r
+    loop_used:=true;\r
+\r
+    txt:=get_dat(i,zm,',',true);\r
+    _doo:=integer( oblicz_wartosc(txt,zm) );\r
+    testRange(zm, _doo, 0);\r
+\r
+\r
+    old_rept    := ___rept_ile;\r
+    ___rept_ile := 0;\r
+\r
+\r
+  // test obecnosci czegokolwiek\r
+    k:=i;  txt:=get_datUp(i,zm,#0,true);  i:=k;\r
+\r
+    if struct.use then begin\r
+\r
+     rpt:=_doo;\r
+     omin_spacje(i,zm);\r
+\r
+    end else begin\r
+\r
+      old_case  := FOX_ripit;\r
+      FOX_ripit := true;        // zwracamy wartosc licznika petli dla '#'\r
+\r
+      indeks    := line_add;\r
+\r
+\r
+      save_lab(ety,adres,bank,zm);\r
+\r
+      idx:=High(t_mac);\r
+\r
+      txt:=get_dat(i,zm,'\',false);\r
+      save_mac(txt);\r
+\r
+      line_add:=line-1;\r
+\r
+      _odd := idx+1;\r
+      analizuj_mem__(idx,_odd, zm,a,old_str, 0,_doo, false);\r
+\r
+\r
+      loop_used := false;\r
+\r
+      FOX_ripit := old_case;\r
+\r
+      line_add  := indeks;\r
+\r
+\r
+      SetLength(t_mac,idx+1);\r
+\r
+      mne.l:=__nill;\r
+      ety:='';\r
+    end;\r
+\r
+    ___rept_ile := old_rept;\r
+\r
+   // FOX_ripit := false;\r
+   end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  sprawdzamy czy to dyrektywa, tylko niektore dyrektywy moga byc petlone:   *)\r
+(*  .PRINT, .BYTE, .WORD, .LONG, .DWORD, .GET, .PUT, .HE, .BY, .WO, .SB, .FL  *)\r
+(*  innych dyrektyw nie mozemy powtarzac                                      *)\r
+(*----------------------------------------------------------------------------*)\r
+   if zm[i]='.' then begin\r
+\r
+    tmp:=get_directive(i,zm);\r
+\r
+    mne.l:=fCRC16(tmp);\r
+\r
+    if not(mne.l in [__macro..__over]) then\r
+     blad_und(zm,tmp,68)\r
+    else\r
+     if loop_used then\r
+      if not(mne.l in [__byte..__dword, __print, __sav, __get, __put, __he, __by, __wo, __sb, __fl]) then blad(zm,36);\r
+\r
+   end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  zamiana IFT ELS EIF ELI na ich odpowiedniki .IF .ELSE .ENDIF .ELSEIF      *)\r
+(*  zostala zrealizowane przez modyfikacje tablicy HASH                       *)\r
+(*  podobnie dyrektywy .DB i .DW wskazuja na .BYTE i .WORD                    *)\r
+(*  !!! koniecznie tylko w tym miejscu, w innym kod nie zostanie wykonany !!! *)\r
+(*----------------------------------------------------------------------------*)\r
+  if UpCase(zm[i]) in ['E','I'] then begin\r
+\r
+    j:=i;\r
+    txt:=get_datUp(i,zm,#0,false);\r
+    v:=fASC(txt);               \r
+\r
+    if length(txt)<>3 then\r
+     i:=j\r
+    else\r
+     if not(v in [__if,__else,__endif,__elseif]) then\r
+      i:=j\r
+     else\r
+      mne.l:=v;\r
+\r
+  end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  zamiana dyrektywy .OR na pseudo rozkaz ORG                                *)\r
+(*  obsluga dyrektywy .NOWARN                                                 *)\r
+(*----------------------------------------------------------------------------*)\r
+  case mne.l of\r
+\r
+       __or: mne.l:=__org;\r
+\r
+   __nowarn: begin\r
+              noWarning:=true;\r
+              mne.l:=0;\r
+\r
+//              omin_spacje(i,zm);       // !!! tutaj omijanie spacji niedopuszczalne !!!\r
+              goto LOOP\r
+             end;\r
+\r
+  end;\r
+\r
+\r
+\r
+  if not(skip.hlt) then test_skipa;\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  odczytaj mnemonik                                                         *)\r
+(*----------------------------------------------------------------------------*)\r
+  if (mne.l=0) and if_test and not(enum.use) then\r
+   if i<=length(zm) then mne:=oblicz_mnemonik(i,zm,zm);\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  odczyt etykiet wystepujacych w bloku .ENUM                                *)\r
+(*----------------------------------------------------------------------------*)\r
+  if enum.use then\r
+   if (ety<>'') and (mne.l=0) then begin\r
+\r
+    i:=1;\r
+\r
+    get_parameters(i,zm,par,false, '.',':');\r
+\r
+    old_case   := dreloc.use;   // deklaracje etykiet w bloku .RELOC nie moga byc relokowalne\r
+    dreloc.use := false;\r
+\r
+    if High(par)>1 then begin\r
+      save_lst(' ');\r
+      justuj;\r
+      put_lst(t+zm);\r
+    end;\r
+\r
+    for _odd:=0 to High(par)-1 do begin\r
+     txt:=par[_odd];\r
+\r
+     k:=1;  ety:=get_lab(k, txt, false);   // sprawdzamy czy etykieta posiada poprawne znaki\r
+     if ety='' then blad_ill(zm,txt[1]);   // pierwszy znak etykiety jest niewlasciwy\r
+\r
+     if txt[k]='=' then begin\r
+       str:=copy(txt,k+1,length(txt));\r
+\r
+       enum.val:=oblicz_wartosc(str,zm);\r
+     end else\r
+      if not(test_char(k,txt,#0,#0)) then blad_ill(zm,txt[k]);  // wystapil niedozwolony znak\r
+\r
+\r
+     label_type:='C';\r
+\r
+     branch:=true;                         // dla etykiet .ENUM nie ma relokowalnosci\r
+\r
+     save_lab(ety, enum.val, bank, zm);\r
+\r
+     bez_lst:=true;\r
+\r
+     if enum.val>enum.max then enum.max:=enum.val;    // MAX dla okreslenia rozmiaru ENUM\r
+\r
+     nul.i:=integer( enum.val );\r
+     save_lst('l');\r
+\r
+     if High(par)=1 then\r
+      zapisz_lst(zm)\r
+     else\r
+      zapisz_lst(ety);\r
+\r
+     inc(enum.val);\r
+    end;\r
+\r
+    dreloc.use := old_case;\r
+\r
+    nul.i:=0;\r
+\r
+    ety:='';\r
+   end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  dodatkowy test dla etykiet w bloku .STRUCT                                *)\r
+(*----------------------------------------------------------------------------*)\r
+  if struct.use then\r
+   if (ety<>'') and (mne.l=0) then begin\r
+\r
+    idx:=l_lab(ety);\r
+\r
+    if idx<0 then begin\r
+     if pass=pass_end then blad(zm,58)\r
+    end else\r
+     if t_lab[idx].bnk=__id_struct then begin\r
+       mne.l := __struct_run_noLabel;\r
+       mne.i := t_lab[idx].adr;\r
+     end else\r
+      if pass=pass_end then blad(zm,58);\r
+\r
+   end;\r
+\r
+   \r
+JUMP_2:\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .END                                                                      *)\r
+(*  zastepuje inne dyrektywy .END?                                            *)\r
+(*----------------------------------------------------------------------------*)\r
+ if mne.l=__dend then\r
+  if end_idx=0 then\r
+   blad(zm,72)\r
+  else\r
+   mne.l:=t_end[end_idx-1].kod;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  specjalna forma definicji wartosci etykiety tymczasowej za pomoca znakow  *)\r
+(*  '=' , '+=' , '-=' , '++' , '--'                                           *)\r
+(*----------------------------------------------------------------------------*)\r
+ if mne.l=__addEqu then begin\r
+  ety:=get_lab(i,zm, true);\r
+\r
+  omin_spacje(i,zm);\r
+\r
+  tmpZM:=zm;\r
+\r
+  if UpCase(zm[i])='E' then\r
+   inc(i,2)\r
+  else\r
+   if zm[i] in ['+','-'] then operator_zlozony(i,zm,ety, false);\r
+\r
+  __inc(i,zm);\r
+ end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  laczenie mnemonikow za pomoca znaku ':', w stylu XASM'a                   *)\r
+(*----------------------------------------------------------------------------*)\r
+  if mne.l=__xasm then begin\r
+\r
+   save_lab(ety,adres,bank,zm);\r
+\r
+   if (pass=pass_end) and skip.use then warning(98);    // Skipping only the first instruction\r
+\r
+   save_lst('a');\r
+\r
+   loop_used := true;\r
+\r
+   old_case  := case_used;            // nie mozemy zamieniac na duze litery\r
+   case_used := true;                 // zachowujemy ich oryginalna wielkosc (CASE_USED=TRUE)\r
+\r
+   skip.hlt  := true;    \r
+\r
+\r
+   k:=mne.i;\r
+   ety:=get_dat(k,zm,'\',false);      // odczytujemy argumenty\r
+\r
+   case_used := old_case;             // przywracamy stara wartosc CASE_USED\r
+\r
+   line_add:=line-1;                  // numer linii aktualnie przetwarzanej\r
+                                      // przyda sie jesli wystapi blad\r
+\r
+   idx:=High(t_mac);                  // indeks do wolnego wpisu w T_MAC\r
+\r
+   while true do begin                // petla bez konca ;)\r
+\r
+    old_case  := case_used;           // tutaj takze musimy zachowac wielkosc liter\r
+    case_used := true;                // dlatego wymuszamy CASE_USED=TRUE\r
+\r
+    txt:=get_dat(i,zm,':',true);      // odczytujemy mnemonik rozdzielony znakiem ':'\r
+\r
+    case_used := old_case;            // przywracamy stara wartosc CASE_USED\r
+\r
+      str:=' '+txt+ety;               // preparujemy nowa linie do analizy\r
+      t_mac[idx]:=str;                // zapisujemy ja w T_MAC[IDX]\r
+\r
+      test_skipa;\r
+\r
+      _odd := idx+1;\r
+      analizuj_mem__(idx,_odd, zm,a,old_str, 0,1, false);\r
+\r
+    if zm[i]=':' then inc(i) else Break;   // tutaj konczymy petle jesli brak ':'\r
+   end;\r
+\r
+   wymus_zapis_lst(zm);\r
+\r
+   line_add:=0;              // koniecznie zerujemy LINE_ADD\r
+\r
+   if not(FOX_ripit) then bez_lst   := true;\r
+\r
+   loop_used := false;\r
+\r
+   skip.hlt  := false;\r
+\r
+   skip.xsm  := true;        // wystapilo laczenie mnemonikow przez ':'\r
+\r
+   mne.l:=__nill;\r
+   ety:='';\r
+  end else\r
+   if not(mne.l in [0,__nill]) then skip.xsm:=false;    // nie wystapilo laczenie mnemonikow przez ':'  (default)\r
+\r
+   \r
+JUMP:\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  jesli mamy uruchomione makro to zapisz jego zawartosc do pliku LST        *)\r
+(*  puste linie nie sa zapisywane, !!! w tej postaci dziala najlepiej !!!     *)\r
+(*----------------------------------------------------------------------------*)\r
+  if run_macro and if_test then\r
+   if ety<>'' then data_out:=true;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  BLK (kody __blkSpa, __blkRel, __blkEmp)                                   *)\r
+(*----------------------------------------------------------------------------*)\r
+ if mne.l=__blk then\r
+ if ety<>'' then blad(zm,38) else\r
+ if loop_used then blad(zm,36) else begin\r
+\r
+  empty:=false;\r
+\r
+  txt:=get_datUp(i,zm,#0,true);\r
+\r
+  case UpCase(txt[1]) of\r
+  //BLK D[os] a\r
+  'D': mne.l := __org;\r
+\r
+  //BLK S[parta] a\r
+  'S': mne.l := __blkSpa;\r
+\r
+  //BLK R[eloc] M[ain]|E[xtended]\r
+  'R': mne.l := __blkRel;\r
+\r
+  //BLK E[mpty] a M[ain]|E[xtended]\r
+  'E': begin mne.l := __blkEmp; empty:=true end;\r
+\r
+  //BLK N[one] a\r
+  'N': begin mne.l := __org;  opt_h_minus end;\r
+\r
+  //BLK U[pdate] A[ddress]\r
+  //BLK U[pdate] E[xternal]\r
+  //BLK U[pdate] S[ymbols]\r
+  //BLK U[pdate] N[ew] address text\r
+  'U':\r
+    if pass=pass_end then begin\r
+\r
+     oddaj_var;\r
+\r
+     oddaj_ds;\r
+\r
+     txt:=get_datUp(i,zm,#0,true);\r
+\r
+     save_lst('a');\r
+\r
+     _doo:=0;    // liczba adresow do relokacji\r
+     _odd:=0;    // liczba symboli do relokacji\r
+\r
+     for idx:=0 to rel_idx-1 do\r
+      if t_rel[idx].idx>=0 then inc(_odd) else\r
+       if t_rel[idx].idx=-1 then inc(_doo);\r
+\r
+     case UpCase(txt[1]) of\r
+\r
+      'A': begin                       // A[ddress]\r
+            if not(blkupd.adr) then\r
+             if (_doo>0) or dreloc.use then blk_update_address(zm);\r
+            blkupd.adr:=true;\r
+           end;\r
+\r
+      'E': begin                       // E[xternal]\r
+            if not(blkupd.ext) then blk_update_external(zm);\r
+            blkupd.ext:=true;\r
+           end;\r
+\r
+      'P': begin                       // P[ublic]\r
+            if not(blkupd.pub) then blk_update_public(zm);\r
+            blkupd.pub:=true;\r
+           end;\r
+\r
+      'S': begin                       // S[ymbol]\r
+            if not(blkupd.sym) then\r
+             if _odd>0 then blk_update_symbol(zm);\r
+            blkupd.sym:=true;\r
+           end;\r
+\r
+      'N': begin                       // N[ew]\r
+            test_symbols := true;\r
+            blk_update_new(i,zm);\r
+           end;\r
+\r
+     else\r
+      blad(zm,23);\r
+     end;\r
+\r
+    end;\r
+\r
+  else\r
+   blad(zm,0);\r
+  end;\r
+\r
+ end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .DS expression                                                            *)\r
+(*  rezerwujemy "expression" bajtow bez ich inicjalizowania                   *)\r
+(*----------------------------------------------------------------------------*)\r
+ if (mne.l=__ds) and (macro_rept_if_test) then begin\r
+\r
+ // po zmianie adresu asemblacji bloku .PROC, .LOCAL nie ma mo¿liwosci u¿ywania dyrektywy .DS\r
+\r
+   if (org_ofset>0) then blad(zm,71);\r
+\r
+   nul.i:=integer( adres );\r
+   save_lst('l');\r
+\r
+   branch:=true;\r
+   save_lab(ety,adres,bank,zm);\r
+\r
+   _doo:=integer( oblicz_wartosc_noSPC(zm,zm,i,#0,'A') );\r
+\r
+   if dreloc.sdx or dreloc.use then begin\r
+    empty:=true;\r
+    inc(ds_empty, _doo);\r
+\r
+    inc(adres, _doo);\r
+   end else begin\r
+\r
+    txt:=zm;                   // !!! tylko tutaj wymuszamy zapis do LST !!!\r
+    zapisz_lst(txt);\r
+\r
+    NoAllocVar:=true;          // dla .DS nie ma alokacji zmiennych .VAR \r
+    mne.l:=__org;              // teraz mozemy wymusic ORG *+\r
+\r
+    zm:='*+'+IntToStr(_doo);\r
+    i:=1;\r
+\r
+    bez_lst:=true;        \r
+   end;\r
+\r
+   ety:='';\r
+ end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  [label] .ALIGN N[,fill]                                                   *)\r
+(*----------------------------------------------------------------------------*)\r
+ if (mne.l=__align) and (macro_rept_if_test) then begin\r
+\r
+  if loop_used then blad(zm,36);\r
+\r
+  save_lst('a');\r
+\r
+  omin_spacje(i,zm);\r
+\r
+  if test_char(i,zm,#0,#0) then\r
+   _doo:=$100\r
+  else\r
+   _doo:=integer( oblicz_wartosc_noSPC(zm,zm,i,',','A') );\r
+\r
+\r
+  _odd:=-1;\r
+\r
+  if zm[i]=',' then begin\r
+   __inc(i,zm);\r
+\r
+   _odd:=integer( oblicz_wartosc_noSPC(zm,zm,i,',','B') );\r
+  end;\r
+\r
+\r
+  if _doo>0 then\r
+   idx:=(adres div _doo)*_doo\r
+  else\r
+   idx:=adres;\r
+\r
+  if idx<>adres then inc(idx, _doo);\r
+\r
+\r
+  if _odd>=0 then begin\r
+\r
+   if pass=pass_end then begin\r
+    while idx>adres do begin save_dst(byte(_odd)); inc(adres) end;\r
+   end else\r
+    adres:=idx;\r
+\r
+  end else begin                     // wymuszenie ORG\r
+\r
+   justuj;\r
+   put_lst(t+zm);\r
+\r
+   bez_lst:=true;\r
+\r
+   zm:='$'+hex(idx,4);\r
+\r
+   NoAllocVar:=true;                // dla .ALIGN nie ma alokacji zmiennych .VAR\r
+   mne.l:=__org;\r
+\r
+   i:=1;\r
+  end;\r
+\r
+ end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  NMB [adres]                                                               *)\r
+(*  RMB [adres]                                                               *)\r
+(*  LMB #expression [,adres]                                                  *)\r
+(*----------------------------------------------------------------------------*)\r
+ if macro_rept_if_test then begin\r
+\r
+  ch:=' ';              // CH bedzie zawieral znak dyrektywy 'N'MB, 'R'MB, 'L'MB\r
+\r
+  case mne.l of\r
+\r
+   __nmb: begin\r
+           inc(bank);   // zwiekszamy licznik bankow MADS'a\r
+\r
+           ch:='N';\r
+          end;\r
+\r
+   __rmb: begin\r
+           bank:=0;     // zerujemy licznik bankow MADS'a\r
+\r
+           ch:='R';\r
+          end;\r
+\r
+   __lmb: begin         // ustawiamy licznik bankow MADS'a\r
+           omin_spacje(i,zm);\r
+//           if zm[i] in ['<','>'] then else                  // znaki '<', '>' sa akceptowane\r
+           if zm[i]<>'#' then blad(zm,14) else __inc(i,zm); // pozostale znaki inne niz '#' to blad\r
+\r
+           txt:=get_dat_noSPC(i,zm,' ',#0,zm);\r
+           k:=1; j:=integer( ___wartosc_noSPC(txt,zm,k,',','B') );  // wartosc licznika bankow = 0..255\r
+\r
+           bank:=integer( j );\r
+\r
+           ch:='L';\r
+          end;\r
+\r
+  end;\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  wymuszamy wykonanie makra @BANK_ADD (gdy OPT B+) dla LMB, NMB, RMB        *)\r
+(*----------------------------------------------------------------------------*)\r
+ if ch<>' ' then begin\r
+\r
+  if dreloc.use or dreloc.sdx then blad(zm,71);\r
+  if first_org then blad(zm,10);\r
+\r
+  save_lst('i');\r
+\r
+  if opt and $80>0 then begin\r
+\r
+   omin_spacje(i,zm);\r
+   if zm[i]=',' then __inc(i,zm);\r
+\r
+   str:=get_dat_noSPC(i,zm,' ',#0,zm);\r
+   if str<>'' then str:=','+str;\r
+\r
+   wymus_zapis_lst(zm);\r
+\r
+   txt:='@BANK_ADD '''+ch+''''+str;\r
+   i:=1; mne:=oblicz_mnemonik(i,txt,zm);\r
+   zm:=txt;\r
+  end;\r
+\r
+ end;\r
+\r
+ end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  wykonaj .PROC gdy PASS>0                                                  *)\r
+(*  wymus wykonanie makra @CALL jesli procedura miala parametry               *)\r
+(*  jesli procedura zostaje wywolana z poziomu innej procedury zapamietaj     *)\r
+(*  parametry procedury na stosie nie modyfikujac wskaznika stosu,            *)\r
+(*  a po powrocie przywroc je takze nie modyfikujac wskaznika stosu           *)\r
+(*----------------------------------------------------------------------------*)\r
+  if mne.l=__proc_run then\r
+   if macro_rept_if_test then begin\r
+\r
+     save_lab(ety,adres,bank,zm);\r
+\r
+     indeks:=mne.i;\r
+\r
+     idx:=t_prc[indeks].par;          // liczba parametrow\r
+\r
+    if idx>0 then begin\r
+    \r
+     wymus_zapis_lst(zm);\r
+\r
+     ety:='';\r
+     str:='';\r
+\r
+\r
+   // jesli nastepuje wywolanie procedury typu T_PRC[].TYP=__pDef, ktora posiada parametry (IDX>0)\r
+   // z ciala aktualnie przetwarzanej procedury PROC_NR-1\r
+   // to odlozymy na stos parametry procedury aktualnej, a po powrocie przywrocimy je\r
+\r
+     if proc and (t_prc[indeks].typ=__pDef) then begin\r
+      _doo:=t_prc[proc_nr-1].ile;                     // liczba bajtow przypadajaca na parametry\r
+\r
+      if _doo>0 then begin\r
+       //str:=copy(proc_name,1,length(proc_name)-1);  // obcinamy ostatnia kropke w nazwie aktualnej procedury\r
+       str:=proc_name;\r
+       SetLength(str,length(proc_name)-1);\r
+\r
+       ety:=' @PUSH ''I'','+IntToStr(_doo)+' \ ';\r
+       str:=' \ @PULL ''J'','+IntToStr(_doo);\r
+      end;\r
+\r
+     end;\r
+\r
+\r
+     rodzaj := t_prc[indeks].typ;  // rodzaj procedury, sposobu przekazywania parametrow\r
+   \r
+     get_parameters(i,zm,par,false, '.',':');\r
+\r
+\r
+     // sprawdzamy liczbe przekazanych parametrow, jesli ich liczba sie nie zgadza to\r
+     // wystapi blad 'Improper number of actual parameters'\r
+     // w przypadku procedur typu __pReg, __pVar moze byc mniej parametrow, ale nie wiecej\r
+\r
+       _doo:=High(par);\r
+\r
+       for _odd:=_doo-1 downto 0 do begin\r
+\r
+        txt:=par[_odd];\r
+\r
+        if txt='' then\r
+         if rodzaj=__pDef then\r
+          blad(zm,40)\r
+         else\r
+          txt:=';';                       // dla __pReg mozemy pomijac parametry\r
+\r
+        if (txt[1]='"') and (length(txt)>2) then txt:=copy(txt,2,length(txt)-2);\r
+\r
+        par[_odd]:=txt;\r
+       end;\r
+\r
+\r
+     // sprawdz typ parametrow i wymus wykonanie makra @CALL_INIT, @CALL, @CALL_END\r
+     // parametrem @CALL_INIT jest liczba bajtow zajmowanych przez parametry procedury\r
+\r
+       case rodzaj of\r
+     __pDef: begin\r
+              if _doo<>idx then blad(zm,40);\r
+              ety:=ety+' @CALL '+#39+'I'+#39+','+IntToStr(t_prc[indeks].ile);\r
+             end;\r
+\r
+     __pReg, __pVar:\r
+             begin\r
+              if _doo>idx then\r
+               blad(zm,40)\r
+              else\r
+               if (pass=pass_end) and (_doo<idx) then warning(40);\r
+\r
+              ety:=ety+' ';\r
+             end;\r
+       end;\r
+\r
+\r
+       idx:=t_prc[indeks].str;       // indeks do nazw parametrow w T_PAR\r
+\r
+\r
+      if _doo>0 then\r
+       for k:=0 to _doo-1 do\r
+        if par[k][1]<>';' then begin\r
+\r
+         txt:=par[k];\r
+\r
+         case rodzaj of\r
+          __pDef: ety:=ety+' \ @CALL ';\r
+         end;\r
+\r
+         ch:=' ';\r
+         v:=byte(' ');\r
+\r
+         if txt='@' then begin\r
+//          ety:=ety+#39+'@'+#39+',';\r
+          v:=byte('@');\r
+          war:=0;\r
+          ch:='Z';\r
+         end else\r
+          if txt[1]='#' then begin\r
+//           ety:=ety+#39+'#'+#39+',';\r
+           v:=byte('#');\r
+           branch:=true;\r
+           tmp:=copy(txt,2,length(txt));\r
+           war:=oblicz_wartosc(tmp,zm);\r
+           ch:=value_code(war,zm,true);\r
+          end;\r
+\r
+       // typ parametru w deklaracji procedury (B,W,L,D)\r
+       // funkcja VALUE_CODE zwrocila typ parametru (Z,Q,T,D)\r
+        tmpZM:=copy(t_par[idx+k],2,length(t_par[idx+k]));\r
+\r
+        if ch<>' ' then\r
+          case t_par[idx+k][1] of\r
+           'B': if ch<>'Z' then blad_und(zm,tmpZM,41);\r
+           'W': if (ch in ['T','D']) or (txt='@') then blad_und(zm,tmpZM,41); \r
+          end;\r
+\r
+\r
+     if rodzaj<>__pVar then\r
+      if txt[1]='#' then txt[1]:=' ';\r
+\r
+\r
+     case rodzaj of\r
+       __pDef: ety:=ety+#39+chr(v)+#39+',';\r
+\r
+       __pReg: case chr(v) of\r
+                '#': case t_par[idx+k][1] of     // przez wartosc\r
+                      'B': ety:=ety+'LD'+t_par[idx+k][2]+'#'+txt;\r
+                      'W': ety:=ety+'LD'+t_par[idx+k][2]+'>'+txt + '\ LD'+t_par[idx+k][3]+'<'+txt;\r
+                      'L': ety:=ety+'LD'+t_par[idx+k][2]+'^'+txt + '\ LD'+t_par[idx+k][3]+'>'+txt + '\ LD'+t_par[idx+k][4]+'<'+txt;\r
+                     end;\r
+\r
+                ' ': case t_par[idx+k][1] of     // przez adres\r
+                      'B': ety:=ety+'LD'+t_par[idx+k][2]+' '+txt;\r
+                      'W': ety:=ety+'LD'+t_par[idx+k][2]+' '+txt + '+1\ LD'+t_par[idx+k][3]+' '+txt;\r
+                      'L': begin\r
+                            ety:=ety+'LD'+t_par[idx+k][2]+' '+txt + '+2\ LD'+t_par[idx+k][3]+' '+txt + '+1\ LD'+t_par[idx+k][4]+' '+txt;\r
+                            if dreloc.use then warning(86);    // typ 'L' nie jest relokowalny\r
+                           end;\r
+                     end;\r
+\r
+                '@': if t_par[idx+k][2]<>'A' then ety:=ety+'TA'+t_par[idx+k][2];\r
+               end;\r
+\r
+       __pVar: case chr(v) of\r
+                '#',' ': case t_par[idx+k][1] of      // przez wartosc '#' lub wartosc spod adresu ' '\r
+                          'B': ety:=ety+'MVA '+txt+' '+tmpZM;\r
+                          'W': ety:=ety+'MWA '+txt+' '+tmpZM;\r
+                          'L': case chr(v) of\r
+                                '#': begin\r
+                                      txt[1]:='(';  txt:='#'+txt+')';\r
+                                      ety:=ety+' MWA '+txt+'&$FFFF '+tmpZM+'\';\r
+                                      ety:=ety+' MVA '+txt+'>>16 '+tmpZM+'+2\';\r
+                                     end;\r
+\r
+                                ' ': begin\r
+                                      ety:=ety+' MWA '+txt+' '+tmpZM+'\';\r
+                                      ety:=ety+' MVA '+txt+'+2 '+tmpZM+'+2';\r
+                                     end;\r
+                               end;\r
+                          'D': case chr(v) of\r
+                                '#': begin\r
+                                      txt[1]:='(';  txt:='#'+txt+')';\r
+                                      ety:=ety+' MWA '+txt+'&$FFFF '+tmpZM+'\';\r
+                                      ety:=ety+' MWA '+txt+'>>16 '+tmpZM+'+2\';\r
+                                     end;\r
+\r
+                                ' ': begin\r
+                                      ety:=ety+' MWA '+txt+' '+tmpZM+'\';\r
+                                      ety:=ety+' MWA '+txt+'+2 '+tmpZM+'+2';\r
+                                     end;\r
+                               end;\r
+                         end;\r
+\r
+                    '@': ety:=ety+'STA '+tmpZM;\r
+               end;\r
+     end;\r
+\r
+\r
+         if rodzaj=__pDef then begin\r
+          ety:=ety+#39+t_par[idx+k][1]+#39+',';\r
+          if txt[1] = '@' then ety:=ety+'0' else ety:=ety+'"'+txt+'"';\r
+         end else ety:=ety+'\ ';\r
+\r
+        end;\r
+\r
+     if rodzaj=__pDef then\r
+      txt:=ety+' \ @CALL '+#39+'X'+#39+','+t_prc[indeks].nam + ' \ @EXIT '+IntToStr(t_prc[indeks].ile) + str\r
+     else\r
+      txt:=ety+'JSR '+t_prc[indeks].nam;\r
+\r
+     k:=line_add;\r
+\r
+     line_add:=line-1;\r
+\r
+     _odd:=High(t_mac);                      // procedura z parametrami\r
+     t_mac[_odd]:=txt;                       // wymuszamy wykonanie wiêkszej liczby linii\r
+     _doo:=_odd+1;\r
+     analizuj_mem__(_odd,_doo, zm,a,old_str, 0,1, false);\r
+\r
+     line_add:=k;\r
+\r
+     bez_lst:=true;\r
+\r
+    end else begin\r
+     txt:='JSR '+ t_prc[indeks].nam;         // procedura bez parametrow\r
+     i:=1; mne:=oblicz_mnemonik(i,txt,zm);   // wymuszamy wykonanie jednej linii z JSR\r
+    end;\r
+\r
+     ety:='';\r
+    end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .ERROR [ERT] 'text' | .ERROR [ERT] expression                             *)\r
+(*----------------------------------------------------------------------------*)\r
+   if (mne.l in [__error,__ert]) and macro_rept_if_test then\r
+     if pass=pass_end then begin\r
+\r
+        save_lst(' ');\r
+\r
+        txt:=get_string(i,zm,txt,true);\r
+\r
+        if txt<>'' then begin\r
+\r
+         if not(run_macro) then\r
+          writeln(zm)\r
+         else\r
+          writeln(old_str);\r
+\r
+         str:=end_string;  end_string:='';\r
+\r
+         wypisz(i,zm);               // !!! modyfikowana jest zmienna ZM !!!\r
+\r
+         txt:=txt+end_string;\r
+\r
+         end_string:=str;\r
+\r
+         blad(txt,34);\r
+\r
+        end else begin\r
+\r
+          branch := true;             // tutaj nie ma mowy o relokowalnosci\r
+          war:=___wartosc_noSPC(zm,zm,i,',','F');\r
+\r
+          if war<>0 then begin\r
+\r
+           if not(run_macro) then\r
+            writeln(zm)\r
+           else\r
+            writeln(old_str);\r
+\r
+           str:=end_string;  end_string:='';\r
+\r
+           wypisz(i,zm);             // !!! modyfikowana jest zmienna ZM !!!\r
+\r
+           if end_string='' then\r
+            txt:=load_mes(30+1)      // User error\r
+           else\r
+            txt:=end_string;\r
+\r
+           end_string:=str;\r
+\r
+           blad(txt,34);\r
+          end;\r
+\r
+        end;\r
+\r
+      end else\r
+       mne.l:=__nill;\r
+\r
+      \r
+(*----------------------------------------------------------------------------*)\r
+(*  .EXIT                                                                     *)\r
+(*----------------------------------------------------------------------------*)\r
+  if (mne.l=__exit) and macro_rept_if_test then\r
+    if not(run_macro) then blad(zm,58) else begin\r
+\r
+     save_lab(ety,adres,bank,zm);\r
+     save_lst(' ');\r
+\r
+     wymus_zapis_lst(zm);\r
+\r
+     run_macro:=false;\r
+\r
+     wyjscie:=true;\r
+\r
+     ety:='';\r
+\r
+     exit;\r
+    end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .ENDP                                                                     *)\r
+(*----------------------------------------------------------------------------*)\r
+  if (mne.l=__endp) and macro_rept_if_test then \r
+     if ety<>'' then blad(zm,38) else\r
+      if not(proc) then blad(zm,39) else begin\r
+\r
+       save_lst(' ');\r
+\r
+       oddaj_var;\r
+\r
+       oddaj_lokal(zm);\r
+\r
+       t_prc[proc_nr-1].len := cardinal(adres) - t_prc[proc_nr-1].adr;\r
+\r
+\r
+       proc_nr := t_prc[proc_nr-1].pnr;   // !!! koniecznie ta kolejnosc inaczej zawsze PROC_NR=0 !!!\r
+\r
+       get_address_update;\r
+\r
+       proc      := t_prc[proc_nr].prc;\r
+       org_ofset := t_prc[proc_nr].oof;\r
+       proc_name := t_prc[proc_nr].pnm;\r
+\r
+      end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  label .PROC [label]                                                       *)\r
+(*  jesli wystepuja parametry ograniczone nawiasami '()' to zapamietaj je     *)\r
+(*----------------------------------------------------------------------------*)\r
+  if (mne.l=__proc) and macro_rept_if_test then\r
+   if adres<0 then blad(zm,10) else   \r
+         begin\r
+\r
+          if ety='' then ety:=get_lab(i,zm, true);\r
+\r
+          save_lst('a');\r
+          txt:=zm; zapisz_lst(txt);\r
+          bez_lst:=true;\r
+                                  \r
+          label_type:='P';\r
+\r
+          if not(proc) then\r
+           ety:=lokal_name+ety\r
+          else\r
+           ety:=proc_name+ety;\r
+\r
+          zapisz_lokal;\r
+          lokal_name:='';\r
+\r
+\r
+          t_prc[proc_idx].prc := proc;\r
+          t_prc[proc_idx].pnr := proc_nr;\r
+          t_prc[proc_idx].oof := org_ofset;\r
+          t_prc[proc_idx].pnm := proc_name;\r
+\r
+          proc_nr:=proc_idx;     // koniecznie przez ADD_PROC_NR\r
+\r
+\r
+          get_address(i,zm);     // pobieramy nowy adres asemblacji dla .PROC\r
+\r
+\r
+          save_end(__endp);\r
+\r
+          \r
+          proc_lokal:=end_idx;   // koniecznie po SAVE_END, nie wczesniej\r
+\r
+          save_lst('a');  proc_name:='';\r
+\r
+          if (pass=pass_end) and not(exclude_proc) and not(dreloc.use) then\r
+           if not(t_prc[proc_nr].use) then blad_und(zm,ety,69);\r
+\r
+\r
+          txt:=zm;   // jesli TXT<>ZM to UPD_PROCEDURE zmodyfikowala ZM jakims makrem \r
+\r
+          if pass=0 then\r
+           get_procedure(ety,ety,zm ,i)       // zapamietujemy parametry procedury\r
+          else\r
+           upd_procedure(ety,zm,adres);       // uaktualniamy adresy procedury\r
+\r
+\r
+          add_proc_nr;                        // nowa wartosc PROC_NR, PROC_IDX\r
+\r
+\r
+          if (txt<>zm) and proc {and (pass>0)} then begin\r
+            save_lst(' ');\r
+            i:=1; mne:=oblicz_mnemonik(i,zm,zm);\r
+          end;\r
+\r
+          proc      := true;\r
+\r
+          proc_name := ety+'.';\r
+\r
+          ety:=''\r
+         end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  wykonaj .STRUCT (np. deklaracja pola struktury za pomoca innej struktury) *)\r
+(*  mo¿liwe jest przypisanie pol zdefiniowanych przez strukture nowej zmiennej*)\r
+(*----------------------------------------------------------------------------*)\r
+  if mne.l in [__struct_run, __struct_run_noLabel, __enum_run] then\r
+   if ety='' then blad(zm,15) else\r
+    if macro_rept_if_test then begin\r
+\r
+     if (mne.l=__enum_run) and struct.use then\r
+      mne.l:=__byteValue+mne.i                  // typ wyliczeniowy na rozmiar w bajtach\r
+     else begin\r
+      create_struct_variable(zm, ety, mne, true, adres);\r
+      ety:='';\r
+     end;\r
+\r
+    end;\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*----------------------------------------------------------------------------*)\r
+(*----------------------------------------------------------------------------*)\r
+\r
+\r
+  case mne.l of\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  wykonaj .MACRO gdy PASS>0                                                 *)\r
+(*----------------------------------------------------------------------------*)\r
+  __macro_run:\r
+//        if macro then halt {inc(macro_nr)} else\r
+        if if_test then begin\r
+\r
+         save_lab(ety,adres,bank,zm);\r
+\r
+         if not(FOX_ripit) then save_lst('i');\r
+\r
+         txt:=zm;\r
+         zapisz_lst(txt);\r
+\r
+         indeks:=mne.i;\r
+\r
+         old_komentarz:=komentarz;\r
+\r
+       // zapamietujemy aktualne makro w 'OLD_MACRO_NR'\r
+\r
+         old_macro_nr:=macro_nr;\r
+         \r
+         txt:=t_mac[indeks+1];\r
+         str:='Macro: '+txt+' [Source: '+t_mac[indeks+0]+']';\r
+\r
+       // !!! nazwa obszaru LOCAL powtorzy sie 2x - KONIECZNIE !!!\r
+         if macro_nr='' then\r
+          macro_nr:=macro_nr+lokal_name+proc_name+txt+t_mac[indeks+3]+'.'\r
+         else\r
+          macro_nr:=macro_nr+proc_name+txt+t_mac[indeks+3]+'.';\r
+\r
+         omin_spacje(i,zm);  SetLength(par,2);\r
+        // na pozycji par[0] zostanie wpisana liczba parametrow\r
+\r
+         k:=ord(t_mac[indeks+2][1]);      // tryb pracy\r
+         ch:=t_mac[indeks+2][2];          // separator\r
+\r
+\r
+         while not(test_char(i,zm,#0,#0)) do begin\r
+\r
+          txt:=get_dat(i,zm,ch,true);   \r
+\r
+        // jesli to licznik petli FOX_RIPIT '#' (lub .R) to wyliczymy wartosc\r
+          if (txt='#') or (txt='.R') then begin\r
+            war:=oblicz_wartosc(txt,zm);\r
+            txt:=IntToStr(war);\r
+          end;\r
+\r
+        // jesli przekazywany parametr jest miedzy apostrofami " " to jest to ciag znakowy\r
+          if txt<>'' then\r
+           if (txt[1]='"') and (txt[length(txt)]='"') then txt:=copy(txt,2,length(txt)-2);\r
+\r
+          _odd:=High(par);\r
+\r
+          if k=byte('''') then begin\r
+           par[_odd]:=txt;\r
+           SetLength(par,_odd+2);\r
+          end else begin\r
+\r
+            if txt[1]='#' then begin\r
+             par[_odd]:='''#''';\r
+             txt:=copy(txt,2,length(txt));\r
+            end else\r
+             if txt[1] in ['<','>'] then begin\r
+              par[_odd]:='''#''';\r
+              war:=oblicz_wartosc(txt,zm);\r
+              txt:=IntToStr(war);\r
+             end else par[_odd]:=''' ''';\r
+\r
+           SetLength(par,_odd+3);\r
+           par[_odd+1]:=txt;\r
+          end;\r
+\r
+//          omin_spacje(i,zm);\r
+          if zm[i] in [',',' ',#9] then __next(i,zm);\r
+\r
+           if ch<>' ' then\r
+            if zm[i]=ch then __inc(i,zm); // else Break;\r
+\r
+         end;\r
+\r
+        // zapisujemy liczbe parametrow dla :0\r
+         par[0]:=IntToStr(Int64(High(par))-1);\r
+\r
+\r
+         // zwiekszamy numer wywolania makra T_MAC[indeks+3], T_MAC[indeks+5]\r
+         // !!! koniecznie w tym miejscu !!!\r
+\r
+         _doo:=integer( StrToInt(t_mac[indeks+3]) );\r
+         t_mac[indeks+3]:=IntToStr(Int64(_doo)+1);\r
+\r
+         _doo:=integer( StrToInt(t_mac[indeks+5]) );\r
+         t_mac[indeks+5]:=IntToStr(Int64(_doo)+1);\r
+\r
+         // !!! zabezpieczenie przed rekurencja bez konca !!!\r
+         // zatrzymujemy wykonanie makra jesli liczba wywolan przekroczy 255\r
+\r
+         if _doo>255 then blad(zm,66);\r
+\r
+\r
+         _doo:=integer( StrToInt(t_mac[indeks+4]) );  // numer linii\r
+\r
+         txt:=t_mac[indeks];       // nazwa pliku z aktualnie wykonywanym makrem\r
+\r
+         inc(wyw_idx);\r
+         if wyw_idx>High(t_wyw) then SetLength(t_wyw,wyw_idx+1);\r
+\r
+         t_wyw[wyw_idx].zm := zm;  // jesli wystapi blad to te dane pomoga go zlokalizowac\r
+         t_wyw[wyw_idx].pl := txt;\r
+         t_wyw[wyw_idx].nr := _doo;\r
+\r
+\r
+        // zapamietujemy aktualny indeks do T_MAC w _ODD\r
+        // odczytujemy makro z T_MAC[indeks], podstawiamy parametry i zapisujemy do T_MAC\r
+        // potem zwolnimy miejsce na podstawie wczesniej zapamietanego indeksu w _ODD\r
+\r
+         _odd:=High(t_mac);\r
+\r
+         while true do begin\r
+          txt:=t_mac[indeks+6];\r
+\r
+          j:=1;\r
+\r
+          ety:=get_datUp(j,txt,#0,false);  // wczytujemy nieznany ciag duzych liter\r
+\r
+          if not(fCRC16(ety)=__endm) then begin  // aby odnalezc wpis .ENDM, .MEND\r
+\r
+           j:=1;\r
+           while j<=length(txt) do\r
+            if test_param(j,txt) then begin\r
+\r
+             k:=j;\r
+             if txt[j]=':' then inc(j) else inc(j,2);\r
+\r
+             ety:='';\r
+             while _dec(txt[j]) do begin ety:=ety+txt[j]; inc(j) end;\r
+\r
+             war:=StrToInt(ety);\r
+\r
+             delete(txt,k,j-k);  dec(j,j-k);\r
+             if war>Int64(High(par))-1 then begin\r
+              insert('$FFFFFFFF',txt,k); inc(j,9);   // musi koniecznie wpisac ciag $FFFFFFFF\r
+             end else begin\r
+              insert(par[war],txt,k);\r
+              inc(j,length(par[war]));\r
+             end;\r
+\r
+            end else inc(j);\r
+\r
+           save_mac(txt);\r
+          end else Break;\r
+\r
+          inc(indeks);\r
+         end;\r
+\r
+\r
+         if not(FOX_ripit) and not(rept_run) then put_lst(str);\r
+\r
+        // zapamietaj w zmiennych lokalnych\r
+\r
+         indeks          := line_add;\r
+         line_add        := 0;\r
+\r
+         old_rept        := ___rept_ile;\r
+\r
+         par             := reptPar;\r
+\r
+         old_case        := rept_run;\r
+         rept_run        := false;\r
+\r
+         old_run_macro   := run_macro;\r
+         old_ifelse      := ifelse;\r
+         old_loopused    := loop_used;\r
+\r
+\r
+         komentarz := old_komentarz;\r
+\r
+         run_macro := true;\r
+\r
+         loop_used := false;\r
+\r
+         _doo:=High(t_mac);\r
+\r
+//         for idx:=_odd to _doo-1 do writeln(t_mac[idx],' | '); halt;\r
+\r
+         analizuj_mem__(_odd,_doo, zm,a,old_str, idx,idx+1, false);\r
+\r
+         if not(FOX_ripit) then bez_lst:=true;\r
+\r
+                     \r
+         if run_macro and (old_ifelse<>ifelse) then blad(zm,1);\r
+\r
+\r
+         run_macro   := old_run_macro;\r
+\r
+\r
+         t_mac[mne.i+5]:='0';\r
+\r
+\r
+         loop_used   := old_loopused;\r
+\r
+         rept_run    := old_case;\r
+\r
+         ifelse      := old_ifelse;\r
+         macro_nr    := old_macro_nr;\r
+\r
+         ___rept_ile := old_rept;\r
+\r
+         reptPar     := par;\r
+\r
+         line_add    := indeks;\r
+\r
+         if not(lst_off) and not(FOX_ripit) and not(rept_run) then put_lst(show_full_name(a,full_name,true));\r
+\r
+         dec(wyw_idx);\r
+\r
+         SetLength(t_mac,_odd+1);\r
+\r
+         ety:='';\r
+        end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  label .MACRO [label]                                                      *)\r
+(*  wystapienie dyrektywy .MACRO oznacza conajmniej 3 przebiegi asemblacji    *) \r
+(*----------------------------------------------------------------------------*)\r
+   __macro:\r
+         begin\r
+          if ety='' then ety:=get_lab(i,zm, true);\r
+\r
+          if (pass=0) and if_test then begin\r
+\r
+// Konop postulowal aby przywrocic makra z blokow PROC          \r
+//           if proc then t_prc[proc_nr-1].use:=true;  // jesli makro w .PROC to takie .PROC zawsze w uzyciu\r
+\r
+           reserved_word(ety,zm{, false});\r
+           save_lab(ety,High(t_mac),__id_macro,zm);\r
+\r
+           str:=show_full_name(a,full_name,false);  save_mac(str);  // zapisanie nazwy pliku z makrem\r
+           str:={lokal_name+}ety;                   save_mac(str);  // zapisanie nazwy makra\r
+\r
+           ety:=''''; ch:=',';\r
+\r
+           omin_spacje(i,zm);\r
+           if zm[i] in ['''','"'] then begin\r
+           // wczytujemy i sprawdzamy poprawnosc\r
+            ety:=zm[i];\r
+            str:=get_string(i,zm,zm,true);\r
+\r
+            if str<>'' then ch:=str[1];\r
+\r
+//            if length(txt)>1 then blad(zm,3) else\r
+//             if txt='' then txt:=',';\r
+           end;\r
+\r
+           omin_spacje(i,zm);\r
+           if not(test_char(i,zm,#0,#0)) then blad(zm,4);\r
+\r
+           str:=ety+ch;         save_mac(str); // separator i tryb dzialania\r
+           str:='0';            save_mac(str); // numer wywolania makra\r
+           str:=IntToStr(line); save_mac(str); // numer linii z makrem\r
+\r
+           str:='0';            save_mac(str); // licznik wywolan dla testu 'infinite loop'\r
+\r
+           if pass_end<3 then pass_end:=3;     // jesli sa makra to musza byc conajmniej 3 przebiegi\r
+          end;\r
+\r
+          macro := true;\r
+\r
+          save_lst(' ');\r
+\r
+//          save_end(__endm);\r
+\r
+          ety:=''\r
+         end;\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .IF [IFT] expression                                                      *)\r
+(*----------------------------------------------------------------------------*)\r
+   __if, __ifndef, __ifdef:\r
+         begin\r
+\r
+           save_lab(ety,adres,bank,zm);\r
+                           \r
+\r
+           txt:=zm;              // TXT = ZM, w celu pozniejszej modyfikacji TXT\r
+\r
+           if mne.l in [__ifndef, __ifdef] then begin\r
+\r
+             insert('.DEF',txt,i);\r
+\r
+             if mne.l=__ifndef then insert('.NOT ',txt,i);\r
+\r
+           end;\r
+\r
+\r
+           if_stos[ifelse].old_iftest := if_test;\r
+\r
+\r
+           inc(ifelse);\r
+           if ifelse>High(if_stos) then SetLength(if_stos,ifelse+1);\r
+\r
+\r
+           if_stos[ifelse]._okelse:=$7FFFFFFF;      // zablokowany .ELSE\r
+\r
+           if if_test then begin\r
+             save_lst(' ');\r
+\r
+             if_stos[ifelse]._else   := false;\r
+\r
+             if_stos[ifelse]._okelse := ifelse;\r
+\r
+             branch := true;             // tutaj nie ma mowy o relokowalnosci\r
+             war:=___wartosc_noSPC(txt,zm,i,#0,'F');\r
+\r
+             if_test := (war<>0);\r
+           end;\r
+\r
+           if_stos[ifelse]._if_test := if_test;\r
+\r
+          ety:='';\r
+         end;\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .ENDIF [EIF]                                                              *)\r
+(*----------------------------------------------------------------------------*)\r
+   __endif:\r
+       if ety<>'' then blad(zm,38) else\r
+         if ifelse>0 then begin\r
+\r
+           dec(ifelse);\r
+\r
+//           if_test     := if_stos[ifelse]._if_test;\r
+//           else_used   := if_stos[ifelse]._else;\r
+\r
+           if_test := if_stos[ifelse].old_iftest;\r
+\r
+         end else\r
+          blad(zm,37);\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .ENDM                                                                     *)\r
+(*----------------------------------------------------------------------------*)\r
+   __endm: dec_end(zm, __endm);\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .ELSE [ELS]                                                               *)\r
+(*----------------------------------------------------------------------------*)\r
+   __else:\r
+       if ety<>'' then blad(zm,38) else\r
+         if if_stos[ifelse]._okelse=ifelse then begin\r
+\r
+          if if_stos[ifelse]._else then blad(zm,1);\r
+          if ifelse=0 then blad(zm,37);\r
+\r
+          if_stos[ifelse]._else:=true;\r
+\r
+          if_test := not(if_stos[ifelse]._if_test);\r
+         end;\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .PRINT 'string' [,string2...] [,expression1,expression2...]               *)\r
+(*----------------------------------------------------------------------------*)\r
+   __print:\r
+       if ety<>'' then blad(zm,38) else\r
+        if macro_rept_if_test then\r
+         if pass=pass_end then begin\r
+\r
+          wypisz(i,zm);\r
+\r
+         end;\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .ELSEIF [ELI] expression                                                  *)\r
+(*----------------------------------------------------------------------------*)\r
+   __elseif:\r
+      if ety<>'' then blad(zm,38) else\r
+       if if_stos[ifelse]._okelse=ifelse then begin     // !!! konieczny warunek\r
+\r
+              if if_stos[ifelse]._else then blad(zm,1);\r
+              if ifelse=0 then blad(zm,37);\r
+\r
+              if_test := not(if_stos[ifelse]._if_test);\r
+\r
+              if if_test then begin\r
+\r
+                save_lst(' ');\r
+\r
+                branch:=true;            // tutaj nie ma mowy o relokowalnosci\r
+                war:=___wartosc_noSPC(zm,zm,i,#0,'F');\r
+\r
+                if_test     := (war<>0);\r
+\r
+                if_stos[ifelse]._if_test := if_test;    // !!! koniecznie zapisz IF_TEST\r
+              end;\r
+\r
+       end;\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  label .LOCAL [label]                                                      *)\r
+(*----------------------------------------------------------------------------*)\r
+   __local:\r
+        if macro_rept_if_test then begin\r
+\r
+          if ety='' then begin\r
+           omin_spacje(i,zm);\r
+           ety:=get_lab(i,zm, false);\r
+          end;\r
+\r
+        // jesli brak nazwy obszaru .LOCAL to przyjmij domyslna nazwe\r
+          if ety='' then begin\r
+           ety:='L@C?L?'+IntToStr(lc_nr);\r
+           inc(lc_nr);\r
+          end;\r
+\r
+          if pass=0 then if ety[1]='?' then warning(8);\r
+\r
+\r
+          t_loc[lokal_nr].ofs := org_ofset;\r
+\r
+\r
+          get_address(i,zm);         // nowy adres asemblacji dla .LOCAL\r
+\r
+\r
+          if not(test_char(i,zm,#0,#0)) then blad(zm,4);\r
+\r
+\r
+          new_local:=true;\r
+          save_lab(ety, adres, bank, zm);\r
+          new_local:=false;\r
+\r
+          save_lst('a');\r
+\r
+          t_loc[lokal_nr].adr := adres;\r
+\r
+\r
+          idx:=load_lab(ety, true);  // !!! TRUE\r
+          t_loc[lokal_nr].idx := idx;\r
+\r
+\r
+          save_end(__endl);\r
+\r
+          zapisz_lokal;\r
+          lokal_name:=lokal_name+ety+'.';\r
+\r
+          ety:='';\r
+         end;\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .ENDL                                                                     *)\r
+(*----------------------------------------------------------------------------*)\r
+   __endl:\r
+        if ety<>'' then blad(zm,38) else\r
+         if macro_rept_if_test then\r
+          if lokal_nr>0 then begin\r
+\r
+           save_lst(' ');\r
+\r
+           if not(proc) then oddaj_var;\r
+\r
+           oddaj_lokal(zm);\r
+\r
+           if t_loc[lokal_nr].idx>=0 then begin\r
+            t_lab[t_loc[lokal_nr].idx].lln:=adres-t_loc[lokal_nr].adr;\r
+            t_lab[t_loc[lokal_nr].idx].lid:=true;\r
+           end;\r
+\r
+           org_ofset := t_loc[lokal_nr].ofs;\r
+\r
+//           dec(end_idx);\r
+\r
+           get_address_update;\r
+\r
+          end else\r
+           blad(zm,28);\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .REPT expression                                                          *)\r
+(*----------------------------------------------------------------------------*)\r
+   __rept:\r
+        if if_test then\r
+         if rept then blad(zm,43) else begin\r
+\r
+         save_lab(ety,adres,bank,zm);\r
+         save_lst(' ');\r
+\r
+         save_end(__endr);\r
+\r
+         get_parameters(i,zm, reptPar, false, #0,#0);\r
+\r
+         if High(reptPar)=0 then blad(zm,23);      // Unexpected end of line\r
+\r
+\r
+         rept_ile:=oblicz_wartosc(reptPar[0],zm);  // REPT_ILE\r
+\r
+         if rept_ile<0 then blad(zm, 0);           // !!! mozliwa wartosc powyzej $ffff !!!\r
+\r
+//         testRange(zm, rept_ile, 0);\r
+\r
+         reptPar[0]:=IntToStr(Int64(High(reptPar))-1);    // liczba parametrów przekazana do .REPT\r
+\r
+\r
+         rept_nr  := High(t_mac);                  // zapamietujemy indeks do T_MAC\r
+         rept     := true;\r
+\r
+         \r
+         ety:=IntToStr(___rept_ile);               // zapisujemy aktualna wartosc ___REPT_ILE\r
+         save_mac(ety);                            // !!! koniecznie po zapamietaniu indeksu !!!\r
+\r
+         ety:=IntToStr(line);                      // zapisujemy numer wiersza z dyrektywa .REPT\r
+         save_mac(ety);\r
+\r
+         ety:='';\r
+        end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .ENDR                                                                     *)\r
+(*----------------------------------------------------------------------------*)\r
+   __endr:\r
+         begin\r
+\r
+          dirENDR(zm,a,old_str,rept_nr,rept_ile);\r
+\r
+          ety:='';\r
+         end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  label .STRUCT [label]                                                     *)\r
+(*  wystapienie dyrektywy .STRUCT oznacza conajmniej trzy przebiegi asemblacji*)\r
+(*----------------------------------------------------------------------------*)\r
+   __struct:\r
+        if macro_rept_if_test then\r
+         if struct.use then blad(zm,56) else begin\r
+\r
+           if ety='' then ety:=get_lab(i,zm, true);\r
+\r
+           if pass=0 then reserved_word(ety,zm{, false});\r
+\r
+           omin_spacje(i,zm);\r
+           if not(test_char(i,zm,#0,#0)) then blad(zm,4);\r
+\r
+           label_type:='C';\r
+\r
+           struct.drelocUSE := dreloc.use;\r
+           struct.drelocSDX := dreloc.sdx;\r
+\r
+           dreloc.use := false;\r
+           dreloc.sdx := false;\r
+\r
+\r
+           upd_structure(ety, zm);\r
+\r
+\r
+           zapisz_lokal;\r
+           lokal_name:=lokal_name+ety+'.';\r
+\r
+           struct.use := true;\r
+\r
+         // zapamietujemy adres, aby oddac go po .ENDS\r
+           struct.adres := adres;\r
+\r
+           save_lst('a');\r
+\r
+           save_end(__ends);\r
+\r
+           ety:='';\r
+         end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .ENDS                                                                     *)\r
+(*  zapisujemy w tablicy 'T_STR' dlugosc i liczbe pol struktury               *)\r
+(*----------------------------------------------------------------------------*)\r
+   __ends:\r
+        if ety<>'' then blad(zm,38) else\r
+         if macro_rept_if_test then\r
+          if not(struct.use) then blad(zm,55) else begin\r
+\r
+           save_lst(' ');\r
+\r
+           oddaj_lokal(zm);\r
+\r
+           struct.use := false;\r
+\r
+           t_str[struct.idx].siz := adres - struct.adres; // zapisujemy dlugosc struktury\r
+\r
+           t_str[struct.idx].ofs := struct.cnt;           // i liczbe pol struktury\r
+\r
+           adres := struct.adres;                         // zwracamy stary adres asemblacji\r
+\r
+           inc(struct.id);  // zwiekszamy identyfikator struktury (liczba struktur)\r
+\r
+           struct.cnt := -1;\r
+\r
+//           dec(end_idx);\r
+           dec_end(zm, __ends);\r
+\r
+           dreloc.use := struct.drelocUSE;\r
+           dreloc.sdx := struct.drelocSDX;\r
+          end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .ENUM                                                                     *)\r
+(*----------------------------------------------------------------------------*)\r
+   __enum:\r
+        if macro_rept_if_test then\r
+         if enum.use then blad(zm,56) else begin\r
+\r
+           if ety='' then ety:=get_lab(i,zm, true);\r
+\r
+           if pass=0 then reserved_word(ety,zm{, false});\r
+\r
+           omin_spacje(i,zm);\r
+           if not(test_char(i,zm,#0,#0)) then blad(zm,4);\r
+\r
+           label_type:='C';\r
+\r
+           enum.drelocUSE := dreloc.use;\r
+           enum.drelocSDX := dreloc.sdx;\r
+\r
+           dreloc.use:=false;\r
+           dreloc.sdx:=false;\r
+\r
+           save_lab(ety, 0, __id_enum, zm);\r
+                           \r
+\r
+           zapisz_lokal;\r
+           lokal_name:=lokal_name+ety+'.';\r
+\r
+           enum.use := true;\r
+           enum.val := 0;\r
+           enum.max := 0;\r
+\r
+           save_lst('a');\r
+\r
+           save_end(__ende);\r
+\r
+           ety:='';\r
+         end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .ENDE                                                                     *)\r
+(*----------------------------------------------------------------------------*)\r
+   __ende:\r
+        if ety<>'' then blad(zm,38) else\r
+         if macro_rept_if_test then\r
+          if not(enum.use) then blad(zm,55) else begin\r
+\r
+           txt:=lokal_name;\r
+           SetLength(txt, length(txt)-1);\r
+           idx:=load_lab(txt,false);\r
+\r
+           t_lab[idx].adr:=ValueToType(enum.max);\r
+                                 \r
+           save_lst(' ');       \r
+\r
+           oddaj_lokal(zm);\r
+\r
+           enum.use := false;\r
+\r
+//           dec(end_idx);\r
+           dec_end(zm,__ende);\r
+\r
+           dreloc.use := enum.drelocUSE;\r
+           dreloc.sdx := enum.drelocSDX;\r
+\r
+          end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  zapisujemy wartosc do tablicy .ARRAY                                      *)\r
+(*----------------------------------------------------------------------------*)\r
+   __array_run:\r
+      if ety<>'' then blad(zm,38) else begin\r
+\r
+        get_data_array(i,zm, t_arr[array_idx-1].idx, t_arr[array_idx-1].siz);\r
+\r
+      end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .ARRAY                                                                    *)\r
+(*  tablica ze zdefiniowanymi wartosciami                                     *)\r
+(*----------------------------------------------------------------------------*)\r
+   __array:\r
+        if aray then blad(zm,60) else\r
+         if macro_rept_if_test then begin\r
+\r
+          if ety='' then ety:=get_lab(i,zm, true);\r
+\r
+          if pass=0 then reserved_word(ety,zm{, true});\r
+\r
+          save_lab(ety, array_idx, __id_array, zm);\r
+          save_lst('a');\r
+\r
+          save_arr(adres, bank);          // tutaj ARRAY_IDX zostaje zwiekszone o 1\r
+\r
+          omin_spacje(i,zm);              // od tego momentu uzywamy ARRAY_IDX-1\r
+\r
+          if zm[i]<>'.' then begin\r
+           txt:=get_dat(i,zm,' ',true);\r
+           idx := integer( oblicz_wartosc(txt,zm) );\r
+\r
+           t_arr[array_idx-1].def:=true;  // okreslony rozmiar tablicy\r
+          end else begin\r
+           idx:=$FFFF;\r
+           t_arr[array_idx-1].def:=false; // brak rozmiaru tablicy\r
+          end;\r
+\r
+          array_used.max:=0;\r
+\r
+          t_arr[array_idx-1].idx:=idx;\r
+\r
+          r:=get_type(i,zm,zm,true);\r
+\r
+          t_arr[array_idx-1].siz := r;\r
+\r
+          if not(t_arr[array_idx-1].def) then idx:=idx div r;\r
+\r
+          t_arr[array_idx-1].len := (idx+1)*r;\r
+\r
+          //if (idx<0) or (t_arr[array_idx-1].len>$FFFF) then blad(zm,62);\r
+          testRange(zm, idx, 62);\r
+\r
+          if t_arr[array_idx-1].len-1>$FFFF then blad(zm,62);\r
+\r
+          array_used.typ := tType[ t_arr[array_idx-1].siz ];\r
+\r
+          war:=0;       // dopuszczalna maksymalna wartosc typu D-WORD\r
+\r
+          omin_spacje(i,zm);\r
+          if zm[i]='=' then begin\r
+            __inc(i,zm);\r
+            war:=oblicz_wartosc_noSPC(zm,zm,i,#0,tType[r]);\r
+          end;\r
+\r
+          omin_spacje(i,zm);\r
+          if not(test_char(i,zm,#0,#0)) then blad(zm,4);\r
+\r
+          \r
+          for j:=0 to idx do t_tmp[j]:=cardinal(war);    // FILLCHAR wypelnia tylko bajtami\r
+\r
+          aray := true;\r
+\r
+          save_end(__enda);\r
+\r
+          ety:='';\r
+         end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .ENDA                                                                     *)\r
+(*----------------------------------------------------------------------------*)\r
+   __enda:\r
+        if ety<>'' then blad(zm,38) else\r
+         if macro_rept_if_test then\r
+          if not(aray) then blad(zm,59) else begin\r
+\r
+           aray := false;\r
+\r
+           v    := t_arr[array_idx-1].siz;\r
+\r
+\r
+           if t_arr[array_idx-1].def then       // okreslony rozmiar tablicy\r
+\r
+            _doo := t_arr[array_idx-1].idx+1 \r
+\r
+           else begin\r
+            _doo := array_used.max ;            // rozmiar tablicy na podstawie ilosci danych\r
+\r
+            t_arr[array_idx-1].idx := _doo-1;\r
+            t_arr[array_idx-1].len := _doo*v;\r
+\r
+            if t_arr[array_idx-1].len-1>$FFFF then blad(zm,62);\r
+           end;\r
+\r
+\r
+           for idx:=0 to _doo-1 do save_dta(t_tmp[idx],zm, tType[v],0);\r
+\r
+           t:=''; save_lst(' ');\r
+\r
+//           dec(end_idx);\r
+           dec_end(zm,__enda);\r
+\r
+          end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  label EXT type                                                            *)\r
+(*----------------------------------------------------------------------------*)\r
+   __ext:\r
+   if ety='' then blad(zm,15) else\r
+    if macro_rept_if_test then\r
+     if loop_used then blad(zm,36) else begin\r
+\r
+      v := get_typeExt(i,zm);\r
+\r
+      save_extLabel(i,ety,zm,v);\r
+\r
+      nul.i:=0;\r
+      save_lst('l');\r
+\r
+      ety:='';\r
+     end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .EXTRN label .PROC (par1, par2, ...) [.var]|[.reg]                        *)\r
+(*  .EXTRN label1, label2, label3 ... type                                    *)\r
+(*  rozbudowany odpowiednik pseudo rozkazu EXT                                *)\r
+(*----------------------------------------------------------------------------*)\r
+ __extrn:\r
+    if macro_rept_if_test then begin\r
+//     if loop_used then blad(zm,36) else begin\r
+\r
+      nul.i:=0;\r
+      save_lst('l');\r
+      v:=0;\r
+\r
+      if ety='' then begin         // jesli .EXTRN nie poprzedza etykieta\r
+\r
+       while true do begin\r
+\r
+        get_parameters(i,zm,par,false, '.',':');\r
+        v:=get_typeExt(i,zm);\r
+\r
+        _doo:=High(par);\r
+        if _doo=0 then blad(zm,15);\r
+\r
+        for _odd:=_doo-1 downto 0 do begin\r
+         txt:=par[_odd];\r
+\r
+         if txt<>'' then\r
+          save_extLabel(i,txt,zm,v)\r
+         else\r
+          blad(zm,15);\r
+          \r
+        end;\r
+\r
+        omin_spacje(i,zm);\r
+        if (v=__proc) or (test_char(i,zm,#0,#0)) then Break;\r
+       end;\r
+\r
+      end else begin               // jesli .EXTRN poprzedza etykieta\r
+       v := get_typeExt(i,zm);\r
+       save_extLabel(i,ety,zm,v);\r
+      end;\r
+\r
+    ety:='';\r
+   end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .VAR label1, label2, label3 ... TYPE [=address]                           *)\r
+(*  .VAR TYPE label1, label2 ....                                             *)\r
+(*  .ZPVAR label1, label2, label3 ... TYPE [=address]                         *)\r
+(*  .ZPVAR TYPE label1, label2 ....                                           *)\r
+(*----------------------------------------------------------------------------*)\r
+ __var, __zpvar:\r
+ if ety<>'' then blad(zm,38) else\r
+  if (pass>0) and macro_rept_if_test then\r
+//   if (adres<0) and (mne.l=__var) then blad(zm,10) else \r
+    if rept_run then blad(zm,36) else begin\r
+\r
+//     nul.i:=0;\r
+     save_lst('a');\r
+\r
+     if pass_end<3 then pass_end:=3;    // !!! potrzebne conajmniej 3 przebiegi !!!\r
+\r
+     while true do begin\r
+      get_vars(i,zm,par, mne.l);\r
+\r
+      omin_spacje(i,zm);\r
+      if test_char(i,zm,#0,'=') then Break;\r
+     end;\r
+\r
+     txt:=zm;\r
+\r
+   // sprawdz czy zostal okreslony adres umiejscowienia zmiennych '= ADDRESS'\r
+     idx:=-1;\r
+\r
+     if High(par)>var_idx then begin     // deklaracja typu przez .STRUCT lub .ENUM\r
+      i:=1;\r
+      txt:=par[var_idx];\r
+     end;\r
+\r
+\r
+     if txt<>'' then\r
+      if txt[i]='=' then begin           // nowy adres alokacji\r
+       inc(i);\r
+       idx:=integer( oblicz_wartosc_noSPC(txt,zm,i,#0,'A') );\r
+\r
+       testRange(zm,idx,87);\r
+      end;\r
+\r
+\r
+     if mne.l=__zpvar then begin\r
+\r
+      if idx>=0 then zpvar:=idx;\r
+\r
+       for _doo:=0 to var_idx-1 do\r
+        if t_var[_doo].id=var_id then begin\r
+\r
+         t_var[_doo].adr:=zpvar;\r
+         t_var[_doo].zpv:=true;\r
+\r
+         if zpvar+t_var[_doo].cnt*t_var[_doo].siz>256 then\r
+          blad(zm,0)\r
+         else\r
+          for k:=0 to t_var[_doo].cnt*t_var[_doo].siz-1 do begin\r
+\r
+           if (pass=pass_end) and t_zpv[zpvar] then warning(109);\r
+\r
+           t_zpv[zpvar]:=true;\r
+\r
+           inc(zpvar);\r
+          end;    \r
+\r
+        end;\r
+\r
+     end else begin\r
+\r
+      if idx>=0 then\r
+       for _doo:=0 to var_idx-1 do\r
+        if t_var[_doo].id=var_id then begin\r
+         t_var[_doo].adr:=idx;\r
+         t_var[_doo].zpv:=false;\r
+         inc(idx, t_var[_doo].cnt*t_var[_doo].siz);\r
+        end;\r
+\r
+     end;\r
+\r
+     inc(var_id);\r
+\r
+     ety:='';\r
+    end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .BY [+byte] bytes and/or ASCII                                            *)\r
+(*  .WO words                                                                 *)\r
+(*  .HE hex bytes                                                             *)\r
+(*----------------------------------------------------------------------------*)\r
+ __by, __wo, __he, __sb:\r
+  if (mne.l<>__he) and (dreloc.use or dreloc.sdx) then blad(zm,71) else\r
+   if macro_rept_if_test then begin\r
+\r
+   save_lab(ety,adres,bank,zm);\r
+\r
+   case mne.l of\r
+    __by: get_maeData(zm,i,'B');\r
+    __wo: get_maeData(zm,i,'W');\r
+    __he: get_maeData(zm,i,'H');\r
+    __sb: get_maeData(zm,i,'S');\r
+   end;\r
+\r
+   ety:='';\r
+  end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .WHILE .TYPE ARG1 OPERAND ARG2 [.AND|.OR .TYPE ARG3 OPERAND ARG4]         *)\r
+(*----------------------------------------------------------------------------*)\r
+ __while:\r
+    if macro_rept_if_test then begin\r
+//     if loop_used then blad(zm,36) else begin\r
+\r
+//      if ety='' then ety:=get_lab(i,zm, true);\r
+\r
+      save_lab(ety,adres,bank,zm);\r
+      save_lst('a');\r
+\r
+      if while_name='' then while_name:=lokal_name;\r
+      while_name:=while_name+IntToStr(while_nr)+'.';   // sciezka dostepu do WHILE\r
+\r
+      long_test:='';\r
+      wyrazenie_warunkowe(i, long_test, zm,txt,tmp,v,r, '\EX LDA#0\:?J/2-1 ORA#0\.ENDL');\r
+\r
+//      if long_test<>'' then begin\r
+//       create_long_test(v, r, long_test, txt, tmp);\r
+//       long_test:=long_test+'\EX LDA#0\:?J/2-1 ORA#0\.ENDL';\r
+//      end;\r
+\r
+\r
+      save_end(__endw);\r
+\r
+\r
+      ety:=__while_label+while_name;        // poczatek .WHILE\r
+\r
+      save_fake_label(ety,zm,adres);\r
+\r
+\r
+      ety:=__endw_label+while_name;         // koniec WHILE\r
+\r
+\r
+      if long_test='' then\r
+       mne := asm_test(txt,tmp,zm, ety, r,v)\r
+      else begin\r
+\r
+       idx:=High(t_mac);  _odd:=idx+1;\r
+\r
+       t_mac[idx]:=long_test+'\ JEQ '+ety;\r
+\r
+       line_add:=line-1;\r
+\r
+       save_lst('i');\r
+       txt:=zm;\r
+       zapisz_lst(txt);\r
+\r
+       opt_tmp:=opt;\r
+       opt:=opt and (not(4));\r
+\r
+       code6502:=true;\r
+\r
+\r
+       analizuj_mem__(idx,_odd, zm,a,old_str, 0,1, false);\r
+\r
+\r
+       code6502:=false;\r
+\r
+       line_add:=0;\r
+\r
+       opt:=opt_tmp;\r
+\r
+       bez_lst:=true;\r
+      end;\r
+  \r
+\r
+      inc(whi_idx);\r
+\r
+      inc(while_nr);\r
+\r
+      ety:='';\r
+    end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .ENDW                                                                     *)\r
+(*----------------------------------------------------------------------------*)\r
+ __endw:\r
+    if ety<>'' then blad(zm,38) else\r
+     if macro_rept_if_test then\r
+      if whi_idx>0 then begin\r
+//     if loop_used then blad(zm,36) else begin\r
+\r
+        save_lst('a');\r
+\r
+        dec(whi_idx);\r
+\r
+\r
+     ety:=__while_label+while_name;\r
+\r
+     war:=load_lab(ety,false);    // odczytujemy wartosc etykiety poczatku petli WHILE ##B\r
+     if war>=0 then begin\r
+      tst:=t_lab[war].adr;\r
+\r
+      save_relAddress(integer(war), reloc_value);\r
+\r
+      if pass=pass_end then\r
+       if t_lab[war].bnk<>bank then warning(70); // petla .WHILE musi znajdowac sie w obszarze tego samego banku\r
+     end else\r
+      tst:=0;\r
+\r
+\r
+        txt:='JMP '+IntToStr(tst);\r
+        k:=1;  mne:=oblicz_mnemonik(k,txt,zm);\r
+\r
+\r
+     ety:=__endw_label+while_name;\r
+\r
+     idx := adres + 3;            // E## = aktualny adres + 3 bajty (JMP)\r
+\r
+     save_fake_label(ety,zm,idx);\r
+\r
+\r
+        obetnij_kropke(while_name);\r
+\r
+//        dec(end_idx);\r
+        dec_end(zm,__endw);\r
+\r
+        ety:='';\r
+       end else blad(zm,88);\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .TEST .TYPE ARG1 OPERAND ARG2 [.AND|.OR .TYPE ARG3 OPERAND ARG4]          *)\r
+(*----------------------------------------------------------------------------*)\r
+ __test:\r
+    if macro_rept_if_test then begin\r
+\r
+      save_lab(ety,adres,bank,zm);\r
+      save_lst('a');\r
+\r
+      if test_name='' then test_name:=lokal_name;\r
+      test_name:=test_name+IntToStr(test_nr)+'.';   // sciezka dostepu do TEST\r
+\r
+      long_test:='';\r
+      wyrazenie_warunkowe(i, long_test,zm,txt,tmp,v,r, '\EX LDA#0\:?J/2-1 ORA#0\.ENDL');\r
+\r
+//      if long_test<>'' then begin\r
+//       create_long_test(v, r, long_test, txt, tmp);\r
+//       long_test:=long_test+'\EX LDA#0\:?J/2-1 ORA#0\.ENDL';\r
+//      end;\r
+\r
+\r
+      save_end(__endt);\r
+\r
+\r
+      ety:=__test_label+test_name;          // poczatek #IF __TEST_LABEL\r
+\r
+      save_fake_label(ety,zm,adres);\r
+\r
+\r
+      ety:=__telse_label+test_name;        // sprawdzamy czy wystapilo #ELSE\r
+      if load_lab(ety,false)<0 then\r
+       ety:=__endt_label+test_name;        // jesli nie bylo #ELSE to skok do #END\r
+\r
+\r
+      if long_test='' then\r
+       mne := asm_test(txt,tmp,zm, ety, r,v)\r
+      else begin\r
+\r
+       idx:=High(t_mac);  _odd:=idx+1;\r
+\r
+       t_mac[idx]:=long_test+'\ JEQ '+ety;\r
+\r
+       line_add:=line-1;\r
+\r
+       save_lst('i');\r
+       txt:=zm;\r
+       zapisz_lst(txt);\r
+\r
+       opt_tmp:=opt;\r
+       opt:=opt and (not(4));\r
+\r
+\r
+       code6502:=true;\r
+\r
+       analizuj_mem__(idx,_odd, zm,a,old_str, 0,1, false);\r
+\r
+       code6502:=false;\r
+\r
+\r
+       line_add:=0;\r
+\r
+       opt:=opt_tmp;\r
+\r
+       bez_lst:=true;\r
+      end;\r
+\r
+\r
+      t_els[test_idx]:=false;\r
+\r
+      inc(test_idx);\r
+\r
+      if test_idx>High(t_els) then SetLength(t_els, test_idx+1);\r
+\r
+\r
+      inc(test_nr);\r
+\r
+      ety:='';\r
+    end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .TELSE                                                                    *)\r
+(*----------------------------------------------------------------------------*)\r
+ __telse:\r
+    if ety<>'' then blad(zm,38) else\r
+     if macro_rept_if_test then\r
+      if test_idx>0 then begin\r
+\r
+        if t_els[test_idx-1] then blad(zm,95);\r
+\r
+        txt:='JMP '+__endt_label+test_name;\r
+        mne:=asm_mnemo(txt, zm);\r
+\r
+        t_els[test_idx-1]:=true;\r
+\r
+        ety:=__telse_label+test_name;          // adres #ELSE __TELSE_LABEL\r
+        save_fake_label(ety,zm,adres);\r
+\r
+\r
+        dec(adres, mne.l);\r
+\r
+\r
+        ety:='';\r
+      end else blad(zm,95);\r
+\r
+       \r
+(*----------------------------------------------------------------------------*)\r
+(*  .ENDT                                                                     *)\r
+(*----------------------------------------------------------------------------*)\r
+ __endt:\r
+    if ety<>'' then blad(zm,38) else\r
+     if macro_rept_if_test then\r
+      if test_idx>0 then begin\r
+//     if loop_used then blad(zm,36) else begin\r
+\r
+        save_lst('a');\r
+\r
+        dec(test_idx);\r
+\r
+\r
+     ety:=__test_label+test_name;\r
+\r
+     war:=load_lab(ety,false);              // adres #IF __TEST_LABEL\r
+     if war>=0 then\r
+      if pass=pass_end then\r
+       if t_lab[war].bnk<>bank then warning(70); // TEST musi znajdowac sie w obszarze tego samego banku\r
+\r
+\r
+     ety:=__endt_label+test_name;           // adres #END dla bloku #IF __ENDT_LABEL\r
+     save_fake_label(ety,zm,adres);\r
+\r
+\r
+        obetnij_kropke(test_name);\r
+\r
+//        dec(end_idx);\r
+        dec_end(zm,__endt);\r
+\r
+        ety:='';\r
+       end else blad(zm,95);\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .DEF label                                                                *)\r
+(*----------------------------------------------------------------------------*)\r
+ __def:\r
+    if ety<>'' then blad(zm,38) else\r
+     if macro_rept_if_test then begin\r
+\r
+      idx:=adres;\r
+\r
+      omin_spacje(i,zm);\r
+\r
+      label_type:='V';\r
+\r
+\r
+      if zm[i]=':' then begin\r
+       old_case:=true;           // zostal uzyty znak ':' w nazwie etykiety\r
+       inc(i);\r
+      end else\r
+       old_case:=false;          // znak ':' nie zostal uzyty w nazwie etykiety\r
+\r
+      ety:=get_lab(i,zm,true);\r
+\r
+      omin_spacje(i,zm);\r
+\r
+      txt:=zm;                   // podstawiamy ZM pod TXT\r
+\r
+      if txt[i] in ['+','-'] then\r
+       if txt[i+1] in ['+','-','='] then operator_zlozony(i,txt,ety, old_case);\r
+\r
+\r
+      if txt[i]='=' then begin\r
+       __inc(i,txt);\r
+\r
+       variable:=false;\r
+\r
+       idx:=oblicz_wartosc_noSPC(txt,zm,i,#0,'W');\r
+\r
+       if not(variable) then label_type:='C';\r
+       \r
+      end else\r
+       if not(test_char(i,txt,#0,#0)) then blad(zm,58);\r
+\r
+\r
+      nul.i:=idx;\r
+      save_lst('l');\r
+      data_out := true;     // wymus pokazanie w pliku LST podczas wykonywania makra\r
+                            // !!! jesli wystapila dyrektywa .IFNDEF to nie pokaze !!!\r
+\r
+      old_run_macro := run_macro;\r
+      run_macro     := false;\r
+\r
+//      old_loopused  := dreloc.use;\r
+//      dreloc.use    := false;\r
+\r
+      mne_used      := true;\r
+\r
+\r
+      if old_case then\r
+       s_lab(ety,idx,bank,zm,ety[1])   // etykieta globalna\r
+      else\r
+       save_lab(ety,idx,bank,zm);      // etykieta w aktualnym zasiegu\r
+\r
+\r
+      run_macro     := old_run_macro;\r
+\r
+//      dreloc.use    := old_loopused;\r
+\r
+      ety:='';\r
+     end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .USING label [,label2...]                                                 *)\r
+(*----------------------------------------------------------------------------*)\r
+ __using:\r
+    if ety<>'' then blad(zm,38) else\r
+     if macro_rept_if_test then begin\r
+\r
+      save_lst('i');\r
+\r
+      get_parameters(i,zm,par,false, '.',':');\r
+\r
+      if pass>0 then\r
+       for k:=High(par)-1 downto 0 do begin\r
+\r
+        txt:=par[k];\r
+\r
+        _odd:=load_lab(txt, false);\r
+        if _odd<0 then blad_und(zm,txt,5);\r
+\r
+        t_usi[usi_idx].lok:=end_idx;\r
+        t_usi[usi_idx].lab:=txt;\r
+\r
+        if proc then\r
+         t_usi[usi_idx].nam:=proc_name\r
+        else\r
+         t_usi[usi_idx].nam:=lokal_name;\r
+\r
+        inc(usi_idx);\r
+\r
+        SetLength(t_usi, usi_idx+1);\r
+       end;\r
+\r
+     end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .FL                                                                       *)\r
+(*----------------------------------------------------------------------------*)\r
+ __fl:\r
+    if macro_rept_if_test then begin\r
+\r
+     save_lab(ety,adres,bank,zm);\r
+\r
+     save_lst('a');\r
+\r
+     omin_spacje(i,zm);\r
+\r
+     while not(test_char(i,zm,#0,#0)) do begin\r
+       txt:=get_dat(i,zm,',',true);\r
+       save_fl(txt, zm);\r
+       if zm[i] in [',',' ',#9] then __next(i,zm) else Break;\r
+     end;\r
+\r
+     ety:='';\r
+    end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  label EQU [=] expression                                                  *)\r
+(*----------------------------------------------------------------------------*)\r
+   __equ,__smb,__addEqu:\r
+       if ety='' then blad(zm,15) else\r
+        if macro_rept_if_test then\r
+         if loop_used then blad(zm,36) else begin\r
+\r
+           if dreloc.use then\r
+            if mne.l in [__equ,__smb] then blad(zm,71);\r
+\r
+           label_type:='C';\r
+\r
+           old_case   := dreloc.use;   // deklaracje etykiet w bloku .RELOC nie moga byc relokowalne\r
+           dreloc.use := false;\r
+\r
+\r
+           if mne.l=__smb then begin   // SMB\r
+\r
+            txt:=get_smb(i,zm);\r
+\r
+          // wymuszamy relokowalnosc dla tej etykiety\r
+          // jesli BLOK>1 to zaznaczy jako etykiete relokowalna\r
+            k:=blok; blok:=$FFFF;\r
+            save_lab(ety,smb_idx,__id_smb,zm);\r
+            blok:=k;\r
+\r
+\r
+          // zapisujemy etykiete symbolu SMB w tablicy T_SMB\r
+            t_smb[smb_idx].smb:=txt;                                 // SAVE_SMB\r
+            inc(smb_idx);                                            //\r
+            if smb_idx>High(t_smb) then SetLength(t_smb,smb_idx+1);  //\r
+\r
+\r
+            war:=__rel;\r
+\r
+           end else begin              // EQU, addEQU\r
+\r
+            branch:=true;              // dla EQU i addEQU nie ma relokowalnosci\r
+\r
+           // nie mozna przypisac wartosci etykiety EXTERNAL, SMB (BLOCKED = TRUE)\r
+            blocked := true;\r
+\r
+           // sprawdzamy czy deklaracja etykiety powiodla sie (UNDECLARED = FALSE)\r
+           // procedura OBLICZ_WARTOSC zmodyfikuje UNDECLARED na TRUE jesli wystapi\r
+           // proba odwolania do niezdefiniowanej etykiety\r
+\r
+            undeclared:=false;\r
+\r
+            \r
+            variable:=false;\r
+\r
+            war:=___wartosc_noSPC(zm,zm,i,#0,'F');\r
+\r
+            if variable then label_type:='V';\r
+\r
+\r
+            blocked := false;          // !!! koniecznie przywracamy BLOCKED = FALSE !!!\r
+\r
+            mne_used:=true;            // konieczny test dla zmieniajacych sie wartosci etykiet\r
+\r
+\r
+            save_lab(ety,cardinal(war),bank,zm);\r
+\r
+            _odd:=load_lab(ety, true); // !!! TRUE\r
+\r
+            if _odd>=0 then t_lab[_odd].sts := undeclared;\r
+\r
+\r
+            undeclared:=false;         // !!! koniecznie przywracamy UNDECLARED = FALSE !!!\r
+\r
+            data_out := true;          // wymus pokazanie w pliku LST podczas wykonywania makra\r
+\r
+            mne_used := false;\r
+\r
+           end;\r
+\r
+\r
+           nul.i:=integer( war );\r
+           save_lst('l');\r
+\r
+\r
+           if mne.l=__addEqu then begin\r
+            zapisz_lst(tmpZM);\r
+            zm:='';\r
+           end;\r
+\r
+\r
+           dreloc.use := old_case;\r
+\r
+           ety:='';\r
+          end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  OPT holscmtb?f +-                                                         *)\r
+(*----------------------------------------------------------------------------*)\r
+(*  bit                                                                       *)\r
+(*   0 - Header                        default = yes   'h+'                   *)\r
+(*   1 - Object file                   default = yes   'o+                    *)\r
+(*   2 - Listing                       default = no    'l-'                   *)\r
+(*   3 - Screen (listing on screen)    default = no    's-'                   *)\r
+(*   4 - CPU 8bit/16bit                default = 6502  'c-'                   *)\r
+(*   5 - visible macro                 default = no    'm-'                   *)\r
+(*   6 - track sep rep                 default = no    't-'                   *)\r
+(*   7 - banked mode                   default = no    'b-'                   *)\r
+(*----------------------------------------------------------------------------*)\r
+   __opt:\r
+       if macro_rept_if_test then begin\r
+\r
+         txt:=get_dat_noSPC(i,zm,',',#0,zm);   // pomijamy spacje\r
+\r
+         j:=1;\r
+\r
+         while j<=length(txt) do begin\r
+\r
+          ch:=txt[j+1];\r
+\r
+          opt_tmp:=opt;\r
+\r
+          tst:=0;\r
+\r
+          case UpCase(txt[j]) of\r
+           'F': raw.use:= (ch='+');\r
+           'H': tst:=1;\r
+           'O': tst:=2;\r
+           'L': tst:=4;\r
+           'S': tst:=8;\r
+           'C': tst:=16;\r
+           'M': tst:=32;\r
+           'T': tst:=64;\r
+           'B': tst:=128;\r
+           '?': mae_labels:= (ch='+'); \r
+           'R': regAXY_opty:= (ch='+');\r
+          else\r
+           blad(zm,16);\r
+          end;\r
+\r
+          case ch of\r
+           '+': opt:=opt or tst;\r
+           '-': opt:=opt and (not(tst));\r
+          else\r
+           blad(zm,16);\r
+          end;\r
+\r
+          if (opt_tmp and 1)<>(opt and 1) then        // OPT H-\r
+           if (opt and 1)=0 then save_hea; \r
+\r
+          inc(j,2);\r
+         end;\r
+\r
+         data_out:=true;\r
+\r
+         save_lst(' ');\r
+       end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  ORG adres [,adres2]                                                       *)\r
+(*  RUN adres                                                                 *)\r
+(*  INI adres                                                                 *)\r
+(*  BLK                                                                       *)\r
+(*----------------------------------------------------------------------------*)\r
+   __org, __run, __ini, __blkSpa, __blkRel, __blkEmp:\r
+    if if_test then\r
+     if loop_used or rept then blad(zm,36) else\r
+      if dreloc.use then blad(zm,71) else\r
+       if first_org and (ety<>'') then blad(zm,10) else begin\r
+\r
+\r
+         if (org_ofset>0) and ((lokal_name<>'') or proc) then blad(zm,71);\r
+\r
+\r
+         if hea_ofs.adr>=0 then\r
+          raw.old := hea_ofs.adr+(adres-hea_ofs.old)\r
+         else\r
+          raw.old := adres;\r
+\r
+\r
+         label_type:='V';\r
+\r
+         data_out:=true;\r
+\r
+         save_lst('a');\r
+\r
+         branch:=true;    // relokowalnosc tutaj niemozliwa\r
+\r
+         rel_ofs:=0; {org_ofs:=0;}\r
+         idx:=-$FFFF;  hea_ofs.adr:=-1;  _odd:=-1;\r
+\r
+         save_lab(ety,adres,bank,zm);\r
+\r
+         omin_spacje(i,zm);\r
+\r
+         r := mne.l;    // !!! koniecznie V := MNE.L !!! aby zadzialalo RUN, INI\r
+                        // !!! RUN, INI modyfikuja MNE.L !!!\r
+\r
+         case r of\r
+\r
+         // BLK SPARTA a\r
+          __blkSpa:\r
+               begin\r
+                dreloc.sdx:=true;\r
+\r
+                blok:=0;\r
+\r
+                opt_tmp:=opt;\r
+                opt_h_minus;\r
+\r
+              // a($fffa),a(str_adr),a(end_adr)\r
+                save_dstW( $fffa );\r
+\r
+                idx:=integer( ___wartosc_noSPC(zm,zm,i,',','A') );\r
+\r
+                opt:=opt_tmp;\r
+               end;\r
+\r
+\r
+         //BLK R[eloc] M[ain]|E[xtended]\r
+          __blkRel:\r
+              begin\r
+                dreloc.sdx:=true;\r
+\r
+                ds_empty:=0;\r
+\r
+                opt_tmp:=opt;\r
+                opt_h_minus;\r
+\r
+                v := getMemType(i,zm);\r
+\r
+                add_blok(zm);\r
+\r
+              // a($fffe),b(blk_num),b(blk_id)\r
+              // a(blk_off),a(blk_len)\r
+                save_dstW( $fffe );\r
+                save_dst(byte(blok));\r
+                save_dst(memType);\r
+\r
+                if blok=1 then\r
+                 idx:=__rel\r
+                else begin\r
+                 rel_ofs:=adres-__rel;\r
+                 _odd:=adres; idx:=adres;\r
+                end;\r
+\r
+                opt:=opt_tmp;\r
+              end;\r
+\r
+\r
+         //BLK E[mpty] a M[ain]|E[xtended]\r
+          __blkEmp:\r
+              begin\r
+                opt_tmp := opt;\r
+                opt_h_minus;\r
+\r
+                _odd:=integer( ___wartosc_noSPC(zm,zm,i,' ','A') );  // !!! koniecznie znak spacji ' ' !!!\r
+                                                                     // blk empty empend-tdbuf extended\r
+                v := getMemType(i,zm);\r
+\r
+                blk_empty(_odd, zm);\r
+\r
+                idx:=adres + _odd;\r
+\r
+                opt := opt_tmp;\r
+\r
+                if ds_empty>0 then blad(zm,57);  // albo .DS albo BLK EMPTY, nie mozna obu naraz\r
+              end;\r
+\r
+\r
+          // ORG\r
+          __org: begin\r
+\r
+                if dreloc.sdx then blad(zm,71);\r
+\r
+                if not(NoAllocVar) and not(proc) and (lokal_nr=0) then oddaj_var;\r
+\r
+                NoAllocVar:=false;\r
+\r
+                if zm[i]='[' then begin\r
+                 opt_tmp := opt;\r
+                 opt_h_minus;\r
+\r
+                 txt:=ciag_ograniczony(i,zm,true);\r
+                 k:=1;\r
+                 if pass>1 then oblicz_dane(k,txt,zm,1);\r
+\r
+                 omin_spacje(i,zm);\r
+                 if zm[i]=',' then begin\r
+                  __inc(i,zm);\r
+                  idx:=integer( ___wartosc_noSPC(zm,zm,i,#0,'A') );\r
+                 end;\r
+\r
+                 opt := opt_tmp;\r
+\r
+                end else\r
+                 idx:=integer( ___wartosc_noSPC(zm,zm,i,',','A') );\r
+\r
+                org_ofset:=0;\r
+\r
+                omin_spacje(i,zm);\r
+                if zm[i]=',' then begin\r
+                 __inc(i,zm);\r
+\r
+                 {org_ofs:=idx;}\r
+                 hea_ofs.adr := integer( ___wartosc_noSPC(zm,zm,i,#0,'A') );\r
+                 if hea_ofs.adr<0 then blad(zm,10);\r
+\r
+                 hea_ofs.old := idx;\r
+\r
+                { if adres<0 then\r
+                  org_ofset := hea_ofs.adr\r
+                 else   }\r
+                  org_ofset := idx - hea_ofs.adr;\r
+\r
+                end;\r
+\r
+\r
+                if not(first_org) then           // koniecznie IF NOT(FIRST_ORG) inaczej nic nie zapisze\r
+                 if (adres<>idx) and raw.use then begin\r
+\r
+                  if raw.old<0 then\r
+                   k:=0\r
+                  else\r
+                   if hea_ofs.adr>=0 then\r
+                    k:=hea_ofs.adr-raw.old\r
+                   else\r
+                    k:=idx-raw.old;\r
+\r
+                  if k<0 then blad(zm,108);\r
+\r
+                  if not(hea) then inc(fill,k);  // IF NOT(HEA) czeka az zacznie zapisywac cos do pliku\r
+\r
+                  adres:=idx;      \r
+\r
+                 end;\r
+\r
+               end;\r
+\r
+\r
+          // RUN,INI\r
+          __run,__ini:\r
+               begin\r
+\r
+                if dreloc.sdx then blad(zm,71);    // Illegal instruction at RELOC block\r
+                if opt and 1=0 then blad(zm,111);  // Illegal when Atari file headers disabled\r
+\r
+                oddaj_var;\r
+\r
+                idx:=integer( ___wartosc_noSPC(zm,zm,i,#0,'A') );\r
+                mne.l:=2;\r
+\r
+                mne.h[0]:=byte(idx);\r
+                mne.h[1]:=byte(idx shr 8);\r
+\r
+                idx:=$2e0 + r - __run;\r
+               end;\r
+         end;\r
+\r
+\r
+         if (adres<>idx) or (_odd>=0) then begin\r
+\r
+           save_hea;\r
+\r
+           adres:=idx;\r
+\r
+           if r<>__blkEmp then org:=true;        // R = MNE.L\r
+         end;\r
+\r
+\r
+         if (idx>=0) and (idx<=$FFFF) then\r
+          first_org:=false\r
+         else\r
+          blad(zm,0);    // !!! koniecznie blad(zm,0) !!! w celu akceptacji\r
+                         // ORG-ów <0 w poczatkowych przebiegach asemblacji\r
+\r
+         if raw.use and (r in [__run, __ini]) then first_org:=true;\r
+\r
+         ety:=''; \r
+        end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .PUT [index] = VALUE,...                                                  *)\r
+(*----------------------------------------------------------------------------*)\r
+   __put:\r
+     if ety<>'' then blad(zm,38) else\r
+      if macro_rept_if_test then begin\r
+\r
+       omin_spacje(i,zm);\r
+\r
+       array_used.max:=0;\r
\r
+       put_used:=true;\r
+\r
+       blocked := true;\r
+       get_data_array(i,zm,$FFFF,1);\r
+       blocked := false;\r
+\r
+       put_used:=false;\r
+      end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .SAV [index] ['file',length] | ['file',ofset,length]                      *)\r
+(*----------------------------------------------------------------------------*)\r
+   __sav:\r
+//    if ety<>'' then blad(zm,38) else\r
+     if macro_rept_if_test then begin\r
+\r
+       save_lab(ety,adres,bank,zm);\r
+\r
+       save_lst('a');\r
+\r
+       idx_get:=0;\r
+\r
+       omin_spacje(i,zm);\r
+\r
+       if zm[i] in ['[','('] then begin\r
+        txt:=ciag_ograniczony(i,zm,true);\r
+        k:=1; idx_get:=integer( ___wartosc_noSPC(txt,zm,k,#0,'A') );\r
+       end;\r
+\r
+       txt:=get_string(i,zm,zm,false);\r
+\r
+       omin_spacje(i,zm);\r
+\r
+       if txt<>'' then\r
+        if zm[i]=',' then\r
+         __inc(i,zm)\r
+        else\r
+         blad(zm,23);\r
+\r
+       _doo:=integer( ___wartosc_noSPC(zm,zm,i,',','A') );\r
+\r
+       omin_spacje(i,zm);\r
+\r
+       if zm[i]=',' then begin\r
+        __inc(i,zm);\r
+        inc(idx_get, _doo);\r
+        _doo:=integer( ___wartosc_noSPC(zm,zm,i,',','A') );\r
+       end;\r
+\r
+       _odd:=idx_get+_doo;  if _odd>0 then dec(_odd);\r
+       \r
+       testRange(zm, _odd, 62); //subrange_bounds(zm,idx_get+_doo,$FFFF);\r
+\r
+       test_eol(i,zm,zm,#0);\r
+\r
+       if txt<>'' then begin\r
+         txt:=GetFile(txt,zm);\r
+\r
+         if pass=pass_end then begin\r
+           WriteAccessFile(txt);\r
+\r
+           AssignFile(g, txt); FileMode:=1; Rewrite(g,1);\r
+           blockwrite(g, t_get[idx_get], _doo);\r
+           closefile(g);\r
+         end;\r
+\r
+       end else begin\r
+\r
+         if (pass=pass_end) and (_doo>0) then\r
+          for idx:=0 to _doo-1 do save_dst(t_get[idx_get+idx]);\r
+\r
+         inc(adres,_doo);\r
+       end;\r
+\r
+       ety:='';\r
+      end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .PAGES                                                                    *)\r
+(*----------------------------------------------------------------------------*)\r
+   __pages:\r
+    if ety<>'' then blad(zm,38) else\r
+     if macro_rept_if_test then\r
+      if adres<0 then blad(zm,10) else begin\r
+\r
+       save_lst('a');\r
+\r
+       war:=1;\r
+       txt:=get_dat_noSPC(i,zm,' ',#0,zm);\r
+\r
+       if txt<>'' then begin\r
+        k:=1; war:=___wartosc_noSPC(txt,zm,k,#0,'A');   // dopuszczalny zakres wartosci to .WORD\r
+\r
+        k:=integer(war);\r
+        testRange(zm, k, 0);\r
+       end;\r
+\r
+       omin_spacje(i,zm);\r
+       if not(test_char(i,zm,#0,#0)) then blad(zm,4);\r
+\r
+       t_pag[pag_idx].adr:= integer(adres and $7FFFFF00);\r
+       t_pag[pag_idx].cnt:= integer(war) shl 8;\r
+\r
+       inc(pag_idx);\r
+       if pag_idx>High(t_pag) then SetLength(t_pag,pag_idx+1);\r
+\r
+       save_end(__endpg);\r
+\r
+//       ety:='';\r
+      end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .ENDPG                                                                    *)\r
+(*----------------------------------------------------------------------------*)\r
+   __endpg:\r
+    if ety<>'' then blad(zm,38) else \r
+     if macro_rept_if_test then\r
+      if pag_idx=0 then blad(zm,64) else begin\r
+\r
+       save_lst('a');\r
+\r
+       dec(pag_idx);\r
+\r
+       _odd := t_pag[pag_idx].adr;\r
+       _doo := (adres-1) and $7FFFFF00;\r
+\r
+       if pass=pass_end then\r
+        if (_doo-_odd) >= t_pag[pag_idx].cnt then warning(70);\r
+\r
+//       dec(end_idx);\r
+       dec_end(zm,__endpg);\r
+       \r
+//       ety:='';\r
+      end;\r
+      \r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .RELOC                                                                    *)\r
+(*----------------------------------------------------------------------------*)\r
+   __reloc:\r
+    if ety<>'' then blad(zm,38) else\r
+     if macro_rept_if_test then\r
+      if not(hea and not(mne_used)) then blad(zm,83) else begin\r
+\r
+       inc(bank);\r
+       if bank>=__id_param then blad(zm,45);\r
+\r
+       test_wyjscia(zm,false);\r
+\r
+       save_hea;\r
+\r
+       if dreloc.use then begin\r
+        rel_idx:=0; ext_idx:=0; extn_idx:=0; skip.idx:=0; pub_idx:=0;\r
+        smb_idx:=0; sym_idx:=0;\r
+        ext_used.use:=false; rel_used:=false; blocked:=false;\r
+        blkupd.adr:=false; blkupd.ext:=false; blkupd.pub:=false;\r
+        blkupd.sym:=false; blkupd.new:=false;\r
+       end;\r
+\r
+       save_lst(' ');\r
+\r
+       k:=get_type(i,zm,zm,false);\r
+\r
+       if k=1 then\r
+        rel_ofs := __rel\r
+       else\r
+        rel_ofs := __relASM;\r
+\r
+       dreloc.use:=true;\r
+       adres:=rel_ofs;\r
+\r
+       first_org:=false;\r
+       org:=true;\r
+\r
+       save_dstW( __relHea );      // dodatkowy naglowek bloku relokowalnego 'MR'\r
+       save_dstW( rel_ofs );       // informacja o rodzaju bloku .WORD (bit0)\r
+\r
+     // zapisujemy wartosci etykiet dla stosu programowego\r
+       indeks:=adr_label(0,false);  save_dstW( indeks );  // @stack_pointer\r
+       indeks:=adr_label(1,false);  save_dstW( indeks );  // @stack_address\r
+       indeks:=adr_label(2,false);  save_dstW( indeks );  // @proc_vars_adr\r
+\r
+      end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .LINK 'filename'                                                          *)\r
+(*  pozwala dolaczyc kod relokowalny tzn. pliki DOS o adresie $0000           *)\r
+(*----------------------------------------------------------------------------*)\r
+   __link:\r
+//    if ety<>'' then blad(zm,38) else\r
+     if macro_rept_if_test then\r
+      if dreloc.use then blad(zm,57) else begin\r
+\r
+       save_lab(ety,adres,bank,zm);\r
+\r
+//       save_lst(zm,'a');\r
+\r
+//       omin_spacje(i,zm);\r
+       txt:=get_string(i,zm,zm,true);\r
+\r
+       txt:=GetFile(txt,zm);   if not(TestFile(txt)) then blad(txt,18);\r
+       test_eol(i,zm,zm,#0);\r
+\r
+       AssignFile(g, txt); FileMode:=0; Reset(g,1);\r
+\r
+     // sprawdzamy czy wczytujemy plik DOS'a (pierwsze dwa bajty pliku = __HEA_DOS)\r
+       t_lnk[0]:=0;\r
+       t_lnk[1]:=0;\r
+\r
+       blockread(g,t_lnk,2);\r
+       if (t_lnk[0]+t_lnk[1] shl 8)<>__hea_dos then blad(zm,74);\r
+\r
+       Reset(g,1);\r
+       blockread(g,t_lnk,sizeof(t_lnk),IDX); // wczytujemy caly plik do T_LNK o dlugosci IDX\r
+\r
+// w glownej petli uzywamy zmiennych IDX, K, _ODD\r
+\r
+ _odd:=0; dlink.use:=false; dlink.len:=0; dlink.emp:=0;\r
+\r
+ while _odd<idx do begin\r
+\r
+        j:=fgetW(_odd);\r
+        if j=$FFFF then j:=fgetW(_odd);\r
+\r
+\r
+        case j of\r
+\r
+ // blk RELOC\r
+ __hea_reloc:\r
+   begin\r
+\r
+       if dlink.use then flush_link;\r
+\r
+       k:=fgetW(_odd);              // odczytujemy dlugosc pliku relokowalnego, maks $FFFE\r
+\r
+       if k=$ffff then              // tzn ze dlugosc pliku = 0\r
+        k:=0\r
+       else\r
+        inc(k);                     // zwiekszamy o 1\r
+\r
+       j:=fgetW(_odd);              // odczytujemy 2 bajty z dodatkowego naglowka 'MR'\r
+       if j<>__relHea then blad(zm,74);\r
+(*----------------------------------------------------------------------------*)\r
+(* bajt 0 - nieuzywany                                                        *)\r
+(* bajt 1 - bit 0     kod strony zerowej (0), kod poza strona zerowa (1)      *)\r
+(*          bit 1..7  nieuzywne                                               *)\r
+(*----------------------------------------------------------------------------*)\r
+       fgetB(_odd);                 // odczytujemy 2 bajty z informacja o pliku .RELOC\r
+       v:=fgetB(_odd);\r
+\r
+       if (v=0) and (adres>$FF) then blad(zm,76);\r
+\r
+       __link_stack_pointer_old := fgetW(_odd);       // @stack_pointer\r
+       __link_stack_address_old := fgetW(_odd);       // @stack_address\r
+       __link_proc_vars_adr_old := fgetW(_odd);       // @proc_vars_adr\r
+\r
+       if pass=0 then begin\r
+\r
+        if dlink.stc then\r
+         if (__link_stack_pointer_old<>__link_stack_pointer) or\r
+            (__link_stack_address_old<>__link_stack_address) or\r
+            (__link_proc_vars_adr_old<>__link_proc_vars_adr) then warning(75);\r
+\r
+        if not(dlink.stc) then begin\r
+         __link_stack_pointer := __link_stack_pointer_old;\r
+         __link_stack_address := __link_stack_address_old;\r
+         __link_proc_vars_adr := __link_proc_vars_adr_old;\r
+\r
+         txt:=mads_stack[0]; save_fake_label(txt,zm,__link_stack_pointer); //@stack_pointer\r
+         txt:=mads_stack[1]; save_fake_label(txt,zm,__link_stack_address); //@stack_address\r
+         txt:=mads_stack[2]; save_fake_label(txt,zm,__link_proc_vars_adr); //@proc_vars_adr\r
+        end;\r
+\r
+       end;\r
+\r
+       move(t_lnk[_odd],t_ins,k);      // wczytujemy blok relokowalny do T_INS\r
+       inc(_odd,k);\r
+\r
+       dlink.len:=k; dlink.use:=true; dlink.stc:=true;\r
+   end;\r
+\r
+      // BLK UPDATE ADDRESS\r
+         __hea_address:\r
+                begin\r
+                 ch := chr( fgetB(_odd) );\r
+                 j  := fgetW(_odd);\r
+\r
+                 while j>0 do begin\r
+\r
+                  idx_get:=fgetW(_odd);\r
+                                \r
+                  tst:=adres;\r
+\r
+                  case ch of\r
+\r
+                   'E': begin                     // pusty blok rezerwujacy pamiec\r
+                         dlink.emp := idx_get;\r
+                        end;\r
+\r
+                   '<','B':\r
+                        begin\r
+                         inc(tst, t_ins[idx_get]);\r
+\r
+                         t_ins[idx_get]  := byte(tst);\r
+                        end;\r
+\r
+                   '>': begin\r
+                         inc(tst, t_ins[idx_get] shl 8);\r
+\r
+                         v:=fgetB(_odd);    // dodatkowy bajt dla relokacji starszych adresow\r
+\r
+                         inc(tst,v);\r
+\r
+                         t_ins[idx_get]  := byte(tst shr 8);\r
+                        end;\r
+\r
+                   'W': begin\r
+                         inc(tst, t_ins[idx_get]);\r
+                         inc(tst, t_ins[idx_get+1] shl 8);\r
+\r
+                         t_ins[idx_get]  := byte(tst);\r
+                         t_ins[idx_get+1]:= byte(tst shr 8);\r
+                        end;\r
+\r
+                   'L': begin\r
+                         inc(tst, t_ins[idx_get]);\r
+                         inc(tst, t_ins[idx_get+1] shl 8);\r
+                         inc(tst, t_ins[idx_get+2] shl 16);\r
+\r
+                         t_ins[idx_get]  := byte(tst);\r
+                         t_ins[idx_get+1]:= byte(tst shr 8);\r
+                         t_ins[idx_get+2]:= byte(tst shr 16);\r
+                        end;\r
+\r
+                   'D': begin\r
+                         inc(tst, t_ins[idx_get]);\r
+                         inc(tst, t_ins[idx_get+1] shl 8);\r
+                         inc(tst, t_ins[idx_get+2] shl 16);\r
+                         inc(tst, t_ins[idx_get+3] shl 24);\r
+\r
+                         t_ins[idx_get]  := byte(tst);\r
+                         t_ins[idx_get+1]:= byte(tst shr 8);\r
+                         t_ins[idx_get+2]:= byte(tst shr 16);\r
+                         t_ins[idx_get+3]:= byte(tst shr 24);\r
+                        end;\r
+\r
+                  end;\r
+\r
+                  dec(j);\r
+                 end;\r
+\r
+                end;\r
+\r
+      // BLK UPDATE EXTERNAL\r
+         __hea_external:\r
+                begin\r
+                 ch := chr ( fgetB(_odd) );\r
+                 j  := fgetW(_odd);\r
+\r
+                 txt:=fgetS(_odd);           // label_ext name\r
+\r
+                 idx_get:=load_lab(txt,false);\r
+                 if idx_get<0 then begin\r
+                  war:=0;\r
+                  if pass=pass_end then blad_und(zm,txt,73);\r
+                 end else\r
+                  war:=oblicz_wartosc(txt,zm);\r
+\r
+                 v:=ord(value_code(war,zm,true));\r
+\r
+              // sprawdzamy czy zgadza sie typ etykiety\r
+                 if pass=pass_end then\r
+                  case ch of\r
+                   'B': if chr(v)<>'Z' then blad_und(zm,txt,41);\r
+                   'W': if not(chr(v) in ['Z','Q']) then blad_und(zm,txt,41);\r
+                   'L': if not(chr(v) in ['Z','Q','T']) then blad_und(zm,txt,41);\r
+                  end;\r
+\r
+\r
+                 while j>0 do begin\r
+                  idx_get:=fgetW(_odd);\r
+\r
+                  tst:=word(war);\r
+\r
+                  case ch of\r
+                    'B','<':\r
+                         begin\r
+                          inc(tst, t_ins[idx_get]);\r
+\r
+                          t_ins[idx_get]  := byte(tst);\r
+                         end;\r
+\r
+                   '>': begin\r
+                         inc(tst, t_ins[idx_get] shl 8);\r
+\r
+                         v:=fgetB(_odd);    // dodatkowy bajt dla relokacji starszych adresow\r
+\r
+                         inc(tst,v);\r
+\r
+                         t_ins[idx_get]  := byte(tst shr 8);\r
+                        end;                         \r
+\r
+                    'W': begin\r
+                          inc(tst, t_ins[idx_get]);\r
+                          inc(tst, t_ins[idx_get+1] shl 8);\r
+\r
+                          t_ins[idx_get]  := byte(tst);\r
+                          t_ins[idx_get+1]:= byte(tst shr 8);\r
+                         end;\r
+\r
+                    'L': begin\r
+                          inc(tst, t_ins[idx_get]);\r
+                          inc(tst, t_ins[idx_get+1] shl 8);\r
+                          inc(tst, t_ins[idx_get+2] shl 16);\r
+\r
+                          t_ins[idx_get]  := byte(tst);\r
+                          t_ins[idx_get+1]:= byte(tst shr 8);\r
+                          t_ins[idx_get+2]:= byte(tst shr 16);\r
+                         end;\r
+\r
+                    'D': begin\r
+                          inc(tst, t_ins[idx_get]);\r
+                          inc(tst, t_ins[idx_get+1] shl 8);\r
+                          inc(tst, t_ins[idx_get+2] shl 16);\r
+                          inc(tst, t_ins[idx_get+3] shl 24);\r
+\r
+                          t_ins[idx_get]  := byte(tst);\r
+                          t_ins[idx_get+1]:= byte(tst shr 8);\r
+                          t_ins[idx_get+2]:= byte(tst shr 16);\r
+                          t_ins[idx_get+3]:= byte(tst shr 24);\r
+                         end;\r
+\r
+                  end;\r
+\r
+                  dec(j);\r
+                 end;\r
+\r
+                end;\r
+\r
+\r
+      // BLK UPDATE PUBLIC\r
+         __hea_public:\r
+                begin\r
+                 j:=fgetW(_odd);\r
+\r
+                  while j>0 do begin\r
+\r
+                   typ:= chr ( fgetB(_odd) );  // TYPE   B-YTE, W-ORD, L-ONG, D-WORD\r
+\r
+                   ch := chr ( fgetB(_odd) );  // LABEL_TYPE   V-ARIABLE, P-ROCEDURE, C-ONSTANT\r
+\r
+                   if dlink.use then tst:=adres else tst:=0;\r
+\r
+                   case ch of\r
+                    'P': begin\r
+                          str:=fgetS(_odd);               // label_pub name\r
+\r
+                          inc(tst, fgetW(_odd));          // adres procedury\r
+\r
+                          r:=fgetB(_odd);                 // kolejnosc rejestrow CPU\r
+\r
+                          rodzaj:=chr(fgetB(_odd));       // typ procedury\r
+\r
+                          if not(rodzaj in [__pDef, __pReg, __pVar]) then blad_und(zm,str,41);\r
+\r
+                          idx_get:=fgetW(_odd);           // liczba danych na temat parametrow\r
+\r
+\r
+                          proc_nr:=proc_idx;         // koniecznie przez ADD_PROC_NR\r
+\r
+                          \r
+                          if pass=0 then begin\r
+\r
+                           _doo:=_odd+idx_get;\r
+\r
+                           txt:='(';\r
+                           while _odd<_doo do begin\r
+\r
+                             v:=TypeToByte( chr( fgetB(_odd) ) );   // liczba bajtow przypadajaca na parametr\r
+\r
+                             txt:=txt+mads_param[v];\r
+\r
+                             case rodzaj of               // parametr jesli trzeba\r
+                              __pDef: tmp:='par'+IntToStr(_odd);\r
+\r
+                              __pReg: begin\r
+                                       tmp:='';\r
+                                       while v<>0 do begin\r
+                                        tmp:=tmp+ByteToReg(r);\r
+                                        dec(v)\r
+                                       end;\r
+                                      end;\r
+\r
+                              __pVar: tmp:=fgetS(_odd);\r
+                             end;\r
+\r
+                             txt:=txt+tmp+' ';\r
+                           end;\r
+\r
+                           txt:=txt+')';\r
+\r
+                           case rodzaj of\r
+                            __pReg: txt:=txt+' .REG';\r
+                            __pVar: txt:=txt+' .VAR';\r
+                           end;\r
+\r
+                           i:=1;\r
+                           get_procedure(str,str,txt,i);    // odczytujemy parametry\r
+\r
+                           proc:=false;                     // koniecznie wylaczamy PROC\r
+                           proc_name:='';                   // i koniecznie PROC_NAME := ''\r
+\r
+                          end else\r
+                           inc(_odd,idx_get);    // koniecznie zwiekszamy _ODD gdy PASS<>0\r
+\r
+                          upd_procedure(str,zm,tst);\r
+\r
+                          proc:=false;           // koniecznie wylaczamy PROC\r
+                          proc_name:='';         // i koniecznie PROC_NAME = ''\r
+\r
+                          add_proc_nr;           // zwiekszamy koniecznie numer procedury\r
+                         end;\r
+\r
+               'A': begin                        // upubliczniamy .ARRAY\r
+                      str:=fgetS(_odd);\r
+\r
+                      _doo:= fgetW(_odd);\r
+\r
+                      inc(tst, _doo);               // nowy adres etykiety\r
+\r
+                      save_lab(str, array_idx, __id_array, zm);\r
+\r
+                      save_arr(tst, bank);          // tutaj ARRAY_IDX zostaje zwiekszone o 1\r
+\r
+                      _doo:= fgetW(_odd);\r
+\r
+                      v:=TypeToByte( chr( fgetB(_odd) ) );\r
+\r
+                      t_arr[array_idx-1].idx:=_doo; // dlatego teraz ARRAY_IDX-1\r
+\r
+                      t_arr[array_idx-1].siz := v;\r
+                      t_arr[array_idx-1].len := (_doo+1)*v;\r
+\r
+                    end;\r
+\r
+               'S': begin                        // upubliczniamy .STRUCT\r
+                      str:=fgetS(_odd);\r
+\r
+                      _doo:= fgetW(_odd);\r
+\r
+                      upd_structure(str, zm);    // UPD_STRUCTURE ustawi wartosc STRUCT.IDX\r
+\r
+                      zapisz_lokal;\r
+                      lokal_name:=lokal_name+str+'.';\r
+\r
+                      struct.adres:=0;\r
+\r
+                      while _doo>0 do begin\r
+                       v:=TypeToByte( chr( fgetB(_odd) ) );\r
+\r
+                       str:=fgetS(_odd);\r
+\r
+                       j:=fgetW(_odd);\r
+\r
+                       save_str(str,struct.adres,v,j,adres,bank);\r
+                       save_lab(str,struct.adres,bank,zm);\r
+\r
+                       inc(struct.adres, v*j);\r
+\r
+                       inc(struct.cnt);\r
+\r
+                       dec(_doo);\r
+                      end;\r
+\r
+                      t_str[struct.idx].siz := struct.adres; // zapisujemy dlugosc struktury\r
+\r
+                      t_str[struct.idx].ofs := struct.cnt;   // i liczbe pol struktury\r
+\r
+                      inc(struct.id);  // zwiekszamy identyfikator struktury (liczba struktur)\r
+\r
+                      struct.cnt := -1;\r
+\r
+                      oddaj_lokal(zm);\r
+                    end;\r
+\r
+               'V': begin\r
+                      str:=fgetS(_odd);\r
+\r
+                      _doo:= fgetW(_odd);\r
+\r
+                      inc(tst, _doo);                  // nowy adres etykiety\r
+\r
+                      save_lab(str,tst,bank,zm);       // variable\r
+                     end;\r
+\r
+               'C': begin\r
+                      str:=fgetS(_odd);\r
+\r
+                      case typ of\r
+                       'B': vtmp:=fgetB(_odd);\r
+                       'W': vtmp:=fgetW(_odd);\r
+                       'L': vtmp:=fgetL(_odd);\r
+                       'D': vtmp:=fgetD(_odd);\r
+                      end;\r
+\r
+                      save_lab(str,vtmp,bank,zm);      // constant\r
+                    end;\r
+\r
+                   end;\r
+\r
+\r
+                   dec(j);\r
+                  end;\r
+\r
+                 end;\r
+        else\r
+\r
+   begin\r
+     flush_link;\r
+\r
+     k:=fgetW(_odd);              // odczytujemy dlugosc pliku relokowalnego\r
+     inc(k);                      // zwiekszamy o 1\r
+\r
+     testRange(zm,k, 62);         // maksymalna dlugosc pliku $FFFF\r
+\r
+     save_hea;\r
+     adres:=j; org:=true;\r
+\r
+     dlink.len:=k-j;\r
+\r
+     move(t_lnk[_odd],t_ins,dlink.len);      // wczytujemy blok relokowalny do T_INS\r
+     inc(_odd,dlink.len);\r
+   end;\r
+\r
+        end;\r
+\r
+\r
+\r
+ end;\r
+\r
+       flush_link;\r
+\r
+       closefile(g);\r
+\r
+       ety:='';\r
+      end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .PUBLIC label [,label2,label3...]                                         *)\r
+(*----------------------------------------------------------------------------*)\r
+   __public:\r
+    if ety<>'' then blad(zm,38) else\r
+     if macro_rept_if_test then begin\r
+\r
+       save_lst(' ');\r
+\r
+       omin_spacje(i,zm);\r
+\r
+       while not(test_char(i,zm,#0,#0)) do begin\r
+\r
+        txt:=get_lab(i,zm, true);\r
+\r
+        save_pub(txt,zm);\r
+\r
+        _odd:=load_lab(txt,false);\r
+        if _odd>=0 then t_lab[_odd].use:=true;     //etykieta domyslnie w uzyciu\r
+\r
+        __next(i,zm);\r
+       end;\r
+\r
+      end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  .SYMBOL label                                                             *)\r
+(*----------------------------------------------------------------------------*)\r
+ __symbol:\r
+    if macro_rept_if_test then\r
+     if not(dreloc.sdx) then blad(zm,53) else begin   // tylko gdy blok relokowalny SDX\r
+\r
+       if ety='' then ety:=get_lab(i,zm, true);\r
+\r
+       if not(test_char(i,zm,#0,#0)) then blad(zm,4);\r
+\r
+       save_lst(' ');\r
+\r
+      // zapisujemy symbol .SYMBOL w T_SYM\r
+       t_sym[sym_idx] := ety;                                  // SAVE_SYM\r
+       inc(sym_idx);                                           //\r
+       if sym_idx>High(t_sym) then SetLength(t_sym,sym_idx+1); //\r
+\r
+     end;\r
+\r
+      \r
+(*----------------------------------------------------------------------------*)\r
+(*  INS 'filename' [+-expression] [,length[,offset]]                          *)\r
+(*  .GET [index] 'filename' [+-expression] [,length[,offset]]                 *)\r
+(*----------------------------------------------------------------------------*)\r
+   __ins,__get:\r
+     if macro_rept_if_test then\r
+//      if loop_used then blad(zm,36) else       \r
+       if first_org and (opt and 1>0) and (mne.l=__ins) then blad(zm,10) else begin\r
+\r
+         data_out:=true;\r
+\r
+         idx_get:=0;\r
+\r
+         omin_spacje(i,zm);\r
+\r
+         if mne.l=__get then\r
+          if zm[i] in ['[','('] then begin\r
+           txt:=ciag_ograniczony(i,zm,true);\r
+           k:=1; idx_get:=integer( ___wartosc_noSPC(txt,zm,k,#0,'A') );\r
+          end;\r
+\r
+//         omin_spacje(i,zm);\r
+         txt:=get_string(i,zm,zm,true); \r
+\r
+         txt:=GetFile(txt,zm);   if not(TestFile(txt)) then blad(txt,18);\r
+\r
+         if (GetFileName(txt)=GetFileName(a)) or (GetFileName(txt)=GetFileName(plik_asm)) then blad(txt,18);\r
+\r
+         AssignFile(g, txt); FileMode:=0; Reset(g,1);\r
+\r
+         k:=integer(FileSize(g)); _odd:=0; _doo:=k;\r
+\r
+         v:=byte( test_string(i,zm,'B') );\r
+\r
+         if zm[i]=',' then begin\r
+          __inc(i,zm);\r
+\r
+          _odd:=integer( ___wartosc_noSPC(zm,zm,i,',','F') );\r
+\r
+          if _odd<0 then begin\r
+           _doo:=abs(_odd); _odd:=k+_odd;\r
+          end else _doo:=k-abs(_odd);\r
+\r
+          if zm[i]=',' then begin\r
+           __inc(i,zm);\r
+\r
+           _doo:=integer( ___wartosc_noSPC(zm,zm,i,',','F') );\r
+// -           testRange(zm, _doo, 13);\r
+           if _doo<0 then begin\r
+            blad(zm,13);\r
+            _doo:=0;\r
+           end;\r
+\r
+           test_eol(i,zm,zm,#0);\r
+          end;\r
+         end else test_eol(i,zm,zm,#0);\r
+\r
+        // sprawdz czy nie zostala przekroczona dlugosc pliku\r
+         if (abs(_odd)>k) or (abs(_odd)+abs(_doo)>k) then blad(zm,24);\r
+         k:=_doo;\r
+\r
+\r
+        // dlugosc pliku nie moze byc mniejsza od 0\r
+// -         testRange(zm, k, 25); //if k>$FFFF then blad(zm,25);\r
+         if k<0 then begin\r
+          blad(zm,25);\r
+          k:=0;\r
+         end;\r
+\r
+\r
+         save_lst('a');\r
+\r
+         if mne.l=__get then begin           // .GET\r
+\r
+           j:=idx_get+_doo;\r
+           testRange(zm, j, 62);  // subrange_bounds(zm,idx_get+_doo,$FFFF+1);\r
+\r
+           if _odd>0 then seek(g,_odd);      // omin _ODD bajtow w pliku\r
+           blockread(g,t_get[idx_get],_doo); // odczytaj _DOO bajtow od indeksu [IDX_GET]\r
+\r
+         end else                            // INS\r
+         if (pass=pass_end) and (_doo>0) then begin\r
+\r
+//           if opt and 1=0 then first_org := true;\r
+\r
+           if _odd>0 then seek(g,_odd);         // omin _ODD bajtow w pliku\r
+\r
+           for j:=0 to (_doo div $10000)-1 do begin\r
+            blockread(g, t_ins, $10000);        // odczytaj 64KB bajtow\r
+            for idx:=0 to $FFFF do save_dst( byte( t_ins[idx]+v ) );\r
+           end;\r
+\r
+           j:=_doo mod $10000;                  // odczytaj pozostale bajty\r
+\r
+           blockread(g, t_ins, j);\r
+\r
+           for idx:=0 to j-1 do save_dst( byte( t_ins[idx]+v ) );\r
+         end;\r
+\r
+         closefile(g);\r
+\r
+         save_lab(ety,adres,bank,zm);\r
+\r
+         if mne.l<>__get then inc(adres, k);\r
+         ety:='';\r
+        end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  END                                                                       *)\r
+(*----------------------------------------------------------------------------*)\r
+   __end, __en:\r
+        if loop_used then blad(zm,36) else begin\r
+\r
+          end_file:=true;\r
+\r
+          save_lab(ety,adres,bank,zm);\r
+\r
+          save_lst('a');\r
+\r
+          mne.l:=0;\r
+          ety:='';\r
+        end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  DTA [abefgtcd] 'string',expression...                                     *)\r
+(*  lub dodajemy nowe pola do struktury  .STRUCT                              *)\r
+(*----------------------------------------------------------------------------*)\r
+   __dta,__byte..__dword:\r
+        if macro_rept_if_test then\r
+         if first_org and (opt and 1>0) and not(struct.use) then blad(zm,10) else begin\r
+                                                     \r
+          if struct.use then begin              // zapisujemy pola struktury\r
+\r
+            if ety='' then blad(zm,15);         // pola struktury musza posiadac etykiety\r
+            if mne.l=__dta then blad(zm,58);    // przyjmujemy tylko nazwy typow\r
+\r
+            j:=mne.l-__byteValue;               // J = <1..4>\r
+            k:=adres-struct.adres;\r
+\r
+            if ety+'.'=lokal_name then blad(zm,57);  // nazwa pola musi byc <> od nazwy struktury\r
+\r
+            save_str(ety,k,j,rpt,adres,bank);\r
+            save_lab(ety,k,bank,zm);\r
+\r
+            nul.i:=k;\r
+            save_lst('l');\r
+\r
+            if loop_used then begin\r
+             loop_used:=false;\r
+             j := j*rpt;\r
+            end;\r
+\r
+            inc(adres, j);\r
+\r
+            inc(struct.cnt);                    // zwiekszamy licznik pol struktury\r
+\r
+//            ety:='';\r
+\r
+          end else\r
+           create_struct_data(i,zm,ety, mne.l);\r
+\r
+          ety:='';\r
+         end;\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  ICL 'filename'                                                            *)\r
+(*----------------------------------------------------------------------------*)\r
+   __icl:\r
+       if macro_rept_if_test then\r
+        if loop_used then blad(zm,36) else begin\r
+\r
+          save_lab(ety,adres,bank,zm);\r
+          save_lst('a');\r
+\r
+          txt:=get_string(i,zm,zm,true);\r
+\r
+          txt:=GetFile(txt,zm);\r
+\r
+          if not(TestFile(txt)) then begin\r
+           tmp:=GetFile(txt+'.asm', zm);\r
+\r
+           if not(TestFile(tmp)) then\r
+            blad(txt,18)\r
+           else\r
+            txt:=tmp;\r
+\r
+          end;\r
+\r
+          test_eol(i,zm,zm,#0);\r
+\r
+//          if (GetFileName(txt)=GetFileName(a)) or (GetFileName(txt)=GetFileName(plik_asm)) then blad(txt,18);\r
+          if (txt=a) or (txt=plik_asm) then blad(txt,18);\r
+\r
+        // sprawdzamy czy jest to plik tekstowy w pierwszych dwóch przebiegach asemblacji\r
+          if pass<2 then begin\r
+           assignfile(f, txt); FileMode:=0; Reset(f);\r
+           readln(f, tmp);\r
+           CloseFile(f);\r
+           if pos(#0,tmp)>0 then blad(zm,74);\r
+          end;\r
+\r
+          str:=zm; zapisz_lst(str);\r
+\r
+          old_icl_used := icl_used;\r
+          icl_used:=true;\r
+\r
+          analizuj_plik__(txt,zm);\r
+\r
+          bez_lst:=true;\r
+//          put_lst(show_full_name(a,full_name,true),'');\r
+          global_name:=a;\r
+\r
+          line:=nr;\r
+\r
+          icl_used := old_icl_used;\r
+\r
+          ety:='';\r
+          mne.l:=0;\r
+         end;\r
+\r
+  end;\r
+\r
+\r
+ // zapamietanie etykiety jesli wystapila\r
+ // i zapisanie zdekodowanych rozkazow\r
+  if if_test then begin\r
+\r
+   omin_spacje(i,zm);\r
+   txt:=''; ___search_comment_block(i,zm,txt);\r
+\r
+   if ety<>'' then begin\r
+\r
+//    if mne_used then\r
+\r
+     label_type:='V';          // !!! koniecznie label_type = V-ariable\r
+\r
+//    else\r
+//     label_type:='C';\r
+\r
+    if pass=pass_end then\r
+     if adres<0 then warning(10);\r
+\r
+    save_lab(ety,adres,bank,zm);   // pozostale etykiety bez zmian\r
+\r
+    save_lst('a');\r
+   end;\r
+\r
+\r
+//   writeln(zm,' | ',if_test);\r
+\r
+\r
+   if mne.l<__equ then begin\r
+\r
+    nul:=mne;\r
+\r
+    if (mne.l=0) and (ety='') then\r
+     save_lst(' ')\r
+    else\r
+     save_lst('a');\r
+\r
+    nul.l:=0;\r
+   end;\r
+\r
+  end;\r
+\r
+\r
+ // zapisz wynik asemblacji do pliku LST\r
+\r
+  if not(loop_used) and not(FOX_ripit) then begin\r
+\r
+   if not(bez_lst) then zapisz_lst(zm);\r
+\r
+\r
+   bez_lst:=false;\r
+ end;\r
+\r
+end;\r
+\r
+\r
+procedure get_line(var zm:string; var end_file,ok:Boolean; var _odd,_doo:integer; var app: Boolean; var appLine: string);\r
+(*----------------------------------------------------------------------------*)\r
+(*  pobieramy linie i sprawdzamy czy linia nie jest komentarzem               *)\r
+(*----------------------------------------------------------------------------*)\r
+var i, j: integer;\r
+    str: string;\r
+begin\r
+   if end_file then exit;\r
+\r
+    noWarning:=false;\r
+\r
+   if not(macro) and not(rept) then\r
+    if komentarz then begin\r
+     i:=1;\r
+     str:=''; search_comment_block(i,zm,str);\r
+\r
+     if str<>'' then begin\r
+       save_lst(' ');\r
+       justuj;\r
+       put_lst(t+zm);\r
+\r
+       zm:=copy(zm,i,length(zm));\r
+      end;\r
+\r
+    end;\r
+\r
+\r
+    if not(komentarz) then\r
+    if not(macro) and not(rept) and (pos('\',zm)>0) then begin   // pobie¿ny test na obecnosc znaku '\'\r
+     i:=1;\r
+     str:=get_dat(i,zm,'\',false);                 // tutaj sprawdzamy dokladniej\r
+\r
+     SetLength(t_lin, 1);\r
+\r
+     if zm[i]='\' then begin\r
+       save_lst(' ');\r
+       justuj;\r
+       put_lst(t+zm);\r
+\r
+       _odd:=High(t_lin);\r
+       i:=1;\r
+       while true do begin\r
+        str:=get_dat(i,zm,'\',false);\r
+\r
+        j:=1; omin_spacje(j, str);\r
+        if j>length(str) then str:='';\r
+\r
+        j:=High(t_lin);       // SAVE_LIN\r
+        t_lin[j]:=str;        //\r
+        SetLength(t_lin,j+2); //\r
+\r
+        if zm[i]='\' then inc(i) else Break;\r
+       end;\r
+\r
+       _doo:=High(t_lin);\r
+\r
+\r
+       if str='' then begin\r
+        app:=true;\r
+\r
+        appLine:=appLine+t_lin[_doo-2];\r
+\r
+        dec(_doo,2);\r
+       end;\r
+\r
+\r
+       lst_off:=true;\r
+\r
+       ok:=false;\r
+       exit;\r
+     end;\r
+\r
+    end;\r
+\r
+\r
+   app:=false;\r
+\r
+   i:=1;\r
+\r
+   if zm<>'' then begin\r
+    omin_spacje(i,zm);\r
+\r
+    if not((zm[i] in [';','*']) or ((zm[i]='|') and (zm[i+1]<>'|'))  or komentarz) then ok:=true;\r
+\r
+    str:=''; ___search_comment_block(i,zm, str);\r
+   end;\r
+\r
+\r
+// !!! linie z komentarzem /* */ byly traktowane jako puste linie !!!\r
+\r
+{ omin_spacje(i,zm);                // sprawdzamy czy wiersz nie zawiera samych "bialych znakow"\r
+\r
+ if not(macro) and not(rept) then\r
+  if (i>length(zm)) then begin\r
+   ok:=false;\r
+\r
+   if not(komentarz) then zm:='';  // jesli nie jest to komentarz to zapiszemy tylko pusty wiersz\r
+  end;  }\r
+\r
+\r
+ if not(macro) and not(rept) and not(run_macro) and not(rept_run) then\r
+  if (zm='') or not(ok) then begin\r
+   save_lst(' ');\r
+\r
+   if zm<>'' then\r
+    justuj\r
+   else\r
+    SetLength(t,6);\r
+\r
+   put_lst(t+zm);\r
+\r
+   ok:=false;\r
+  end;\r
+\r
+end;\r
+\r
+\r
+procedure analizuj_plik(var a:string; var old_str: string);\r
+(*----------------------------------------------------------------------------*)\r
+(*  odczyt pliku ASM wiersz po wierszu                                        *)\r
+(*----------------------------------------------------------------------------*)\r
+var f: textfile;\r
+    rept_nr, rept_ile, nr, _odd, _doo: integer;\r
+    end_file, ok, wyjscie, app, _app: Boolean;\r
+    zm, appLine, _appLine: string;\r
+    v: byte;\r
+begin\r
+ if not(TestFile(a)) then blad(a,18);\r
+\r
+ AssignFile(f,a); FileMode:=0; Reset(f);\r
+\r
+ _odd:=0; _doo:=0; rept_ile:=0; rept_nr:=0;\r
+\r
+ nr:=0;                        // nr linii w asemblowanym pliku\r
+ global_name:=a;               // nazwa pliku dla funkcji 'BLAD'\r
+ end_file:=false;              // czy napotkal rozkaz 'END'\r
+ wyjscie:=false;               // czy wystapilo EXIT w makrze\r
+\r
+ app:=false; appLine:='';\r
+ _app:=false; _appLine:='';\r
+\r
+\r
+ // nazwe pierwszego pliku zawsze zapisze do LST\r
+ // pod warunkiem ze (opt and 4>0) czyli wystapilo OPT L+\r
+ if (opt and 4>0) then\r
+  if (pass=pass_end) and (a[2]=':') then\r
+   writeln(lst,show_full_name(global_name,true,true))\r
+  else\r
+   put_lst(show_full_name(global_name,full_name,true));\r
+\r
+\r
+ while (not eof(f)) or (_doo>0) do begin\r
+\r
+  ok:=false;\r
+\r
+  if _doo>0 then begin\r
+   zm:=t_lin[_odd];\r
+   inc(_odd);\r
+   if _odd>=_doo then begin _doo:=0; lst_off:=false; end;\r
+\r
+   get_line(zm,end_file,ok,_odd,_doo, _app,_appLine);  \r
+\r
+  end else begin\r
+   readln(f,zm);\r
+\r
+   if length(zm)>$FFFF then begin       // maksymalna dlugosc wiersza 65535 znakow\r
+    blad(zm,101); koniec(2)\r
+   end;\r
+\r
+   inc(nr); line:=nr; inc(line_all);\r
+\r
+   get_line(zm,end_file,ok,_odd,_doo, app,appLine);\r
+\r
+   if ok and not(app) and (appLine<>'') then begin\r
+    save_lst(' ');\r
+    justuj;\r
+    put_lst(t+zm);\r
+\r
+    zm:=appLine+zm;\r
+    appLine:='';       \r
+   end;\r
+\r
+  end;\r
+\r
+\r
+  if macro then begin\r
+   v:=dirMACRO(zm);\r
+\r
+   if v in [{__end+1,} __en] then end_file:=true;       // !!! dla __end+1 zatrzyma sie gdy 'lda end' \r
+\r
+  end else       \r
+\r
+    if rept then begin\r
+\r
+     v:=dirREPT(zm); \r
+\r
+     if v=__endr then\r
+      dirENDR(zm,a,old_str,rept_nr,rept_ile)\r
+     else\r
+      if v in [__end+1, __en] then end_file:=true;\r
+\r
+    end else\r
+                          \r
+     if ok and not(komentarz) then\r
+      analizuj_linie(zm,a,old_str, rept_nr,rept_ile, nr, end_file,wyjscie);\r
+\r
+\r
+  if end_file then Break;\r
+\r
+ end;\r
+\r
+\r
+ if appLine<>'' then analizuj_linie(appLine,a,old_str, rept_nr,rept_ile, nr, end_file,wyjscie);\r
+\r
+\r
+ test_skipa;\r
+ if skip.use then blad(zm,84);             // Can't skip over this\r
+\r
+\r
+ oddaj_var;\r
+\r
+ if a=plik_asm then oddaj_ds;  // !!! koniecznie tutaj, inaczej po ICL z .DS bedzie generowal nowy blok EMPTY\r
+\r
+\r
+ if pass=pass_end then\r
+ if (a=plik_asm) {and not(first_org)} then begin    // wymuszamy BLK UPDATE na koncu glownego pliku\r
+\r
+  if dreloc.use or dreloc.sdx then begin\r
+\r
+   save_lst('a');\r
+   if not(blkupd.adr) then begin zm:=load_mes(91)+load_mes(92); blk_update_address(zm) end;\r
+   save_lst('a');\r
+   if not(blkupd.ext) then begin zm:=load_mes(91)+load_mes(93); blk_update_external(zm) end;\r
+   save_lst('a');\r
+   if not(blkupd.pub) then begin zm:=load_mes(91)+load_mes(94); blk_update_public(zm) end;\r
+   save_lst('a');\r
+   if not(blkupd.sym) then begin zm:=load_mes(91)+load_mes(95); blk_update_symbol(zm) end;\r
+   save_lst('a');\r
+\r
+   oddaj_sym;\r
+\r
+  end;\r
+\r
+ end;\r
+\r
+\r
+ test_wyjscia(zm,wyjscie);\r
+\r
+ closefile(f);\r
+end;\r
+\r
+\r
+\r
+procedure analizuj_mem(const start,koniec:integer; var old,a,old_str:string; licz:integer; const p_max:integer; const rp:Boolean);\r
+(*----------------------------------------------------------------------------*)\r
+(*  odczyt i analiza wierszy zapisanych w tablicy dynamicznej T_MAC           *)\r
+(*  P_MAX okresla liczbe powtorzen                                            *)\r
+(*----------------------------------------------------------------------------*)\r
+var rept_ile, rept_nr, licznik, nr, _odd, _doo, old_line_add: integer;\r
+    end_file, ok, wyjscie, old_icl_used, app, _app: Boolean;\r
+    zm, appLine, _appLine: string;\r
+    v: byte;\r
+begin\r
+\r
+ old_icl_used := icl_used;\r
+ icl_used     := true;\r
+\r
+ old_line_add := line_add;     // !!! koniecznie zapamietac LINE_ADD !!!\r
+ line_add     := 0;            // inaczej numer linii z bledem dla np. "lda:cmp:rq" bedzie zly\r
+\r
+\r
+ _odd:=0; _doo:=0; rept_ile:=0; rept_nr:=0;\r
+\r
+ while licz < p_max do begin\r
+\r
+ if rp or FOX_ripit then ___rept_ile := licz;\r
+\r
+ licznik:=start;\r
+\r
+ nr:=old_line_add;             // nr linii w asemblowanym pliku\r
+ end_file:=false;              // czy napotkal rozkaz 'END'\r
+ wyjscie:=false;               // czy wystapilo EXIT w makrze\r
+\r
+ app:=false; appLine:='';\r
+ _app:=false; _appLine:='';\r
+\r
+             \r
+ while (licznik<koniec) or (_doo>0) do begin\r
+\r
+  ok:=false;\r
+\r
+  if _doo>0 then begin\r
+\r
+   zm:=t_lin[_odd];  inc(_odd);\r
+\r
+   if _odd>=_doo then begin\r
+    _doo:=0; lst_off:=false\r
+   end;\r
+\r
+   get_line(zm,end_file,ok, _odd,_doo, _app,_appLine);\r
+\r
+  end else begin\r
+   zm:=t_mac[licznik];\r
+\r
+   reptLine(zm);       // podstawiamy parametry w bloku .REPT\r
+\r
+   inc(licznik);\r
+\r
+   inc(nr);\r
+   line:=nr;    \r
+\r
+   inc(line_all);\r
+\r
+   get_line(zm,end_file,ok, _odd,_doo, app,appLine);\r
+\r
+   if ok and not(app) and (appLine<>'') then begin\r
+    save_lst(' ');\r
+    justuj;\r
+    put_lst(t+zm);\r
+       \r
+    zm:=appLine+zm;\r
+    appLine:='';    \r
+   end;\r
+\r
+  end;\r
+                    \r
+\r
+   if rept then begin\r
+\r
+     v:=dirREPT(zm);\r
+\r
+     if v=__endr then\r
+      dirENDR(zm,a,old_str,rept_nr,rept_ile)\r
+     else\r
+      if v in [__end+1, __en] then end_file:=true;\r
+\r
+   end else\r
+\r
+    if ok and not(end_file) and not(komentarz) then\r
+     analizuj_linie(zm,a,old_str, rept_nr,rept_ile, nr, end_file,wyjscie);\r
+\r
+\r
+  if wyjscie then Break;          // zakonczenie przetwarzania makra przez dyrektywe .EXIT\r
+\r
+ end;\r
+\r
+\r
+ if appLine<>'' then analizuj_linie(appLine,a,old_str, rept_nr,rept_ile, nr, end_file,wyjscie);\r
+\r
+\r
+ test_wyjscia(old,wyjscie);\r
\r
+ inc(licz);\r
+ end;\r
+\r
+      icl_used      := old_icl_used;\r
+      line_add      := old_line_add;\r
+end;\r
+\r
+\r
+\r
+procedure asem(var a:string);\r
+(*----------------------------------------------------------------------------*)\r
+(*  asemblacja glownego pliku *.ASM                                           *)\r
+(*----------------------------------------------------------------------------*)\r
+var i: integer;\r
+    s: string;\r
+begin\r
+\r
+ while (pass<=pass_end) and (pass<pass_max) do begin   // maksymalnie PASS_MAX przebiegow\r
+\r
+  line_all:=0;\r
+\r
+  s:='';\r
+  analizuj_plik(a, s);\r
+                         \r
+  if list_mac then begin\r
+   s:=' icl '''+plik_mac+'''';\r
+   analizuj_plik(plik_mac, s);\r
+  end;\r
+\r
+  t_hea[hea_i]:=adres-1;           // koniec programu, ostatni wpis\r
+\r
+  inc(pass);\r
+\r
+ // jesli NEXT_PASS = TRUE to zwieksz liczbe przebiegow\r
+  if (pass>=pass_end) or (pass<1) then\r
+   if next_pass then inc(pass_end);\r
+\r
+ // !!! zerowanie numeru wywolania makra !!!\r
+  for i:=High(t_lab)-1 downto 0 do\r
+   if t_lab[i].bnk=__id_macro then t_mac[ t_lab[i].adr + 3 ] := '0';\r
+\r
+  label_type:='V';\r
+\r
+  zpvar:=$80;\r
+\r
+  adres:=-$FFFF; raw.old:=-$FFFF;\r
+\r
+  hea_ofs.adr:=-1; struct.cnt:=-1; ___rept_ile:=-1;\r
+\r
+  regOpty.reg[0]:=-1; regOpty.reg[1]:=-1; regOpty.reg[2]:=-1;\r
+\r
+  array_used.max:=0;\r
+\r
+  fillchar(t_zpv, sizeof(t_zpv), false);\r
+\r
+  hea_i:=0; bank:=0; ifelse:=0; blok:=0; rel_ofs:=0; org_ofset:=0;\r
+  proc_idx:=0; proc_nr:=0; lokal_nr:=0; lc_nr:=0; fill:=0;\r
+  line_add:=0; struct.id:=0; wyw_idx:=0; rel_idx:=0; array_idx:=0;\r
+  ext_idx:=0; extn_idx:=0; skip.idx:=0; smb_idx:=0; sym_idx:=0;\r
+  pag_idx:=0; end_idx:=0; var_idx:=0; pub_idx:=0; usi_idx:=0;\r
+  whi_idx:=0; while_nr:=0; ora_nr:=0; test_nr:=0;\r
+  test_idx:=0; var_id:=0; proc_lokal:=0;\r
+\r
+  __link_stack_pointer := adr_label(0,false);       // @STACK_POINTER\r
+  __link_stack_address := adr_label(1,false);       // @STACK_ADDRESS\r
+  __link_proc_vars_adr := adr_label(2,false);       // @PROC_VARS_ADR\r
+\r
+  siz_idx:=1;\r
+\r
+  opt := optDefault;\r
+\r
+  hea:=true; first_org:=true; if_test:=true; TestWhileOpt:=true;\r
+  exProcTest:=true;\r
+\r
+  regOpty.use:=false; regOpty.blk:=false; mae_labels:=false;\r
+  loop_used:=false; macro:=false; proc:=false; regAXY_opty:=false;\r
+  undeclared:=false; new_local:=false;\r
+  icl_used:=false; bez_lst:=false; empty:=false; enum.use:=false;\r
+  reloc:=false; branch:=false; vector:=false; rept:=false; rept_run:=false;\r
+  struct.use:=false; dta_used:=false; code6502:=false;\r
+  struct_used.use:=false; aray:=false; next_pass:=false;\r
+  mne_used:=false; skip.use:=false; skip.xsm:=false; FOX_ripit:=false;\r
+  put_used:=false; ext_used.use:=false; dreloc.use:=false; dreloc.sdx:=false;\r
+  rel_used:=false; blocked:=false; dlink.stc:=false;\r
+  blokuj_zapis:=false; overflow:=false; test_symbols:=false;\r
+  lst_off:=false; noWarning:=false; raw.use:=false; variable:=false;\r
+\r
+  komentarz:=false; org:=false;\r
+\r
+  lokal_name:=''; macro_nr:=''; str_blad:=''; while_name:=''; test_name:='';\r
+\r
+  warning_old:='';\r
+\r
+\r
+//  SetLength(t_lin, 1);              // T_LIN mozemy zapisywac od nowa\r
+\r
+  \r
+  if binary_file.use then begin\r
+   adres     := binary_file.adr;\r
+   org       := true;\r
+   first_org := false;\r
+  end;\r
+\r
+ end;\r
+\r
+\r
+ // jesli nie wystapil zaden blad i mamy 16 przebiegow to na pewno nastapila petla bez konca\r
+\r
+ if (status=0) and (pass=pass_max) then begin\r
+  writeln(#13#10'Infinite loop !!!');\r
+  koniec(2);\r
+ end;\r
\r
+end;\r
+\r
+\r
+procedure Syntax;\r
+(*----------------------------------------------------------------------------*)\r
+(*  wyswietlamy informacje na temat przelacznikow, konfiguracji MADS'a        *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+ Writeln(load_mes(119+1));\r
+ Writeln(load_mes(117+1));\r
+ halt(3);\r
+end;\r
+\r
+\r
+function NewFileExt(nam: string; const ext: string): string;\r
+begin\r
+\r
+ if pos('.',nam)>0 then begin\r
+  obetnij_kropke(nam);\r
+  Result:=nam+ext;\r
+ end else\r
+  Result:=nam+'.'+ext;\r
+\r
+end;\r
+\r
+\r
+function nowy_plik(var a: string; var i:integer): string;\r
+var name, path: string;\r
+begin\r
+\r
+ path:='';\r
+\r
+ Result:=a;\r
+\r
+ inc(i,2);                          // omijamy znak przelacznika i znak ':'\r
+\r
+ name:=copy(t,i,length(t));\r
+\r
+ if GetFilePath(name)<>'' then path:=GetFilePath(name);\r
+\r
+ if name<>'' then Result:=path+GetFileName(name);\r
+\r
+ inc(i,length(name));\r
+end;\r
+\r
+\r
+procedure INITIALIZE;\r
+(*----------------------------------------------------------------------------*)\r
+(*  procedura obliczajaca tablice CRC16, CRC32, mniej miejsca zajmuje anizeli *)\r
+(*  gotowa predefiniowana tablica                                             *)\r
+(*----------------------------------------------------------------------------*)\r
+var IORes, _i, x, y: integer;\r
+    crc: cardinal;\r
+    crc_: Int64;\r
+    tmp: string;\r
+\r
+const\r
+ // HASH_VAL i HASH_OFS wylicza osobny program\r
+ // nie trzeba przechowywac w pamieci stringow z nazwami\r
+ hash_val: array [0..282] of byte=(\r
+ $56,$01,$58,$42,$1E,$1F,$E0,$59,$F0,$3E,$0E,$86,\r
+ $A0,$04,$9E,$9E,$29,$2A,$98,$98,$43,$48,$8D,$89,\r
+ $8C,$93,$97,$3C,$CA,$3D,$D3,$9D,$0A,$33,$9F,$9B,\r
+ $9B,$07,$50,$12,$22,$18,$13,$51,$36,$9F,$9B,$9B,\r
+ $E2,$4E,$9D,$9C,$24,$44,$1B,$49,$08,$85,$9C,$97,\r
+ $BC,$57,$63,$32,$9F,$9B,$9B,$A2,$63,$A2,$65,$83,\r
+ $B9,$B6,$F0,$68,$CD,$54,$23,$19,$AA,$31,$9F,$9B,\r
+ $9B,$8A,$67,$20,$AC,$6B,$45,$94,$17,$A6,$A2,$87,\r
+ $9C,$5B,$9C,$15,$30,$97,$9F,$9B,$9B,$5C,$09,$5A,\r
+ $4C,$55,$D6,$BF,$C6,$61,$C2,$88,$40,$C3,$70,$3B,\r
+ $3A,$1C,$1D,$0F,$0C,$3F,$BE,$2F,$4D,$41,$35,$9F,\r
+ $9B,$9B,$A5,$99,$99,$14,$16,$AC,$0B,$0D,$34,$9F,\r
+ $9B,$9B,$4F,$A6,$84,$21,$37,$9F,$9B,$9B,$2B,$AF,\r
+ $A1,$D4,$38,$A3,$8B,$82,$F0,$8E,$69,$95,$81,$B2,\r
+ $1A,$A3,$9A,$9A,$9C,$B8,$9C,$97,$A4,$62,$2D,$02,\r
+ $28,$46,$4A,$BA,$68,$26,$11,$CB,$2E,$05,$9E,$9E,\r
+ $53,$2C,$03,$27,$47,$4B,$25,$10,$06,$9E,$9E,$52,\r
+ $AB,$D7,$39,$E1,$6F,$A9,$67,$6D,$6A,$A7,$69,$C9,\r
+ $B7,$A7,$D1,$77,$62,$F0,$CE,$71,$74,$76,$F0,$AA,\r
+ $A9,$B9,$AE,$D5,$61,$A4,$B0,$C1,$BB,$65,$B4,$66,\r
+ $AD,$64,$BE,$BD,$CF,$AE,$C5,$B0,$CC,$C0,$73,$75,\r
+ $6E,$C8,$66,$A1,$C3,$6C,$B1,$6B,$D8,$6C,$CF,$D8,\r
+ $CE,$B3,$6A,$D0,$B4,$CD,$C4,$C3,$C7,$72,$CC,$AA,\r
+ $64,$A8,$D0,$C0,$AF,$B5,$D2);\r
+\r
+ hash_ofs: array [0..282] of word=(\r
+ $0458,$048C,$04A4,$04B0,$0510,$0590,$059E,$05C9,$060E,$0642,$064F,$0684,\r
+ $068A,$0693,$06CD,$06ED,$0714,$0734,$0853,$0881,$0910,$0990,$09AC,$09AE,\r
+ $09B2,$09B3,$0A03,$0A54,$0A68,$0A74,$0A82,$0AB3,$0C53,$0C62,$0C6A,$0C72,\r
+ $0C73,$0C81,$0C94,$0CA4,$0CB3,$0D83,$0DC9,$0E74,$0EC2,$0ECA,$0ED2,$0ED3,\r
+ $0EF2,$1074,$1081,$10A4,$10B3,$1110,$1183,$1190,$11C1,$11C5,$11C9,$1203,\r
+ $1284,$1478,$155E,$15C2,$15CA,$15D2,$15D3,$1925,$1A4F,$1B79,$1C4B,$1E4F,\r
+ $1EE6,$1EE7,$20ED,$2258,$22D8,$2437,$24B3,$2583,$2585,$25A2,$25AA,$25B2,\r
+ $25B3,$25C9,$266F,$2692,$2760,$2C28,$2D10,$2D82,$2E42,$2F88,$2FDC,$3069,\r
+ $30A4,$31AA,$31C9,$31F2,$3202,$3203,$320A,$3212,$3213,$3242,$3261,$326A,\r
+ $3292,$3497,$3538,$354A,$361E,$3721,$3AA5,$3AB2,$3ACD,$3FD3,$400D,$40B2,\r
+ $40B3,$4110,$4190,$41A3,$41AA,$41E3,$41E6,$41EE,$4293,$42CD,$44A2,$44AA,\r
+ $44B2,$44B3,$463C,$4910,$4990,$49E5,$49F2,$4A25,$4A6A,$4A6C,$4C62,$4C6A,\r
+ $4C72,$4C73,$4C74,$4D85,$4DC9,$4E92,$4EC2,$4ECA,$4ED2,$4ED3,$4F14,$4FA1,\r
+ $50C9,$50FC,$5122,$51D4,$51E2,$520F,$521A,$5245,$5297,$5305,$5625,$56C2,\r
+ $5983,$5A04,$5C53,$5C81,$5CA4,$5D5E,$5DC9,$5E03,$5E83,$5EDF,$6034,$608C,\r
+ $60A4,$6110,$6190,$61A1,$61A6,$61C9,$6203,$6231,$6274,$6293,$62CD,$62ED,\r
+ $6334,$6434,$648C,$64A4,$6510,$6590,$65C9,$6603,$6693,$66CD,$66ED,$6714,\r
+ $68C2,$6A46,$6A93,$6B3A,$733C,$73F5,$7833,$7B65,$7C8D,$7D7A,$7E9D,$7F58,\r
+ $7F79,$8154,$843F,$864A,$8976,$8A4B,$8C5C,$8D4A,$92F2,$9704,$987A,$990E,\r
+ $9998,$9B88,$9E9D,$9F41,$9F52,$A152,$A307,$A3EE,$A421,$A934,$A9FB,$AB24,\r
+ $ACD0,$AFC6,$B2B3,$B633,$B904,$B9DA,$B9F0,$BA41,$BFBD,$C10A,$C257,$CA0E,\r
+ $CA5A,$CD5F,$CDE6,$CE0D,$CF8A,$D040,$D0C2,$D0CD,$D417,$D894,$D91C,$DB0C,\r
+ $DE1A,$E073,$E3FC,$E767,$E829,$E97F,$EB60,$EBA8,$F129,$F166,$F1FE,$F353,\r
+ $F5F1,$F6D0,$F6E5,$F88C,$F8D5,$FAC5,$FCCE);\r
+\r
+begin\r
+\r
+// szukanie indeksow dla MES\r
+ y:=0;\r
+ for x:=0 to sizeof(mes)-1 do\r
+  if ord(mes[x])>$7f then begin\r
+   dec(mes[x],$80);\r
+   imes[y]:=x;\r
+   inc(y);\r
+  end;\r
\r
+\r
+ for x:=0 to 255 do begin\r
+\r
+  crc:=x shl 8;\r
+  crc_:=crc;\r
+\r
+  for y:=1 to 8 do begin\r
+   crc := crc shl 1;\r
+   crc_ := crc_ shr 1;\r
+\r
+   if (crc and $00010000) > 0 then crc := crc xor $1021;\r
+   if (crc_ and $80) > 0 then crc_ := crc_ xor $edb8832000;\r
+  end;\r
+\r
+  tcrc16[x] := integer(crc);\r
+  tcrc32[x] := cardinal(crc_ shr 8);\r
+ end;\r
+\r
+\r
+ for IORes:=sizeof(hash_val)-1 downto 0 do hash[hash_ofs[IORes]] := hash_val[IORes];\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*  przetwarzanie parametrow, inicjalizacja zmiennych                         *)\r
+(*----------------------------------------------------------------------------*)\r
+\r
+ plik_asm:=''; \r
+\r
+ if ParamCount<1 then Syntax;\r
+\r
+ // odczyt parametrow\r
+ for IORes:=1 to ParamCount do begin\r
+  t:=ParamStr(IORes);\r
+\r
+  if t<>'' then\r
+//  if not(t[1] in ['/','-']) then begin\r
+  if not(t[1]='-') then begin              // w celu kompatybilnosci z Linuxami, Mac OS X\r
+\r
+   if plik_asm<>'' then      \r
+    Syntax\r
+   else\r
+    plik_asm:=t\r
+    \r
+  end else begin\r
+\r
+   _i:=2;\r
+   while _i<=length(t) do begin\r
+\r
+   case UpCase(t[_i]) of\r
+\r
+\r
+    'C': case_used    := true;\r
+    'F': labFirstCol  := true;\r
+    'P': full_name    := true;\r
+    'S': silent       := true;\r
+    'X': exclude_proc := true;\r
+    'U': unused_label := true;\r
+    'V': if UpCase(t[_i+1])='U' then begin inc(_i,2); VerifyProc := true end;\r
+\r
+\r
+    'B': if t[_i+1]<>':' then\r
+          Syntax\r
+         else begin\r
+          inc(_i,2);\r
+\r
+          tmp:=get_dat(_i,t,' ',true);\r
+\r
+          binary_file.adr := integer( oblicz_wartosc(tmp, t) );\r
+\r
+          binary_file.use := true;\r
+         end;\r
+    \r
+    'D': if t[_i+1]<>':' then Syntax else begin\r
+          inc(_i,2);\r
+          def_label:=get_lab(_i,t, true);\r
+\r
+          if t[_i]<>'=' then\r
+           nul.i:=1\r
+          else begin\r
+           inc(_i);\r
+           nul.i:=integer( get_expres(_i,t,t, false) );\r
+          end; \r
+\r
+          s_lab(def_label,nul.i,bank,t,def_label[1]);\r
+         end;\r
+\r
+    'H': begin\r
+          inc(_i);\r
+\r
+          case UpCase(t[_i]) of\r
+           'C': begin\r
+                 list_hhh:=true;\r
+                 if t[_i+1]=':' then plik_h:=nowy_plik(plik_h, _i);\r
+                end;\r
+\r
+           'M': begin\r
+                 list_mmm:=true;\r
+                 if t[_i+1]=':' then plik_hm:=nowy_plik(plik_hm, _i);\r
+                end;\r
+           else\r
+            Syntax\r
+           end;\r
+\r
+         end;\r
+\r
+    'I': if t[_i+1]<>':' then Syntax else begin\r
+          name:=nowy_plik(name, _i);\r
+\r
+          if name='' then Syntax else begin\r
+           t_pth[High(t_pth)]:=name;            \r
+           SetLength(t_pth, High(t_pth)+2);\r
+          end;\r
+\r
+         end;\r
+\r
+    'L': begin\r
+          opt:=opt or 4;\r
+          if t[_i+1]=':' then plik_lst:=nowy_plik(plik_lst, _i);\r
+         end;\r
+\r
+    'M': if t[_i+1]<>':' then Syntax else begin\r
+          list_mac:=true;\r
+          plik_mac:=nowy_plik(plik_mac, _i);\r
+         end;\r
+\r
+    'O': if t[_i+1]<>':' then Syntax else plik_obj:=nowy_plik(plik_obj, _i);\r
+\r
+    'T': begin\r
+          list_lab:=true;\r
+          if t[_i+1]=':' then plik_lab:=nowy_plik(plik_lab, _i);\r
+         end;\r
+\r
+   else\r
+    Syntax;\r
+   end;\r
+\r
+   inc(_i);\r
+   end;\r
+\r
+  end;\r
+\r
+ end;\r
+\r
+\r
+ if (plik_asm='') or (GetFileName(plik_asm)='') then Syntax;\r
+\r
+ path:=GetFilePath(plik_asm);\r
+ if path='' then begin GetDir(0,path); path:=path+PathDelim end;\r
+\r
+ name:=GetFileName(plik_asm);\r
+ global_name:=name;\r
+\r
+// sprawdzamy obecnosc pliku ASM\r
+ plik_asm:=path+name;\r
+ if not(TestFile(plik_asm)) then plik_asm := path + NewFileExt(name,'asm');\r
+\r
+\r
+ if plik_lst = '' then plik_lst := path + NewFileExt(name,'lst');\r
+ if plik_obj = '' then plik_obj := path + NewFileExt(name,'obx');\r
+ if plik_lab = '' then plik_lab := path + NewFileExt(name,'lab');\r
+ if plik_mac = '' then plik_mac := path + NewFileExt(name,'mac');\r
+ if plik_h   = '' then plik_h   := path + NewFileExt(name,'h');\r
+ if plik_hm  = '' then plik_hm  := path + NewFileExt(name,'hea');\r
+\r
+ t:=load_mes(119+1);\r
+\r
+// if not(silent) then new_message(t);\r
+\r
+ if list_lab then begin\r
+  WriteAccessFile(plik_lab); AssignFile(lab,plik_lab); FileMode:=1; Rewrite(lab);\r
+  writeln(lab,t);\r
+  writeln(lab,load_mes(54+1));\r
+ end;\r
+\r
+\r
+ name:=GetFileName(plik_asm);\r
+ _i:=1; name:=get_datUp(_i,name,'.',false);\r
+                              \r
+ if list_mmm then begin\r
+  WriteAccessFile(plik_hm); AssignFile(mmm,plik_hm); FileMode:=1; Rewrite(mmm);\r
+ end;\r
+\r
+ if list_hhh then begin\r
+  WriteAccessFile(plik_h); AssignFile(hhh,plik_h); FileMode:=1; Rewrite(hhh);\r
+  writeln(hhh,'#ifndef _'+name+'_ASM_H_');\r
+  writeln(hhh,'#define _'+name+'_ASM_H_'+#13#10);\r
+ end;\r
+\r
+ WriteAccessFile(plik_lst); AssignFile(lst,plik_lst); FileMode:=1; Rewrite(lst);\r
+\r
+ WriteAccessFile(plik_obj); Assignfile(dst,plik_obj); FileMode:=1; Rewrite(dst,1);\r
+\r
+ Writeln(lst,t);                       // naglowek z nazwa programu do pliku LST\r
+end;\r
+\r
+\r
+{\r
+procedure tttt(a: string);\r
+begin\r
+ case length(a) of\r
+  1,2: writeln(hex(ord(a[1]) shl 8+ord(a[2]),8));\r
+  3: writeln(hex(ord(a[1]) shl 16+ord(a[2]) shl 8+ord(a[3]),8));\r
+  4: writeln(hex(ord(a[1]) shl 24+ord(a[2]) shl 16+ord(a[3]) shl 8+ord(a[4]),8));\r
+ end;\r
+end;\r
+}\r
+\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(*                         M A I N   P R O G R A M                            *)\r
+(*----------------------------------------------------------------------------*)\r
+begin\r
+\r
+ ___search_comment_block := search_comment_block;\r
+\r
+ oblicz_mnemonik__ :=  oblicz_mnemonik;\r
+ analizuj_plik__   :=  analizuj_plik;\r
+ analizuj_mem__    :=  analizuj_mem;\r
+ ___wartosc_noSPC  :=  oblicz_wartosc_noSPC;\r
+\r
+ SetLength(t_lab,1);\r
+ SetLength(t_hea,1);\r
+ SetLength(t_mac,1);\r
+ SetLength(t_par,1);\r
+ SetLength(t_loc,1);\r
+ SetLength(t_prc,1);\r
+ SetLength(t_pth,1);\r
+ SetLength(t_wyw,1);\r
+ SetLength(t_rel,1);\r
+ SetLength(t_smb,1);\r
+ SetLength(t_ext,1);\r
+ SetLength(t_extn,1);\r
+ SetLength(t_str,1);\r
+ SetLength(t_arr,1);\r
+ SetLength(t_pag,1);\r
+ SetLength(t_end,1);\r
+ SetLength(t_mad,1);\r
+ SetLength(t_pub,1);\r
+ SetLength(t_var,1);\r
+ SetLength(t_skp,1);\r
+// SetLength(t_lin,1);\r
+ SetLength(t_sym,1);\r
+ SetLength(t_usi,1);\r
+ SetLength(t_els,1);\r
+ SetLength(if_stos,1);\r
+\r
+ SetLength(t_siz,2);\r
+\r
+ SetLength(messages,1);\r
+\r
+\r
+ pass:=1;\r
+\r
+(*----------------------------------------------------------------------------*)\r
+(* tworzenie tablic 'TCRC16', 'TCRC32' oraz tablicy 'HASH', odczyt parametrow *)\r
+(*----------------------------------------------------------------------------*)\r
+ INITIALIZE;\r
+\r
+\r
+ if binary_file.use then begin\r
+  opt       := opt or 2;\r
+  adres     := binary_file.adr;\r
+  org       := true;\r
+  first_org := false;\r
+ end;\r
+\r
+ optDefault := opt;\r
+\r
+ open_ok:=true;\r
+\r
+ t:='';\r
+\r
+ nul.l:=0;\r
+ nul.i:=0;\r
+\r
+ pass:=0;\r
+\r
+ asem(plik_asm);\r
+\r
+ over:=true;\r
+ koniec(status);\r
+end.\r
index fbcdc56..5093ce6 100755 (executable)
@@ -26,3 +26,6 @@ $(PLAYERS_OBX_DIR)/rmt8.obx: ../players/rmt.asx
 
 $(PLAYERS_OBX_DIR)/%.obx: ../players/%.asx
        $(XASM) $<
+
+clean:
+       $(RM) $(PLAYERS_OBX)
diff --git a/xbmc/cores/paplayer/asap/xasm/Makefile b/xbmc/cores/paplayer/asap/xasm/Makefile
new file mode 100644 (file)
index 0000000..3cdd469
--- /dev/null
@@ -0,0 +1,56 @@
+VERSION = 3.0.2\r
+\r
+ASCIIDOC = asciidoc -o $@ -a doctime\r
+ASCIIDOC_POSTPROCESS = perl -pi.bak -e "s/527bbd;/20a0a0;/;END{unlink '$@.bak'}" $@\r
+ASCIIDOC_VALIDATE = xmllint --valid --noout --nonet $@\r
+RM = rm -f\r
+ZIP = 7z a -mx=9 -tzip $@\r
+\r
+all: xasm\r
+\r
+xasm.o: xasm.d\r
+       gdc -c -o xasm.o -O2 $<\r
+\r
+xasm: xasm.o\r
+       gdc -o xasm xasm.o\r
+\r
+xasm.html: xasm.1.txt\r
+       $(ASCIIDOC) -d manpage $<\r
+       $(ASCIIDOC_POSTPROCESS)\r
+       $(ASCIIDOC_VALIDATE)\r
+\r
+dist: xasmpage-$(VERSION).zip\r
+\r
+xasmpage-$(VERSION).zip: xasm261.zip xasm-$(VERSION)-src.zip xasm-$(VERSION)-windows.zip inflate6502.zip index.html inflate.html scite.png\r
+       $(RM) $@\r
+       $(ZIP) $^\r
+\r
+xasm-$(VERSION)-src.zip: xasm.d Makefile xasm.1.txt\r
+       $(RM) $@\r
+       $(ZIP) $^\r
+\r
+xasm-$(VERSION)-windows.zip: xasm.exe xasm.html xasm.properties\r
+       $(RM) $@\r
+       $(ZIP) $^\r
+\r
+inflate6502.zip: inflate.asx gzip2deflate.c gzip2deflate.exe\r
+       $(RM) $@\r
+       $(ZIP) $^\r
+\r
+gzip2deflate.exe: gzip2deflate.c\r
+       mingw32-gcc -s -O2 -Wall -o $@ $<\r
+\r
+index.html: index.txt\r
+       $(ASCIIDOC) $<\r
+       $(ASCIIDOC_POSTPROCESS)\r
+       $(ASCIIDOC_VALIDATE)\r
+\r
+inflate.html: inflate.txt\r
+       $(ASCIIDOC) $<\r
+       $(ASCIIDOC_POSTPROCESS)\r
+       $(ASCIIDOC_VALIDATE)\r
+\r
+clean:\r
+       $(RM) xasm.o xasm\r
+\r
+.DELETE_ON_ERROR:\r
diff --git a/xbmc/cores/paplayer/asap/xasm/xasm.1.txt b/xbmc/cores/paplayer/asap/xasm/xasm.1.txt
new file mode 100644 (file)
index 0000000..5285922
--- /dev/null
@@ -0,0 +1,825 @@
+XASM (1)\r
+========\r
+Piotr Fusik <fox@scene.pl>\r
+\r
+NAME\r
+----\r
+xasm - 6502 cross-assembler\r
+\r
+SYNOPSIS\r
+--------\r
+*xasm* '[OPTIONS] SOURCE_FILE'\r
+\r
+DESCRIPTION\r
+-----------\r
+*xasm* is a cross-assembler for the 6502 family processors.\r
+\r
+'SOURCE_FILE' is the name of the source file\r
+(you may omit the default `.asx` extension).\r
+When invoked without any options, *xasm* assembles 'SOURCE_FILE'\r
+and writes the result to an object file named 'SOURCE_FILE'\r
+with the extension changed to `.obx`.\r
+\r
+OPTIONS\r
+-------\r
+\r
+*/c*::\r
+Specifies that lines skipped due to a false condition\r
+should be included in the listing file.\r
+\r
+[[new_deflabel]]*/d:*'LABEL'='VALUE'::\r
+Defines a label.\r
+'LABEL' should be a valid label name.\r
+'VALUE' may be any expression (may reference to labels defined in source files).\r
+You may use several */d* options to define many labels from the command line.\r
+\r
+*/i*::\r
+Excludes included files from the listing file.\r
+\r
+*/l*'[:LISTING_FILE]'::\r
+Generates listing file.\r
+If 'LISTING_FILE' is omitted, the listing filename\r
+is 'SOURCE_FILE' with the extension changed to `.lst`.\r
+\r
+[[new_makefile]]*/M*::\r
+Prints a rule for use in a `Makefile`.\r
+First line of the rule lists 'OBJECT_FILE' as the target of the rule\r
+and all source files (including the ones specified by `icl` and `ins` directives)\r
+as dependencies. The second line contains the command line with `OBJECT_FILE`\r
+replaced by the *make* macro `$@` and `SOURCE_FILE` replaced by the macro `$<`.\r
+Dollars in the command line are doubled.\r
+Your `make` or shell may require more escaping.\r
+\r
+*/o*':OBJECT_FILE'::\r
+Sets output file name.\r
+The default is 'SOURCE_FILE' with the extension changed to `.obx`.\r
+\r
+[[new_fullpaths]]*/p*::\r
+Prints fully qualified file names in listing and error messages.\r
+This option works only on Windows and is silently ignored on other platforms.\r
+\r
+[[new_quiet]]*/q*::\r
+Quiet mode. Prevents *xasm* from printing the logo and the summary.\r
+\r
+*/t*'[:LABEL_FILE]'::\r
+Generates label table.\r
+If 'LABEL_FILE' is omitted then the table is appended to the listing.\r
+\r
+[[new_unlabels]]*/u*::\r
+Issues a warning message for each label whose value is unused.\r
+\r
+Alternatively, you may use Unix-style options, for example:\r
+\r
+-----------------------------------------------------------\r
+xasm -i -d DEBUG=1 -l listing.lst source.asx\r
+-----------------------------------------------------------\r
+\r
+SYNTAX\r
+------\r
+\r
+Source files should be plain ASCII files.\r
+LF, CR, CR/LF and Atari ($9b) line terminators are supported.\r
+Labels and instructions are case-insensitive.\r
+\r
+*xasm* is backward compatible with Quick Assembler.\r
+To compile QA sources with *xasm*, simply replace ATASCII-specific characters\r
+with their integer codes. You also have to update all `OPT` directives,\r
+but usually you can simply remove them.\r
+\r
+'Label' is a symbol that represents a signed 32-bit integer.\r
+You define a label by putting its name at the beginning of a line\r
+(with no spaces before).\r
+The label will be assigned the current value of the 'origin counter'\r
+(i.e. the address of the compiled instruction),\r
+unless you use it with the `EQU` directive where it is assigned\r
+the value of the argument.\r
+\r
+Instructions and directives must be preceded with some whitespace.\r
+Without leading whitespace they are treated as label names.\r
+For example:\r
+----\r
+ nop\r
+----\r
+is a 6502 instruction, whereas\r
+----\r
+nop\r
+----\r
+defines a label called `nop`.\r
+\r
+Whole-line comments must start with a semicolon, an asterisk or a pipe,\r
+with optional label definition and spaces before.\r
+Here are examples of whole-line comments:\r
+--------------------\r
+; this is a comment\r
+ * so it is\r
+label | and this too\r
+--------------------\r
+\r
+[[new_linerep]]\r
+Lines with instructions (and selected directives) may be 'repeated'.\r
+To assemble a single line several times,\r
+precede the repeat count with a colon, for example:\r
+-----------------\r
+:4 asl @\r
+table :32*5 dta 5\r
+-----------------\r
+\r
+In lines with instructions or directives, a comment starts immediately\r
+after the instruction/directive has been successfully parsed.\r
+That is, in these lines *xasm* does not require a special character\r
+to start a comment.\r
+-------------------------------------------------------------\r
+ lda foo ; this is a comment\r
+ sta bar this too\r
+ tax #0  tax has no operand, therefore #0 starts this comment\r
+-------------------------------------------------------------\r
+\r
+[[new_pairing]]\r
+You may put two instructions in one line so they share the operand.\r
+For example:\r
+------------\r
+ eor:sta foo\r
+------------\r
+is equivalent to\r
+------------\r
+ eor foo\r
+ sta foo\r
+------------\r
+\r
+Note that\r
+------------\r
+ lda:tax #0\r
+------------\r
+is allowed because `#0` is treated as a comment for `tax`.\r
+\r
+EXPRESSIONS\r
+-----------\r
+Expressions are numbers combined with operators and brackets.\r
+You should use square brackets, because parentheses are reserved\r
+for 6502 indirect addressing.\r
+\r
+A number is:\r
+\r
+- a 32-bit decimal integer, e.g. `-12345`\r
+- a 32-bit hexadecimal integer, e.g. `$abcd`\r
+- a 32-bit binary integer, e.g. `%10100101`\r
+- an ASCII character, e.g. `'a'` or `"a"`\r
+- origin counter: `*`\r
+- a hardware register (see below), e.g. `^4e`\r
+- [[new_opcode]]an opcode (see below), e.g. `{lda #0}` is `$a9`\r
+- [[new_linecnt]]the line repeat counter (see below): `#`\r
+\r
+Abbreviations of Atari hardware registers are provided\r
+to save two characters (`$d40e` vs `^4e`)\r
+and to facilitate porting software between Atari 8-bit computers\r
+and the Atari 5200 console.\r
+These are very similar machines, one of the biggest differences\r
+is the location of hardware registers.\r
+\r
+[cols="^m,^d,^m,^d",options="header"]\r
+|================================================\r
+|Syntax|Chip |Value|Value (Atari 5200 mode `opt g+`)\r
+|  ^0x |GTIA |$D00x|`$C00x`\r
+|  ^1x |GTIA |$D01x|`$C01x`\r
+|  ^2x |POKEY|$D20x|`$E80x`\r
+|  ^3x |PIA  |$D30x|'error (there's no PIA chip)'\r
+|  ^4x |ANTIC|$D40x|`$D40x`\r
+|================================================\r
+\r
+The opcode syntax represents the opcode byte of the instruction inside braces.\r
+The operand of the instruction is discarded and is needed only to recognize\r
+the addressing mode. The instruction should begin right after the left brace\r
+and the right brace should immediately follow the operand 'or' the instruction.\r
+[[new_op_op]]You can skip the operand if the addressing mode is fixed.\r
+Examples: `{lda #}`, `{jsr}`, `{bne}`, `{jmp ()}`, `{sta a:,x}`.\r
+\r
+You can use the line repeat counter (`#`) in the repeated lines.\r
+It counts the iterations starting from zero. Examples:\r
+----------------------------------------------------\r
+:3 dta # ; generates three bytes: 0, 1, 2.\r
+line_lo :192 dta l(screen+40*#)\r
+line_hi :192 dta h(screen+40*#)\r
+dl :59 dta $4f,a(screen+40*#),0,$4f,a(screen+40*#),0\r
+----------------------------------------------------\r
+\r
+The following 'binary operators' are supported:\r
+\r
+- `+` Addition\r
+- `-` Subtraction\r
+- `*` Multiplication\r
+- `/` Division\r
+- `%` Remainder\r
+- `&` Bitwise AND\r
+- `|` Bitwise OR\r
+- `^` Bitwise XOR\r
+- `<<` Arithmetic shift left\r
+- `>>` Arithmetic shift right\r
+- `==` Equal\r
+- `=` Equal (same as `==`)\r
+- `!=` Not equal\r
+- `<>` Not equal (same as `!=`)\r
+- `<` Less than\r
+- `>` Greater than\r
+- `<=` Less or equal\r
+- `>=` Greater or equal\r
+- `&&` Logical AND\r
+- `||` Logical OR\r
+\r
+[[new_unary]]\r
+The following 'unary operators' are supported:\r
+\r
+- `+` Plus (does nothing)\r
+- `-` Minus (changes the sign)\r
+- `~` Bitwise NOT (complements all bits)\r
+- `!` Logical NOT (changes true to false and vice versa)\r
+- `<` Low (extracts the low byte)\r
+- `>` High (extracts the high byte)\r
+\r
+The operator precedence is following:\r
+\r
+- first: `[]` (brackets)\r
+- `+ - ~ < >` (unary)\r
+- `* / % & << >>` (binary)\r
+- `+ - | ^` (binary)\r
+- `= == <> != < > <= >=` (binary)\r
+- `!` (unary)\r
+- `&&` (binary)\r
+- last: `||` (binary)\r
+\r
+Although the operators are similar to those used in C, C++ and Java,\r
+their priorities are different than in these languages.\r
+\r
+Compare and logical operators assume that zero is false and a non-zero\r
+is true. They return 1 for true.\r
+\r
+Expressions are calculated in signed 32-bit arithmetic.\r
+"Arithmetic overflow" error signals overflow of the 32-bit range.\r
+\r
+DIRECTIVES\r
+----------\r
+\r
+*EQU* - assign value of expression to label::\r
+Examples:\r
+----------\r
+five equ 5\r
+here equ *\r
+----------\r
+\r
+[[new_opt]]*OPT* - set assembler options::\r
+Five options are available:\r
+\r
+- `F` - fill the space between memory areas with `$FF`\r
+- `G` - Atari 5200 mode for hardware register abbreviations\r
+- `H` - generate Atari executable headers\r
+- `L` - write to the listing\r
+- `O` - write to the object file\r
+\r
+You can turn any of these on or off.\r
+The default (if no `OPT` specified) is `opt f-g-h+l+o+`.\r
+Examples:\r
+------------------------------------------------------------------------------\r
+ opt l-     listing off\r
+ opt l+o-   listing on, object file off\r
+ opt f+g+h- useful for Atari 5200 cartridges - raw output, 5200 hw regs\r
+------------------------------------------------------------------------------\r
+\r
+*ORG* - change value of the origin counter::\r
+If Atari executable headers are enabled, you can include an operand prefix:\r
+\r
+- `a:` starts a new block even if it's superfluous\r
+  because the new address equals the current address.\r
+- `f:` is same as `a:`, but additionally generates a double-`$FF` prefix\r
+  before the new header. This prefix is automatically generated\r
+  at the beginning of the file (no need to include `f:` in the first `ORG`).\r
+Examples:\r
+---------------\r
+ org $600\r
+ org f:$700\r
+table org *+100\r
+---------------\r
+In the latter example `table` points to 100 bytes\r
+of uninitialized data (label is assigned with `*`\r
+before the `ORG` directive is executed).\r
+\r
+[[new_orgr]]Starting with version 2.6.0, *xasm* supports code\r
+that is relocated in the memory at runtime. Let's say you want your code\r
+to be located on page zero. You can't normally load it directly into this\r
+place, so you load it at a different address and then move in your program.\r
+`org r:` changes the address that it used for code generation\r
+but not the address used for generating Atari executable headers.\r
+Example:\r
+--------------------------------------\r
+ org $8000\r
+ ldx #code_length-1\r
+ mva:rpl code_loaded,x z:code_zpage,x-\r
+ jmp code_zpage\r
+\r
+code_loaded\r
+ org r:$30\r
+code_zpage\r
+ jmp * ; ... or something more sensible\r
+code_length equ *-code_zpage\r
+--------------------------------------\r
+Note that both `*` and label definitions use the counter used\r
+for code generation. There is no direct access to the other counter,\r
+because I think this is not useful. If you really need it, you can\r
+always type something like:\r
+---------------------------------------\r
+where_am_i equ *-code_zpage+code_loaded\r
+---------------------------------------\r
+\r
+[[new_dta]]*DTA* - define data::\r
+\r
+- integers\r
++\r
+--\r
+* bytes: `b(200)` or simply `200`\r
+* words: `a(10000)`\r
+* low bytes of words: `l(511)` (byte 255)\r
+* high bytes of words: `h(511)` (byte 1)\r
+\r
+You may enter many expressions in parentheses and combine different types\r
+of data in single line, separating things with commas.\r
+\r
+You may also define a sine lookup table. The syntax is:\r
+-------------------------------\r
+sin(center,amp,size,first,last)\r
+-------------------------------\r
+where:\r
+\r
+* `center` is an integer which is added to every sine value\r
+* `amp` is the sine amplitude\r
+* `size` is the sine period\r
+* `first,last` define the range of sine arguments.\r
+  They are optional. The default are `0,size-1`.\r
+\r
+Example:\r
+----------------------------\r
+ dta a(sin(0,1000,256,0,63))\r
+----------------------------\r
+defines a table of 64 words representing a quarter of sine with the amplitude of 1000.\r
+--\r
+\r
+- real numbers: `r(-1.23456e12)`\r
++\r
+Real numbers are stored in the 6-byte Atari Floating-Point format.\r
+\r
+- text strings\r
++\r
+--\r
+* ASCII strings: `c'Text'` or `c"Text"`\r
+* ANTIC strings: `d'Text'` or `d"Text"`\r
+\r
+A character string consists of any number of characters surrounded by quotation\r
+marks. You can include the quotation marks in the string by doubling them.\r
+Placing a `*` character after a string inverts\r
+the highest bit in every byte of the string.\r
+--\r
++\r
+Examples of `DTA`:\r
++\r
+------------------------------------------------\r
+ dta b(1,2),3,a(1000,-1),l(12345,sin(0,127,256))\r
+ dta d"ANTIC"*,c'It''s a string',$9b\r
+------------------------------------------------\r
+\r
+*ICL* - include another source file::\r
+Specifies another file to be included in the assembly as if the contents\r
+of the referenced file appeared in place of the `ICL` statement.\r
+The included file may contain other `ICL` statements.\r
+The `.asx` extension is added if none given.\r
+Examples:\r
+-----------------\r
+ icl 'macros.asx'\r
+ icl 'lib/fileio'\r
+-----------------\r
+Note: for portability, use only relative paths and slash as the separator.\r
+This way your sources will compile under Windows and Linux.\r
+\r
+*END* - end assembling file::\r
+May be used if the source file ends with something which shouldn't\r
+be read by *xasm* (e.g. your notes). At the end of file it's optional.\r
+\r
+*INS* - insert contents of file::\r
+Copies every byte of the specified file into the object file and updates\r
+the origin counter, as if these bytes were defined with `DTA`.\r
+You may specify a range of the file to insert. The syntax is:\r
+-----------------------------\r
+ ins 'file'[,offset[,length]]\r
+-----------------------------\r
+The first byte in a file has the offset of zero.\r
+If the offset is negative, it counts from the end of the file.\r
+Examples:\r
+-----------------------------------------------\r
+ ins 'picture.raw'\r
+ ins 'file',-256  insert last 256 bytes of file\r
+ ins 'file',10,10 insert bytes 10..19 of file\r
+-----------------------------------------------\r
+\r
+*RUN* - set run address in the Atari executable format::\r
+---------\r
+ run main\r
+---------\r
+is equivalent to:\r
+------------\r
+ org $2e0\r
+ dta a(main)\r
+------------\r
+\r
+*INI* - set init address in the Atari executable format::\r
+Example:\r
+------------\r
+ ini showpic\r
+------------\r
+\r
+*ERT* - generate error if expression evaluates to true::\r
+Examples:\r
+-----------------------\r
+ ert *>$c000\r
+ ert len1>$ff||len2>$ff\r
+-----------------------\r
+\r
+[[new_eli]]*IFT* - assemble if expression is true::\r
+*ELI* - else if::\r
+*ELS* - else::\r
+*EIF* - end if::\r
+With these directives you can construct fragments which\r
+are assembled only when a condition is met.\r
+Conditional constructions can be nested.\r
+Example:\r
+-------------\r
+noscr equ 1\r
+widescr equ 1\r
+ ift noscr\r
+ lda #0\r
+ eli widescr\r
+ lda #$23\r
+ els\r
+ lda #$22\r
+ eif\r
+ sta $22f\r
+-------------\r
+Note: the above example may be rewritten using the 'repeat line' feature:\r
+--------------------------\r
+noscr equ 1\r
+widescr equ 1\r
+:noscr lda #0\r
+:!noscr&&widescr lda #$23\r
+:!noscr&&!widescr lda #$22\r
+ sta $22f\r
+--------------------------\r
+\r
+PSEUDO COMMANDS\r
+---------------\r
+'Pseudo commands' are built-in macros. There are no user-defined macros in *xasm*.\r
+\r
+*ADD* - addition without carry::\r
+If you have ever programmed a 6502, you must have noticed that you had\r
+to use a `CLC` before `ADC` for every simple addition.\r
++\r
+*xasm* can do it for you. `ADD` replaces two instructions: `CLC` and `ADC`.\r
+\r
+*SUB* - subtraction::\r
+It is `SEC` and `SBC`.\r
+\r
+[[new_repskip]]*RCC, RCS, REQ, RMI, RNE, RPL, RVC, RVS* - conditional repeat::\r
+These are branches to the previous instruction.\r
+They take no operand, because the branch target is the address\r
+of the previously assembled instruction or pseudo command.\r
+Example:\r
++\r
+-----------------------\r
+ ldx #0\r
+ mva:rne $500,x $600,x+\r
+-----------------------\r
++\r
+The above code copies a 256-byte memory block from $500 to $600.\r
+Here is the same written with standard 6502 commands only:\r
++\r
+--------------------\r
+ ldx #0\r
+copy_loop lda $500,x\r
+ sta $600,x\r
+ inx\r
+ bne copy_loop\r
+--------------------\r
+\r
+*SCC, SCS, SEQ, SMI, SNE, SPL, SVC, SVS* - conditional skip::\r
+These are branches over the next instruction. No operand is required,\r
+because the target is the address of the instruction following\r
+the next instruction.\r
+Example:\r
++\r
+--------------\r
+ lda #40\r
+ add:sta ptr\r
+ scc:inc ptr+1\r
+--------------\r
++\r
+In the above example the 16-bit variable `ptr` is incremented by 40.\r
+\r
+*JCC, JCS, JEQ, JMI, JNE, JPL, JVC, JVS* - conditional jumps::\r
+These are long branches. While standard branches (such as `BNE`)\r
+have range of -128..+127, these jumps have range of 64 kB.\r
+For example:\r
++\r
+---------\r
+ jne dest\r
+---------\r
++\r
+is equivalent to:\r
++\r
+-------------\r
+ seq:jmp dest\r
+-------------\r
+\r
+*INW* - increment word::\r
+Increments a 16-bit word in the memory.\r
+Example:\r
++\r
+---------\r
+ inw dest\r
+---------\r
++\r
+is equivalent to:\r
++\r
+---------------\r
+ inc dest\r
+ sne:inc dest+1\r
+---------------\r
+\r
+*MVA, MVX, MVY* - move byte using accumulator, X or Y::\r
+Each of these pseudo commands requires two operands\r
+and substitutes two commands:\r
++\r
+----------------------------------------\r
+ mva source dest = lda source : sta dest\r
+ mvx source dest = ldx source : stx dest\r
+ mvy source dest = ldy source : sty dest\r
+----------------------------------------\r
+\r
+[[new_mwinde]]*MWA, MWX, MWY* - move word using accumulator, X or Y::\r
+These pseudo commands require two operands and are combinations of two `MV*`'s:\r
+one to move the low byte, and the other to move the high byte.\r
+You can't use indirect nor pseudo addressing mode with `MW*`.\r
+Destination must be an absolute address, optionally indexed.\r
+When source is also an absolute address, an `mw* source dest` expands to:\r
++\r
+--------------------\r
+ mv* source  dest\r
+ mv* source+1 dest+1\r
+--------------------\r
++\r
+When source is an immediate value, an `mw* #immed dest` expands to:\r
++\r
+------------------\r
+ mv* <immed dest\r
+ mv* >immed dest+1\r
+------------------\r
++\r
+When `<immed` equals `>immed` and `immed` is not forward-referenced,\r
+*xasm* skips the second `LD*`:\r
++\r
+----------------\r
+ mv* <immed dest\r
+ st* dest+1\r
+----------------\r
++\r
+If possible, `MWX` and `MWY` use increment/decrement commands.\r
+For example, `mwx #1 dest` expands to:\r
++\r
+-----------\r
+ ldx #1\r
+ stx dest\r
+ dex\r
+ stx dest+1\r
+-----------\r
+\r
+ADDRESSING MODES\r
+----------------\r
+\r
+All addressing modes are entered in the standard 6502 convention\r
+except for the accumulator addressing mode,\r
+which should be marked with the `@` character (as in Quick Assembler).\r
+\r
+For Quick Assembler compatibility, there are two extra immediate\r
+addressing modes: `<` and `>`, which use the low/high byte of a 16-bit word constant.\r
+Unlike in Quick Assembler, you can alternatively use\r
+the more common syntax: `#<` and `#>`.\r
+Note the difference:\r
+-------------------------------\r
+ lda >$ff+5   ; loads 1 (>$104)\r
+ lda #>$ff+5  ; loads 5 (0+5)\r
+-------------------------------\r
+\r
+You can explicitly specify absolute (`a:`) and zero-page (`z:`) addressing modes.\r
+\r
+Examples:\r
+--------------------------------------\r
+ nop\r
+ asl @\r
+ lda >$1234  assembles to lda #$12\r
+ lda $100,x\r
+ lda 0       zero-page (8-bit address)\r
+ lda a:0     absolute (16-bit address)\r
+ jmp ($0a)\r
+ lda ($80),y\r
+--------------------------------------\r
+\r
+[[new_adrmodes]]\r
+There are 'pseudo addressing modes', which are similar to pseudo commands.\r
+You may use them just like standard addressing modes in all 6502 commands\r
+and pseudo commands, except for `MWA`, `MWX` and `MWY`:\r
+------------------------------------------\r
+ cmd a,x+   =  cmd a,x   : inx\r
+ cmd a,x-   =  cmd a,x   : dex\r
+ cmd a,y+   =  cmd a,y   : iny\r
+ cmd a,y-   =  cmd a,y   : dey\r
+ cmd (z),y+ =  cmd (z),y : iny\r
+ cmd (z),y- =  cmd (z),y : dey\r
+ cmd (z,0)  =  ldx #0    : cmd (z,x)\r
+ cmd (z),0  =  ldy #0    : cmd (z),y\r
+ cmd (z),0+ =  ldy #0    : cmd (z),y : iny\r
+ cmd (z),0- =  ldy #0    : cmd (z),y : dey\r
+------------------------------------------\r
+\r
+HISTORY\r
+-------\r
+\r
+Version 3.0.2 (2009-10-17)\r
+~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+- fixed "Branch out of range" error message - was overstated by 256 bytes\r
+  for backward branches\r
+- <<new_makefile,new command-line option */M* prints Makefile rule>>\r
+- command-line options are now case-insensitive\r
+- on Windows error messages are printed in red, warnings in yellow\r
+\r
+Version 3.0.1 (2007-04-22)\r
+~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+- fixed a bug in `OPT H-` mode\r
+- made *xasm* compilable with the latest D compiler v1.010\r
+  (there were incompatible changes in the D language and library)\r
+\r
+Version 3.0.0 (2005-05-22)\r
+~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+- rewritten from the x86 assembly language to the\r
+  http://www.digitalmars.com/d[D programming language] - Linux version\r
+  is now available and DOS is no longer supported\r
+- no limits for line length, number of `ICLs`, `ORGs`,`IFTs` and labels\r
+- Unix-style command-line options are supported\r
+- */e* option is no longer supported\r
+- the label table is now sorted alphabetically\r
+\r
+Version 2.6.1 (2005-05-21)\r
+~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+- no more "Arithmetic overflow" and "Division by zero" errors for correct\r
+  use of forward-referenced labels (bug found by Marcin Lewandowski)\r
+- an error was reported in the following correct code:\r
++\r
+---------\r
+ ift 0\r
+foo equ 1\r
+ ift foo\r
+ eif\r
+ eif\r
+---------\r
++\r
+(bug found by Adrian Matoga)\r
+\r
+- errors for non-existing `INC @` and `DEC @`\r
+- negative numbers fixed in the listing\r
+\r
+Version 2.6.0 (2005-02-07)\r
+~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+- long file names are supported under Windows\r
+- <<new_orgr,support for code relocated at runtime>>\r
+- <<new_linecnt,line repeat counter>>\r
+- label values are now 32-bit, not just 17-bit\r
+- command-line options */n* and */s* are no longer supported\r
+- fatal I/O errors (such as floppy not ready) no longer print the annoying\r
+  "Abort, Retry, Ignore" message\r
+\r
+Version 2.5.2 (2002-10-03)\r
+~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+- version 2.5.1 broke Unix EOLs - fixed\r
+- version 2.5.1 omitted all blank/comment/label lines, unless */c* was used\r
+\r
+Version 2.5.1 (2002-08-21)\r
+~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+- fixed assembling sources with Atari EOLs\r
+- blank/comment/label lines in false conditionals are now correctly omitted\r
+  in listing\r
+\r
+Version 2.5 (2002-07-08)\r
+~~~~~~~~~~~~~~~~~~~~~~~~\r
+- fixed another bug, very similar to the previous one, e.g.\r
++\r
+----------\r
+ ift 0\r
+:label nop\r
+ eif\r
+----------\r
++\r
+reported "Label not defined before" error for the repeat count\r
+\r
+- <<new_opt,`OPT F+` causes `ORG` to fill the space\r
+  between the old and the new location with `$FFs`>>\r
+- <<new_opt,`OPT G+` enables Atari 5200 mode for hardware\r
+  register abbreviations>>\r
+\r
+Version 2.4.1 (2002-06-27)\r
+~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+- fixed a bug related to label definitions in conditionally skipped code,\r
+e.g.\r
++\r
+----------\r
+ ift 0\r
+label\r
+ eif\r
+----------\r
++\r
+reported "No ORG specified" error for the label definition\r
+\r
+Version 2.4 (2002-05-22)\r
+~~~~~~~~~~~~~~~~~~~~~~~~\r
+- fixed incorrect unary operator precedence\r
+- fixed wrong label value after a skip pseudo command\r
+- the assembler is .EXE (.COM caused problems with DJGPP *make* due\r
+  to a bug in the DJGPP runtime)\r
+- the assembler executable is not compressed (so it occupies less space in the ZIP)\r
+- improved command-line parsing: options may be used before source file name,\r
+  tab character is a valid separator, slash may be used as a directory separator\r
+- error and warning messages are written to stderr, not stdout\r
+- added `==` (equals) operator, which is equivalent to `=`,\r
+  but more natural for C/C++/Java programmers\r
+- <<new_deflabel,added `/d:label=value` option: define a label>>\r
+- <<new_fullpaths,added `/p` option: print full paths\r
+  in listing and error messages>>\r
+- <<new_quiet,added `/q` option: quiet mode>>\r
+- <<new_unlabels,added `/u` option: warn of unused labels>>\r
+- <<new_opt,writing to the object file may be suppressed with `OPT O-`>>\r
+- <<new_eli,added `ELI` (else if) directive>>\r
+- <<new_mwinde,`MWX` and `MWY` may use `INX`/`DEX` and `INY`/`DEY`,\r
+  respectively, for generating shorter code>>\r
+\r
+Version 2.3 (2002-02-10)\r
+~~~~~~~~~~~~~~~~~~~~~~~~\r
+- fixed double skip (e.g. `SCC:SNE`)\r
+- fixed real numbers with two-digit exponent\r
+- trailing spaces are trimmed from listing lines\r
+- label definitions allowed in blank, comment and repeated lines\r
+- <<new_unary,unary operators>>\r
+- <<new_dta,`DTA` implied byte mode>>\r
+- <<new_op_op,operand can be skipped for some opcodes>>\r
+\r
+Version 2.2 (1999-09-10)\r
+~~~~~~~~~~~~~~~~~~~~~~~~\r
+- fixed invalid opcodes of absolute `CPX` and `CPY`\r
+- fixed: addressing mode not checked for branch commands\r
+- fixed `ICL` in last line\r
+- fixed `OPT H-H+`\r
+- fixed first `ORG *`\r
+- no need to set origin counter until it's used\r
+- allow Unix, Macintosh and Atari EOLs\r
+- value of 'true' changed to 1\r
+- command-line option to set environment variables on error\r
+- commane-line option to assemble only if source is newer than object file\r
+- <<new_opcode,opcode extracting>>\r
+- <<new_linerep,repeat line>>\r
+- <<new_pairing,two instructions in line>>\r
+- <<new_repskip,conditional repeat and skip pseudo commands>>\r
+- <<new_adrmodes,`(),0+` and `(),0-` pseudo addressing modes>>\r
+\r
+Version 2.0 (1998-11-12)\r
+~~~~~~~~~~~~~~~~~~~~~~~~\r
+- fixed: name of object file was truncated\r
+- fixed forward references in `EQU` and `DTA`\r
+- fixed hex numbers\r
+- `.OBX` is now the default extension for the object file\r
+- options (command-line switches and `OPT`)\r
+- listing\r
+- label table\r
+- conditional assembly\r
+- user errors (`ERT`)\r
+- warnings\r
+- 6 new pseudo commands (memory-to-memory move)\r
+- 8 pseudo addressing modes\r
+- indirect conditional jumps\r
+- Atari floating-point numbers\r
+- object file headers optimization\r
+- improved expressions - 19 operators and brackets, 32-bit arithmetic\r
+- improved signed numbers\r
+- improved `INS`: inserting specified part of file\r
+\r
+Version 1.2 (1998-08-14)\r
+~~~~~~~~~~~~~~~~~~~~~~~~\r
+- first release\r
+\r
+AUTHOR\r
+------\r
+Piotr Fusik <fox@scene.pl>\r
+\r
+SEE ALSO\r
+--------\r
+\r
+Website: http://xasm.atari.org[]\r
diff --git a/xbmc/cores/paplayer/asap/xasm/xasm.d b/xbmc/cores/paplayer/asap/xasm/xasm.d
new file mode 100644 (file)
index 0000000..280ca28
--- /dev/null
@@ -0,0 +1,3227 @@
+// xasm 3.0.2 by Piotr Fusik <fox@scene.pl>\r
+// http://xasm.atari.org\r
+// Can be compiled with DMD v1.030.\r
+\r
+// Poetic License:\r
+//\r
+// This work 'as-is' we provide.\r
+// No warranty express or implied.\r
+// We've done our best,\r
+// to debug and test.\r
+// Liability for damages denied.\r
+//\r
+// Permission is granted hereby,\r
+// to copy, share, and modify.\r
+// Use as is fit,\r
+// free or for profit.\r
+// These rights, on this notice, rely.\r
+\r
+import std.math;\r
+import std.stream;\r
+import std.cstream;\r
+import std.string;\r
+\r
+version (Windows) {\r
+       import std.c.windows.windows;\r
+\r
+       extern (Windows) export int GetFullPathNameA(char* lpFileName, int nBufferLength, char* lpBuffer, char** lpFilePart);\r
+       extern (Windows) HANDLE GetStdHandle(DWORD nStdHandle);\r
+\r
+       char[] getFullPath(char[] filename) {\r
+               char[260] fullPath;\r
+               char* filePath;\r
+               int r = GetFullPathNameA(cast(char*) (filename ~ "\0"), 260, cast(char*) fullPath, &filePath);\r
+               if (r > 0) {\r
+                       return fullPath[0 .. r].dup;\r
+               }\r
+               return filename;\r
+       }\r
+\r
+       const char[] OPTION_P_DESC = "Print fully qualified file names in listing and error messages";\r
+\r
+} else {\r
+\r
+       char[] getFullPath(char[] filename) {\r
+               return filename;\r
+       }\r
+\r
+       const char[] OPTION_P_DESC = "Ignored for compatibility";\r
+}\r
+\r
+const char[] TITLE = "xasm 3.0.2";\r
+\r
+char[] sourceFilename = null;\r
+\r
+bit[26] options;\r
+\r
+char[][26] optionParameters;\r
+\r
+char[][] commandLineDefinitions = null;\r
+\r
+char[] makeTarget = null;\r
+\r
+char[] makeSources = "";\r
+\r
+int exitCode = 0;\r
+\r
+int totalLines;\r
+\r
+bit pass2 = false;\r
+\r
+bit optionFill; // opt f\r
+\r
+bit option5200; // opt g\r
+\r
+bit optionHeaders; // opt h\r
+\r
+bit optionListing; // opt l\r
+\r
+bit optionObject; // opt o\r
+\r
+char[] line;\r
+\r
+int column;\r
+\r
+class Location {\r
+\r
+       char[] filename;\r
+\r
+       int lineNo = 0;\r
+\r
+       this(char[] filename) {\r
+               this.filename = filename;\r
+       }\r
+}\r
+\r
+Location[] locations;\r
+\r
+Location currentLocation;\r
+\r
+bit foundEnd;\r
+\r
+class AssemblyError : Exception {\r
+\r
+       this(char[] msg) {\r
+               super(msg);\r
+       }\r
+}\r
+\r
+class Label {\r
+\r
+       int value;\r
+\r
+       bit unused = true;\r
+\r
+       bit unknownInPass1 = false;\r
+\r
+       bit passed = false;\r
+\r
+       this(int value) {\r
+               this.value = value;\r
+       }\r
+}\r
+\r
+Label[char[]] labelTable;\r
+\r
+Label currentLabel;\r
+\r
+typedef int function(int a, int b) OperatorFunction;\r
+\r
+bit inOpcode = false;\r
+\r
+struct ValOp {\r
+\r
+       int value;\r
+\r
+       OperatorFunction func;\r
+\r
+       int priority;\r
+}\r
+\r
+ValOp[] valOpStack;\r
+\r
+int value;\r
+\r
+bit unknownInPass1;\r
+\r
+enum AddrMode {\r
+       ACCUMULATOR = 0,\r
+       IMMEDIATE = 1,\r
+       ABSOLUTE = 2,\r
+       ZEROPAGE = 3,\r
+       ABSOLUTE_X = 4,\r
+       ZEROPAGE_X = 5,\r
+       ABSOLUTE_Y = 6,\r
+       ZEROPAGE_Y = 7,\r
+       INDIRECT_X = 8,\r
+       INDIRECT_Y = 9,\r
+       INDIRECT = 10,\r
+       ABS_OR_ZP = 11, // temporarily used in readAddrMode\r
+       STANDARD_MASK = 15,\r
+       INCREMENT = 0x20,\r
+       DECREMENT = 0x30,\r
+       ZERO = 0x40\r
+}\r
+\r
+AddrMode addrMode;\r
+\r
+int origin = -1;\r
+\r
+int loadOrigin;\r
+\r
+int loadingOrigin;\r
+\r
+ushort[] blockEnds;\r
+\r
+int blockIndex;\r
+\r
+bit repeating; // line\r
+\r
+int repeatCounter; // line\r
+\r
+bit instructionBegin;\r
+\r
+bit pairing;\r
+\r
+bit willSkip;\r
+\r
+bit skipping;\r
+\r
+ushort[] skipOffsets;\r
+\r
+int skipOffsetsIndex = 0;\r
+\r
+int repeatOffset; // instruction repeat\r
+\r
+bit wereManyInstructions;\r
+\r
+typedef void function(int move) MoveFunction;\r
+\r
+int value1;\r
+\r
+AddrMode addrMode1;\r
+\r
+int value2;\r
+\r
+AddrMode addrMode2;\r
+\r
+struct IfContext {\r
+\r
+       bit condition;\r
+\r
+       bit wasElse;\r
+\r
+       bit aConditionMatched;\r
+}\r
+\r
+IfContext[] ifContexts;\r
+\r
+Stream listingStream = null;\r
+\r
+char[32] listingLine;\r
+\r
+int listingColumn;\r
+\r
+char[] lastListedFilename = null;\r
+\r
+Stream objectStream = null;\r
+\r
+int objectBytes = 0;\r
+\r
+bit getOption(char letter) {\r
+       assert(letter >= 'a' && letter <= 'z');\r
+       return options[letter - 'a'];\r
+}\r
+\r
+void warning(char[] msg, bool error = false) {\r
+       dout.flush();\r
+       version (Windows) {\r
+               HANDLE h = GetStdHandle(STD_ERROR_HANDLE);\r
+               CONSOLE_SCREEN_BUFFER_INFO csbi;\r
+               GetConsoleScreenBufferInfo(h, &csbi);\r
+               SetConsoleTextAttribute(h, (csbi.wAttributes & ~0xf) | (error ? 12 : 14));\r
+       }\r
+       if (line !is null) {\r
+               derr.printf("%.*s\n", line);\r
+       }\r
+       derr.printf("%.*s (%d) %.*s: %.*s\n",\r
+               currentLocation.filename,\r
+               currentLocation.lineNo,\r
+               error ? "ERROR" : "WARNING",\r
+               msg\r
+       );\r
+       version (Windows) {\r
+               SetConsoleTextAttribute(h, csbi.wAttributes);\r
+       }\r
+       exitCode = 1;\r
+}\r
+\r
+void illegalCharacter() {\r
+       throw new AssemblyError("Illegal character");\r
+}\r
+\r
+bit eol() {\r
+       return column >= line.length;\r
+}\r
+\r
+char readChar() {\r
+       if (eol()) {\r
+               throw new AssemblyError("Unexpected end of line");\r
+       }\r
+       return line[column++];\r
+}\r
+\r
+int readDigit(int base) {\r
+       if (eol()) return -1;\r
+       int r = line[column];\r
+       if (r >= '0' && r <= '9') {\r
+               r -= '0';\r
+       } else {\r
+               r &= 0xdf;\r
+               if (r >= 'A' && r <= 'Z') {\r
+                       r -= 'A' - 10;\r
+               } else {\r
+                       return -1;\r
+               }\r
+       }\r
+       if (r < base) {\r
+               column++;\r
+               return r;\r
+       }\r
+       return -1;\r
+}\r
+\r
+int readNumber(int base) {\r
+       long r = readDigit(base);\r
+       if (r < 0) {\r
+               illegalCharacter();\r
+       }\r
+       do {\r
+               int d = readDigit(base);\r
+               if (d < 0) {\r
+                       return cast(int) r;\r
+               }\r
+               r = r * base + d;\r
+       } while (r <= 0x7fffffff);\r
+       throw new AssemblyError("Number too big");\r
+}\r
+\r
+void readSpaces() {\r
+       switch (readChar()) {\r
+       case '\t':\r
+       case ' ':\r
+               break;\r
+       default:\r
+               throw new AssemblyError("Space expected");\r
+       }\r
+       while (!eol()) {\r
+               switch (line[column]) {\r
+               case '\t':\r
+               case ' ':\r
+                       column++;\r
+                       break;\r
+               default:\r
+                       return;\r
+               }\r
+       }\r
+}\r
+\r
+char[] readLabel() {\r
+       char[] label = "";\r
+       while (!eol()) {\r
+               char c = line[column++];\r
+               if (c >= '0' && c <= '9' || c == '_') {\r
+                       label ~= c;\r
+                       continue;\r
+               }\r
+               c &= 0xdf;\r
+               if (c >= 'A' && c <= 'Z') {\r
+                       label ~= c;\r
+                       continue;\r
+               }\r
+               column--;\r
+               break;\r
+       }\r
+       return label >= "A" ? label : null;\r
+}\r
+\r
+void readComma() {\r
+       if (readChar() != ',') {\r
+               throw new AssemblyError("Bad or missing function parameter");\r
+       }\r
+}\r
+\r
+char[] readInstruction() {\r
+       char[] r = "";\r
+       for (int i = 0; i < 3; i++) {\r
+               char c = readChar() & 0xdf;\r
+               if (c < 'A' || c > 'Z') {\r
+                       throw new AssemblyError("Illegal instruction");\r
+               }\r
+               r ~= c;\r
+       }\r
+       return r;\r
+}\r
+\r
+char[] readFunction() {\r
+       if (column + 5 >= line.length) return "";\r
+       if (line[column + 3] != '(') return "";\r
+       char[] r = "";\r
+       for (int i = 0; i < 3; i++) {\r
+               char c = line[column + i] & 0xdf;\r
+               if (c < 'A' || c > 'Z') return "";\r
+               r ~= c;\r
+       }\r
+       column += 4;\r
+       return r;\r
+}\r
+\r
+char[] readFilename() {\r
+       char[] filename = "";\r
+       readSpaces();\r
+       char delimiter = readChar();\r
+       switch (delimiter) {\r
+       case '"':\r
+       case '\'':\r
+               char c;\r
+               while ((c = readChar()) != delimiter) {\r
+                       filename ~= c;\r
+               }\r
+               return filename;\r
+       default:\r
+               illegalCharacter();\r
+       }\r
+}\r
+\r
+void readStringChar(char c) {\r
+       if (readChar() != c) {\r
+               throw new AssemblyError("String error");\r
+       }\r
+}\r
+\r
+ubyte[] readString() {\r
+       if (eol()) return null;\r
+       ubyte[] r;\r
+       char delimiter = readChar();\r
+       switch (delimiter) {\r
+       case '"':\r
+       case '\'':\r
+               for (;;) {\r
+                       char c = readChar();\r
+                       if (c == delimiter) {\r
+                               if (eol()) return r;\r
+                               if (line[column] != delimiter) {\r
+                                       if (line[column] == '*') {\r
+                                               column++;\r
+                                               foreach (inout ubyte b; r) {\r
+                                                       b ^= 0x80;\r
+                                               }\r
+                                       }\r
+                                       return r;\r
+                               }\r
+                               column++;\r
+                       }\r
+                       r ~= cast(ubyte) c;\r
+               }\r
+       default:\r
+               column--;\r
+               return null;\r
+       }\r
+}\r
+\r
+void checkNoExtraCharacters() {\r
+       if (eol()) return;\r
+       switch (line[column]) {\r
+       case '\t':\r
+       case ' ':\r
+               return;\r
+       default:\r
+               throw new AssemblyError("Extra characters on line");\r
+       }\r
+}\r
+\r
+void checkOriginDefined() {\r
+       if (origin < 0) {\r
+               throw new AssemblyError("No ORG specified");\r
+       }\r
+}\r
+\r
+int operatorPlus(int a, int b) {\r
+       return b;\r
+}\r
+\r
+int operatorMinus(int a, int b) {\r
+       return -b;\r
+}\r
+\r
+int operatorLow(int a, int b) {\r
+       return b & 0xff;\r
+}\r
+\r
+int operatorHigh(int a, int b) {\r
+       return (b >> 8) & 0xff;\r
+}\r
+\r
+int operatorLogicalNot(int a, int b) {\r
+       return !b;\r
+}\r
+\r
+int operatorBitwiseNot(int a, int b) {\r
+       return ~b;\r
+}\r
+\r
+int operatorAdd(int a, int b) {\r
+       long r = cast(long) a + b;\r
+       if (r < -0x80000000L || r > 0x7fffffffL) {\r
+               throw new AssemblyError("Arithmetic overflow");\r
+       }\r
+       return a + b;\r
+}\r
+\r
+int operatorSubtract(int a, int b) {\r
+       long r = cast(long) a - b;\r
+       if (r < -0x80000000L || r > 0x7fffffffL) {\r
+               throw new AssemblyError("Arithmetic overflow");\r
+       }\r
+       return a - b;\r
+}\r
+\r
+int operatorMultiply(int a, int b) {\r
+       long r = cast(long) a * b;\r
+       if (r < -0x80000000L || r > 0x7fffffffL) {\r
+               throw new AssemblyError("Arithmetic overflow");\r
+       }\r
+       return a * b;\r
+}\r
+\r
+int operatorDivide(int a, int b) {\r
+       if (b == 0) {\r
+               throw new AssemblyError("Divide by zero");\r
+       }\r
+       return a / b;\r
+}\r
+\r
+int operatorModulus(int a, int b) {\r
+       if (b == 0) {\r
+               throw new AssemblyError("Divide by zero");\r
+       }\r
+       return a % b;\r
+}\r
+\r
+int operatorAnd(int a, int b) {\r
+       return a & b;\r
+}\r
+\r
+int operatorOr(int a, int b) {\r
+       return a | b;\r
+}\r
+\r
+int operatorXor(int a, int b) {\r
+       return a ^ b;\r
+}\r
+\r
+int operatorEqual(int a, int b) {\r
+       return a == b;\r
+}\r
+\r
+int operatorNotEqual(int a, int b) {\r
+       return a != b;\r
+}\r
+\r
+int operatorLess(int a, int b) {\r
+       return a < b;\r
+}\r
+\r
+int operatorGreater(int a, int b) {\r
+       return a > b;\r
+}\r
+\r
+int operatorLessEqual(int a, int b) {\r
+       return a <= b;\r
+}\r
+\r
+int operatorGreaterEqual(int a, int b) {\r
+       return a >= b;\r
+}\r
+\r
+int operatorShiftLeft(int a, int b) {\r
+       if (b < 0) {\r
+               return operatorShiftRight(a, -b);\r
+       }\r
+       if (a != 0 & b >= 32) {\r
+               throw new AssemblyError("Arithmetic overflow");\r
+       }\r
+       long r = cast(long) a << b;\r
+       if (r & 0xffffffff00000000L) {\r
+               throw new AssemblyError("Arithmetic overflow");\r
+       }\r
+       return a << b;\r
+}\r
+\r
+int operatorShiftRight(int a, int b) {\r
+       if (b < 0) {\r
+               return operatorShiftLeft(a, -b);\r
+       }\r
+       if (b >= 32) {\r
+               b = 31;\r
+       }\r
+       return a >> b;\r
+}\r
+\r
+int operatorLogicalAnd(int a, int b) {\r
+       return a && b;\r
+}\r
+\r
+int operatorLogicalOr(int a, int b) {\r
+       return a || b;\r
+}\r
+\r
+void pushValOp(int value, OperatorFunction func, int priority) {\r
+       ValOp valOp;\r
+       valOp.value = value;\r
+       valOp.func = func;\r
+       valOp.priority = priority;\r
+       valOpStack ~= valOp;\r
+}\r
+\r
+void readValue() {\r
+       assert(valOpStack.length == 0);\r
+       unknownInPass1 = false;\r
+       int priority = 0;\r
+       do {\r
+               int operand;\r
+               char c = readChar();\r
+               switch (c) {\r
+               case '[':\r
+                       priority += 10;\r
+                       continue;\r
+               case '+':\r
+                       pushValOp(0, &operatorPlus, priority + 8);\r
+                       continue;\r
+               case '-':\r
+                       pushValOp(0, &operatorMinus, priority + 8);\r
+                       continue;\r
+               case '<':\r
+                       pushValOp(0, &operatorLow, priority + 8);\r
+                       continue;\r
+               case '>':\r
+                       pushValOp(0, &operatorHigh, priority + 8);\r
+                       continue;\r
+               case '!':\r
+                       pushValOp(0, &operatorLogicalNot, priority + 4);\r
+                       continue;\r
+               case '~':\r
+                       pushValOp(0, &operatorBitwiseNot, priority + 8);\r
+                       continue;\r
+               case '(':\r
+                       throw new AssemblyError("Use square brackets instead");\r
+               case '*':\r
+                       checkOriginDefined();\r
+                       operand = origin;\r
+                       break;\r
+               case '#':\r
+                       if (!repeating) {\r
+                               throw new AssemblyError("'#' is allowed only in repeated lines");\r
+                       }\r
+                       operand = repeatCounter;\r
+                       break;\r
+               case '\'':\r
+               case '"':\r
+                       operand = readChar();\r
+                       if (operand == c) {\r
+                               readStringChar(c);\r
+                       }\r
+                       readStringChar(c);\r
+                       if (!eol() && line[column] == '*') {\r
+                               column++;\r
+                               operand ^= 0x80;\r
+                       }\r
+                       break;\r
+               case '^':\r
+                       switch (readChar()) {\r
+                       case '0':\r
+                               operand = option5200 ? 0xc000 : 0xd000;\r
+                               break;\r
+                       case '1':\r
+                               operand = option5200 ? 0xc010 : 0xd010;\r
+                               break;\r
+                       case '2':\r
+                               operand = option5200 ? 0xe800 : 0xd200;\r
+                               break;\r
+                       case '3':\r
+                               if (option5200) {\r
+                                       throw new AssemblyError("There's no PIA chip in Atari 5200");\r
+                               }\r
+                               operand = 0xd300;\r
+                               break;\r
+                       case '4':\r
+                               operand = 0xd400;\r
+                               break;\r
+                       default:\r
+                               illegalCharacter();\r
+                       }\r
+                       int d = readDigit(16);\r
+                       if (d < 0) {\r
+                               illegalCharacter();\r
+                       }\r
+                       operand += d;\r
+                       break;\r
+               case '{':\r
+                       if (inOpcode) {\r
+                               throw new AssemblyError("Nested opcodes not supported");\r
+                       }\r
+                       ValOp[] savedValOpStack = valOpStack;\r
+                       AddrMode savedAddrMode = addrMode;\r
+                       bit savedUnknownInPass1 = unknownInPass1;\r
+                       bit savedInstructionBegin = instructionBegin;\r
+                       valOpStack.length = 0;\r
+                       inOpcode = true;\r
+                       assemblyInstruction(readInstruction());\r
+                       if (readChar() != '}') {\r
+                               throw new AssemblyError("Missing '}'");\r
+                       }\r
+                       assert(!instructionBegin);\r
+                       inOpcode = false;\r
+                       valOpStack = savedValOpStack;\r
+                       addrMode = savedAddrMode;\r
+                       unknownInPass1 = savedUnknownInPass1;\r
+                       instructionBegin = savedInstructionBegin;\r
+                       operand = value;\r
+                       break;\r
+               case '$':\r
+                       operand = readNumber(16);\r
+                       break;\r
+               case '%':\r
+                       operand = readNumber(2);\r
+                       break;\r
+               default:\r
+                       column--;\r
+                       if (c >= '0' && c <= '9') {\r
+                               operand = readNumber(10);\r
+                               break;\r
+                       }\r
+                       char[] label = readLabel();\r
+                       if (label is null) {\r
+                               illegalCharacter();\r
+                       }\r
+                       if (label in labelTable) {\r
+                               Label l = labelTable[label];\r
+                               operand = l.value;\r
+                               l.unused = false;\r
+                               if (pass2) {\r
+                                       if (l.passed) {\r
+                                               if (l.unknownInPass1) {\r
+                                                       unknownInPass1 = true;\r
+                                               }\r
+                                       } else {\r
+                                               if (l.unknownInPass1) {\r
+                                                       throw new AssemblyError("Illegal forward reference");\r
+                                               }\r
+                                               unknownInPass1 = true;\r
+                                       }\r
+                               } else {\r
+                                       if (l.unknownInPass1) {\r
+                                               unknownInPass1 = true;\r
+                                       }\r
+                               }\r
+                       } else {\r
+                               if (pass2) {\r
+                                       throw new AssemblyError("Undeclared label: " ~ label);\r
+                               }\r
+                               unknownInPass1 = true;\r
+                       }\r
+                       break;\r
+               }\r
+               while (!eol() && line[column] == ']') {\r
+                       column++;\r
+                       priority -= 10;\r
+                       if (priority < 0) {\r
+                               throw new AssemblyError("Unmatched bracket");\r
+                       }\r
+               }\r
+               if (eol()) {\r
+                       if (priority != 0) {\r
+                               throw new AssemblyError("Unmatched bracket");\r
+                       }\r
+                       pushValOp(operand, &operatorPlus, 1);\r
+               } else {\r
+                       switch (line[column++]) {\r
+                       case '+':\r
+                               pushValOp(operand, &operatorAdd, priority + 6);\r
+                               break;\r
+                       case '-':\r
+                               pushValOp(operand, &operatorSubtract, priority + 6);\r
+                               break;\r
+                       case '*':\r
+                               pushValOp(operand, &operatorMultiply, priority + 7);\r
+                               break;\r
+                       case '/':\r
+                               pushValOp(operand, &operatorDivide, priority + 7);\r
+                               break;\r
+                       case '%':\r
+                               pushValOp(operand, &operatorModulus, priority + 7);\r
+                               break;\r
+                       case '<':\r
+                               switch (readChar()) {\r
+                               case '<':\r
+                                       pushValOp(operand, &operatorShiftLeft, priority + 7);\r
+                                       break;\r
+                               case '=':\r
+                                       pushValOp(operand, &operatorLessEqual, priority + 5);\r
+                                       break;\r
+                               case '>':\r
+                                       pushValOp(operand, &operatorNotEqual, priority + 5);\r
+                                       break;\r
+                               default:\r
+                                       column--;\r
+                                       pushValOp(operand, &operatorLess, priority + 5);\r
+                                       break;\r
+                               }\r
+                               break;\r
+                       case '=':\r
+                               switch (readChar()) {\r
+                               default:\r
+                                       column--;\r
+                                       goto case '=';\r
+                               case '=':\r
+                                       pushValOp(operand, &operatorEqual, priority + 5);\r
+                                       break;\r
+                               }\r
+                               break;\r
+                       case '>':\r
+                               switch (readChar()) {\r
+                               case '>':\r
+                                       pushValOp(operand, &operatorShiftRight, priority + 7);\r
+                                       break;\r
+                               case '=':\r
+                                       pushValOp(operand, &operatorGreaterEqual, priority + 5);\r
+                                       break;\r
+                               default:\r
+                                       column--;\r
+                                       pushValOp(operand, &operatorGreater, priority + 5);\r
+                                       break;\r
+                               }\r
+                               break;\r
+                       case '!':\r
+                               switch (readChar()) {\r
+                               case '=':\r
+                                       pushValOp(operand, &operatorNotEqual, priority + 5);\r
+                                       break;\r
+                               default:\r
+                                       illegalCharacter();\r
+                               }\r
+                               break;\r
+                       case '&':\r
+                               switch (readChar()) {\r
+                               case '&':\r
+                                       pushValOp(operand, &operatorLogicalAnd, priority + 3);\r
+                                       break;\r
+                               default:\r
+                                       column--;\r
+                                       pushValOp(operand, &operatorAnd, priority + 7);\r
+                                       break;\r
+                               }\r
+                               break;\r
+                       case '|':\r
+                               switch (readChar()) {\r
+                               case '|':\r
+                                       pushValOp(operand, &operatorLogicalOr, priority + 2);\r
+                                       break;\r
+                               default:\r
+                                       column--;\r
+                                       pushValOp(operand, &operatorOr, priority + 6);\r
+                                       break;\r
+                               }\r
+                               break;\r
+                       case '^':\r
+                               pushValOp(operand, &operatorXor, priority + 6);\r
+                               break;\r
+                       default:\r
+                               column--;\r
+                               if (priority != 0) {\r
+                                       throw new AssemblyError("Unmatched bracket");\r
+                               }\r
+                               pushValOp(operand, &operatorPlus, 1);\r
+                               break;\r
+                       }\r
+               }\r
+               for (;;) {\r
+                       int sp = valOpStack.length - 1;\r
+                       if (sp <= 0 || valOpStack[sp].priority > valOpStack[sp - 1].priority) {\r
+                               break;\r
+                       }\r
+                       int operand1 = valOpStack[sp - 1].value;\r
+                       OperatorFunction func1 = valOpStack[sp - 1].func;\r
+                       valOpStack[sp - 1] = valOpStack[sp];\r
+                       valOpStack.length = sp;\r
+                       if (pass2 || !unknownInPass1) { // skip operations if unknown operands\r
+                               valOpStack[sp - 1].value = func1(operand1, valOpStack[sp - 1].value);\r
+                       }\r
+               }\r
+       } while (valOpStack.length != 1 || valOpStack[0].priority != 1);\r
+       value = valOpStack[0].value;\r
+       valOpStack.length = 0;\r
+}\r
+\r
+debug int testValue(char[] l) {\r
+       line = l;\r
+       column = 0;\r
+       readValue();\r
+       dout.printf("Value of %.*s is %x\n", line, value);\r
+       return value;\r
+}\r
+\r
+unittest {\r
+       assert(testValue("123") == 123);\r
+       assert(testValue("$1234abCd") == 0x1234abcd);\r
+       assert(testValue("%101") == 5);\r
+       assert(testValue("^07") == 0xd007);\r
+       assert(testValue("^1f") == 0xd01f);\r
+       assert(testValue("^23") == 0xd203);\r
+       assert(testValue("^31") == 0xd301);\r
+       assert(testValue("^49") == 0xd409);\r
+       assert(testValue("!0") == 1);\r
+       assert(testValue("<$1234") == 0x34);\r
+       assert(testValue(">$1234567") == 0x45);\r
+       assert(testValue("1+2") == 3);\r
+       assert(testValue("1+2*3") == 7);\r
+       assert(testValue("[1+2]*3") == 9);\r
+       assert(testValue("{nop}") == 0xea);\r
+       assert(testValue("{CLC}+{sec}") == 0x50);\r
+       assert(testValue("{Jsr}") == 0x20);\r
+       assert(testValue("{bit a:}") == 0x2c);\r
+       assert(testValue("{bIt $7d}") == 0x24);\r
+}\r
+\r
+void mustBeKnownInPass1() {\r
+       if (unknownInPass1) {\r
+               throw new AssemblyError("Label not defined before");\r
+       }\r
+}\r
+\r
+void readWord() {\r
+       readValue();\r
+       if ((!unknownInPass1 || pass2) && (value < -0xffff || value > 0xffff)) {\r
+               throw new AssemblyError("Value out of range");\r
+       }\r
+}\r
+\r
+void readUnsignedWord() {\r
+       readWord();\r
+       if ((!unknownInPass1 || pass2) && value < 0) {\r
+               throw new AssemblyError("Value out of range");\r
+       }\r
+}\r
+\r
+void readKnownPositive() {\r
+       readValue();\r
+       mustBeKnownInPass1();\r
+       if (value <= 0) {\r
+               throw new AssemblyError("Value out of range");\r
+       }\r
+}\r
+\r
+void optionalIncDec() {\r
+       if (eol()) return;\r
+       switch (line[column]) {\r
+       case '+':\r
+               column++;\r
+               addrMode += AddrMode.INCREMENT;\r
+               return;\r
+       case '-':\r
+               column++;\r
+               addrMode += AddrMode.DECREMENT;\r
+               return;\r
+       default:\r
+               return;\r
+       }\r
+}\r
+\r
+void readAddrMode() {\r
+       readSpaces();\r
+       char c = readChar();\r
+       switch (c) {\r
+       case '@':\r
+               addrMode = AddrMode.ACCUMULATOR;\r
+               return;\r
+       case '#':\r
+       case '<':\r
+       case '>':\r
+               addrMode = AddrMode.IMMEDIATE;\r
+               if (inOpcode && line[column] == '}') {\r
+                       return;\r
+               }\r
+               readWord();\r
+               switch (c) {\r
+               case '#':\r
+                       break;\r
+               case '<':\r
+                       value &= 0xff;\r
+                       break;\r
+               case '>':\r
+                       value = (value >> 8) & 0xff;\r
+                       break;\r
+               }\r
+               return;\r
+       case '(':\r
+               if (inOpcode) {\r
+                       switch (readChar()) {\r
+                       case ',':\r
+                               switch (readChar()) {\r
+                               case 'X':\r
+                               case 'x':\r
+                                       break;\r
+                               default:\r
+                                       illegalCharacter();\r
+                               }\r
+                               if (readChar() != ')') {\r
+                                       throw new AssemblyError("Need parenthesis");\r
+                               }\r
+                               addrMode = AddrMode.INDIRECT_X;\r
+                               return;\r
+                       case ')':\r
+                               if (readChar() == ',') {\r
+                                       switch (readChar()) {\r
+                                       case 'Y':\r
+                                       case 'y':\r
+                                               break;\r
+                                       default:\r
+                                               illegalCharacter();\r
+                                       }\r
+                                       addrMode = AddrMode.INDIRECT_Y;\r
+                                       return;\r
+                               } else {\r
+                                       column--;\r
+                                       addrMode = AddrMode.INDIRECT;\r
+                                       return;\r
+                               }\r
+                       default:\r
+                               column--;\r
+                               break;\r
+                       }\r
+               }\r
+               readUnsignedWord();\r
+               switch (readChar()) {\r
+               case ',':\r
+                       switch (readChar()) {\r
+                       case 'X':\r
+                       case 'x':\r
+                               addrMode = AddrMode.INDIRECT_X;\r
+                               break;\r
+                       case '0':\r
+                               addrMode = cast(AddrMode) (AddrMode.INDIRECT_X + AddrMode.ZERO);\r
+                               break;\r
+                       default:\r
+                               illegalCharacter();\r
+                       }\r
+                       if (readChar() != ')') {\r
+                               throw new AssemblyError("Need parenthesis");\r
+                       }\r
+                       return;\r
+               case ')':\r
+                       if (eol()) {\r
+                               addrMode = AddrMode.INDIRECT;\r
+                               return;\r
+                       }\r
+                       if (line[column] == ',') {\r
+                               column++;\r
+                               switch (readChar()) {\r
+                               case 'Y':\r
+                               case 'y':\r
+                                       addrMode = AddrMode.INDIRECT_Y;\r
+                                       break;\r
+                               case '0':\r
+                                       addrMode = cast(AddrMode) (AddrMode.INDIRECT_Y + AddrMode.ZERO);\r
+                                       break;\r
+                               default:\r
+                                       illegalCharacter();\r
+                               }\r
+                               optionalIncDec();\r
+                               return;\r
+                       }\r
+                       addrMode = AddrMode.INDIRECT;\r
+                       return;\r
+               default:\r
+                       illegalCharacter();\r
+               }\r
+               break;\r
+       case 'A':\r
+       case 'a':\r
+               if (!eol() && line[column] == ':') {\r
+                       column++;\r
+                       addrMode = AddrMode.ABSOLUTE;\r
+               } else {\r
+                       addrMode = AddrMode.ABS_OR_ZP;\r
+                       column--;\r
+               }\r
+               break;\r
+       case 'Z':\r
+       case 'z':\r
+               if (!eol() && line[column] == ':') {\r
+                       column++;\r
+                       addrMode = AddrMode.ZEROPAGE;\r
+               } else {\r
+                       addrMode = AddrMode.ABS_OR_ZP;\r
+                       column--;\r
+               }\r
+               break;\r
+       default:\r
+               addrMode = AddrMode.ABS_OR_ZP;\r
+               column--;\r
+               break;\r
+       }\r
+       // absolute or zeropage addressing, optionally indexed\r
+       if (inOpcode && (addrMode == AddrMode.ABSOLUTE || addrMode == AddrMode.ZEROPAGE)) {\r
+               switch (readChar()) {\r
+               case '}':\r
+                       column--;\r
+                       return;\r
+               case ',':\r
+                       switch (readChar()) {\r
+                       case 'X':\r
+                       case 'x':\r
+                               addrMode += cast(AddrMode) (AddrMode.ABSOLUTE_X - AddrMode.ABSOLUTE);\r
+                               return;\r
+                       case 'Y':\r
+                       case 'y':\r
+                               addrMode += cast(AddrMode) (AddrMode.ABSOLUTE_Y - AddrMode.ABSOLUTE);\r
+                               return;\r
+                       default:\r
+                               illegalCharacter();\r
+                       }\r
+                       return;\r
+               default:\r
+                       column--;\r
+                       break;\r
+               }\r
+       }\r
+       readUnsignedWord();\r
+       if (addrMode == AddrMode.ABS_OR_ZP) {\r
+               if (unknownInPass1 || value > 0xff) {\r
+                       addrMode = AddrMode.ABSOLUTE;\r
+               } else {\r
+                       addrMode = AddrMode.ZEROPAGE;\r
+               }\r
+       }\r
+       if (eol()) return;\r
+       if (line[column] == ',') {\r
+               column++;\r
+               switch (readChar()) {\r
+               case 'X':\r
+               case 'x':\r
+                       addrMode += cast(AddrMode) (AddrMode.ABSOLUTE_X - AddrMode.ABSOLUTE);\r
+                       optionalIncDec();\r
+                       return;\r
+               case 'Y':\r
+               case 'y':\r
+                       addrMode += cast(AddrMode) (AddrMode.ABSOLUTE_Y - AddrMode.ABSOLUTE);\r
+                       optionalIncDec();\r
+                       return;\r
+               default:\r
+                       illegalCharacter();\r
+               }\r
+       }\r
+}\r
+\r
+void readAbsoluteAddrMode() {\r
+       if (inOpcode && readChar() == '}') {\r
+               column--;\r
+       } else {\r
+               readAddrMode();\r
+               switch (addrMode) {\r
+               case AddrMode.ABSOLUTE:\r
+               case AddrMode.ZEROPAGE:\r
+                       break;\r
+               default:\r
+                       illegalAddrMode();\r
+               }\r
+       }\r
+       addrMode = AddrMode.ABSOLUTE;\r
+}\r
+\r
+debug AddrMode testAddrMode(char[] l) {\r
+       line = l;\r
+       column = 0;\r
+       readAddrMode();\r
+       dout.printf("Addressing mode of \"%.*s\" is %x\n", line, addrMode);\r
+       return addrMode;\r
+}\r
+\r
+unittest {\r
+       assert(testAddrMode(" @") == AddrMode.ACCUMULATOR);\r
+       assert(testAddrMode(" #0") == AddrMode.IMMEDIATE);\r
+       assert(testAddrMode(" $abc,x-") == cast(AddrMode) (AddrMode.ABSOLUTE_X + AddrMode.DECREMENT));\r
+       assert(testAddrMode(" $ab,Y+") == cast(AddrMode) (AddrMode.ZEROPAGE_Y + AddrMode.INCREMENT));\r
+       assert(testAddrMode(" (0,x)") == AddrMode.INDIRECT_X);\r
+       assert(testAddrMode(" ($ff),Y+") == cast(AddrMode) (AddrMode.INDIRECT_Y + AddrMode.INCREMENT));\r
+       assert(testAddrMode(" ($abcd)") == AddrMode.INDIRECT);\r
+       inOpcode = true;\r
+       assert(testAddrMode(" a:}") == AddrMode.ABSOLUTE);\r
+       assert(testAddrMode(" z:}") == AddrMode.ZEROPAGE);\r
+       assert(testAddrMode(" a:,x}") == AddrMode.ABSOLUTE_X);\r
+       assert(testAddrMode(" z:,y}") == AddrMode.ZEROPAGE_Y);\r
+       assert(testAddrMode(" (,X)}") == AddrMode.INDIRECT_X);\r
+       assert(testAddrMode(" (),y}") == AddrMode.INDIRECT_Y);\r
+       assert(testAddrMode(" ()}") == AddrMode.INDIRECT);\r
+       inOpcode = false;\r
+}\r
+\r
+bit inFalseCondition() {\r
+       foreach (IfContext ic; ifContexts) {\r
+               if (!ic.condition) return true;\r
+       }\r
+       return false;\r
+}\r
+\r
+int filenameExt(char[] filename) {\r
+       int i = filename.length;\r
+       while (--i >= 0) {\r
+               switch (filename[i]) {\r
+               case '.':\r
+                       return i;\r
+               case '/':\r
+               case '\\':\r
+                       return -1;\r
+               default:\r
+                       break;\r
+               }\r
+       }\r
+       return -1;\r
+}\r
+\r
+unittest {\r
+       assert(filenameExt("foo.bar") == 3);\r
+       assert(filenameExt("foo.bar/foo") == -1);\r
+       assert(filenameExt("foobar") == -1);\r
+       assert(filenameExt("test\\foo.bar") == 8);\r
+}\r
+\r
+char[] makeEscape(char[] s) {\r
+       return replace(s, "$", "$$");\r
+}\r
+\r
+Stream openInputFile(char[] filename) {\r
+       makeSources ~= ' ' ~ makeEscape(filename);\r
+       try {\r
+               return new BufferedFile(filename, FileMode.In);\r
+       } catch (OpenException e) {\r
+               throw new AssemblyError(e.toString());\r
+       }\r
+}\r
+\r
+Stream openOutputFile(char letter, char[] defaultExt) {\r
+       char[] filename;\r
+       if (optionParameters[letter - 'a'] is null) {\r
+               filename = sourceFilename;\r
+               int i = filenameExt(filename);\r
+               if (i > 0) {\r
+                       filename = filename[0 .. i];\r
+               }\r
+               filename ~= defaultExt;\r
+       } else {\r
+               filename = optionParameters[letter - 'a'];\r
+       }\r
+       if (letter == 'o') {\r
+               makeTarget = makeEscape(filename);\r
+       }\r
+       try {\r
+               return new BufferedFile(filename, FileMode.OutNew);\r
+       } catch (OpenException e) {\r
+               throw new AssemblyError(e.toString());\r
+       }\r
+}\r
+\r
+void ensureListingFileOpen(char letter, char[] msg) {\r
+       if (listingStream is null) {\r
+               listingStream = openOutputFile(letter, ".lst");\r
+               if (!getOption('q')) {\r
+                       dout.printf(msg);\r
+               }\r
+               listingStream.printf(TITLE ~ "\r\n");\r
+       }\r
+}\r
+\r
+void listNibble(int x) {\r
+       listingLine[listingColumn++] = x <= 9 ? x + '0' : x + ('A' - 10);\r
+}\r
+\r
+void listByte(ubyte x) {\r
+       listNibble(x >> 4);\r
+       listNibble(x & 0xf);\r
+}\r
+\r
+void listWord(ushort x) {\r
+       listByte(cast(ubyte) (x >> 8));\r
+       listByte(cast(ubyte) x);\r
+}\r
+\r
+void listLine() {\r
+       if (!optionListing || !getOption('l') || line is null) {\r
+               return;\r
+       }\r
+       assert(pass2);\r
+       if (inFalseCondition() && !getOption('c')) {\r
+               return;\r
+       }\r
+       if (getOption('i') && locations.length > 0) {\r
+               return;\r
+       }\r
+       ensureListingFileOpen('l', "Writing listing file...\n");\r
+       if (currentLocation.filename != lastListedFilename) {\r
+               listingStream.printf("Source: %.*s\n", currentLocation.filename);\r
+               lastListedFilename = currentLocation.filename;\r
+       }\r
+       int i = 4;\r
+       int x = currentLocation.lineNo;\r
+       while (x > 0 && i >= 0) {\r
+               listingLine[i--] = '0' + x % 10;\r
+               x /= 10;\r
+       }\r
+       while (i >= 0) {\r
+               listingLine[i--] = ' ';\r
+       }\r
+       listingLine[5] = ' ';\r
+       while (listingColumn < 32) {\r
+               listingLine[listingColumn++] = ' ';\r
+       }\r
+       listingStream.printf("%.32s%.*s\r\n", cast(char*) listingLine, line);\r
+}\r
+\r
+void listCommentLine() {\r
+       if (currentLabel is null) {\r
+               listingColumn = 6;\r
+       } else {\r
+               assert(!inFalseCondition());\r
+               checkOriginDefined();\r
+       }\r
+       listLine();\r
+}\r
+\r
+void listLabelTable() {\r
+       if (optionParameters['t' - 'a'] !is null && listingStream !is null) {\r
+               listingStream.close();\r
+               listingStream = null;\r
+       }\r
+       ensureListingFileOpen('t', "Writing label table...\n");\r
+       listingStream.printf("Label table:\r\n");\r
+       foreach (char[] name; labelTable.keys.sort) {\r
+               Label l = labelTable[name];\r
+               listingStream.write(l.unused ? 'n' : ' ');\r
+               listingStream.write(l.unknownInPass1 ? '2' : ' ');\r
+               int value = l.value;\r
+               char sign = ' ';\r
+               if (value < 0) {\r
+                       sign = '-';\r
+                       value = -value;\r
+               }\r
+               listingStream.printf(\r
+                       (l.value & 0xffff0000) != 0 ? " %c%08X %.*s\r\n" : "     %c%04X %.*s\r\n",\r
+                       sign, value, name\r
+               );\r
+       }\r
+}\r
+\r
+debug ubyte[] objectBuffer;\r
+\r
+void objectByte(ubyte b) {\r
+       debug {\r
+               objectBuffer ~= b;\r
+       } else {\r
+               assert(pass2);\r
+               if (!optionObject) return;\r
+               if (objectStream is null) {\r
+                       objectStream = openOutputFile('o', ".obx");\r
+                       if (!getOption('q')) {\r
+                               dout.printf("Writing object file...\n");\r
+                       }\r
+               }\r
+               try {\r
+                       objectStream.write(b);\r
+               } catch (WriteException e) {\r
+                       throw new AssemblyError("Error writing object file");\r
+               }\r
+       }\r
+       objectBytes++;\r
+}\r
+\r
+void objectWord(ushort w) {\r
+       objectByte(cast(ubyte) w);\r
+       objectByte(cast(ubyte) (w >> 8));\r
+}\r
+\r
+void putByte(ubyte b) {\r
+       if (inOpcode) {\r
+               if (instructionBegin) {\r
+                       value = b;\r
+                       instructionBegin = false;\r
+               }\r
+               return;\r
+       }\r
+       if (willSkip) {\r
+               assert(!pass2);\r
+               willSkip = false;\r
+               skipping = true;\r
+       }\r
+       if (skipping) {\r
+               assert(!pass2);\r
+               skipOffsets[skipOffsets.length - 1]++;\r
+       }\r
+       if (instructionBegin) {\r
+               repeatOffset = -2;\r
+               instructionBegin = false;\r
+       }\r
+       repeatOffset--;\r
+       if (optionFill && loadingOrigin >= 0 && loadingOrigin != loadOrigin) {\r
+               if (loadingOrigin > loadOrigin) {\r
+                       throw new AssemblyError("Can't fill from higher to lower memory location");\r
+               }\r
+               if (pass2) {\r
+                       while (loadingOrigin < loadOrigin) {\r
+                               objectByte(0xff);\r
+                               loadingOrigin++;\r
+                       }\r
+               }\r
+       }\r
+       debug {\r
+               objectByte(b);\r
+       }\r
+       if (pass2) {\r
+               debug {\r
+               }else {\r
+                       objectByte(b);\r
+               }\r
+               if (listingColumn < 29) {\r
+                       listByte(b);\r
+                       listingLine[listingColumn++] = ' ';\r
+               } else {\r
+                       listingLine[29] = '+';\r
+                       listingColumn = 30;\r
+               }\r
+       }\r
+       if (optionHeaders) {\r
+               if (origin < 0)\r
+                       throw new AssemblyError("No ORG specified");\r
+               assert(blockIndex >= 0);\r
+               if (!pass2) {\r
+                       blockEnds[blockIndex] = cast(ushort) loadOrigin;\r
+               }\r
+       }\r
+       if (origin >= 0) {\r
+               origin++;\r
+               loadingOrigin = ++loadOrigin;\r
+       }\r
+}\r
+\r
+void putWord(ushort w) {\r
+       putByte(cast(ubyte) w);\r
+       putByte(cast(ubyte) (w >> 8));\r
+}\r
+\r
+void putCommand(ubyte b) {\r
+       putByte(b);\r
+       if (inOpcode) return;\r
+       switch (addrMode & AddrMode.STANDARD_MASK) {\r
+       case AddrMode.ACCUMULATOR:\r
+               break;\r
+       case AddrMode.IMMEDIATE:\r
+       case AddrMode.ZEROPAGE:\r
+       case AddrMode.ZEROPAGE_X:\r
+       case AddrMode.ZEROPAGE_Y:\r
+       case AddrMode.INDIRECT_X:\r
+       case AddrMode.INDIRECT_Y:\r
+               if (pass2 && (value < -0xff || value > 0xff)) {\r
+                       throw new AssemblyError("Value out of range");\r
+               }\r
+               putByte(cast(ubyte) value);\r
+               break;\r
+       case AddrMode.ABSOLUTE:\r
+       case AddrMode.ABSOLUTE_X:\r
+       case AddrMode.ABSOLUTE_Y:\r
+       case AddrMode.INDIRECT:\r
+               putWord(value);\r
+               break;\r
+       }\r
+       switch (addrMode) {\r
+       case cast(AddrMode) (AddrMode.ABSOLUTE_X + AddrMode.INCREMENT):\r
+       case cast(AddrMode) (AddrMode.ZEROPAGE_X + AddrMode.INCREMENT):\r
+               putByte(0xe8);\r
+               break;\r
+       case cast(AddrMode) (AddrMode.ABSOLUTE_X + AddrMode.DECREMENT):\r
+       case cast(AddrMode) (AddrMode.ZEROPAGE_X + AddrMode.DECREMENT):\r
+               putByte(0xca);\r
+               break;\r
+       case cast(AddrMode) (AddrMode.ABSOLUTE_Y + AddrMode.INCREMENT):\r
+       case cast(AddrMode) (AddrMode.ZEROPAGE_Y + AddrMode.INCREMENT):\r
+       case cast(AddrMode) (AddrMode.INDIRECT_Y + AddrMode.INCREMENT):\r
+       case cast(AddrMode) (AddrMode.INDIRECT_Y + AddrMode.INCREMENT + AddrMode.ZERO):\r
+               putByte(0xc8);\r
+               break;\r
+       case cast(AddrMode) (AddrMode.ABSOLUTE_Y + AddrMode.DECREMENT):\r
+       case cast(AddrMode) (AddrMode.ZEROPAGE_Y + AddrMode.DECREMENT):\r
+       case cast(AddrMode) (AddrMode.INDIRECT_Y + AddrMode.DECREMENT):\r
+       case cast(AddrMode) (AddrMode.INDIRECT_Y + AddrMode.DECREMENT + AddrMode.ZERO):\r
+               putByte(0x88);\r
+               break;\r
+       default:\r
+               break;\r
+       }\r
+}\r
+\r
+void noOpcode() {\r
+       if (inOpcode) {\r
+               throw new AssemblyError("Can't get opcode of this");\r
+       }\r
+}\r
+\r
+void directive() {\r
+       noOpcode();\r
+       if (repeating) {\r
+               throw new AssemblyError("Can't repeat this directive");\r
+       }\r
+       if (pairing) {\r
+               throw new AssemblyError("Can't pair this directive");\r
+       }\r
+}\r
+\r
+void noRepeatSkipDirective() {\r
+       directive();\r
+       if (willSkip) {\r
+               throw new AssemblyError("Can't skip over this");\r
+       }\r
+       repeatOffset = 0;\r
+}\r
+\r
+void illegalAddrMode() {\r
+       throw new AssemblyError("Illegal addressing mode");\r
+}\r
+\r
+void addrModeForMove(int move) {\r
+       switch (move) {\r
+       case 0:\r
+               readAddrMode();\r
+               break;\r
+       case 1:\r
+               value = value1;\r
+               addrMode = addrMode1;\r
+               break;\r
+       case 2:\r
+               value = value2;\r
+               addrMode = addrMode2;\r
+               break;\r
+       }\r
+}\r
+\r
+void assemblyAccumulator(ubyte b, ubyte prefix, int move) {\r
+       addrModeForMove(move);\r
+       if (prefix != 0) {\r
+               putByte(prefix);\r
+       }\r
+       switch (addrMode & AddrMode.STANDARD_MASK) {\r
+       case AddrMode.ACCUMULATOR:\r
+       case AddrMode.INDIRECT:\r
+               illegalAddrMode();\r
+       case AddrMode.IMMEDIATE:\r
+               if (b == 0x80) {\r
+                       // STA #\r
+                       illegalAddrMode();\r
+               }\r
+               putCommand(b + 9);\r
+               break;\r
+       case AddrMode.ABSOLUTE:\r
+               putCommand(b + 0xd);\r
+               break;\r
+       case AddrMode.ZEROPAGE:\r
+               putCommand(b + 5);\r
+               break;\r
+       case AddrMode.ABSOLUTE_X:\r
+               putCommand(b + 0x1d);\r
+               break;\r
+       case AddrMode.ZEROPAGE_X:\r
+               putCommand(b + 0x15);\r
+               break;\r
+       case AddrMode.ZEROPAGE_Y:\r
+               addrMode -= 1;\r
+               goto case AddrMode.ABSOLUTE_Y;\r
+       case AddrMode.ABSOLUTE_Y:\r
+               putCommand(b + 0x19);\r
+               break;\r
+       case AddrMode.INDIRECT_X:\r
+               if ((addrMode & AddrMode.ZERO) != 0) {\r
+                       putWord(0x00a2);\r
+               }\r
+               putCommand(b + 1);\r
+               break;\r
+       case AddrMode.INDIRECT_Y:\r
+               if ((addrMode & AddrMode.ZERO) != 0) {\r
+                       putWord(0x00a0);\r
+               }\r
+               putCommand(b + 0x11);\r
+               break;\r
+       }\r
+}\r
+\r
+void assemblyShift(ubyte b) {\r
+       readAddrMode();\r
+       switch (addrMode & AddrMode.STANDARD_MASK) {\r
+       case AddrMode.ACCUMULATOR:\r
+               if (b == 0xc0 || b == 0xe0) {\r
+                       // INC @, DEC @\r
+                       illegalAddrMode();\r
+               }\r
+               putByte(b + 0xa);\r
+               break;\r
+       case AddrMode.ABSOLUTE:\r
+               putCommand(b + 0xe);\r
+               break;\r
+       case AddrMode.ZEROPAGE:\r
+               putCommand(b + 6);\r
+               break;\r
+       case AddrMode.ABSOLUTE_X:\r
+               putCommand(b + 0x1e);\r
+               break;\r
+       case AddrMode.ZEROPAGE_X:\r
+               putCommand(b + 0x16);\r
+               break;\r
+       default:\r
+               illegalAddrMode();\r
+       }\r
+}\r
+\r
+void assemblyCompareIndex(ubyte b) {\r
+       readAddrMode();\r
+       switch (addrMode) {\r
+       case AddrMode.IMMEDIATE:\r
+               putCommand(b);\r
+               break;\r
+       case AddrMode.ABSOLUTE:\r
+               putCommand(b + 0xc);\r
+               break;\r
+       case AddrMode.ZEROPAGE:\r
+               putCommand(b + 4);\r
+               break;\r
+       default:\r
+               illegalAddrMode();\r
+       }\r
+}\r
+\r
+void assemblyLda(int move) {\r
+       assemblyAccumulator(0xa0, 0, move);\r
+}\r
+\r
+void assemblyLdx(int move) {\r
+       addrModeForMove(move);\r
+       switch (addrMode & AddrMode.STANDARD_MASK) {\r
+       case AddrMode.IMMEDIATE:\r
+               putCommand(0xa2);\r
+               break;\r
+       case AddrMode.ABSOLUTE:\r
+               putCommand(0xae);\r
+               break;\r
+       case AddrMode.ZEROPAGE:\r
+               putCommand(0xa6);\r
+               break;\r
+       case AddrMode.ABSOLUTE_Y:\r
+               putCommand(0xbe);\r
+               break;\r
+       case AddrMode.ZEROPAGE_Y:\r
+               putCommand(0xb6);\r
+               break;\r
+       default:\r
+               illegalAddrMode();\r
+       }\r
+}\r
+\r
+void assemblyLdy(int move) {\r
+       addrModeForMove(move);\r
+       switch (addrMode & AddrMode.STANDARD_MASK) {\r
+       case AddrMode.IMMEDIATE:\r
+               putCommand(0xa0);\r
+               break;\r
+       case AddrMode.ABSOLUTE:\r
+               putCommand(0xac);\r
+               break;\r
+       case AddrMode.ZEROPAGE:\r
+               putCommand(0xa4);\r
+               break;\r
+       case AddrMode.ABSOLUTE_X:\r
+               putCommand(0xbc);\r
+               break;\r
+       case AddrMode.ZEROPAGE_X:\r
+               putCommand(0xb4);\r
+               break;\r
+       default:\r
+               illegalAddrMode();\r
+       }\r
+}\r
+\r
+void assemblySta(int move) {\r
+       assemblyAccumulator(0x80, 0, move);\r
+}\r
+\r
+void assemblyStx(int move) {\r
+       addrModeForMove(move);\r
+       switch (addrMode & AddrMode.STANDARD_MASK) {\r
+       case AddrMode.ABSOLUTE:\r
+               putCommand(0x8e);\r
+               break;\r
+       case AddrMode.ZEROPAGE:\r
+               putCommand(0x86);\r
+               break;\r
+       case AddrMode.ABSOLUTE_Y:\r
+               addrMode += 1;\r
+               goto case AddrMode.ZEROPAGE_Y;\r
+       case AddrMode.ZEROPAGE_Y:\r
+               putCommand(0x96);\r
+               break;\r
+       default:\r
+               illegalAddrMode();\r
+       }\r
+}\r
+\r
+void assemblySty(int move) {\r
+       addrModeForMove(move);\r
+       switch (addrMode & AddrMode.STANDARD_MASK) {\r
+       case AddrMode.ABSOLUTE:\r
+               putCommand(0x8c);\r
+               break;\r
+       case AddrMode.ZEROPAGE:\r
+               putCommand(0x84);\r
+               break;\r
+       case AddrMode.ABSOLUTE_X:\r
+               addrMode += 1;\r
+               goto case AddrMode.ZEROPAGE_X;\r
+       case AddrMode.ZEROPAGE_X:\r
+               putCommand(0x94);\r
+               break;\r
+       default:\r
+               illegalAddrMode();\r
+       }\r
+}\r
+\r
+void assemblyBit() {\r
+       readAddrMode();\r
+       switch (addrMode) {\r
+       case AddrMode.ABSOLUTE:\r
+               putCommand(0x2c);\r
+               break;\r
+       case AddrMode.ZEROPAGE:\r
+               putCommand(0x24);\r
+               break;\r
+       default:\r
+               illegalAddrMode();\r
+       }\r
+}\r
+\r
+void putJump() {\r
+       switch (addrMode) {\r
+       case AddrMode.ZEROPAGE:\r
+               addrMode = AddrMode.ABSOLUTE;\r
+               goto case AddrMode.ABSOLUTE;\r
+       case AddrMode.ABSOLUTE:\r
+               putCommand(0x4c);\r
+               break;\r
+       case AddrMode.INDIRECT:\r
+               if (pass2 && (value & 0xff) == 0xff) {\r
+                       warning("Buggy indirect jump");\r
+               }\r
+               putCommand(0x6c);\r
+               break;\r
+       default:\r
+               illegalAddrMode();\r
+       }\r
+}\r
+\r
+void assemblyJmp() {\r
+       readAddrMode();\r
+       putJump();\r
+}\r
+\r
+void assemblyConditionalJump(ubyte b) {\r
+       noOpcode();\r
+       readAddrMode();\r
+       if ((addrMode == AddrMode.ABSOLUTE || addrMode == AddrMode.ZEROPAGE)\r
+        && pass2 && origin >= 0 && value - origin - 2 >= -0x80 && value - origin - 2 <= 0x7f) {\r
+               warning("Plain branch instruction would be sufficient");\r
+       }\r
+       putByte(b);\r
+       putByte(3);\r
+       putJump();\r
+}\r
+\r
+void assemblyJsr() {\r
+       readAbsoluteAddrMode();\r
+       putCommand(0x20);\r
+}\r
+\r
+ubyte calculateBranch(int offset) {\r
+       if (offset < -0x80 || offset > 0x7f) {\r
+               int dist;\r
+               if (offset < 0) {\r
+                       dist = -offset - 0x80;\r
+               } else {\r
+                       dist = offset - 0x7f;\r
+               }\r
+               throw new AssemblyError("Branch out of range by " ~ toString(dist) ~ " bytes");\r
+       }\r
+       return cast(ubyte) offset;\r
+}\r
+\r
+void assemblyBranch(ubyte b) {\r
+       readAbsoluteAddrMode();\r
+       if (inOpcode) {\r
+               putByte(b);\r
+               return;\r
+       }\r
+       checkOriginDefined();\r
+       putByte(b);\r
+       putByte(pass2 ? calculateBranch(value - origin - 1) : 0);\r
+}\r
+\r
+void assemblyRepeat(ubyte b) {\r
+       noOpcode();\r
+       int offset = repeatOffset;\r
+       if (offset >= 0) {\r
+               throw new AssemblyError("No instruction to repeat");\r
+       }\r
+       if (pass2 && wereManyInstructions) {\r
+               warning("Repeating only the last instruction");\r
+       }\r
+       putByte(b);\r
+       putByte(calculateBranch(offset));\r
+}\r
+\r
+void assemblySkip(ubyte b) {\r
+       noOpcode();\r
+       if (willSkip) {\r
+               skipOffsets[skipOffsets.length - 1] = 2;\r
+               willSkip = false;\r
+       }\r
+       putByte(b);\r
+       if (pass2) {\r
+               putByte(calculateBranch(skipOffsets[skipOffsetsIndex++]));\r
+       } else {\r
+               putByte(0);\r
+               skipOffsets ~= 0;\r
+               willSkip = true;\r
+       }\r
+}\r
+\r
+void assemblyInw() {\r
+       noOpcode();\r
+       readAddrMode();\r
+       switch (addrMode) {\r
+       case AddrMode.ABSOLUTE:\r
+               putCommand(0xee);\r
+               putWord(0x03d0);\r
+               value++;\r
+               putCommand(0xee);\r
+               break;\r
+       case AddrMode.ZEROPAGE:\r
+               putCommand(0xe6);\r
+               putWord(0x02d0);\r
+               value++;\r
+               putCommand(0xe6);\r
+               break;\r
+       case AddrMode.ABSOLUTE_X:\r
+               putCommand(0xfe);\r
+               putWord(0x03d0);\r
+               value++;\r
+               putCommand(0xfe);\r
+               break;\r
+       case AddrMode.ZEROPAGE_X:\r
+               putCommand(0xf6);\r
+               putWord(0x02d0);\r
+               value++;\r
+               putCommand(0xf6);\r
+               break;\r
+       default:\r
+               illegalAddrMode();\r
+       }\r
+}\r
+\r
+void assemblyMove() {\r
+       noOpcode();\r
+       readAddrMode();\r
+       value1 = value;\r
+       addrMode1 = addrMode;\r
+       bit unknown1 = unknownInPass1;\r
+       readAddrMode();\r
+       value2 = value;\r
+       addrMode2 = addrMode;\r
+       unknownInPass1 = unknown1;\r
+}\r
+\r
+void assemblyMoveByte(MoveFunction load, MoveFunction store) {\r
+       assemblyMove();\r
+       load(1);\r
+       store(2);\r
+}\r
+\r
+void assemblyMoveWord(MoveFunction load, MoveFunction store, ubyte inc, ubyte dec) {\r
+       assemblyMove();\r
+       switch (addrMode2) {\r
+       case AddrMode.ABSOLUTE:\r
+       case AddrMode.ZEROPAGE:\r
+       case AddrMode.ABSOLUTE_X:\r
+       case AddrMode.ZEROPAGE_X:\r
+       case AddrMode.ABSOLUTE_Y:\r
+       case AddrMode.ZEROPAGE_Y:\r
+               break;\r
+       default:\r
+               illegalAddrMode();\r
+       }\r
+       switch (addrMode1) {\r
+       case AddrMode.IMMEDIATE:\r
+               int high = value1 >> 8;\r
+               value1 &= 0xff;\r
+               load(1);\r
+               store(2);\r
+               value2++;\r
+               if (unknownInPass1) {\r
+                       value1 = high;\r
+                       load(1);\r
+               } else {\r
+                       if (inc != 0 && cast(ubyte) (value1 + 1) == high) {\r
+                               putByte(inc);\r
+                       } else if (dec != 0 && cast(ubyte) (value1 - 1) == high) {\r
+                               putByte(dec);\r
+                       } else if (value1 != high) {\r
+                               value1 = high;\r
+                               load(1);\r
+                       }\r
+               }\r
+               store(2);\r
+               break;\r
+       case AddrMode.ABSOLUTE:\r
+       case AddrMode.ZEROPAGE:\r
+       case AddrMode.ABSOLUTE_X:\r
+       case AddrMode.ZEROPAGE_X:\r
+       case AddrMode.ABSOLUTE_Y:\r
+       case AddrMode.ZEROPAGE_Y:\r
+               load(1);\r
+               store(2);\r
+               value1++;\r
+               value2++;\r
+               load(1);\r
+               store(2);\r
+               break;\r
+       default:\r
+               illegalAddrMode();\r
+       }\r
+}\r
+\r
+void storeDtaNumber(int val, char letter) {\r
+       int limit = 0xffff;\r
+       if (letter == 'b') limit = 0xff;\r
+       if ((!unknownInPass1 || pass2) && (val < -limit || val > limit)) {\r
+               throw new AssemblyError("Value out of range");\r
+       }\r
+       switch (letter) {\r
+       case 'a':\r
+               putWord(cast(ushort) val);\r
+               break;\r
+       case 'b':\r
+       case 'l':\r
+               putByte(cast(ubyte) val);\r
+               break;\r
+       case 'h':\r
+               putByte(cast(ubyte) (val >> 8));\r
+               break;\r
+       }\r
+}\r
+\r
+void assemblyDtaInteger(char letter) {\r
+       if (readFunction() == "SIN") {\r
+               readWord();\r
+               int sinCenter = value;\r
+               readComma();\r
+               readWord();\r
+               int sinAmp = value;\r
+               readComma();\r
+               readKnownPositive();\r
+               int sinPeriod = value;\r
+               int sinMin = 0;\r
+               int sinMax = sinPeriod - 1;\r
+               switch (readChar()) {\r
+               case ')':\r
+                       break;\r
+               case ',':\r
+                       readUnsignedWord();\r
+                       mustBeKnownInPass1();\r
+                       sinMin = value;\r
+                       readComma();\r
+                       readUnsignedWord();\r
+                       mustBeKnownInPass1();\r
+                       sinMax = value;\r
+                       if (readChar() != ')') {\r
+                               illegalCharacter();\r
+                       }\r
+                       break;\r
+               default:\r
+                       illegalCharacter();\r
+               }\r
+               while (sinMin <= sinMax) {\r
+                       int val = sinCenter + cast(int) rint(sinAmp * sin(sinMin * 2 * PI / sinPeriod));\r
+                       storeDtaNumber(val, letter);\r
+                       sinMin++;\r
+               }\r
+               return;\r
+       }\r
+       readWord();\r
+       storeDtaNumber(value, letter);\r
+}\r
+\r
+bit realSign;\r
+\r
+int realExponent;\r
+\r
+long realMantissa;\r
+\r
+void putReal() {\r
+       if (realMantissa == 0) {\r
+               putWord(0);\r
+               putWord(0);\r
+               putWord(0);\r
+               return;\r
+       }\r
+       while (realMantissa < 0x1000000000L) {\r
+               realMantissa <<= 4;\r
+               realExponent--;\r
+       }\r
+       if ((realExponent & 1) != 0) {\r
+               if (realMantissa & 0xf) {\r
+                       throw new AssemblyError("Out of precision");\r
+               }\r
+               realMantissa >>= 4;\r
+       }\r
+       realExponent = (realExponent + 0x89) >> 1;\r
+       if (realExponent < 64 - 49) {\r
+               throw new AssemblyError("Out of precision");\r
+       }\r
+       if (realExponent > 64 + 49) {\r
+               throw new AssemblyError("Number too big");\r
+       }\r
+       putByte(cast(ubyte) (realSign ? realExponent + 0x80 : realExponent));\r
+       putByte(cast(ubyte) (realMantissa >> 32));\r
+       putByte(cast(ubyte) (realMantissa >> 24));\r
+       putByte(cast(ubyte) (realMantissa >> 16));\r
+       putByte(cast(ubyte) (realMantissa >> 8));\r
+       putByte(cast(ubyte) realMantissa);\r
+}\r
+\r
+bit readSign() {\r
+       switch (readChar()) {\r
+       case '+':\r
+               return false;\r
+       case '-':\r
+               return true;\r
+       default:\r
+               column--;\r
+               return false;\r
+       }\r
+}\r
+\r
+void readExponent() {\r
+       bit sign = readSign();\r
+       char c = readChar();\r
+       if (c < '0' || c > '9') {\r
+               illegalCharacter();\r
+       }\r
+       int e = c - '0';\r
+       c = readChar();\r
+       if (c >= '0' && c <= '9') {\r
+               e = 10 * e + c - '0';\r
+       } else {\r
+               column--;\r
+       }\r
+       realExponent += sign ? -e : e;\r
+       putReal();\r
+}\r
+\r
+void readFraction() {\r
+       for (;;) {\r
+               char c = readChar();\r
+               if (c >= '0' && c <= '9') {\r
+                       if (c != '0' && realMantissa >= 0x1000000000L) {\r
+                               throw new AssemblyError("Out of precision");\r
+                       }\r
+                       realMantissa <<= 4;\r
+                       realMantissa += c - '0';\r
+                       realExponent--;\r
+                       continue;\r
+               }\r
+               if (c == 'E' || c == 'e') {\r
+                       readExponent();\r
+                       return;\r
+               }\r
+               column--;\r
+               putReal();\r
+               return;\r
+       }\r
+}\r
+\r
+void assemblyDtaReal() {\r
+       realSign = readSign();\r
+       realExponent = 0;\r
+       realMantissa = 0;\r
+       char c = readChar();\r
+       if (c == '.') {\r
+               readFraction();\r
+               return;\r
+       }\r
+       if (c < '0' || c > '9') {\r
+               illegalCharacter();\r
+       }\r
+       do {\r
+               if (realMantissa < 0x1000000000L) {\r
+                       realMantissa <<= 4;\r
+                       realMantissa += c - '0';\r
+               } else {\r
+                       if (c != '0') {\r
+                               throw new AssemblyError("Out of precision");\r
+                       }\r
+                       realExponent++;\r
+               }\r
+               c = readChar();\r
+       } while (c >= '0' && c <= '9');\r
+       switch (c) {\r
+       case '.':\r
+               readFraction();\r
+               break;\r
+       case 'E':\r
+       case 'e':\r
+               readExponent();\r
+               break;\r
+       default:\r
+               column--;\r
+               putReal();\r
+               break;\r
+       }\r
+}\r
+\r
+void assemblyDtaNumbers(char letter) {\r
+       if (eol() || line[column] != '(') {\r
+               column--;\r
+               assemblyDtaInteger('b');\r
+               return;\r
+       }\r
+       column++;\r
+       for (;;) {\r
+               switch (letter) {\r
+               case 'a':\r
+               case 'b':\r
+               case 'h':\r
+               case 'l':\r
+                       assemblyDtaInteger(letter);\r
+                       break;\r
+               case 'r':\r
+                       assemblyDtaReal();\r
+                       break;\r
+               }\r
+               switch (readChar()) {\r
+               case ')':\r
+                       return;\r
+               case ',':\r
+                       break;\r
+               default:\r
+                       illegalCharacter();\r
+               }\r
+       }\r
+}\r
+\r
+void assemblyDta() {\r
+       noOpcode();\r
+       readSpaces();\r
+       for (;;) {\r
+               switch (readChar()) {\r
+               case 'A':\r
+               case 'a':\r
+                       assemblyDtaNumbers('a');\r
+                       break;\r
+               case 'B':\r
+               case 'b':\r
+                       assemblyDtaNumbers('b');\r
+                       break;\r
+               case 'C':\r
+               case 'c':\r
+                       ubyte[] s = readString();\r
+                       if (s is null) {\r
+                               column--;\r
+                               assemblyDtaInteger('b');\r
+                               break;\r
+                       }\r
+                       foreach (ubyte b; s) {\r
+                               putByte(b);\r
+                       }\r
+                       break;\r
+               case 'D':\r
+               case 'd':\r
+                       ubyte[] s = readString();\r
+                       if (s is null) {\r
+                               column--;\r
+                               assemblyDtaInteger('b');\r
+                               break;\r
+                       }\r
+                       foreach (ubyte b; s) {\r
+                               switch (b & 0x60) {\r
+                               case 0x00:\r
+                                       putByte(b + 0x40);\r
+                                       break;\r
+                               case 0x20:\r
+                               case 0x40:\r
+                                       putByte(b - 0x20);\r
+                                       break;\r
+                               case 0x60:\r
+                                       putByte(b);\r
+                                       break;\r
+                               }\r
+                       }\r
+                       break;\r
+               case 'H':\r
+               case 'h':\r
+                       assemblyDtaNumbers('h');\r
+                       break;\r
+               case 'L':\r
+               case 'l':\r
+                       assemblyDtaNumbers('l');\r
+                       break;\r
+               case 'R':\r
+               case 'r':\r
+                       assemblyDtaNumbers('r');\r
+                       break;\r
+               default:\r
+                       column--;\r
+                       assemblyDtaInteger('b');\r
+                       break;\r
+               }\r
+               if (eol() || line[column] != ',') {\r
+                       break;\r
+               }\r
+               column++;\r
+       }\r
+}\r
+\r
+void assemblyEqu() {\r
+       directive();\r
+       if (currentLabel is null) {\r
+               throw new AssemblyError("Label name required");\r
+       }\r
+       currentLabel.value = 0;\r
+       readSpaces();\r
+       readValue();\r
+       currentLabel.value = value;\r
+       currentLabel.unknownInPass1 = unknownInPass1;\r
+       if (optionListing) {\r
+               listingLine[6] = '=';\r
+               int val = value;\r
+               listingLine[7] = ' ';\r
+               if (val < 0) {\r
+                       listingLine[7] = '-';\r
+                       val = -val;\r
+               }\r
+               listingColumn = 8;\r
+               if ((val & 0xffff0000) != 0) {\r
+                       listWord(cast(ushort) (val >> 16));\r
+               } else {\r
+                       while (listingColumn < 12) {\r
+                               listingLine[listingColumn++] = ' ';\r
+                       }\r
+               }\r
+               listWord(cast(ushort) val);\r
+       }\r
+}\r
+\r
+void assemblyEnd() {\r
+       directive();\r
+       assert(!foundEnd);\r
+       foundEnd = true;\r
+}\r
+\r
+void assemblyIftEli() {\r
+       ifContexts[ifContexts.length - 1].condition = true;\r
+       if (!inFalseCondition()) {\r
+               readSpaces();\r
+               readValue();\r
+               mustBeKnownInPass1();\r
+               if (value != 0) {\r
+                       ifContexts[ifContexts.length - 1].aConditionMatched = true;\r
+               } else {\r
+                       listLine();\r
+               }\r
+               ifContexts[ifContexts.length - 1].condition = value != 0;\r
+       }\r
+}\r
+\r
+void checkMissingIft() {\r
+       if (ifContexts.length == 0) {\r
+               throw new AssemblyError("Missing IFT");\r
+       }\r
+}\r
+\r
+void assemblyIft() {\r
+       directive();\r
+       ifContexts.length = ifContexts.length + 1;\r
+       assemblyIftEli();\r
+}\r
+\r
+void assemblyEliEls() {\r
+       directive();\r
+       checkMissingIft();\r
+       if (ifContexts[ifContexts.length - 1].wasElse) {\r
+               throw new AssemblyError("EIF expected");\r
+       }\r
+}\r
+\r
+void assemblyEli() {\r
+       assemblyEliEls();\r
+       if (ifContexts[ifContexts.length - 1].aConditionMatched) {\r
+               ifContexts[ifContexts.length - 1].condition = false;\r
+               return;\r
+       }\r
+       assemblyIftEli();\r
+}\r
+\r
+void assemblyEls() {\r
+       assemblyEliEls();\r
+       with (ifContexts[ifContexts.length - 1]) {\r
+               if (condition && aConditionMatched) {\r
+                       listLine();\r
+               }\r
+               wasElse = true;\r
+               condition = !aConditionMatched;\r
+       }\r
+}\r
+\r
+void assemblyEif() {\r
+       directive();\r
+       checkMissingIft();\r
+       ifContexts.length = ifContexts.length - 1;\r
+}\r
+\r
+void assemblyErt() {\r
+       directive();\r
+       readSpaces();\r
+       readValue();\r
+       if (pass2 && value != 0) {\r
+               throw new AssemblyError("User-defined error");\r
+       }\r
+}\r
+\r
+bit readOption() {\r
+       switch (readChar()) {\r
+       case '-':\r
+               return false;\r
+       case '+':\r
+               return true;\r
+       default:\r
+               illegalCharacter();\r
+       }\r
+}\r
+\r
+void assemblyOpt() {\r
+       directive();\r
+       readSpaces();\r
+       while (!eol()) {\r
+               switch (line[column++]) {\r
+               case 'F':\r
+               case 'f':\r
+                       optionFill = readOption();\r
+                       break;\r
+               case 'G':\r
+               case 'g':\r
+                       option5200 = readOption();\r
+                       break;\r
+               case 'H':\r
+               case 'h':\r
+                       optionHeaders = readOption();\r
+                       break;\r
+               case 'L':\r
+               case 'l':\r
+                       optionListing = readOption() && !pass2;\r
+                       break;\r
+               case 'O':\r
+               case 'o':\r
+                       optionObject = readOption();\r
+                       break;\r
+               default:\r
+                       column--;\r
+                       return;\r
+               }\r
+       }\r
+}\r
+\r
+void originWord(ushort value, char listingChar) {\r
+       objectWord(value);\r
+       listWord(value);\r
+       listingLine[listingColumn++] = listingChar;\r
+}\r
+\r
+void setOrigin(int addr, bit requestedHeader, bit requestedFFFF) {\r
+       origin = loadOrigin = addr;\r
+       if (requestedHeader || loadingOrigin < 0 || (addr != loadingOrigin && !optionFill)) {\r
+               blockIndex++;\r
+               if (!pass2) {\r
+                       assert(blockIndex == blockEnds.length);\r
+                       blockEnds ~= cast(ushort) (addr - 1);\r
+               }\r
+               if (pass2 && optionHeaders) {\r
+                       if (addr - 1 == blockEnds[blockIndex]) {\r
+                               if (requestedHeader) {\r
+                                       throw new AssemblyError("Cannot generate an empty block");\r
+                               }\r
+                               return;\r
+                       }\r
+                       if (requestedFFFF || objectBytes == 0) {\r
+                               assert(requestedHeader || addr != loadingOrigin);\r
+                               originWord(0xffff, '>');\r
+                               listingLine[listingColumn++] = ' ';\r
+                       }\r
+                       if (requestedHeader || addr != loadingOrigin) {\r
+                               originWord(cast(ushort) addr, '-');\r
+                               originWord(blockEnds[blockIndex], '>');\r
+                               listingLine[listingColumn++] = ' ';\r
+                               loadingOrigin = -1;\r
+                       }\r
+               }\r
+       }\r
+}\r
+\r
+void checkHeadersOn() {\r
+       if (!optionHeaders) {\r
+               throw new AssemblyError("Illegal when Atari file headers disabled");\r
+       }\r
+}\r
+\r
+void assemblyOrg() {\r
+       noRepeatSkipDirective();\r
+       readSpaces();\r
+       bit requestedFFFF = false;\r
+       bit requestedHeader = false;\r
+       if (column + 2 < line.length && line[column + 1] == ':') {\r
+               switch (line[column]) {\r
+               case 'F':\r
+               case 'f':\r
+                       requestedFFFF = true;\r
+                       goto case 'A';\r
+               case 'A':\r
+               case 'a':\r
+                       checkHeadersOn();\r
+                       column += 2;\r
+                       requestedHeader = true;\r
+                       break;\r
+               case 'R':\r
+               case 'r':\r
+                       column += 2;\r
+                       checkOriginDefined();\r
+                       readUnsignedWord();\r
+                       mustBeKnownInPass1();\r
+                       origin = value;\r
+                       return;\r
+               default:\r
+                       break;\r
+               }\r
+       }\r
+       readUnsignedWord();\r
+       mustBeKnownInPass1();\r
+       setOrigin(value, requestedHeader, requestedFFFF);\r
+}\r
+\r
+void assemblyRunIni(ushort addr) {\r
+       noRepeatSkipDirective();\r
+       checkHeadersOn();\r
+       loadingOrigin = -1; // don't fill\r
+       setOrigin(addr, false, false);\r
+       readSpaces();\r
+       readUnsignedWord();\r
+       putWord(value);\r
+       loadingOrigin = -1; // don't fill\r
+}\r
+\r
+void assemblyIcl() {\r
+       directive();\r
+       char[] filename = readFilename();\r
+       checkNoExtraCharacters();\r
+       listLine();\r
+       assemblyFile(filename);\r
+       line = null;\r
+}\r
+\r
+void assemblyIns() {\r
+       noRepeatSkipDirective();\r
+       char[] filename = readFilename();\r
+       int offset = 0;\r
+       int length = -1;\r
+       if (!eol() && line[column] == ',') {\r
+               column++;\r
+               readValue();\r
+               mustBeKnownInPass1();\r
+               offset = value;\r
+               if (!eol() && line[column] == ',') {\r
+                       column++;\r
+                       readKnownPositive();\r
+                       length = value;\r
+               }\r
+       }\r
+       Stream stream = openInputFile(filename);\r
+       try {\r
+               stream.seek(offset, offset >= 0 ? SeekPos.Set : SeekPos.End);\r
+       } catch (SeekException e) {\r
+               throw new AssemblyError("Error seeking file");\r
+       }\r
+       while (length != 0) {\r
+               ubyte b;\r
+               try {\r
+                       stream.read(b);\r
+               } catch (ReadException e) {\r
+                       if (length > 0) {\r
+                               throw new AssemblyError("File is too short");\r
+                       }\r
+                       break;\r
+               }\r
+               putByte(b);\r
+               if (length > 0) length--;\r
+       }\r
+       // stream.close(); bug in Phobos\r
+}\r
+\r
+void assemblyInstruction(char[] instruction) {\r
+       if (!inOpcode && origin < 0 && currentLabel !is null && instruction != "EQU") {\r
+               throw new AssemblyError("No ORG specified");\r
+       }\r
+       instructionBegin = true;\r
+       switch (instruction) {\r
+       case "ADC":\r
+               assemblyAccumulator(0x60, 0, 0);\r
+               break;\r
+       case "ADD":\r
+               assemblyAccumulator(0x60, 0x18, 0);\r
+               break;\r
+       case "AND":\r
+               assemblyAccumulator(0x20, 0, 0);\r
+               break;\r
+       case "ASL":\r
+               assemblyShift(0x00);\r
+               break;\r
+       case "BCC":\r
+               assemblyBranch(0x90);\r
+               break;\r
+       case "BCS":\r
+               assemblyBranch(0xb0);\r
+               break;\r
+       case "BEQ":\r
+               assemblyBranch(0xf0);\r
+               break;\r
+       case "BIT":\r
+               assemblyBit();\r
+               break;\r
+       case "BMI":\r
+               assemblyBranch(0x30);\r
+               break;\r
+       case "BNE":\r
+               assemblyBranch(0xd0);\r
+               break;\r
+       case "BPL":\r
+               assemblyBranch(0x10);\r
+               break;\r
+       case "BRK":\r
+               putByte(0x00);\r
+               break;\r
+       case "BVC":\r
+               assemblyBranch(0x50);\r
+               break;\r
+       case "BVS":\r
+               assemblyBranch(0x70);\r
+               break;\r
+       case "CLC":\r
+               putByte(0x18);\r
+               break;\r
+       case "CLD":\r
+               putByte(0xd8);\r
+               break;\r
+       case "CLI":\r
+               putByte(0x58);\r
+               break;\r
+       case "CLV":\r
+               putByte(0xb8);\r
+               break;\r
+       case "CMP":\r
+               assemblyAccumulator(0xc0, 0, 0);\r
+               break;\r
+       case "CPX":\r
+               assemblyCompareIndex(0xe0);\r
+               break;\r
+       case "CPY":\r
+               assemblyCompareIndex(0xc0);\r
+               break;\r
+       case "DEC":\r
+               assemblyShift(0xc0);\r
+               break;\r
+       case "DEX":\r
+               putByte(0xca);\r
+               break;\r
+       case "DEY":\r
+               putByte(0x88);\r
+               break;\r
+       case "DTA":\r
+               assemblyDta();\r
+               break;\r
+       case "EIF":\r
+               assemblyEif();\r
+               break;\r
+       case "ELI":\r
+               assemblyEli();\r
+               break;\r
+       case "ELS":\r
+               assemblyEls();\r
+               break;\r
+       case "END":\r
+               assemblyEnd();\r
+               break;\r
+       case "EOR":\r
+               assemblyAccumulator(0x40, 0, 0);\r
+               break;\r
+       case "EQU":\r
+               assemblyEqu();\r
+               break;\r
+       case "ERT":\r
+               assemblyErt();\r
+               break;\r
+       case "ICL":\r
+               assemblyIcl();\r
+               break;\r
+       case "IFT":\r
+               assemblyIft();\r
+               break;\r
+       case "INC":\r
+               assemblyShift(0xe0);\r
+               break;\r
+       case "INI":\r
+               assemblyRunIni(0x2e2);\r
+               break;\r
+       case "INS":\r
+               assemblyIns();\r
+               break;\r
+       case "INX":\r
+               putByte(0xe8);\r
+               break;\r
+       case "INY":\r
+               putByte(0xc8);\r
+               break;\r
+       case "INW":\r
+               assemblyInw();\r
+               break;\r
+       case "JCC":\r
+               assemblyConditionalJump(0xb0);\r
+               break;\r
+       case "JCS":\r
+               assemblyConditionalJump(0x90);\r
+               break;\r
+       case "JEQ":\r
+               assemblyConditionalJump(0xd0);\r
+               break;\r
+       case "JMI":\r
+               assemblyConditionalJump(0x10);\r
+               break;\r
+       case "JMP":\r
+               assemblyJmp();\r
+               break;\r
+       case "JNE":\r
+               assemblyConditionalJump(0xf0);\r
+               break;\r
+       case "JPL":\r
+               assemblyConditionalJump(0x30);\r
+               break;\r
+       case "JSR":\r
+               assemblyJsr();\r
+               break;\r
+       case "JVC":\r
+               assemblyConditionalJump(0x70);\r
+               break;\r
+       case "JVS":\r
+               assemblyConditionalJump(0x50);\r
+               break;\r
+       case "LDA":\r
+               assemblyAccumulator(0xa0, 0, 0);\r
+               break;\r
+       case "LDX":\r
+               assemblyLdx(0);\r
+               break;\r
+       case "LDY":\r
+               assemblyLdy(0);\r
+               break;\r
+       case "LSR":\r
+               assemblyShift(0x40);\r
+               break;\r
+       case "MVA":\r
+               assemblyMoveByte(&assemblyLda, &assemblySta);\r
+               break;\r
+       case "MVX":\r
+               assemblyMoveByte(&assemblyLdx, &assemblyStx);\r
+               break;\r
+       case "MVY":\r
+               assemblyMoveByte(&assemblyLdy, &assemblySty);\r
+               break;\r
+       case "MWA":\r
+               assemblyMoveWord(&assemblyLda, &assemblySta, 0, 0);\r
+               break;\r
+       case "MWX":\r
+               assemblyMoveWord(&assemblyLdx, &assemblyStx, 0xe8, 0xca);\r
+               break;\r
+       case "MWY":\r
+               assemblyMoveWord(&assemblyLdy, &assemblySty, 0xc8, 0x88);\r
+               break;\r
+       case "NOP":\r
+               putByte(0xea);\r
+               break;\r
+       case "OPT":\r
+               assemblyOpt();\r
+               break;\r
+       case "ORA":\r
+               assemblyAccumulator(0x00, 0, 0);\r
+               break;\r
+       case "ORG":\r
+               assemblyOrg();\r
+               break;\r
+       case "PHA":\r
+               putByte(0x48);\r
+               break;\r
+       case "PHP":\r
+               putByte(0x08);\r
+               break;\r
+       case "PLA":\r
+               putByte(0x68);\r
+               break;\r
+       case "PLP":\r
+               putByte(0x28);\r
+               break;\r
+       case "RCC":\r
+               assemblyRepeat(0x90);\r
+               break;\r
+       case "RCS":\r
+               assemblyRepeat(0xb0);\r
+               break;\r
+       case "REQ":\r
+               assemblyRepeat(0xf0);\r
+               break;\r
+       case "RMI":\r
+               assemblyRepeat(0x30);\r
+               break;\r
+       case "RNE":\r
+               assemblyRepeat(0xd0);\r
+               break;\r
+       case "ROL":\r
+               assemblyShift(0x20);\r
+               break;\r
+       case "ROR":\r
+               assemblyShift(0x60);\r
+               break;\r
+       case "RPL":\r
+               assemblyRepeat(0x10);\r
+               break;\r
+       case "RTI":\r
+               putByte(0x40);\r
+               break;\r
+       case "RTS":\r
+               putByte(0x60);\r
+               break;\r
+       case "RUN":\r
+               assemblyRunIni(0x2e0);\r
+               break;\r
+       case "RVC":\r
+               assemblyRepeat(0x50);\r
+               break;\r
+       case "RVS":\r
+               assemblyRepeat(0x70);\r
+               break;\r
+       case "SBC":\r
+               assemblyAccumulator(0xe0, 0, 0);\r
+               break;\r
+       case "SCC":\r
+               assemblySkip(0x90);\r
+               break;\r
+       case "SCS":\r
+               assemblySkip(0xb0);\r
+               break;\r
+       case "SEC":\r
+               putByte(0x38);\r
+               break;\r
+       case "SED":\r
+               putByte(0xf8);\r
+               break;\r
+       case "SEI":\r
+               putByte(0x78);\r
+               break;\r
+       case "SEQ":\r
+               assemblySkip(0xf0);\r
+               break;\r
+       case "SMI":\r
+               assemblySkip(0x30);\r
+               break;\r
+       case "SNE":\r
+               assemblySkip(0xd0);\r
+               break;\r
+       case "SPL":\r
+               assemblySkip(0x10);\r
+               break;\r
+       case "STA":\r
+               assemblyAccumulator(0x80, 0, 0);\r
+               break;\r
+       case "STX":\r
+               assemblyStx(0);\r
+               break;\r
+       case "STY":\r
+               assemblySty(0);\r
+               break;\r
+       case "SUB":\r
+               assemblyAccumulator(0xe0, 0x38, 0);\r
+               break;\r
+       case "SVC":\r
+               assemblySkip(0x50);\r
+               break;\r
+       case "SVS":\r
+               assemblySkip(0x70);\r
+               break;\r
+       case "TAX":\r
+               putByte(0xaa);\r
+               break;\r
+       case "TAY":\r
+               putByte(0xa8);\r
+               break;\r
+       case "TSX":\r
+               putByte(0xba);\r
+               break;\r
+       case "TXA":\r
+               putByte(0x8a);\r
+               break;\r
+       case "TXS":\r
+               putByte(0x9a);\r
+               break;\r
+       case "TYA":\r
+               putByte(0x98);\r
+               break;\r
+       default:\r
+               throw new AssemblyError("Illegal instruction");\r
+       }\r
+       skipping = false;\r
+}\r
+\r
+debug ubyte[] testInstruction(char[] l) {\r
+       objectBuffer.length = 0;\r
+       line = l;\r
+       column = 0;\r
+       assemblyInstruction(readInstruction());\r
+       dout.printf("%.*s assembles to", line);\r
+       foreach (ubyte b; objectBuffer) {\r
+               dout.printf(" %02x", b);\r
+       }\r
+       dout.printf("\n");\r
+       return objectBuffer;\r
+}\r
+\r
+unittest {\r
+       assert(testInstruction("nop") == cast(ubyte[]) x"ea");\r
+       assert(testInstruction("add (5,0)") == cast(ubyte[]) x"18a2006105");\r
+       assert(testInstruction("mwa #$abcd $1234") == cast(ubyte[]) x"a9cd8d3412a9ab8d3512");\r
+       assert(testInstruction("dta 5,d'Foo'*,a($4589)") == cast(ubyte[]) x"05a6efef8945");\r
+       assert(testInstruction("dta r(1,12,123,1234567890,12345678900000,.5,.03,000.1664534589,1e97)")\r
+        == cast(ubyte[]) x"400100000000 401200000000 410123000000 441234567890 461234567890 3f5000000000 3f0300000000 3f1664534589 701000000000");\r
+}\r
+\r
+void assemblyPair() {\r
+       assert(!inOpcode);\r
+       char[] instruction = readInstruction();\r
+       if (!eol() && line[column] == ':') {\r
+               pairing = true;\r
+               column++;\r
+               char[] instruction2 = readInstruction();\r
+               int savedColumn = column;\r
+               if (willSkip) {\r
+                       warning("Skipping only the first instruction");\r
+               }\r
+               assemblyInstruction(instruction);\r
+               checkNoExtraCharacters();\r
+               column = savedColumn;\r
+               wereManyInstructions = false;\r
+               assemblyInstruction(instruction2);\r
+               wereManyInstructions = true;\r
+       } else {\r
+               pairing = false;\r
+               assemblyInstruction(instruction);\r
+               wereManyInstructions = false;\r
+       }\r
+}\r
+\r
+void assemblyLine() {\r
+       debug {\r
+               dout.printf("%.*s\n", line);\r
+       }\r
+       currentLocation.lineNo++;\r
+       totalLines++;\r
+       column = 0;\r
+       listingColumn = 6;\r
+       if (origin >= 0) {\r
+               listWord(origin);\r
+               listingLine[listingColumn++] = ' ';\r
+       }\r
+       char[] label = readLabel();\r
+       currentLabel = null;\r
+       if (label !is null) {\r
+               if (!inFalseCondition()) {\r
+                       if (!pass2) {\r
+                               if (label in labelTable) {\r
+                                       throw new AssemblyError("Label declared twice");\r
+                               }\r
+                               currentLabel = new Label(origin);\r
+                               labelTable[label] = currentLabel;\r
+                       } else {\r
+                               assert(label in labelTable);\r
+                               currentLabel = labelTable[label];\r
+                               currentLabel.passed = true;\r
+                               if (currentLabel.unused && getOption('u')) {\r
+                                       warning("Unused label");\r
+                               }\r
+                       }\r
+               }\r
+               if (eol()) {\r
+                       listCommentLine();\r
+                       return;\r
+               }\r
+               readSpaces();\r
+       }\r
+       commentOrRep: for (;;) {\r
+               if (eol()) {\r
+                       listCommentLine();\r
+                       return;\r
+               }\r
+               switch (line[column]) {\r
+               case '\t':\r
+               case ' ':\r
+                       column++;\r
+                       continue;\r
+               case '*':\r
+               case ';':\r
+               case '|':\r
+                       listCommentLine();\r
+                       return;\r
+               case ':':\r
+                       if (inFalseCondition()) {\r
+                               listCommentLine();\r
+                               return;\r
+                       }\r
+                       column++;\r
+                       readUnsignedWord();\r
+                       mustBeKnownInPass1();\r
+                       int repeatLimit = value;\r
+                       if (repeatLimit == 0) {\r
+                               listCommentLine();\r
+                               return;\r
+                       }\r
+                       readSpaces();\r
+                       repeating = true;\r
+                       if (repeatLimit == 1) {\r
+                               break;\r
+                       }\r
+                       if (willSkip) {\r
+                               warning("Skipping only the first instruction");\r
+                       }\r
+                       int savedColumn = column;\r
+                       for (repeatCounter = 0; repeatCounter < repeatLimit; repeatCounter++) {\r
+                               column = savedColumn;\r
+                               assemblyPair();\r
+                       }\r
+                       checkNoExtraCharacters();\r
+                       listLine();\r
+                       wereManyInstructions = true;\r
+                       return;\r
+               default:\r
+                       repeating = false;\r
+                       break commentOrRep;\r
+               }\r
+       }\r
+       if (inFalseCondition()) {\r
+               switch (readInstruction()) {\r
+               case "END":\r
+                       assemblyEnd();\r
+                       break;\r
+               case "IFT":\r
+                       assemblyIft();\r
+                       break;\r
+               case "ELI":\r
+                       assemblyEli();\r
+                       break;\r
+               case "ELS":\r
+                       assemblyEls();\r
+                       break;\r
+               case "EIF":\r
+                       assemblyEif();\r
+                       break;\r
+               default:\r
+                       listCommentLine();\r
+                       return;\r
+               }\r
+               checkNoExtraCharacters();\r
+               listCommentLine();\r
+               return;\r
+       }\r
+       assemblyPair();\r
+       checkNoExtraCharacters();\r
+       listLine();\r
+}\r
+\r
+void assemblyFile(char[] filename) {\r
+       if (filenameExt(filename) < 0) {\r
+               filename ~= ".asx";\r
+       }\r
+       if (currentLocation !is null) {\r
+               locations ~= currentLocation;\r
+       }\r
+       if (getOption('p')) {\r
+               filename = getFullPath(filename);\r
+       }\r
+       currentLocation = new Location(filename);\r
+       foundEnd = false;\r
+       Stream stream = openInputFile(filename);\r
+       line = "";\r
+       try {\r
+               readChar: while (!foundEnd) {\r
+                       ubyte c;\r
+                       try {\r
+                               stream.read(c);\r
+                       } catch (ReadException e) {\r
+                               break;\r
+                       }\r
+                       switch (c) {\r
+                       case '\r':\r
+                               assemblyLine();\r
+                               line = "";\r
+                               try {\r
+                                       stream.read(c);\r
+                               } catch (ReadException e) {\r
+                                       break readChar;\r
+                               }\r
+                               if (c != '\n') {\r
+                                       line ~= cast(char) c;\r
+                               }\r
+                               break;\r
+                       case '\n':\r
+                       case '\x9b':\r
+                               assemblyLine();\r
+                               line = "";\r
+                               break;\r
+                       default:\r
+                               line ~= cast(char) c;\r
+                               break;\r
+                       }\r
+               }\r
+               if (!foundEnd) {\r
+                       assemblyLine();\r
+               }\r
+               foundEnd = false;\r
+       } finally {\r
+//             stream.close(); // bug in Phobos\r
+       }\r
+       if (locations.length > 0) {\r
+               currentLocation = locations[locations.length - 1];\r
+               locations.length = locations.length - 1;\r
+       }\r
+}\r
+\r
+void assemblyPass() {\r
+       origin = -1;\r
+       loadOrigin = -1;\r
+       loadingOrigin = -1;\r
+       blockIndex = -1;\r
+       optionFill = false;\r
+       option5200 = false;\r
+       optionHeaders = true;\r
+       optionListing = pass2;\r
+       optionObject = true;\r
+       willSkip = false;\r
+       skipping = false;\r
+       repeatOffset = 0;\r
+       wereManyInstructions = false;\r
+       if (commandLineDefinitions.length > 0) {\r
+               currentLocation = new Location("command line");\r
+               foreach (char[] definition; commandLineDefinitions) {\r
+                       int i = find(definition, '=');\r
+                       assert(i >= 0);\r
+                       line = definition[0 .. i] ~ " equ " ~ definition[i + 1 .. definition.length];\r
+                       assemblyLine();\r
+               }\r
+               line = null;\r
+       }\r
+       currentLocation = null;\r
+       totalLines = 0;\r
+       assemblyFile(sourceFilename);\r
+       if (ifContexts.length != 0) {\r
+               throw new AssemblyError("Missing EIF");\r
+       }\r
+       if (willSkip) {\r
+               throw new AssemblyError("Can't skip over this");\r
+       }\r
+}\r
+\r
+bit isOption(char[] arg) {\r
+       if (arg.length < 2) return false;\r
+       if (arg[0] == '-') return true;\r
+       if (arg[0] != '/') return false;\r
+       if (arg.length == 2) return true;\r
+       if (arg[2] == ':') return true;\r
+       return false;\r
+}\r
+\r
+void setOption(char letter) {\r
+       assert(letter >= 'a' && letter <= 'z');\r
+       if (options[letter - 'a']) {\r
+               exitCode = 3;\r
+               return;\r
+       }\r
+       options[letter - 'a'] = true;\r
+}\r
+\r
+int main(char[][] args) {\r
+       for (int i = 1; i < args.length; i++) {\r
+               char[] arg = args[i];\r
+               if (isOption(arg)) {\r
+                       char letter = arg[1];\r
+                       if (letter >= 'A' && letter <= 'Z')\r
+                               letter += 'a' - 'A';\r
+                       switch (letter) {\r
+                       case 'c':\r
+                       case 'i':\r
+                       case 'm':\r
+                       case 'p':\r
+                       case 'q':\r
+                       case 'u':\r
+                               if (arg.length != 2) {\r
+                                       exitCode = 3;\r
+                               }\r
+                               setOption(letter);\r
+                               break;\r
+                       case 'd':\r
+                               char[] definition = null;\r
+                               if (arg[0] == '/') {\r
+                                       if (arg.length >= 3 && arg[2] == ':') {\r
+                                               definition = arg[3..arg.length];\r
+                                       }\r
+                               } else if (i + 1 < args.length && !isOption(args[i + 1])) {\r
+                                       definition = args[++i];\r
+                               }\r
+                               if (definition is null || find(definition, '=') < 0) {\r
+                                       exitCode = 3;\r
+                               }\r
+                               commandLineDefinitions ~= definition;\r
+                               break;\r
+                       case 'l':\r
+                       case 't':\r
+                       case 'o':\r
+                               setOption(letter);\r
+                               char[] filename = null;\r
+                               if (arg[0] == '/') {\r
+                                       if (arg.length >= 3 && arg[2] == ':') {\r
+                                               filename = arg[3..arg.length];\r
+                                       }\r
+                               } else if (i + 1 < args.length && !isOption(args[i + 1])) {\r
+                                       filename = args[++i];\r
+                               }\r
+                               if (filename is null && (letter == 'o' || arg.length != 2)) {\r
+                                       exitCode = 3;\r
+                               }\r
+                               optionParameters[letter - 'a'] = filename;\r
+                               break;\r
+                       default:\r
+                               exitCode = 3;\r
+                               break;\r
+                       }\r
+                       continue;\r
+               }\r
+               if (sourceFilename !is null) {\r
+                       exitCode = 3;\r
+               }\r
+               sourceFilename = arg;\r
+       }\r
+       if (sourceFilename is null) {\r
+               exitCode = 3;\r
+       }\r
+       if (!getOption('q')) {\r
+               dout.printf(TITLE ~ "\n");\r
+       }\r
+       if (exitCode != 0) {\r
+               dout.printf(\r
+                       "Syntax: xasm source [options]\n"\r
+                       "/c             Include false conditionals in listing\n"\r
+                       "/d:label=value Define a label\n"\r
+                       "/i             Don't list included files\n"\r
+                       "/l[:filename]  Generate listing\n"\r
+                       "/o:filename    Set object file name\n"\r
+                       "/M             Print Makefile rule\n"\r
+                       "/p             " ~ OPTION_P_DESC ~ "\n"\r
+                       "/q             Suppress info messages\n"\r
+                       "/t[:filename]  List label table\n"\r
+                       "/u             Warn of unused labels\n"\r
+               );\r
+               return exitCode;\r
+       }\r
+       try {\r
+               assemblyPass();\r
+               pass2 = true;\r
+               assemblyPass();\r
+               if (getOption('t') && labelTable.length > 0) {\r
+                       listLabelTable();\r
+               }\r
+       } catch (AssemblyError e) {\r
+               warning(e.msg, true);\r
+               exitCode = 2;\r
+       }\r
+       if (listingStream !is null) {\r
+               listingStream.close();\r
+       }\r
+       if (objectStream !is null) {\r
+               objectStream.close();\r
+       }\r
+       if (exitCode <= 1) {\r
+               if (!getOption('q')) {\r
+                       dout.printf("%d lines of source assembled\n", totalLines);\r
+                       if (objectBytes > 0) {\r
+                               dout.printf("%d bytes written to the object file\n", objectBytes);\r
+                       }\r
+               }\r
+               if (getOption('m')) {\r
+                       dout.printf("%.*s:%.*s\n\txasm", makeTarget, makeSources);\r
+                       for (int i = 1; i < args.length; i++) {\r
+                               char[] arg = args[i];\r
+                               if (isOption(arg)) {\r
+                                       char letter = arg[1];\r
+                                       if (letter >= 'A' && letter <= 'Z')\r
+                                               letter += 'a' - 'A';\r
+                                       switch (letter) {\r
+                                       case 'm':\r
+                                               break;\r
+                                       case 'o':\r
+                                               if (arg[0] == '/') {\r
+                                                       dout.printf(" /%c:$@", arg[1]);\r
+                                               } else {\r
+                                                       dout.printf(" -%c $@", arg[1]);\r
+                                                       ++i;\r
+                                               }\r
+                                               break;\r
+                                       default:\r
+                                               if (arg[0] == '-'\r
+                                                && (letter == 'd' || letter == 'l' || letter == 't')\r
+                                                && i + 1 < args.length && !isOption(args[i + 1])) {\r
+                                                       dout.printf(" %.*s %.*s", arg, makeEscape(args[++i]));\r
+                                               }\r
+                                               else {\r
+                                                       dout.printf(" %.*s", makeEscape(arg));\r
+                                               }\r
+                                               break;\r
+                                       }\r
+                                       continue;\r
+                               }\r
+                               dout.printf(" $<");\r
+                       }\r
+                       dout.printf("\n");\r
+               }\r
+       }\r
+       return exitCode;\r
+}\r