Важная информация

User Tag List

Страница 1 из 2 12 ПоследняяПоследняя
Показано с 1 по 10 из 13

Тема: насчет эмуляции ULA

  1. #1
    Master Аватар для boo_boo
    Регистрация
    10.05.2005
    Адрес
    Москва
    Сообщений
    715
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    2
    Поблагодарили
    2 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию насчет эмуляции ULA

    во многих эмулях практикуется такой подход к эмуляции ULA-видеоконтроллера: после того, как процессор исполнит очередную команду, берется кол-во тактов, затраченное на эту команду, и выполняется соответствующий обьем отрисовки ULA.
    к примеру: некий PUSH занял 11 тактов, стало быть (в случае прямого хода луча) ULA рисует 22 точки. и так далее.
    НО -- ведь если у нас машина с раздельными полями памяти, ULA и Z80 обращаются к данным одновременно, то есть может возникнуть ситуация, когда PUSH положил на стек, находящийся в экранной памяти, старший байт слова, тем временем ULA считала байт по предыдущему адресу, а затем PUSH положил и младший байт, но ULA уже ускакала вперед, и на экран таким образом попал только старший байт слова, которое клал на стек PUSH.
    в упомянутом выше алгоритме эмуляции это не будет учтено, на экран попадут оба байта, то есть, строго говоря, такая эмуляция некорректна.

    прав ли я?

  2. #1
    С любовью к вам, Yandex.Direct
    Размещение рекламы на форуме способствует его дальнейшему развитию

  3. #2
    Guru
    Регистрация
    08.10.2005
    Адрес
    Москва
    Сообщений
    13,557
    Спасибо Благодарностей отдано 
    1,220
    Спасибо Благодарностей получено 
    1,754
    Поблагодарили
    683 сообщений
    Mentioned
    67 Post(s)
    Tagged
    1 Thread(s)

    По умолчанию

    Да, ты прав, такая эмуляция не вполне корректна

  4. #3
    Guru Аватар для Lethargeek
    Регистрация
    08.09.2005
    Адрес
    Воронеж
    Сообщений
    4,551
    Записей в дневнике
    3
    Спасибо Благодарностей отдано 
    264
    Спасибо Благодарностей получено 
    209
    Поблагодарили
    167 сообщений
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Давно уже пора полноценно эмулировать не только проц "изнутри" да юлу, но и шину (потактовое состояние). И всякие "девайсоплагины" будет проще прикручивать. Правда, эмуль тормознутый получится... но это ничего, у винтела дури хватает.
    Прихожу без разрешения, сею смерть и разрушение...

  5. #4
    Veteran
    Регистрация
    06.05.2006
    Адрес
    Ливны, Орловская обл
    Сообщений
    1,169
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    0
    Поблагодарили
    0 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Потактово это конечно хорошо, да и дури хватит(а при хорошей архитектуре эмуля может и лучше будет), но вот инфы по интимным делам железа внутри команд надо будет ещё поискать...

  6. #5
    Master Аватар для Vladimir Kladov
    Регистрация
    09.02.2005
    Адрес
    Новосибирск
    Сообщений
    933
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    17
    Поблагодарили
    17 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    в каких это - многих? у меня в процессе выполнения команды НА КАЖДОМ ЦИКЛЕ строится видеолуч, например. И я уверен, что так же делается во всех эмуляторах, работающих с ULA (а не с рассыпухой). Иначе это уже не мультиколор, а частичный мультиколор.

    Инфы - море. Идите на worldofspectrum, там все лежит, и даже обновляется.
    Последнюю версию EmuZWin (2.7) можно получить по этой ссылке, а "официальная" страница с описанием здесь. Если что-то не пашет, берите там же версии 2.6 или старше. [B]

  7. #6
    Master Аватар для boo_boo
    Регистрация
    10.05.2005
    Адрес
    Москва
    Сообщений
    715
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    2
    Поблагодарили
    2 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Lethargeek
    Давно уже пора полноценно эмулировать не только проц "изнутри" да юлу, но и шину (потактовое состояние). И всякие "девайсоплагины" будет проще прикручивать. Правда, эмуль тормознутый получится... но это ничего, у винтела дури хватает.
    попробую, глянем, сколько там у винтела дури
    Цитата Сообщение от NovaStorm
    Потактово это конечно хорошо, да и дури хватит(а при хорошей архитектуре эмуля может и лучше будет), но вот инфы по интимным делам железа внутри команд надо будет ещё поискать...
    по каким "делам внутри команд"?
    Цитата Сообщение от Vladimir Kladov
    в каких это - многих? у меня в процессе выполнения команды НА КАЖДОМ ЦИКЛЕ строится видеолуч, например. И я уверен, что так же делается во всех эмуляторах, работающих с ULA (а не с рассыпухой). Иначе это уже не мультиколор, а частичный мультиколор.
    ну у тебя я не смотрел, сорцы-то закрыты
    в zemu, в глюкалке с точностью до опкода ULA работает. в US все кошерно.
    а у тебя как это реализовано? жестко на каждом такте дергается ULA, или как в US -- после записи в видеопамять/порт?

  8. #7
    Veteran
    Регистрация
    06.05.2006
    Адрес
    Ливны, Орловская обл
    Сообщений
    1,169
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    0
    Поблагодарили
    0 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Интим - это например LDIR,условные переходы и вообще что-то более-менее "сложное". Порядок изменения этоми инструкциями регистров разнится на клонах Z80, да на разных по технологии изготовления Z80. Для точной эмуляции, нужно было бы выбирать конкретный проц.

  9. #8
    Master Аватар для Vladimir Kladov
    Регистрация
    09.02.2005
    Адрес
    Новосибирск
    Сообщений
    933
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    17
    Поблагодарили
    17 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию ULA в EmuzWin

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

    это - код макросов для эмуляции задержек и ULA.

    Код:
    ////////////////////////////////////////////////////////////////////////////////
    
              //         //   //                  ////
              //         //   //                 // //
              //         //   //                //  //
              //         //   //               //   //
              //         //   //              ////////
              //         //   //             //     //
                /////////     ////////////  //      //
    
    ////////////////////////////////////////////////////////////////////////////////
    
    MC_VIDEO_SCREEN_READY MACRO
        // буфер заполнен, вывод экрана и другие действия
        MOV  EAX, [VideoOutObj]
    
        // вывод экрана
        LEAVE_MMX
        PUSH ECX
          PUSH EAX
            XOR  B[&ZX].Reg_F, flag_N
            XCHG D[MC_Screen_Buffer_Pos], EDI
            .IF AntiSlowDown and 0
              MOV EDI, 71690+256
            .ENDIF
            MOV  D[&ZX].TactCount, EDI
            SUB  D[&ZX].TactCount, $100
            MOV  [&ZX].Reg_PC, BX
            CALL VideoOutObj_FrameReady
            XCHG [MC_Screen_Buffer_Pos], EDI
            .IF Gfx256
              MOV D[GfxVideoTarget], VideoOutObj_GfxPixels
              MOV D[ScreenAttrTarget], VideoOutObj_ScreenAttrs
            .ENDIF
          POP  EAX
          MOV  DL, 1 // ManageFlash = TRUE
          CALL VideoOutObj_ScreenReady
        POP  ECX
        ENTER_MMX
        XOR  EDI, EDI
      END //MC_VIDEO_SCREEN_READY
    
    //******************************************************************************
    ULA_unit MACRO Flag=YES
      .IF MultiColor
    
        .IF AntiSlowDown
          CMP D[&ZX].AntiSlow_HaltDetected, 0
          JZ  @@ULA_antislow1_&&
          CMP D[&ZX].AntiSlow_HaltDetected, 8
          JB  @@ULA_antislow_end&&
          // halt detected, ...
    @@ULA_antislow1_&&: // нет halt'ов, только in-ы
          CMP EDI, 71680
          JAE LONG @@ULA_end_all&&
          XCHG EDI, [MC_Screen_Buffer_Pos]
          CMP  EDI, MC_Screen_Buffer_Size
          XCHG EDI, [MC_Screen_Buffer_Pos]
          JAE LONG @@ULA_end_all&&
    @@ULA_antislow_end&&:
        .ENDIF
    
      .IF PrepareVideo
        LEA  ECX, [EDI-256]
        .IF UlaBuffer > 0
          ADD  ECX, UlaBuffer
        .ENDIF
        SUB  ECX, [ULA_TCounter0]
        JLE  LONG @@_ULA_end&&
        SHR  ECX, 2
        JZ   LONG @@_ULA_end&&
    
        MOV  EDX, ECX
        SHL  EDX, 2
        ADD  [ULA_TCounter0], EDX
    
        // CL = число байтов для отображения > 0
        XCHG EDI, [MC_Screen_Buffer_Pos]
        .IF "&Flag" = "YES"
          MOV  [&ZX].Reg_F, AH // если будет вызван FrameReady,
                               // то нужно текущее состояние Reg_F для TimeStamper-а
        .ENDIF
        PUSH EAX  //-------------------------------------\
    
        // цикл вывода байтов
    @@_ULAout_loop&&:
    
        .IF AntiSlowDown
          CMP EDI, MC_Screen_Buffer_Size
          JAE LONG @@_ULAfin&&
        .ENDIF
        // первым сохраняем текущий BorderColor и видеорежим
        MOV  DL, [&ZX].BorderColor
        MOV  DH, [&ZX].VideoMode
        MOV  [EDI*4+2+MC_Screen_Buffer], DX
    
        .IF Gfx256 = 0 OR GfxDraw = 0
          .IF GigaScreen
            MOV  [EDI*4+2+MC_Screen_Buffer_Giga], DL
            //int 3
          .ENDIF
        .ENDIF
    
        // продолжаем цепочку бордюра
        MOV  DX, [&ZX].BorderColorNext
        MOV  [&ZX].BorderColor, DX
        AND  B[&ZX].BorderColorNxt2, $F
    
    
        .IF Gfx256 AND GfxDraw  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          // в режиме мультиколора с включенным Gfx надо
          // пересылать Gfx-данные, которых в 8 раз больше
          MOVSX EAX, W[EDI*2+MC_Screen_Table_Pixels]
          //ADD EAX, EAX
          SHL EAX, 3
          JS  SHORT @@_ULA_8pixels_stored&&
          ADD EAX, [GFXVidAddress] // откуда брать 8 байтов
          XCHG ESI, EAX
            XCHG EDI, [GfxVideoTarget]
            MOVSD
            MOVSD
            XCHG EDI, [GfxVideoTarget]
          XCHG ESI, EAX
          // теперь нужен еще атрибут, хотя и Gfx-режим
          // берем байт атрибутов
          MOVZX EAX, W[EDI*2+MC_Screen_Table_Attrs]
          DEC  EAX
          JZ   LONG @@_ULA_8pixels_stored&&
    
          ADD  EAX, [&ZX].VideoBaseAddr
          MOVZX EDX, B[EAX]
          MOV  DH, [&ZX].Flash
          MOV  AL, B[EDX+GfxAttrConvertTable]
    
          XCHG EDI, [ScreenAttrTarget]
          STOSB
          XCHG EDI, [ScreenAttrTarget]
    
        .ELSE Gfx256 = 0 OR GfxDraw = 0   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          // берем байт атрибутов
          MOVZX EAX, W[EDI*2+MC_Screen_Table_Attrs]
          DEC  EAX
          JZ   LONG @@_ULA_8pixels_stored&&
    
          // проверяем эффект "снег"
          CMP  B[&ZX].SnowEffect, 0
          JZ   SHORT @@_ULAload_data&&
    
          MOV  AL, B[&ZX].TactRCount
          AND  AL, $7F
          OR   AL, [&ZX].Reg_R_7
    
          ADD  EAX, [&ZX].VideoBaseAddr
          MOVZX EDX, B[EAX]
          MOV  DH, [&ZX].Flash
          MOV  DL, B[EDX+AttrConvertTable]
    
          // берем очередной байт 8 пикселов
          MOVZX EAX, W[EDI*2+MC_Screen_Table_Pixels]
    
          MOV  AL, B[&ZX].TactRCount
          AND  AL, $7F
          OR   AL, [&ZX].Reg_R_7
    
          ADD  EAX, [VideoBaseAddr]
          MOV  DH, B[EAX]
    
          MOV  W[EDI*4+MC_Screen_Buffer], DX
    
          JMP  SHORT @@_ULA_8pixels_stored&&
    
    @@_ULAload_data&&:
    
          ADD  EAX, [&ZX].VideoBaseAddr
          MOVZX EDX, B[EAX]
          MOV  DH, [&ZX].Flash
          MOV  DL, B[EDX+AttrConvertTable]
    
          // берем очередной байт 8 пикселов
          MOVZX EAX, W[EDI*2+MC_Screen_Table_Pixels]
          ADD  EAX, [&ZX].VideoBaseAddr
          MOV  DH, B[EAX]
    
          MOV  W[EDI*4+MC_Screen_Buffer], DX
    
          .IF GigaScreen // для GigaScreen, то же самое для альтернативного экрана:
              MOVZX EAX, W[EDI*2+MC_Screen_Table_Attrs]
              DEC  EAX
              JZ   SHORT @@_ULA_8pixels_stored&&
    
              ADD  EAX, [&ZX].AltVideoBaseAddr
              MOVZX EDX, B[EAX]
              MOV  DH, [&ZX].Flash
              MOV  DL, B[EDX+AttrConvertTable]
              // берем очередной байт 8 пикселов
              MOVZX EAX, W[EDI*2+MC_Screen_Table_Pixels]
              ADD  EAX, [&ZX].AltVideoBaseAddr
              MOV  DH, B[EAX]
    
              MOV  W[EDI*4+MC_Screen_Buffer_Giga], DX
          .ENDIF //GigaScreen
    
        .ENDIF //not Gfx256 ~~~~~~~~~~~~~~~~~~~~~~~~~
    
    @@_ULA_8pixels_stored&&:
        INC  EDI
        .IF RZX_play = 0
          CMP  EDI, BytesInFrame
          JB   LONG @@_ULAnext&&
    
          .IF AntiSlowDown
    //        CMP BX, $4000
    //        JAE @@ULA_AntiSlow_ScreenReady&&
    //        MC_VIDEO_SCREEN_READY
    //@@ULA_AntiSlow_ScreenReady&&:
          .ELSE
            MC_VIDEO_SCREEN_READY
          .ENDIF
    @@ULA_skipscreen&&:
    
          CMP  B[&ZX].StopOnEndOfFrame, 0
          JZ   SHORT @@_ULAnext&&
          MOV  D[&ZX].JumpPt, StopExec
        .ELSE
          CMP  EDI, BytesInFrame
          JB   SHORT @@_ULAnext&&
    
          DEC  EDI
        .ENDIF RZX_play = 0
    
    @@_ULAnext&&:
        DEC  ECX
        JG   @@_ULAout_loop&&
        //LOOP @@_ULAout_loop&&
    
    @@_ULAfin&&:
        POP  EAX
    
        XCHG EDI, [MC_Screen_Buffer_Pos] // EDI = TactCounter+256
    
    @@_ULA_end&&:
      .ELSE //not PrepareVideo
        LEA  ECX, [EDI-256]
        .IF UlaBuffer > 0
          ADD  ECX, UlaBuffer
        .ENDIF
    
        SUB  ECX, [ULA_TCounter0]
        JLE  LONG @@_ULAnovideo_end&&
        SHR  ECX, 2
        JZ   LONG @@_ULAnovideo_end&&
    
        MOV  EDX, ECX
        SHL  EDX, 2
        ADD  [ULA_TCounter0], EDX
    
        // CL = число байтов для "отображения" > 0
        XCHG EDI, [MC_Screen_Buffer_Pos]
        .IF "&Flag" = "YES"
          MOV  [&ZX].Reg_F, AH // если будет вызван FrameReady,
                               // то нужно текущее состояние Reg_F для TimeStamper-а
        .ENDIF
        PUSH EAX  //-------------------------------------\
    
        // цикл вывода байтов
    @@_ULAnovideo_out_loop&&:
    
        INC  EDI
        .IF RZX_play = 0
          CMP  EDI, BytesInFrame
          JB   SHORT @@_ULAnovideo_next&&
    
          .IF AntiSlowDown
    //        CMP EBX, $4000
    //        JAE @@ULA_AntiSlow_ScreenReady1_&&
    //        MC_VIDEO_SCREEN_READY
    //@@ULA_AntiSlow_ScreenReady1_&&:
          .ELSE
            MC_VIDEO_SCREEN_READY
          .ENDIF
    
          CMP  B[&ZX].StopOnEndOfFrame, 0
          JZ   SHORT @@_ULAnovideo_next&&
          MOV  D[&ZX].JumpPt, StopExec
        .ELSE
          CMP  EDI, BytesInFrame
          JB   SHORT @@_ULAnovideo_next&&
    
          DEC  EDI
        .ENDIF RZX_play = 0
    
    @@_ULAnovideo_next&&:
        DEC  ECX
        JG   @@_ULAnovideo_out_loop&&
        //LOOP @@_ULAnovideo_out_loop&&
    
        POP  EAX
    
        XCHG EDI, [MC_Screen_Buffer_Pos] // EDI = TactCounter+256
    
    @@_ULAnovideo_end&&:
      .ENDIF //PrepareVideo
    @@ULA_end_all&&:
      .ENDIF //MultiColor
      END  //ULA_unit
    продолжение следует...
    Последнюю версию EmuZWin (2.7) можно получить по этой ссылке, а "официальная" страница с описанием здесь. Если что-то не пашет, берите там же версии 2.6 или старше. [B]

  10. #9
    Master Аватар для Vladimir Kladov
    Регистрация
    09.02.2005
    Адрес
    Новосибирск
    Сообщений
    933
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    17
    Поблагодарили
    17 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию продолжение про ULA в EmuZWin

    макросы, продолжение:

    Код:
    //******************************************************************************
    Delay MACRO Time, Mem, Temp=D
      .IF MultiColor
        .IF AntiSlowDown
          CMP EDI, 71690
          JB  @@Delay1_&&
          .IF &Time > 1
            ADD EDI, &Time
          .ELSEIF &Time = 1
            INC EDI
          .ENDIF
          JMP SHORT @@DelayEnd&&
    @@Delay1_&&:
        .ENDIF
        .IF NoDelay = 0
          MOVZX E&Temp.X, &Mem.H
          MOV &Temp.H, [&ZX].CurRAMBank
          MOVZX E&Temp.X, B[E&Temp.X+MC_Contended_Mem_Table]
          ADD EDI, D[EDI*8+E&Temp.X+MC_Contended_Delay_Table]
          .IF &Time > 2
            ADD EDI, &Time-1
          .ELSEIF &Time = 2
            INC EDI
          .ENDIF
        .ELSE NoDelay
          .IF &Time > 1
            ADD EDI, &Time
          .ELSEIF &Time = 1
            INC EDI
          .ENDIF
        .ENDIF
        .IF AntiSlowDown
    @@DelayEnd&&:
        .ENDIF
      .ENDIF
      END   //MACRO Delay
    
    //******************************************************************************
    DelayMore MACRO Time=1, Temp=D, Count=1
      .IF MultiColor
        .IF AntiSlowDown
          CMP EDI, 71690
          JB  @@DelayMore1_&&
          .IF &Time * &Count > 1
            ADD EDI, &Time * &Count
          .ELSEIF &Time * &Count = 1
            INC EDI
          .ENDIF
          JMP SHORT @@DelayMoreEnd&&
    @@DelayMore1_&&:
        .ENDIF
        .IF NoDelay = 0
          .REPEAT &Count
            ADD EDI, D[EDI*8+E&Temp.X+MC_Contended_Delay_Table]
            .IF &Time > 2
              ADD EDI, &Time-1
            .ELSEIF &Time = 2
              INC EDI
            .ENDIF
          .ENDREP
        .ELSE NoDelay
          .IF &Time * &Count > 1
            ADD EDI, &Time * &Count
          .ELSEIF &Time * &Count = 1
            INC EDI
          .ENDIF
        .ENDIF
        .IF AntiSlowDown
    @@DelayMoreEnd&&:
        .ENDIF
      .ENDIF
      END //MACRO DelayMore
    
    //******************************************************************************
    outDelay MACRO Port, Temp=D, io=
      .IF MultiColor
        .IF NoDelay = 0
          .IF "&io" = ""
            //--------------
            MOVZX EDX, &Port.H
            MOV &Temp.H, [&ZX].CurRAMBank
            MOVZX E&Temp.X, B[E&Temp.X+MC_Contended_Mem_Table]
            TEST &Port.L, 1
            JZ   SHORT @@_outFE&&
                // N:4 or C:1 C:1 C:1 C:1
            XOR &Temp.L, 4
            JNZ SHORT @@_outN4&&
    
            .IF AntiSlowDown
              CMP EDI, 71690
              JB  @@outDelay1_&&
              ADD EDI, 4
              JMP SHORT @@_outN4&&
    @@outDelay1_&&:
            .ENDIF
            ADD EDI, D[EDI*8+4+MC_Contended_Delay_Table]
            ADD EDI, D[EDI*8+4+MC_Contended_Delay_Table]
            ADD EDI, D[EDI*8+4+MC_Contended_Delay_Table]
            ADD EDI, D[EDI*8+4+MC_Contended_Delay_Table]
    
    @@_outN4&&:
            ADD EDI, E&Temp.X
            JMP SHORT @@_end_out_contention&&
    
    @@_outFE&&:
            xor &Temp.L, 4
            JNZ SHORT @@_outN1C3_&&
            .IF AntiSlowDown
              CMP EDI, 71690
              JAE @@_outN1C3_&&
            .ENDIF
            ADD EDI, D[EDI*8+4+MC_Contended_Delay_Table]
            DEC EDI
    @@_outN1C3_&&:
            INC EDI
            .IF AntiSlowDown
              CMP EDI, 71690
              JB  @@outDelay3_&&
              ADD EDI, 3
              JMP SHORT @@_end_out_contention&&
    @@outDelay3_&&:
            .ENDIF
            ADD EDI, D[EDI*8+4+MC_Contended_Delay_Table]
            ADD EDI, 3-1
    @@_end_out_contention&&:
            //--------------
          .ELSE
            //--------------
            .IF AntiSlowDown
              CMP EDI, 71690
              JAE @@outDelay5&&
            .ENDIF
            MOVZX E&Temp.X, &Port.H
            MOV &Temp.H, [&ZX].CurRAMBank
            MOVZX E&Temp.X, B[E&Temp.X+MC_Contended_Mem_Table]
            TEST &Port.L, 1
            JNZ SHORT @@outDelay4&&
            MOV &Temp.L, 4
    @@outDelay4&&:
            ADD EDI, D[EDI*8+E&Temp.X+MC_Contended_Delay_Table]
            ADD EDI, &io-1
    @@outDelay5&&:
            //--------------
          .ENDIF
        .ELSE NoDelay
          .IF "&io" = ""
            ADD EDI, 4
          .ELSEIF &io > 1
            ADD EDI, &io
          .ELSEIF &io = 1
            INC EDI
          .ENDIF
        .ENDIF
      .ENDIF //MultiColor
      END //MACRO outDelay
    
    //******************************************************************************
    inDelay MACRO Port, Temp=D
      .IF MultiColor <> 0
        .IF NoDelay = 0
          MOVZX E&Temp.X, &Port.H
          MOV &Temp.H, [&ZX].CurRAMBank
          MOVZX E&Temp.X, B[E&Temp.X+MC_Contended_Mem_Table]
          TEST &Port.L, 1
          JZ  SHORT @@_inFE&&
               // bit 0 of port addr set - N:4 or C:1 C:1 C:1 C:1
          XOR &Temp.L, 4
          JNZ SHORT @@_inN4&&
    
          .IF AntiSlowDown
          CMP EDI, 71690
          JB  @@inDelay1_&&
          ADD EDI, 4
          JMP SHORT @@_inN4&&
    @@inDelay1_&&:
          .ENDIF
          ADD EDI, D[EDI*8+4+MC_Contended_Delay_Table]
          ADD EDI, D[EDI*8+4+MC_Contended_Delay_Table]
          ADD EDI, D[EDI*8+4+MC_Contended_Delay_Table]
          ADD EDI, D[EDI*8+4+MC_Contended_Delay_Table]
    @@_inN4&&:
          ADD EDI, E&Temp.X
          JMP SHORT @@_end_in_contention&&
    
    @@_inFE&&:
          .IF AntiSlowDown
            CMP EDI, 71690
            JAE @@_end_in_contention&&
          .ENDIF
          XOR &Temp.L, 4
          JnZ SHORT @@_inN1C3_&&
          ADD EDI, D[EDI*8+4+MC_Contended_Delay_Table]
          DEC EDI
    @@_inN1C3_&&:
          INC EDI
          ADD EDI, D[EDI*8+4+MC_Contended_Delay_Table]
          ADD EDI, 3-1
    @@_end_in_contention&&:
        .ELSE NoDelay
          ADD EDI, 4
        .ENDIF
      .ENDIF //MultiColor
      //--------------
      END //MACRO inDelay
    
    //******************************************************************************
    
    ioDelay MACRO Port, Temp
        .IF MultiColor
          .IF NoDelay = 0
            .IF AntiSlowDown
              CMP EDI, 71690
              JAE @@ioDelayEnd&&
            .ENDIF
            MOVZX E&Temp.X, &Port.H
            MOV &Temp.H, [&ZX].CurRAMBank
            MOVZX E&Temp.X, B[E&Temp.X+MC_Contended_Mem_Table]
            TEST &Port.L, 1
            JNZ SHORT @@ioDelay1_&&
            MOV &Temp.L, 4
    @@ioDelay1_&&:
            ADD EDI, D[EDI*8+ECX+MC_Contended_Delay_Table]
            .IF AntiSlowDown
    @@ioDelayEnd&&:
            .ENDIF
          .ELSE NoDelay
            //ADD EDI, 4
          .ENDIF
    
        .ENDIF
        END //MACRO ioDelay
    и еще чуть-чуть...
    Последнюю версию EmuZWin (2.7) можно получить по этой ссылке, а "официальная" страница с описанием здесь. Если что-то не пашет, берите там же версии 2.6 или старше. [B]

  11. #10
    Master Аватар для Vladimir Kladov
    Регистрация
    09.02.2005
    Адрес
    Новосибирск
    Сообщений
    933
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    17
    Поблагодарили
    17 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию ULA в EMUZWin, продолжение. Часть 3

    А вот это - реализация команд LDI/LDIR/LDD/LDDR. Разберитесь, если есть желание.

    Код:
    @@_ld&direction.r:  // LDIR, LDDR
      .IF (FastLDIR <> 0) and ("&LDIRHL" <> "")
        CMP B[&ZX].DebuggerVisible, 0
        JNZ @@_ld&direction.r_usual
    
        MOVZX ECX, W[&ZX].Regs.Reg_BC
        DEC ECX
        JZ  @@_ld&direction.r_usual
        MOVZX EDX, W[&ZX].Regs.Reg_DE
        MOV ECX, EBX
        DEC CX
        CMP CX, DX
        JZ  @@_ld&direction.r_usual
        .if MemPtrNew
            MOV [&ZX].reg_Hidden, CH
        .endif
        DEC CX
        CMP CX, DX
        JZ  @@_ld&direction.r_usual
        MOV EBX, ECX
        PUSH EAX
        .IF "&LDIRHL" = "BX"
          PUSH EBX
        .ENDIF
        MOVZX &ELDIRHL, W[&ZX].Regs.Reg_HL
        .IF GeneralSnd
          ADD D[&ZX].TStatesToExecute, 16
        .ENDIF
        .IF MultiColor
          MOV [&ZX].TempFlip, EDI
          ADD D[&ZX].TempFlip, 256
        .ENDIF
        JMP SHORT @@_ld&direction.r_fast_next
    
    @@_ld&direction.r_fast_loop:
        .IF RZX_play
          ADD D[&ZX].NumFetches, 2
        .ELSEIF GeneralSnd
          INC D[&ZX].NumFetches
        .ENDIF
    
        .IF MultiColor
          ADD B[&ZX].TactRCount, 2
          .IF NoDelay
            ADD EDI, 8
          .ELSEIF "&LDIRHL" = "BX"
            POP  EAX
            PUSH EAX
            Delay Time=4, Mem=A, Temp=C
            INC AX
            Delay Time=4, Mem=A, Temp=C
          .ELSE
            Delay Time=4, Mem=B, Temp=C
            INC BX
            Delay Time=4, Mem=B, Temp=C
            DEC BX
          .ENDIF
        .ELSEIF MultiColor = 0
          ADD D[&ZX].TactRCount, $100002
          AND W[&ZX].TactRCount, $7F
        .ENDIF
    
    @@_ld&direction.r_fast_next:
        .IF "&LDIRHL" = "BX"
          Delay Time=3, Mem=B, Temp=C
          GetMem1 Dest=AL, Addr=B, Temp=C, Gfx=mm0
        .ELSE
          MOV EAX, &ELDIRHL
          Delay Time=3, Mem=A, Temp=C
          GetMem1 Dest=AL, Addr=A, Temp=C, Gfx=mm0
        .ENDIF
        .IF Plus3 or NoDelay
          Delay Time=5, Mem=D, Temp=C  // задержка DE wr:5
        .ELSE
          Delay Time=3, Mem=D, Temp=C  // задержка DE wr:3
          DelayMore Temp=C, Count=2
        .ENDIF
        PutMem Addr=D, Reg=AL, Temp=C, Gfx=mm0
        DEC W[&ZX].Regs.Reg_BC
        JZ  @@_ld&direction.r_fast_end_incRegs
    
        .IF "&direction" = "i"
          INC DX
          INC &LDIRHL
          .IF "&LDIRHL" = "BX"
            CMP DX, [ESP]
          .ELSE
            AND &ELDIRHL, $FFFF
            CMP DX, BX
          .ENDIF
          JZ  SHORT @@_ld&direction.r_fast_fin
          .IF MultiColor
            CMP EDI, 60000
            JGE SHORT @@_ld&direction.r_fast_fin
          .ENDIF
        .ELSE
          DEC DX
          DEC &LDIRHL
          DEC DX
          .IF "&LDIRHL" = "BX"
            CMP DX, [ESP]
          .ELSE
            AND &ELDIRHL, $FFFF
            CMP DX, BX
          .ENDIF
          JZ  SHORT @@_ld&direction.r_fast_fin_INCDX
          .IF MultiColor
            CMP EDI, 60000
            JGE SHORT @@_ld&direction.r_fast_fin_INCDX
          .ENDIF
          INC DX
        .ENDIF
    
        .IF MultiColor = 0
          ADD W[&ZX].TactRCount + 2, 5
          JS  SHORT @@_ld&direction.r_fast_fin
        .ELSE
          .IF Plus3 or NoDelay
            Delay Time=5, Mem=D, Temp=C  // дополнительно 5 задержек DE:1
          .ELSE
            Delay Time=1, Mem=D, Temp=C  // дополнительно 5 задержек DE:1
            DelayMore Temp=C, Count=4
          .ENDIF
        .ENDIF
    
        .IF GeneralSnd
          SUB [&ZX].TStatesToExecute, 21
          CMP [&ZX].TStatesToExecute, 21
          JG  @@_ld&direction.r_fast_loop
          MOV ECX, [&ZX].NumFetches
          CMP ECX, [&ZX].MaxFetches
          JGE  @@_ld&direction.r_fast_fin
        .ELSEIF RZX_play
          MOV ECX, [&ZX].NumFetches
          CMP ECX, [&ZX].MaxFetches
          JGE  @@_ld&direction.r_fast_fin
          .IF MultiColor
            CMP  B[EDI+MC_IntSignal_Table], 0
            JNZ  SHORT @@_ld&direction.r_fast_fin
          .ENDIF
        .ELSE
          .IF MultiColor
            CMP  B[EDI+MC_IntSignal_Table], 0
            JNZ  SHORT @@_ld&direction.r_fast_fin
            CMP  EDI, [&ZX].TempFlip
            JGE  SHORT @@_ld&direction.r_fast_fin
          .ELSE
          .ENDIF
        .ENDIF
        JMP LONG @@_ld&direction.r_fast_loop
    
    @@_ld&direction.r_fast_fin_INCDX:
        INC DX
    @@_ld&direction.r_fast_fin: // завершаем цикл быстрого LDIR по разным причинам,
                                // кроме исчерпания Reg_BC
        MOV ECX, &ELDIRHL
        MOV [&ZX].Regs.Reg_HL, CX
        MOV [&ZX].Regs.Reg_DE, DX
        .IF "&LDIRHL" = "BX"
          POP EBX
        .ENDIF
        POP  ECX
        MOV  AH, CH
    
        ADD  AL, [&ZX].Reg_A         // !!! формируем флажки X и Y !!!
        .IF LDIR_BY_TABLE
          AND  EAX, $FFFF
          MOV  AX, W[EAX*2+Table_LDIR1]
        .ELSE
          // !!! формируем флажки X и Y !!!
          MOV  CL, AL
          AND  CL, 2
          SAL  CL, 4
          AND  AL, $F
          OR   AL, CL              //-------------------------------
          AND  AH, not flag_H
        .ENDIF
        OR   AH, flag_N or flag_P
        NextInstr
    
    @@_ld&direction.r_fast_end_incRegs: // завершение быстрого LDIR по исчерпании Reg_BC
        .IF "&direction" = "i"
          INC DX
          INC &LDIRHL
        .ELSE
          DEC DX
          DEC &LDIRHL
        .ENDIF
    
    @@_ld&direction.r_fast_end: // завершение быстрого LDIR по исчерпании Reg_BC
        .IF GeneralSnd
          ADD D[&ZX].TStatesToExecute, 5
        .ENDIF
        MOV ECX, &ELDIRHL
        MOV [&ZX].Regs.Reg_HL, CX
        MOV [&ZX].Regs.Reg_DE, DX
        .IF "&LDIRHL" = "BX"
          POP EBX
        .ENDIF
        POP  ECX
        MOV  AH, CH
    
        ADD  AL, [&ZX].Reg_A         // !!! формируем флажки X и Y !!!
        .IF LDIR_BY_TABLE
          AND  EAX, $FFFF
          MOV  AX, W[EAX*2+Table_LDIR1]
        .ELSE
          // !!! формируем флажки X и Y !!!
          MOV  CL, AL
          AND  CL, 2
          SAL  CL, 4
          AND  AL, $F
          OR   AL, CL              //-------------------------------
          AND  AH, not (flag_P or flag_H)
        .ENDIF
        OR   AH, flag_N
        INC  BX
        INC  BX
        NextInstr
    
      .ENDIF
    
    @@_ld&direction.r_usual:
      INC_TactRCount Value=5, ReturnTStates=16, ReturnPC=2, ReturnR=2, ReturnFetches=1
      MOVZX ECX, W[&ZX].Regs.reg_HL
      Delay Time=3, Mem=C  // задержка HL:3
      GetMem1 Dest=AL, Addr=C, Gfx=mm0
      MOVZX ECX, W[&ZX].Regs.reg_DE
      .IF Plus3 or NoDelay
        Delay Time=5, Mem=C  // задержка DE wr:5
      .ELSE
        Delay Time=3, Mem=C  // задержка DE wr:3
        DelayMore Count=2
      .ENDIF
      PutMem Addr=C, Reg=AL, Gfx=mm0
      ADD  AL, [&ZX].Reg_A         // !!! формируем флажки X и Y !!!
      .IF LDIR_BY_TABLE
        AND  EAX, $FFFF
        MOV  AX, W[EAX*2+Table_LDIR1]
      .ELSE
        // !!! формируем флажки X и Y !!!
        MOV  CL, AL
        AND  CL, 2
        SAL  CL, 4
        AND  AL, $F
        OR   AL, CL              //-------------------------------
        AND  AH, not (flag_P or flag_H)
        OR   AH, flag_N
      .ENDIF
      MOVZX EDX, W[&ZX].Regs.reg_DE
      .IF "&direction" = "i"
        INC  W[&ZX].Regs.reg_HL
        INC  W[&ZX].Regs.reg_DE
      .ELSE
        DEC  W[&ZX].Regs.reg_HL
        DEC  W[&ZX].Regs.reg_DE
      .ENDIF
      DEC  W[&ZX].Regs.reg_BC
      JZ   SHORT @@ld&direction.r_exit
      .IF Plus3 or NoDelay
        Delay Time=5, Mem=D  // дополнительно 5 задержек DE:1
      .ELSE
        Delay Time=1, Mem=D  // дополнительно 5 задержек DE:1
        DelayMore Count=4
      .ENDIF
      OR   AH, flag_P
      DEC  BX
      .if MemPtrNew
           MOV [&ZX].reg_Hidden, BH
      .endif
      DEC  BX
    @@ld&direction.r_exit:
      NextInstr
    .ENDFOR //direction
    я жебил, я не шерхан, хавал жёваны штаны...
    Последний раз редактировалось Vladimir Kladov; 19.01.2007 в 19:09.
    Последнюю версию EmuZWin (2.7) можно получить по этой ссылке, а "официальная" страница с описанием здесь. Если что-то не пашет, берите там же версии 2.6 или старше. [B]

Страница 1 из 2 12 ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. либа для эмуляции z80, v0.1
    от boo_boo в разделе Эмуляторы
    Ответов: 27
    Последнее: 24.08.2010, 22:37
  2. мысли по написанию модуля эмуляции z80 на С
    от boo_boo в разделе Эмуляторы
    Ответов: 9
    Последнее: 24.01.2006, 19:28

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •