SAS Emulator (эмулятор «ПК-01 Львов»)

...
  • P.S. онлайн антивирус https://www.virustotal.com , опять чего-то там жалуется на наличие вирусов в "SASEmulator for Windows.7z". Ну уж незнаю! Установленый на компьютере Avast, - не жалуется!
  • P.S. забыл написать: архив "SASEmulator for Windows.7z" [3.26 МБ] с играми в комплекте, точнее говоря прямо в эмуляторе.
  • Image
    Image
  • Image
    Image
  • Image
    Image
  • Rick1
    Image
    Image
  • Image
    Image
  • ALEXS1983 wrote:Понимая это я поступил следующим образом: Почему бы не написать эмулятор который будет уже со встроенной в него игрой (программой)?!... а создавать такие «кос-екзешники» можно будет с помощью доработанного эмулятора который для Windows.
    Получается, что с каждой игрой, будет дублироваться эмулятор. Как-то расточительно, помоему. Эмулятор наверно больше весит, чем один файл с игрой? :?
    А почему бы, не отдельно эмулятор? А игры, можно было бы, загружать в эмулятор, через ассоциации в assoc.ini, при помощи файлового менеджера. :roll:
    ALEXS1983 wrote:ВВЕРХ — “P” (scancode: 25/153)
    ВЛЕВО — “L” (scancode: 38/166)
    ВНИЗ — “;” (scancode: 39/167)
    ВПРАВО — “'” (scancode: 40/168)
    :shock: Как по мне - так стрелочки, были бы удобнее. Но, пишущему виднее.

    P.S. Не плохо бы расширение .bin, из файлов убрать. А то неудобно, переименовывать каждый файл, перед началом игры. :?
    P.P.S.А ещё, 100% загрузка ЦПУ игрой, напрягает! :?
    P.P.P.S. Эх, жаль масштабирования нет! А так, не плохо. :)
  • Yason wrote:Получается, что с каждой игрой, будет дублироваться эмулятор. Как-то расточительно, помоему. Эмулятор наверно больше весит, чем один файл с игрой? :?
    Ну сейчас приблизительно подсчитаем: запускной файл в целом 377600 байт, если убрать массивы, которые могут быть созданы во время запуска (может выделяться им память), то можно вычесть из операривки-эмуля 48000 Байт,(остальное биос 16000Байт всё равно должен оставаться), можно еще вычесть видеопямять 16000 байт, можно вычистить «черновую» (предыдущего кадра) видеопамять 16000 байт которая тоже может выделятся при запуске, ну там, порты - 256 байт, флаги - 256 байт........
    О-о-о-о-о! Тут на остальном можно и не заморачиваться, сама картинка для вывода на экран содержится в файле и её масив занимает 262144 байт.
    Ну вот теперь подсчитаем:
    если сделать, что картинке будет выделяться память во время запуска то размер запускного станет, 377600- 262144 = 115456 байт вот это по существу! Ну остальное если отминусовать то 115456 — 48000 - 16000 - 16000 — 256 — 256 = 34935 — получается что это мог бы занимать сам код с биосом (16000 байт) (но без игры), если вычесть биос (для интереса) то сам код исполнительный код («в чистую») приблизительно равен 18935.
    Сама игра со «всеми патрохами» (и с биосом) занимает 65536(RAM и ROM) +16384(VIDEO картинка изначальная, иногда можно обойтись)+256(порты)+256(флаги)+(ну 100 байт на регистры и прочее)= ну скажем 82532.

    А вот теперь объясню очень существенные вещи.
    Ассемблер я как таково не знаю. Точнее говоря знаю поверхностно. А про функции КОС я вообще молчу. Если ты, Yason, готов предоставить мне готовую часть кода которая будет выделять и освобождать массив...

    Code: Select all

    ; размеры области для рисования
    CanvasWidth = 256*1
    CanvasHeight = 256*1
    ImageData rd (CanvasWidth * CanvasHeight) ; сюда рисовать перед выводом на экран
    
    а также код со способом доступа к тому массиву, который сейчас вот такой:

    Code: Select all

       PutPixel_x: rd 1
       PutPixel_y rd 1
       PutPixel_color rd 1
    PutPixel:
        mov eax, [PutPixel_x]
        mov ebx ,[PutPixel_y]
        mov ecx ,[PutPixel_color]
        imul ebx, CanvasWidth * 4
        mov [ImageData+eax*4+ebx], ecx
        ret
    
    То я готов его переделать, чтобы освободить 262144 из запускного файла.
    Об остальном позже. :-)
  • Продолжение.
    Yason wrote:А почему бы, не отдельно эмулятор? А игры, можно было бы, загружать в эмулятор, через ассоциации в assoc.ini, при помощи файлового менеджера. :roll:
    1.Как я уже говорил, - я новичок в программировании для КОС и не знаю как это делать! Yason, ты готов помогать кусками готового кода ? :-)
    2. Считаю, (может быть по себе любимому :-) ), что люди не любят «заморачиваться» на «прибамбацах» эмуляторов, - Файл/отркыть/закрыть и т. д. И вот решил пойти таким путём, который в сочетании с моими «нулевыми» знаниями о том, как создавать меню в форме «файл\открыть\закрыть и т.д», как загружать, сохранять файл и т. д. можно написать эмулятор со встроенной игрой, без всяких «прибамбацов», а генерировать это будет «SASEmulator for Windows.7z». Если ты его (SASEmulator for Windows.7z) рассматривал, то мысленно можешь представить, что, - выбрал игрушку, даже выбрал момент с которого можно сохранить в запускной-КОС-файл, жмёшь «Generate for KOS” (или что-то подобное, “save for KOS”, оно еще пока не реализовано). И вуа-ля! Готовый кос-«ексзешник»»! Причём, что хорошо, что всё в единственном файле(!), “носись с ним” как “дурень со ступой” :-) по каталогам как с готовым и единственным файлом в котором «всё при нём»! :-)
    Также планируется тот генератор сделать с настройками быстродействия, «легкой» калибровкой цветов, и калибровкой клавиатуры и т. д.
    3.Ты и впрям думаешь, что для КОС это творение нужно в виде эмулятора ?!... рассмотри игрушки в SASEmulator for Windows.7z, задай себе вопрос,- какое количество ты хотел бы, чтобы они были под КОС ?!... думаю, 2 или 3 или 5, да пусть даже и 10. Ну вот, сгенерировал бы нужные игры под КОС и вуа-ля, «забрасывай» SASEmulator for Windows.7z в архив или «на мусорку», играй только в те, что выбрал, со временем и те поудаляешь при необходимости.
    Продолжение следует. :-)
  • Yason wrote: :shock: Как по мне - так стрелочки, были бы удобнее. Но, пишущему виднее.

    Ответ всё тот же: я не знаю как это делать! Но этим я конечно займусь в первую очередь.
    Вот смотри код:

    (
    Пояснение к коду.
    В начале программы переключаю в сканкоды, вот так вот call KeyBoardInit.
    Далее.
    Стандартный обработчик событий взятый из EXAMPLE.ASM (входящий в дистибутив), запускет процедуру KeyProcess (см. код ниже)
    вот так вот:
    key: ; нажата клавиша на клавиатуре
    call KeyProcess
    Далее смотри по коду той процедуры, (на call kbdA не обращай внимание то в данный момент не существенно).
    В общем всё завязано на процедуру readmask2 рассмотри её внимательно.
    Мне нужен код(!), реализации хотя бы одной клавиши, чтобы самому целую неделю или даже месяц с этим не мудохаться!
    Как видишь по процедуре readmask2 на выходе (readmask_Result) должна появляться соответственная маска клавиши. Разница между нажатой и отжатой, как видишь только в запусках процедур call kbdA с передачей параметра для [kbd_press],единицы или нуля. А маска(результат) readmask_Result при нажатой и отжатой одной и той же клвиши должна быть одинаковая....
    короче говоря, :-) как манипулировать с этим доп. кодами (двойными кодами?! Или как там их правильно?!... если код=224 повторно опрашивать клаву?!... Или пропускать 224 ?!... где он в каких битах или байтах этот признак (224) дополнительной клавиши, фигурирует?!... и т.д.
    Ну вообщем программу готовую видел ?! Код выложенный внизу видишь ?! :-)
    Нужен готовый код (часть кода) в реализации хотябы одной клавиши из дополнительных!

    )
    Spoiler:

    Code: Select all

    ;======================================
    KeyBoardInit:
    mov eax,66
    mov ebx,1
    mov ecx,1 ;     * 0 = обычный (ASCII-символы)    * 1 = сканкоды
    int 0x40
    ret
    ;======================================
    
    
    readmask_keynum rd 1
    readmask_Result rd 1
    
    readmask2:
     mov [readmask_Result],$000072ff
    ;//ПРОБЕЛ
       cmp dword [readmask_keynum],57
                 jnz readmask2_m1
     mov [readmask_Result],$000030ff
                   ret
    ;//ВЛЕВО;
    readmask2_m1: cmp dword [readmask_keynum],38
                 jnz readmask2_m2
     mov [readmask_Result],$0000ff32
                   ret 
    ;//{ВВЕРХ}
    readmask2_m2:  cmp dword [readmask_keynum],25
                 jnz readmask2_m3
     mov [readmask_Result],$0000ff31
                   ret ;
    ;//ВПРАВО;
    readmask2_m3:  cmp dword [readmask_keynum],40
                 jnz readmask2_m4
     mov [readmask_Result],$0000ff30
                   ret ;
    ;//ВНИЗ;
    
    readmask2_m4: cmp dword [readmask_keynum],39
                  jnz readmask2_m5
     mov [readmask_Result],$0000ff33
    
     ;//ENTER;
    readmask2_m5: cmp dword [readmask_keynum],28
                  jnz  readmask2_ret
     mov [readmask_Result],$000013FF
    
     readmask2_ret:     ret
    
    KeyDownUD:
           call readmask2
           mov eax,[readmask_Result]
           mov [kbd_mask],eax
                 ret
    
    
    KeyProcess:
    mov eax,2
    int 0x40
        shr  eax,8                   ; scancode
        and  eax,0xff
        cmp  eax,128
        jb   KeyProcess_m1   
                
    ;; если 'UP'
       sub eax,128
    mov [readmask_keynum],eax
      call KeyDownUD
     mov [kbd_press],0
         call kbdA     
           ret
           
    ;; если 'DOWN'       
    KeyProcess_m1:
    mov [readmask_keynum],eax  
    call KeyDownUD
    mov [kbd_press],1    
         call kbdA     
           ret
    
    Ну в дельфи это всё вообще выглядит просто, может быть так понятней будет:
    Spoiler:

    Code: Select all

    procedure kbdA;
    begin
    ......
    ЭТА ПРОЦЕДУРА НЕ ПО СУЩЕСТВУ В ДАННОМ МОМЕНТЕ!
    выкладывать её не буду!
    ......
    end;
    
    Procedure readmask2D; // маска клавы
    begin
    readmask_Result:= $72FF;
    if readmask_keynum = 32 then  begin readmask_Result:= $30FF end else 
    if readmask_keynum = 37 then begin readmask_Result:= $FF32 end else 
    if readmask_keynum = 38 then  begin readmask_Result:= $FF31 end else
    if readmask_keynum = 39 then begin readmask_Result:= $FF30 end else 
    if readmask_keynum = 40 then begin readmask_Result:= $FF33 end; 
    end;
    
    procedure KeyDownUD;
    begin
    readmask2D;
    kbd_mask:=readmask_Result;
    end;
    
    procedure KeyDown1;
    begin
    KeyDownUD;
    kbd_press:=1;
    kbdA; // нажали
    end;
    
    
    procedure KeyUp1;
    begin
    KeyDownUD;
    kbd_press:=0;
    kbdA; // отжали
    end;
    
    procedure TMainForm.FormKeyDown(Sender: TObject; var Key: Word; //опрос клавы
     Shift: TShiftState);
    begin
     readmask_keynum:=key; KeyDown1;
    end;
    
    procedure TMainForm.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
    begin
       readmask_keynum:=key;   KeyUp1;
    end;
    
    Вопрос в том: КАК ИЗНАЧАЛЬНО ОПОЗНАТЬ ДОП КЛАВИШИ И ИСПОЛЬЗОВАТЬ ИХ ПОДТОЧИВ ПОД ЭТО ВСЁ?
    Часть кода внедренное в это попросить можно ? хотя бы реализацию одной клавиши, по которой можно будет понять как сделать такое с остальными.
  • ALEXS1983 wrote:Если ты, Yason, готов предоставить мне готовую часть кода которая будет выделять и освобождать массив...
    Вот, набросал на скорую руку. Не проверял. Но должно работать.
    Update: Новый "memory.inc", лежит тут.
    Last edited by Yason on Fri Mar 25, 2016 12:41 pm, edited 3 times in total.
  • Yason wrote:
    ALEXS1983 wrote:Если ты, Yason, готов предоставить мне готовую часть кода которая будет выделять и освобождать массив...
    Вот, набросал на скорую руку. Не проверял. Но должно работать.
    СПАСИБО РАССМОТРЮ!
  • Yason wrote: P.P.S.А ещё, 100% загрузка ЦПУ игрой, напрягает! :?
    «Пожирание» ресурсов.
    Происходит оно не от того что код неоптимизирован а скорее всего из-за того что в обработчике событий который стандартный, но «подточенный» под эмуль вместо mcall 10 ; функция 10 - ждать события, установлена функция Функция 11 - проверить, есть ли событие, без ожидания. (см.код основного модуля внизу). И даже если сам блок цикла
    начиная от:

    Code: Select all

    CycleProgram: ; метка цикла программы:
    call CycleProcesEvents ;  ЦИКЛ ОБРАБОТКИ СОБЫТИЙ
    
    сделать пустым до:

    Code: Select all

    cmp byte [@FLagExit],0
    jz CycleProgram ;
       mov EAX, -1            ; иначе конец программы
    jmp CycleProgram
     
    I_END:                             ; метка конца программы
    
    Пожирание рессурсов всё равно не прекратится! Поэтому не надо пинять на говнокод! Этот же код в винде, «крутится» «на ура!», без пожирания ресурсов!
    Downloaded 349 times
    Нужна процедура отдающая ресурсы процессору в свободное время которую нужно вставить после «main_m2:», и соответственно перед «main_m2:» нужно будет поставить jmp CycleProgram или что-то в этом роде.
    Spoiler:

    Code: Select all

    use32              ; включить 32-битный режим ассемблера
    org    0x0         ; адресация с нуля
    db     'MENUET01'  ; 8-байтный идентификатор MenuetOS
    dd     0x01        ; версия заголовка (всегда 1)
    dd     START       ; адрес первой команды
    dd     I_END       ; размер программы
    dd     0x60000      ; количество памяти
    dd     0x60000      ; адрес вершины стэка
    dd     0x0         ; адрес буфера для параметров
    dd     0x0         ; зарезервировано
    
            include 'uLVComp.asm'
            include 'uKeyBoard.asm'
            include 'uMem.asm'
            include 'uDrawScreen.asm'
            include 'ui8080.asm'
    ;        include 'scancodeLV.asm'
    titleE:      db   'Games in SAS emulator 1.0 beta',0
    opcodes_to_run: dd 68500;
            
    @FLagExit: rd  1; // флаг выхода из программы (заглушка для выхода)
    macro INT0x40 { int 0x40 }
    CycleProcesEvents: ;  ЦИКЛ ОБРАБОТКИ СОБЫТИЙ
    Mov eax, 11 ;Функция 11 - проверить, есть ли событие, без ожидания. =======
    INT0x40
    cmp  eax,0
    je CycleProcesEvents_ret
    
        cmp  eax,1          ; перерисовать окно ?
        je  DrawWindow     ; перерисовать окно
        cmp  eax,2          ; нажата клавиша ?
        je   key            ; если да - на key
        cmp  eax,3          ; нажата кнопка ?
        je   button         ; если да - на button
    CycleProcesEvents_ret:    ret
    ;---  ОПРЕДЕЛЕНИЕ И ОТРИСОВКА ОКНА  ----------------------------------
    DrawWindow:
    mov EAX, 12
    mov EBX, 1
    INT0x40; 
    
     mov EAX, 0
     mov EBX, (10*65536+257+10)
     mov ECX, (10*65536+270+10)
     mov EDX, 0x34000000
     mov  edi, titleE
    
    INT0x40;  
    
    mov EAX, 12
    mov EBX, 2
    INT0x40;   
      
    jmp CycleProcesEvents                ; выходим из процедуры
    ;---------------------------------------------------------------------
    key:                  ; нажата клавиша на клавиатуре
    call KeyProcess
    jmp CycleProcesEvents
    ;---------------------------------------------------------------------
      button:
      mov EAX, 17 ;    mcall 17            ; 17 - получить идентификатор нажатой кнопки
      INT0x40;
    
        cmp   ah, 1         ; если НЕ нажата кнопка с номером 1,
        jne   CycleProcesEvents         ;  вернуться
     .exit:
      Mov EAX, -1 ;   mcall -1            ; иначе конец программы
      INT0x40;
    ;---------------------------------------------------------------------
    CountTime_result rd 1
    CountTime:
    mov eax,26
    mov ebx,9
    int 0x40
    mov [CountTime_result],eax ;= число сотых долей секунды, прошедших с момента
    ret    
     
     TimeT rd 1
     PlatoonTimer: ; взвод таймера (для блока комманд) 
    Call CountTime
    mov eax,[CountTime_result]
    add eax,2
    mov [TimeT],eax
    ret
    
    START:
    mov dword [@FLagExit],0
    call uVIDEOinit
    call init_table_in_case_opcode
    call KeyBoardInit
    
     call PlatoonTimer
    
    CycleProgram: ; метка цикла программы:
    call CycleProcesEvents ;  ЦИКЛ ОБРАБОТКИ СОБЫТИЙ
    
    main_m1:
    Call CountTime
    mov eax,[CountTime_result]
    Cmp eax, [TimeT]
    jb main_m2
       call PlatoonTimer ; взвод таймера
     
           mov eax,[opcodes_to_run]
           mov [i8080_do_opcodes_nb_cycles],eax
           call i8080_do_opcodes
                  call draw_screen
    main_m2:
    
    
    ;mov dword [@FLagExit],1  ; в случает когда нужен будет выход    
    cmp byte [@FLagExit],0
    jz CycleProgram ;
       mov EAX, -1            ; иначе конец программы
    jmp CycleProgram
     
    I_END:                             ; метка конца программы
    
    
  • Who is online

    Users browsing this forum: No registered users and 3 guests