Speccy - наш выбор!

Speccy - наш выбор! (http://zx-pk.ru/index.php)
-   Эмуляторы отечественных компьютеров (http://zx-pk.ru/forumdisplay.php?f=61)
-   -   Пожелания и планы по эмулятору Башкирия-2М (http://zx-pk.ru/showthread.php?t=8373)

Error404 16th April 2012 17:15

Quote:

Originally Posted by b2m (Post 494676)
Основная проблема сейчас: в отладочной информации никак не отражена оптимизация. Например, в результате оптимизации переменные были размещены в регистрах, и доступ к локальным переменным через IX больше стал не нужен. В итоге, стандартный пролог функции PUSH IX/LD IX,0/ADD IX,SP был выкинут, к аргументам он адресуется через SP, но в отладочной информации об этом ни байта, более того, смещения к аргументам так и остались с учётом того, что в стек кладётся IX. Но с этой мелочью я справился (проверяю наличие пролога). Гораздо хуже, что иногда, несмотря на то, что переменная находится в стеке, и в отладочной информации именно это и сказано, переменная временно располагается в регистре, т.е. при отладке по шагам показываемое значение переменной (из стека) не соответствует реальному значению, т.е. переменная как-бы не меняется, хотя на самом деле это не так. А ещё, бывает, в отладочной информации сказано, что переменная в регистре, а имя регистра не указано (пустая строка). Вот так.

---------- Post added at 14:56 ---------- Previous post was at 14:49 ----------

А ещё, такие перлы:
Code:

        ld        4 (ix),l
        C$conio.c$99$1$30        = .
        .globl        C$conio.c$99$1$30
;conio.c:99: } while (value != 0);
        ld        5 (ix), h
        ld        a, h
        or        a,4 (ix)
        jr        NZ,00101$

Здесь: ld 5 (ix), h сохранение старшего байта переменной, относящееся к строке 98, и если мы стоим на строке 99, оно ещё не выполнилось. Отладчик покажет половину старого и половину нового значения переменной :)

Маркер 99 строки похоже на строку раньше входит. Сначала идет присвоение (видимо 98 строка) - записью HL в IX+4+5, затем проверка на неноль (строка 99).
Похоже на шутки от Peephole optimization. Если исключить опции оптимизации, то может оно получше станет? Тогда будем отлаживаться без оптимизации.

b2m 16th April 2012 18:02

Quote:

Originally Posted by Error404 (Post 494720)
Похоже на шутки от Peephole optimization.

А можно поподробнее про Peephole optimization? Я искал ключи, чтобы отключить оптимизацию, но мне показалось что peephole optimization это какая-то конкретная оптимизация, а не вся, и я даже не стал пробовать. А опцию, чтобы отключить вообще всю оптимизацию я не нашёл.

---------- Post added at 18:02 ---------- Previous post was at 17:46 ----------

Действительно, с опцией --no-peep получилось так:
Code:

        ld        4 (ix),l
        ld        5 (ix),h
        C$conio.c$99$1$30        = .
        .globl        C$conio.c$99$1$30
;conio.c:99: } while (value != 0);
        ld        a,5 (ix)
        or        a, 4 (ix)
        or        a, a
        jp        NZ,00101$


Error404 16th April 2012 18:04

Quote:

Originally Posted by b2m (Post 494732)
А можно поподробнее про Peephole optimization? Я искал ключи, чтобы отключить оптимизацию, но мне показалось что peephole optimization это какая-то конкретная оптимизация, а не вся, и я даже не стал пробовать. А опцию, чтобы отключить вообще всю оптимизацию я не нашёл.

Ну, там правила описываются, типа "конструкции { AA; AA; BB } менять на { 2AA; BB }", оптимизатор шерстит окном в несколько соседних строк по тексту и по шаблону меняет совпадающие конструкции. Я особенно их не изучал, но думаю что переставлять или еще как перекашивать строки оно может.

А опций компилятора там действительно богато:
Code:

3.2.8 Optimization Options
--nogcse Will not do global subexpression elimination, this option may be used when the compiler creates
undesirably large stack/data spaces to store compiler temporaries (spill locations, sloc). A warning
message will be generated when this happens and the compiler will indicate the number of extra bytes
it allocated. It is recommended that this option NOT be used, #pragma nogcse can be used to turn off
global subexpression elimination for a given function only.
--noinvariant Will not do loop invariant optimizations, this may be turned off for reasons explained for the previous
option. For more details of loop optimizations performed see Loop Invariants in section 8.1.4. It is recommended that this option NOT be used, #pragma noinvariant can be used to turn off invariant optimizations for a given function only.
--noinduction Will not do loop induction optimizations, see section strength reduction for more details. It is recommended that this option is NOT used, #pragma noinduction can be used to turn off induction optimizations for a given function only.
--nojtbound Will not generate boundary condition check when switch statements are implemented using jumptables. See section 8.1.7 Switch Statements for more details. It is recommended that this option is
NOT used, #pragma nojtbound can be used to turn off boundary checking for jump tables for a given function only.
--noloopreverse Will not do loop reversal optimization.
--nolabelopt Will not optimize labels (makes the dumpfiles more readable).
--no-xinit-opt Will not memcpy initialized data from code space into xdata space. This saves a few bytes in code space if you don’t have initialized data.
--nooverlay The compiler will not overlay parameters and local variables of any function, see section Parameters and local variables for more details.
--no-peep Disable peep-hole optimization with built-in rules.
--peep-file <filename> This option can be used to use additional rules to be used by the peep hole optimizer. See section 8.1.13 Peep Hole optimizations for details on how to write these rules.
--peep-asm Pass the inline assembler code through the peep hole optimizer. This can cause unexpected changes to inline assembler code, please go through the peephole optimizer rules defined in the source file tree
’<target>/peeph.def’ before using this option.
--peep-return Let the peep hole optimizer do return optimizations. This is the default without --debug.
--no-peep-return Do not let the peep hole optimizer do return optimizations. This is the default with --debug.
--opt-code-speed The compiler will optimize code generation towards fast code, possibly at the expense of code size.
--opt-code-size The compiler will optimize code generation towards compact code, possibly at the expense of code speed.
--fomit-frame-pointer Frame pointer will be omitted when the function uses no local variables.

Я бы для начала удалил из командника компиляции ключи "--opt-*" и добавил все "--no-*", ну может кроме --no-xinit-opt и --nogcse

b2m 16th April 2012 18:46

А что это за оптимизация?
Code:

        ld        a,-19 (ix)
        ld        -33 (ix),a
        ld        a,-18 (ix)
        ld        -32 (ix),a
00139$:
        pop        hl
        push        hl

Здесь ix-33 это верхнее значение стека, pop hl как раз его и достаёт.

---------- Post added at 18:29 ---------- Previous post was at 18:16 ----------

Quote:

Originally Posted by Error404 (Post 494741)
Я бы для начала удалил из командника компиляции ключи "--opt-*"

У меня ни одного такого не используется. Похоже, он сам по-умолчанию всю оптимизацию активирует. Отключить всё подряд можно, но, думаю, нет необходимости. Хотя, попробовать нужно.

---------- Post added at 18:46 ---------- Previous post was at 18:29 ----------

Похоже, постинкремент всегда обрабатывается так: для неувеличенного значения заводится временная переменная, туда копируется значение, и переменная увеличивается, далее используется временная переменная. А в вышеописанном случае эта временная переменная оказалась на вершине стека, что и вылилось в pop/push. Только я не понял, почему дальше увеличивалась уже временная переменная, а нормальная (смещение которой указано в отладочной информации) - вообще не использовалась.

Tim0xA 18th April 2012 20:02

b2m, что с "Кристой-2". Будет поддержка в эмуляторе?

b2m 18th April 2012 20:28

Quote:

Originally Posted by Tim0xA (Post 495817)
b2m, что с "Кристой-2". Будет поддержка в эмуляторе?

Наверное будет :) Там ведь только видеовывод доделать, так?

Tim0xA 19th April 2012 01:08

Quote:

Originally Posted by b2m (Post 495828)
Наверное будет :) Там ведь только видеовывод доделать, так?

Видеовывод, параллельный порт имеет отличия от вектора, плюс последовательный порт.
Вся существенная инфа тут
http://www.sensi.org/~svo/scalar/ware/562
http://www.sensi.org/~svo/scalar/ware/703
http://www.sensi.org/~svo/scalar/ware/842
В "секретах" описаны еще разные варианты подключения контроллера дисковода.

b2m 19th April 2012 11:35

Quote:

Originally Posted by b2m (Post 494746)
А что это за оптимизация?

Незнаю, что и делать с оптимизацией. Вобщем, выложил на сайте текущую версию EMU IDE. Переменные показываются в текстовом окне Output. Если какая-либо переменная не показана, или не меняется в процессе отладки, значит (чаще всего) виновата оптимизация. Т.е. отладочная информация не соответствует коду. Вывод содержимого структур пока не сделан.

Eltaron 19th April 2012 12:26

Quote:

Originally Posted by Error404 (Post 485349)
Фиг там. Интеграцию с SDCC доделали только до компиляции. Отладчик SDCDB не прицеплен, полагаю ввиду его нестандартности. Т.к. для стандартных протоколов опции интеграции отладчиков в рассмотренном плагине Eclipse просматриваются

Нету.
Для любого gdb, отличного от стандартного, надо свой плагин к эклипсу писать. Eclipse шибко умный, он результат своей компиляции сам встроенными парсерами парсит, чтобы понять, может ли он это отлаживать.
Более-менее какая-то гибкость появляется, если компилировать в ELF. Но для z80 таких компиляторов нет.

b2m 23rd April 2012 11:18

Quote:

Originally Posted by Tim0xA (Post 495817)
b2m, что с "Кристой-2". Будет поддержка в эмуляторе?

Сделал.

esl 23rd April 2012 12:54

Привет b2m

есть просьба
немного допилить конфиги для корвета
сделать явно korvet1/korvet2
korvet1:
rom: korvet11.rom
канал 2 таймера
syn2: ~vbl
ct2: как и для каналов 0 и 1 (как я понял "1")

irq4: ~VBL


korvet2:
rom: korvet2.rom
канал 2 таймера
syn2: ~hbl
ct2: ~SVBL


irq4: ~SVBL

---
и еще, задать по умолчанию номер РМУ=0 (чтоб с диска грузился без F1)
lan.netid (оно инвертировано там)
там в коде

Code:

; ЗАГРУЗЧИК ОС МикроДОС
LOADTST        LDA        ADRRM        ; НОМЕР РАБОЧЕГО МЕСТА
        ORA        A
        JNZ        LOADBAS
LOADOS        LDA        CONFG        ; НАЛИЧИЕ ДИСКОВОДА
        ORA        A
        JNZ        LOADBAS



---------- Post added at 10:54 ---------- Previous post was at 10:23 ----------

и кстате, давно хотел написать
перенести все папки с данными внутрь папки cinfig
тогда все чистенько будет ;)

b2m 23rd April 2012 14:46

Quote:

Originally Posted by esl (Post 497680)
есть просьба
немного допилить конфиги для корвета

Хорошо, я учту (на будущее).

Quote:

Originally Posted by esl (Post 497680)
перенести все папки с данными внутрь папки cinfig
тогда все чистенько будет ;)

Не, мне так неудобно. Папка config является частью архива с исходниками, будет неудобно архивировать исходники проекта. Если уж собирать всё в один каталог, то назвать его data, и всё туда свалить.

esl 26th April 2012 15:11

Еще хотелка для Корвета - добавить кнопочку 'Color mode'
основная масса мониторов под корвет была ЧБ

b2m 26th April 2012 19:20

Quote:

Originally Posted by esl (Post 499149)
Еще хотелка для Корвета - добавить кнопочку 'Color mode'
основная масса мониторов под корвет была ЧБ

А как там градации чёрного формировались?

esl 26th April 2012 19:39

у себя я так делал

Code:

  for (i=0;i<16;i++) {
// COLOR PALETTE
      bright=(LUT[i]&0x8)?21:0;
      pallete[LUT_BASE_COLOR+i].r=((LUT[i]&0x4)?42:0)+bright;
      pallete[LUT_BASE_COLOR+i].g=((LUT[i]&0x2)?42:0)+bright;
      pallete[LUT_BASE_COLOR+i].b=((LUT[i]&0x1)?42:0)+bright;

      if (BWFlag) {// BLACK & WHILE PALETTE
        c=pallete[LUT_BASE_COLOR+i].r*0.3+pallete[LUT_BASE_COLOR+i].g*0.5+pallete[LUT_BASE_COLOR+i].b*0.2;

        pallete[LUT_BASE_COLOR+i].r=c;
        pallete[LUT_BASE_COLOR+i].g=c; // if r=0 & b=0 -- cool black green pallete
        pallete[LUT_BASE_COLOR+i].b=c;
      }
  }
  set_palette_range(pallete,LUT_BASE_COLOR,LUT_BASE_COLOR+16,1);

а посмотрел по схема (лист 8) - бардак :(
на двух разны - разные значения резистров
а на двух других - биты другие ;)

I - 75k
G -75k
R - 33K
B - 33K

на второй
I - 3k
G -12k
R - 24K
B - 6.2K

в обчем бардак

svofski 4th September 2012 18:32

1) Неприятность, которая делает совершенно невозможной отладку программы в начале ее исполнения:
а) открываю какой-нибудь ром
б) открываю дебуггер, опционально ставлю брекпоинт
в) переключаюсь в основное окно
г) Alt+F, 1 (перегружаю тот же ром)
д) все падает
Повторяемость 100%.

2) Видел, что в дебуггер можно засасывать листинг. Какой должен быть формат у листинга?

b2m 5th September 2012 16:35

Quote:

Originally Posted by svofski (Post 537230)
1) Неприятность, которая делает совершенно невозможной отладку программы в начале ее исполнения:

Открытие файла сопровождается закрытием текущей сессии, так что отладчик со всеми бряками должен был бы закрыться. А он, зараза, падает. Такая-же фигня была раньше, если при открытом отладчике закрыть окно эмулятора, но это я отловил. А твой вариант - не догадался.

Quote:

Originally Posted by svofski (Post 537230)
2) Видел, что в дебуггер можно засасывать листинг. Какой должен быть формат у листинга?

TASM, которым я пользуюсь, выдаёт такой формат:
Code:

NNNN  AAAA XX XX XX      \tSource line

NNNN номер строки исходного файла (я игнорирую)
AAAA адрес
XX XX XX байты (между ними один пробел)


svofski 5th September 2012 16:38

А еще: как сделать, чтобы при перегрузке файла сохранялись точки останова? Бывает, что становится немного утомительно устанавливать все заново в 40-й раз ;)

b2m 5th September 2012 16:54

Не предусмотрено. Только если через отладчик загружать бинарный файл.

fifan 6th September 2012 19:10

1 Attachment(s)
Дмитрий, а почему на эмулляторе не работают на 50% самопально написанные программы, используемые обращения к MX-DOS под Специалистом_МХ? Вроде использую оригинальные подпрограммы работы с дискетой, но просто висит эмулятор. Каким образом происходит проверка наличия дискеты (образа odi)?
Я написал на 50%, потому что моя прога с имиджа дискеты (my1disk.odi/From Fifam/SpetsCom.EXE) запускается, а вот если загружать в эмулляторе через File/Open, то - нефига.
В атаче прикрепил три файла. Имидж диска и два файла cpu/i80 самой программы.
При запуске программы требуется выбрать диск (дискету А или В, или С - ROM-диск). Для дискеты предварительно нужно подцепить образ. Пока реализованы три клавиши: F1, F2, F3, F4, по Enterу - запуск программ (правда пока с ROM-диска).
Если нужно, могу дать исходники.

b2m 6th September 2012 20:45

Quote:

Originally Posted by fifan (Post 537820)
Вроде использую оригинальные подпрограммы работы с дискетой, но просто висит эмулятор.

Я пробовал по всякому, но не висит эмулятор, хоть плач :)
Открываю через File/Open твой файл, подключаю образ, жму enter - показывает каталог. Если жму enter, а потом подключаю образ - всё равно показывает. Что я делаю не так?

Quote:

Originally Posted by fifan (Post 537820)
Каким образом происходит проверка наличия дискеты (образа odi)?

Откуда я знаю, как в твоих "стандартных" процедурах происходит проверка наличия дискеты?

---------- Post added at 20:45 ---------- Previous post was at 20:40 ----------

Единственное, чего не понял: это так и задумано, что клава так тормозно реагирует? Нельзя, что-ли, сделать нормальный опрос клавы?

esl 6th September 2012 20:52

вдруг будет новая версия
на всяуий случай напоминаю про Корвет ;)

http://zx.pk.ru/showpost.php?p=497680&postcount=571

fifan 6th September 2012 22:03

1 Attachment(s)
У меня через File/Open прога загружается, но по Enter А и В диски не загружаются, только С, а должны.
Про клаву. Использую стандартно: call #c81b.

P.S. Почти написал другую прогу - высвечивает таблицу FAT посекторно на экран. Там ситуация хуже - на процедурах опроса дисковода - всё виснит. Почему знаю что вообще работает? На другом эмуляторе spmx_v42 всё прекрасно работает, но он зараза по виндой 7 вообще не работает....

ZEman 7th September 2012 15:21

fifan, через Dosbox запускайте эмулятор spmx_v42 и будет вам щастье ;)

fifan 8th September 2012 06:56

Жаль. ситуация с новой прогой повторилась. Т.е. записываю прогу в образ odi, запускаю - работает. Через File/Open загрузка cpu/i80 - висит на начальном этапе.

fifan 9th September 2012 19:17

Нашёл ещё один глюк в Специалисте_МХ. Не переключаются дискеты в MX-DOS по F3. Вернее в место выбора диска В, просто перечитывается дисковод А. В системе имя диска В пишется верно, образы odi для обоих дисков назначаю и разные.

Error404 11th September 2012 19:51

Quote:

Originally Posted by fifan (Post 538221)
Жаль. ситуация с новой прогой повторилась. Т.е. записываю прогу в образ odi, запускаю - работает. Через File/Open загрузка cpu/i80 - висит на начальном этапе.

Может, у тебя в программе что-то недоинициализировано перед стартом основных процедур? Поэтому и разница в зависисмости от способа запуска (на по-разному инициализированной памяти/портах).

fifan 11th September 2012 20:56

5 Attachment(s)
Так и было. Прошу прощения у b2m за нарекания. Взял дизассемблировал MX-DOS v3.6, который записывался в начало каждой дискеты для Специалиста_МХ. Нашёл там процедуры опроса состояния ВГ93 и установки дисковода на нулевую дорожку. Вставил в SpetsCommnder. Но теперь отсутствие дисковода (не назначены образы в эмулляторе) приводит к зависанию проги. Вот скриншоты некоторых функций программы. В основном процесс написания SpetsCommanderа я выкладываю здесь.

P.S. Всё ж не поддержка дисковода В в MX-DOS не работает в данном эмуляторе. Проверял в spmx_v42, там всё в порядке.

b2m 12th September 2012 10:33

Quote:

Originally Posted by fifan (Post 539044)
Но теперь отсутствие дисковода (не назначены образы в эмулляторе) приводит к зависанию проги.

Ну, наверное, в проге так и задумано. Просто ждёт готовности дисковода.

Quote:

Originally Posted by fifan (Post 539044)
Всё ж поддержка дисковода В в MX-DOS не работает в данном эмуляторе.

Заглянул в конфиг - действительно нет выбора. Надо добавить. Ну и какими битами там дисковод выбирается?

CodeMaster 12th September 2012 10:41

Quote:

Originally Posted by b2m (Post 151606)
В первом посте я буду собирать их вместе, и по мере реализации отмечать как сделанные.

А можно добавить в первый пост кумулятивный список эмулируемых компов, а то на сайте его тоже нет. А просто качать, что бы посмотреть этот список в выборе конфигурации ИМХО не правильно. Или вот этот список из даунлоада полный?

Quote:

Башкирия-2М, Агат-7, Апогей, БК-0010, БК-0011м, Вектор-06ц, Вектор Старт-1200, Ириша, Корвет, Лик, Львов ПК-01, Микро-80, Микроша, Наири, Океан-240, Орион-128, Орион-Про, Партнёр, ПК-6128ц, ПК 8000 Сура/Веста/Хобби, ПК 8002 Эльф, Радио-86РК, Специалист, Специалист-МХ, Юниор, ЮТ-88

b2m 12th September 2012 11:01

Quote:

Originally Posted by CodeMaster (Post 539127)
Или вот этот список из даунлоада полный?

Да, этот список я стараюсь держать актуальным. В этом списке нет тех, которые не входят в основной архив (игровые автоматы на основе компов) и которые нужно скачивать отдельно. Кроме того, нет тех, эмуляция которых находится в зачаточном состоянии (например Арго).

---------- Post added at 11:01 ---------- Previous post was at 10:56 ----------

Хотя, наверное стоит добавить в этот список MSX, MSX-2, Robotron 1715, ZX Spectrum 48, ZX Spectrum 128. Но это не отечественные компы...

fifan 12th September 2012 12:02

Quote:

Originally Posted by b2m (Post 539126)
Заглянул в конфиг - действительно нет выбора. Надо добавить. Ну и какими битами там дисковод выбирается?

Бит 0/1 задаёт дисковод А/В путём записи в порт #fff3. Вот схема контроллера дисковода, триггер D4.1.

Ещё глюк, сегодня обнаружил. Мне нужно организовать переход по нажатию F8 и F9, но на записанные коды #8b и #8c эмулятор никак не реагирует. Используется стандартная подпрограмма по вводу кода нажатой клавиши - #c81b. Все остальные (F1...F7) и назначенная Esc вместо АР2 прекрасно работают.

b2m 12th September 2012 13:07

Quote:

Originally Posted by fifan (Post 539137)
Вот схема контроллера дисковода, триггер D4.1.

Спасибо, вроде раньше её не видел. Судя по этой схеме, у меня вообще неправильно сделано. Совпадают только проты ВГ93 и номер стороны. :)

Quote:

Originally Posted by fifan (Post 539137)
Мне нужно организовать переход по нажатию F8 и F9, но на записанные коды #8b и #8c эмулятор никак не реагирует.

Не понял, куда "записанные коды #8b и #8c"?

fifan 12th September 2012 21:39

Quote:

Originally Posted by b2m (Post 539154)
Не понял, куда "записанные коды #8b и #8c"?

Они должны соответствовать нажатым клавишам F8 и F9 при опросе клавиатуры, но не тут то было. Вот по такому коду переход на метки F8 и F9 не происходит:
Quote:

Quote:

CycleScan1 call #c81b ; опрос клавиатуры
cp #19
jp z, Up1 ; курсор вверх
cp #1a
jp z, Down1 ; курсор вниз
cp #0d
jp z, Enter1 ; клавиша ВК
cp #00
jp z, F1 ; выбор левой панели файлов
cp #01
jp z, F2 ; выбор правой панели файлов
cp #02
jp z, F3 ; печать инфо панели
cp #03
jp z, F4 ; редактор
cp #04
jp z, F5 ; копирование
cp #05
jp z, F6 ; переименование/перенос
cp #06
jp z, F7 ; создание каталога
cp #8b
jp z, F8 ; удаление
cp #8c
jp z, F9 ; меню
jp CycleScan1


b2m 12th September 2012 22:47

Клавиши F8-F10 служебные, при их нажатии меняется верхняя служебная строка, а драйвер их попросту не выдаёт.

fifan 16th September 2012 17:41

Я смотрю эмулятор обновился и теперь дисководы меняются. Спасибо. Как же быть с F8 и F9? Никак нельзя задействовать их?

b2m 16th September 2012 19:51

Quote:

Originally Posted by fifan (Post 540045)
Как же быть с F8 и F9? Никак нельзя задействовать их?

Можно, напиши свой драйвер клавы.
Хотя, там наверняка можно имеющиеся процедуры использовать, и много переписывать не придётся.

fifan 6th December 2012 21:29

1 Attachment(s)
b2m, привет! Нашёл тут глюк в твоей программе. В отладчике View/Start debugger по запросу Ctrl+L не верно считается длина загружаемого блока - наверное нужно на байт больше.

b2m 7th December 2012 12:43

Скачай новую версию. Этот диалог уже давно не так выглядит :)

esl 27th December 2012 04:33

b2m, принимай багрепорт
что-то не так с эмуляцией звука,
у Корвета и нашел еще явно теже грабли у "Zx Spectrum 128 tr-dos"
причем у ZX эт прям со старта
а у Корвета, надо запустить любую игрушку с эмуляцией AY
c моего disk.kdi
XYZON
BINALEND
NINJA
MAFIA
ну или у моего нового ATHLETIC LAND (то что park_sound)

похоже грабли когда часто в порт ВИ53 пишем ?
хотя у ZX же стоит AY ...
самая старая версия что у меня есть эт 20120423
ну и на последней тоже проверил


All times are GMT +4. The time now is 02:57.

Powered by vBulletin® Version 3.8.3
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.