На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
В этом разделе можно создавать темы, которые относятся к поколению 32-битных компиляторов.
Здесь решаются вопросы портирования кода из старого доброго Турбо Паскаля в FPC, TMT, VP, GPC компиляторы, а также особенностей программирования на них для Windows/Linux и других ОС.
Указывайте тип компилятора, его версию, а также платформу (Windows/Linux/..) компиляции, другими словами, Target.
Модераторы: volvo877
Страницы: (3) [1] 2 3  все  ( Перейти к последнему сообщению )  
> Переносим код из Турбо Паскаля
    Переносим код из Турбо Паскаля


    Давайте здесь будем помогать людям переносить свои программы из Турбо Паскаля (графику, Turbo Vision). Если у кого есть проблемы с портированием, опишите подробно проблему.
    Важно: не забудьте также указать тип компилятора и его версию.
    Большие куски текста не вставлять! Можно показать лишь часть кода. А если этого недостаточно, то присоедините архив к сообщению.

    Добавлено
    Советы:
    Чтобы программы переносились легко, надо
    • Писать их на чистом Паскале, и не смешивать их со встроенным ассемблером. Плохой пример - графика в режиме 13h с применением ассемблерных процедур
    • Применять структурное программирование: чётко разбить всё по процедурам и на модули. Желательно, всё же, использовать стандартные.
    • Не обращаться напрямую к памяти и портам.
      Народ, давайте писать здесь о том, как портировать код со старых ТР7 программ в новые компиляторы.
      • Как использовать графику
      • Адаптация типов данных
      • и другое

      Это сообщение было перенесено сюда или объединено из темы "Особенности программирования в TMT/FPC"
        А встроенный ассемблерный код? У меня именно с этим проблемы и есть. :wacko: :rolleyes:

        Добавлено
        Могу писАть про ТМТ.. Так и сделаю. ;)

        Это сообщение было перенесено сюда или объединено из темы "Особенности программирования в TMT/FPC"
          Напишу немного про TMT Graph.
          Сразу кину ссылочку.. Загляните, посмотрите. Там все подробно.

          Основные отличия от родственного 16битного Grapha.

          1. Инициализация графики.
          Вместо InitGraph делаем так:
          ExpandedWrap disabled
            SetSVGAMode(XRes, YRes, BPP, VMode: Word)

          xRes и yRes - разрешение экрана, варируется от 640х480 до 1600х1200.
          BPP - глубина цвета, т.е. 2 в BPP степени цветов у вас будет
          VMode может принимать следующие значения в дипазоне [1..3]:
          ExpandedWrap disabled
             
                Константа   Значение   Пояснение
                LFBorBanked 0          Установить режим LFB или с переключением банков
                BankedOnly  1          Установить режим только с переключением банков
                LFBOnly     2          Установить только LFB режим

          Выход далается любимым
          ExpandedWrap disabled
            GloseGraph
          .

          2. Картинки, т.е. спрайты. Вроде, ничего особа не изменилось. Но если интересно, то можно заглянуть:
          Работа с картинками ;)

          3. Есть такая вещь, как
          ExpandedWrap disabled
            SetWriteMode(WriteMode: DWord)
          , она "Устанавливает режим записи при рисовании линии., ...оказывает воздействие на результат вывода следующих процедур: DrawPoly, Line, Spline, LineRel, LineTo, Rectangle, Circle, Ellipse, Bar3D, Putpixel, PutSprite и PutImage".
          Узнать что у вас установлено можно с помощью
          ExpandedWrap disabled
            GetWriteMode
          .

          4. А еще
          ExpandedWrap disabled
            SetTranspMode(Mode: Boolean; Color: DWord)

          Если выставить Mode в True, то цвет Color при использовании PutPixel, PutSprite и PutImage не будет выводиться. Если Mode = False, то все цвета работить будут.
          Опять же, что установлено можно узнать, используйте
          ExpandedWrap disabled
            GetTranspSettings (var Mode: Boolean; Color: DWord)
          .

          5. Вроде, в 16битном не было
          ExpandedWrap disabled
            SetFillColor (Color: DWord)
          , которая устанавливает закрашивание сплошным цветом Color. Ну и
          ExpandedWrap disabled
            SetFillStyle(Pattern: DWord; Color: DWord)
          сюде же, только в зтой процедуре можно установить pattern по следующим константам:
          ExpandedWrap disabled
             
                Константа      Значение Пояснение
                EmptyFill      0        не заливаем
                SolidFill      1        заливаем вплошным цветом
                LineFill       2        ---
                LtSlashFill    3        ///
                SlashFill      4        ///
                BkSlashFill    5        \\\
                LtBkSlashFill  6        \\\
                HatchFill      7        крестик
                XHatchFill     8        крестик
                InterleaveFill 9        чередующиеся линии
                WideDotFill    10       точки
                CloseDotFill   11       точки
                UserFill       12       определяется пользователем

          6. А теперь вспомним, что количество поддерживаемых цветов уже не 256! :)
          Это влияет не только на тип номера цвета. По этому поводу очень полезны подпрограмки
          ExpandedWrap disabled
            RGBColor(R, G, B: Byte)
          , которая по компонентам RGB заданного цвета возвращает его номер, и
          ExpandedWrap disabled
            AnalizeRGB (Color: Dword; var R,G,B: Byte)
          , которая делает противоположное, т.е. по номеру цвета возвращает его RGB составляющие.

          Это все основное, что, с моей точки зрения, знать надо. Остальное есть по ранее указанной ссылке.

          Это сообщение было перенесено сюда или объединено из темы "Особенности программирования в TMT/FPC"
            KiRiK, а какие могут быть проблемы с ассемблером ??? :)

            Это сообщение было перенесено сюда или объединено из темы "Особенности программирования в TMT/FPC"
              Какие-какие, ну нельзя же его влоб портировать, правильно. Ведь был 16биный, а сталь 32х. А я 32битных регистров не знаю. :unsure: Увы.

              Это сообщение было перенесено сюда или объединено из темы "Особенности программирования в TMT/FPC"
                KiRiK, тут все просто: если не знаешь 32-хбитных регистров, можешь пользоваться 16-тибитными, главное помнить:

                1) указатели как были, так и остались 32-хбитными, только вместо сегмента - старшие 16 бит смещения (указатели стали ближними!); сегментные регистры не используются (в смысле - не изменяются), используется модель памяти flat (тот же tiny, только больше :);

                2) кстати: НЕ ТРОГАЙ СЕГМЕНТНЫЕ РЕГИСТРЫ! просто имей в виду, что DS=ES=FS=GS=SS;

                3) на вершину стека указывает не 16-тибитный SP, а 32-хбитный ESP;

                4) где раньше неявно использовались 16-тибитные регистры (SI/DI/CX в строковых операциях, CX в LOOP-е, BX в XLAT, BP/SP в LEAVE и т. п.), теперь используются 32-хбитные, например:
                ExpandedWrap disabled
                  { записать ярко-зеленый восклицательный знак по указанному адресу в видеобуфере }
                   
                  { was: 16 bit }
                   
                  procedure PutExcl(where: pointer); assembler;
                  asm
                      les di,where    { ES:DI }
                      mov ax,0A21h
                      stosw
                  end;
                   
                  { is: 32 bit }
                   
                  procedure PutExcl(where: pointer); assembler;
                  asm
                      mov edi,where   { EDI }
                      mov ax,0A21h
                      stosw
                  end;


                5) вместо PUSHF/POPF, PUSHA/POPA следует использовать PUSHFD/POPFD, PUSHAD/POPAD чтобы класть в стек или снимать с него 32-хбитные регистры; также следует использовать RETFD/IRETD вместо RETF/IRET, но эти команды теперь не требуются;

                6) кстати, на всякий случай: дальние процедуры/функции не используются, теперь они все - ближние!

                7) и самое главное, на всякий случай: если не вполне понимаешь, что делает программа - НЕ ПОРТИРУЙ ЕЕ! (впрочем, это очевидно :)

                Но этот способ портирования неэффективен, некрасив и неинтересен. Лучше пойти другим путем - переписать код в 32-хбитных инструкциях. Следует помнить следующее:

                8) к 16-тибитным регистрам общего назначения (и к IP и FLAGS) добавилось 16 бит сверху и буковка "E" слева :), т. е. получились EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI, EIP, EFLAGS. При этом 16-разрядные "предки" стали неотъемлемой частью 32-хбитных "потомков", пример:
                ExpandedWrap disabled
                      xor eax,eax     { EAX := 0 }
                      mov ax,0ABCDh   { EAX := 0000ABCDh }
                      shl eax,4       { EAX := 000ABCD0h }
                      sar ax,4        { EAX := 000AFBCDh }
                      rol ah,4        { EAX := 000ABFCDh }


                9) все команды работают с 32-хбитными операндами так же, как и с 16-тибитными, нужно только подставить везде буковку "E" и заменить word на dword; я имею в виду следующее:
                ExpandedWrap disabled
                  { 16 bit }
                      cwd         { DX:AX := AX (signed) }
                      mov bx,some_var { word ptr }
                      idiv    bx      { AX := DX:AX div BX }
                                  { DX := DX:AX mod BX }

                переделываешь в
                ExpandedWrap disabled
                  { 32 bit }
                      cdq         { EDX:EAX := EAX (signed) }
                      mov ebx,some_var{ dword ptr }
                      idiv    ebx     { EAX := EDX:EAX div EBX }
                                  { EDX := EDX:EAX mod EBX }


                10) команды PUSHxx/POPxx теперь работают с двойными словами (и вообще, везде, где раньше было слово - теперь два :)

                11) появились весьма полезные 32-хбитные команды, вот некоторые из них:
                CWDE: EAX := AX (со знаком)
                CQD: EDX:EAX := EAX (со знаком)

                32-хбитные строковые операции: LODSD, STOSD, SCASD, CMPSD, MOVSD, INSD, OUTSD, используется EAX вместо AX,
                ESI/EDI +-= 4; REP/REPE/REPZ/REPNE/REPNZ используют ECX вместо CX

                список далеко :) не полный, если хочешь узнать больше - RTFM :)

                12) адресация: теперь смещения могут быть размером в 1 или 4 байта; можно использовать любые 32-хбитные регистры общего назначения (до двух регистров); один из используемых регистров (кроме ESP) можно умножать (без последствий :) на 2, 4 или 8, например:
                ExpandedWrap disabled
                      mov eax,PointerList[edx + eax*4]


                В остальном, вроде бы, без изменений (я имею в виду - при портировании :)

                P. S. А вообще - RTFM (Хайда, Зубкова, Юрова...).

                Это сообщение было перенесено сюда или объединено из темы "Особенности программирования в TMT/FPC"
                Сообщение отредактировано: AVA12 -
                  AVA12, пасиба, расписал. ;)
                  Хотя пока и не очень понятно, но если нужно будет, то теперь разберусь. Просто пока еще не возникало большой необходимости в портировании ассемблера, но было интересно понять какая зависимость мужду 16ти и 32х битными регистрами.

                  Это сообщение было перенесено сюда или объединено из темы "Особенности программирования в TMT/FPC"
                    Хорошо. То, что касается встроенного ассемблера - вроде, разобрались.
                    Теперь давайте и о Паскале поговорим. :)

                    Добавлено
                    Цитата KiRiK @ 26.10.04, 18:29
                    5. Вроде, в 16битном не было
                    ExpandedWrap disabled
                      SetFillColor (Color: DWord)
                    , которая устанавливает закрашивание сплошным цветом Color. Ну и
                    ExpandedWrap disabled
                      SetFillStyle(Pattern: DWord; Color: DWord)
                    сюде же, только в зтой процедуре можно установить pattern по следующим константам:
                    ExpandedWrap disabled
                       
                          Константа      Значение Пояснение
                          EmptyFill      0        не заливаем
                          SolidFill      1        заливаем вплошным цветом
                          LineFill       2        ---
                          LtSlashFill    3        ///
                          SlashFill      4        ///
                          BkSlashFill    5        \\\
                          LtBkSlashFill  6        \\\
                          HatchFill      7        крестик
                          XHatchFill     8        крестик
                          InterleaveFill 9        чередующиеся линии
                          WideDotFill    10       точки
                          CloseDotFill   11       точки
                          UserFill       12       определяется пользователем

                    А по-моему, было.

                    Это сообщение было перенесено сюда или объединено из темы "Особенности программирования в TMT/FPC"
                      насчет графики: в ТМТ появилась такая процедура - SetVirtualMode(var p:pointer) которая перенаправляет весь вывод на экран (при установленном граф.режиме) в буфер памяти, размер которого - одно окно (getpagesize), этот буфер предварительно нужно выделить getmem'ом. После ее вызова изображение на экране обновляться не будет до вызова fliptoscreen(p), где p - переменная, содержащая экран (либо та, которая была использована в вызове setvirtualmode, либо еще какая-нибудь такого же размера, в которую был загружен образ экрана откуда-то еще). Возврат к нормальному режиму - SetNormalMode.
                      Также есть процедура снятия скриншота - FlipToMemory(p).

                      Это сообщение было перенесено сюда или объединено из темы "Особенности программирования в TMT/FPC"
                        Цитата Romtek, 27.10.04, 13:30
                        А по-моему, было.

                        SetFillStyle был,
                        SetFillColor не было.

                        Цитата Vesper, 27.10.04, 13:57
                        насчет графики: в ТМТ появилась такая процедура - SetVirtualMode(var p:pointer) которая перенаправляет весь вывод на экран (при установленном граф.режиме) в буфер памяти, размер которого - одно окно (getpagesize), этот буфер предварительно нужно выделить getmem'ом. После ее вызова изображение на экране обновляться не будет до вызова fliptoscreen(p), где p - переменная, содержащая экран (либо та, которая была использована в вызове setvirtualmode, либо еще какая-нибудь такого же размера, в которую был загружен образ экрана откуда-то еще). Возврат к нормальному режиму - SetNormalMode.
                        Также есть процедура снятия скриншота - FlipToMemory(p).


                        Не работает в бесплатном ТМТ. Увы.

                        Это сообщение было перенесено сюда или объединено из темы "Особенности программирования в TMT/FPC"
                          Цитата KiRiK, 27.10.04, 16:30
                          Не работает в бесплатном ТМТ. Увы.

                          С чего ты взял? у меня работает к примеру 3.9lite

                          Это сообщение было перенесено сюда или объединено из темы "Особенности программирования в TMT/FPC"
                            Да?! Здорово! Надо будет проверить.
                            У меня в ТМТ 3.5. не пашет, да и в мануале так написано...

                            Это сообщение было перенесено сюда или объединено из темы "Особенности программирования в TMT/FPC"
                              Как правельно партировать переменные процедурного типа из TP7 в TMT.Какие могут быть ошибки?
                              ExpandedWrap disabled
                                var pp:procedure(var x,y:integer);
                                 
                                procedure pp1(var x,y:integer);far;
                                begin
                                 
                                end;
                                 
                                begin
                                pp:=pp1;
                                end.

                              Это сообщение было перенесено сюда или объединено из темы "Особенности программирования в TMT/FPC"
                              Сообщение отредактировано: Romtek -
                                Вообщето и так работать будет, но far излишне.

                                Да, еще при вызове процедур не стоит забывать никакие параметры, а то может откомпилиться, но работать неправильно.

                                Это сообщение было перенесено сюда или объединено из темы "Особенности программирования в TMT/FPC"
                                  Графика в FPC, модуль Graph :

                                  Есть небольшие поправки в программах, написанных для Турбо Паскаля, хотя всё остаётся прежним.

                                  Чтобы миновать консольное окно, нужно указать вначале программы (перед Uses)
                                  ExpandedWrap disabled
                                    {$ifdef Win32}
                                     {$apptype GUI}
                                    {$endif}

                                  Теперь в разделе Uses :
                                  CRT надо заменить на WinCrt, хотя лучше вообще удалить, если не используются функции KeyPressed, ReadKey.
                                  Windows - добавить, т.к будет использоваться дальше.
                                  ExpandedWrap disabled
                                    uses
                                    {$ifdef Win32}
                                      WinCrt,
                                      Windows,
                                    {$endif}
                                      Graph; // без изменений


                                  Инициализация графики:
                                  ExpandedWrap disabled
                                    var
                                    GraphDriver, GraphMode: SmallInt;
                                    ...
                                         {$ifdef Win32}
                                         ShowWindow(GetActiveWindow,0);
                                         {$endif}
                                     
                                         GraphDriver := d8bit;
                                         // количество бит цвета: 8-бит = 2^8 = 256 цветов, 16-бит = 2^16, 32-бит = 2^32
                                     
                                         GraphMode := m800x600; // графический режим
                                         InitGraph(GraphDriver,GraphMode,'');
                                         if Graphresult<>0 then
                                            exit;


                                  Выход из графики:
                                  Если присутствует Readln; в качестве ожидания завершения программы, то лучше заменить на этот код:
                                  ExpandedWrap disabled
                                         {$ifndef Win32}
                                         readln;
                                         {$else: Win32}
                                         repeat
                                         until Keypressed;
                                         {$endif}
                                     
                                         CloseGraph; // как обычно


                                  Это сообщение было перенесено сюда или объединено из темы "Особенности программирования в TMT/FPC"
                                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                  0 пользователей:
                                  Страницы: (3) [1] 2 3  все


                                  Рейтинг@Mail.ru
                                  [ Script execution time: 0,0617 ]   [ 19 queries used ]   [ Generated: 28.03.24, 07:55 GMT ]