SAS Emulator (эмулятор «ПК-01 Львов»)
Когда-то, года два-три назад, один хороший человек, на одном из форумов выложил Дельфи-исходники эмулятора ретро машины «ПК-01 «Львов». Я используя их, решил написать свой эмулятор «ПК-01 «Львов» для ОС Windows.
Некоторое время я тот эмулятор дорабатывал, после чего забросил и забыл.
Когда я познакомился с КОС и решил написать, что либо для КОС, вспомнил о том эмуляторе, но не сразу решился реализовать его для КОС, так как в программировании на ассемблере, я очень слабоват, а в других ЯВУ, таких как VS6 и прочих, которые можно бы было использовать для написания программ для КОС, я «абсолютный ноль».
Я делал всевозможные пробы и попытки создать хоть какую-то игру для КОС и всё время меня мысль наталкивала на написание эмулятора, так как, если написать ОДНУ игру или программу, - будет всего лишь ОДНА игра (программа). Если написать эмулятор, то будет, - десятки, сотни игр и программ для какой либо ОС.
Понятное дело, что эмулятор такой же как для Windows, я написать не смог бы для КОС, ни за что и никогда. Понимая это я поступил следующим образом: Почему бы не написать эмулятор который будет уже со встроенной в него игрой (программой)?!... а создавать такие «кос-екзешники» можно будет с помощью доработанного эмулятора который для Windows.
Прошу внимания, почтенную публику, познакомится с эмулятором-со-встроенной-игрой
данный эмулятор, не является полноценным для использования. Он ещё в очень «сыром» виде и будет дорабатываться.
Пока, для примера, реализованы, лишь некоторые игры, такие как «Aerocobra», «Arcanoid», «King Valey», «Rick1», «Пьяный лифтёр». Да и клавиатура реализована не полностью и «со смещением» клавиш, так как я еще не разобрался как использовать дополнительные клавиши в SCANCODE. Надеюсь на помощь форумчан.
Реализованы следующие клавиши:
ВВЕРХ — “P” (scancode: 25/153)
ВЛЕВО — “L” (scancode: 38/166)
ВНИЗ — “;” (scancode: 39/167)
ВПРАВО — “'” (scancode: 40/168)
ПРОБЕЛ и ВВОД, - соответвуют расположению на клавиатуре.
Остальные пока не реализованы.
Прошу все оценить моё творение, с учётом того, что это всё таки «черновик», а так же хотелось бы конструктивной критики и пожеланий, а самое главное помощи в совершенствовании этого творения.
SAS Emulator (эмулятор «ПК-01 Львов»)
P.S. онлайн антивирус https://www.virustotal.com , опять чего-то там жалуется на наличие вирусов в "SASEmulator for Windows.7z". Ну уж незнаю! Установленый на компьютере Avast, - не жалуется!
P.S. забыл написать: архив "SASEmulator for Windows.7z" [3.26 МБ] с играми в комплекте, точнее говоря прямо в эмуляторе.
Получается, что с каждой игрой, будет дублироваться эмулятор. Как-то расточительно, помоему. Эмулятор наверно больше весит, чем один файл с игрой?ALEXS1983 wrote:Понимая это я поступил следующим образом: Почему бы не написать эмулятор который будет уже со встроенной в него игрой (программой)?!... а создавать такие «кос-екзешники» можно будет с помощью доработанного эмулятора который для Windows.
А почему бы, не отдельно эмулятор? А игры, можно было бы, загружать в эмулятор, через ассоциации в assoc.ini, при помощи файлового менеджера.
Как по мне - так стрелочки, были бы удобнее. Но, пишущему виднее.ALEXS1983 wrote:ВВЕРХ — “P” (scancode: 25/153)
ВЛЕВО — “L” (scancode: 38/166)
ВНИЗ — “;” (scancode: 39/167)
ВПРАВО — “'” (scancode: 40/168)
P.S. Не плохо бы расширение .bin, из файлов убрать. А то неудобно, переименовывать каждый файл, перед началом игры.
P.P.S.А ещё, 100% загрузка ЦПУ игрой, напрягает!
P.P.P.S. Эх, жаль масштабирования нет! А так, не плохо.
Ну сейчас приблизительно подсчитаем: запускной файл в целом 377600 байт, если убрать массивы, которые могут быть созданы во время запуска (может выделяться им память), то можно вычесть из операривки-эмуля 48000 Байт,(остальное биос 16000Байт всё равно должен оставаться), можно еще вычесть видеопямять 16000 байт, можно вычистить «черновую» (предыдущего кадра) видеопамять 16000 байт которая тоже может выделятся при запуске, ну там, порты - 256 байт, флаги - 256 байт........Yason wrote:Получается, что с каждой игрой, будет дублироваться эмулятор. Как-то расточительно, помоему. Эмулятор наверно больше весит, чем один файл с игрой?
О-о-о-о-о! Тут на остальном можно и не заморачиваться, сама картинка для вывода на экран содержится в файле и её масив занимает 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
Об остальном позже.
Продолжение.
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 в архив или «на мусорку», играй только в те, что выбрал, со временем и те поудаляешь при необходимости.
Продолжение следует.
1.Как я уже говорил, - я новичок в программировании для КОС и не знаю как это делать! Yason, ты готов помогать кусками готового кода ?Yason wrote:А почему бы, не отдельно эмулятор? А игры, можно было бы, загружать в эмулятор, через ассоциации в assoc.ini, при помощи файлового менеджера.
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: Как по мне - так стрелочки, были бы удобнее. Но, пишущему виднее.
Ответ всё тот же: я не знаю как это делать! Но этим я конечно займусь в первую очередь.
Вот смотри код:
(
Пояснение к коду.
В начале программы переключаю в сканкоды, вот так вот 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;
Часть кода внедренное в это попросить можно ? хотя бы реализацию одной клавиши, по которой можно будет понять как сделать такое с остальными.
СПАСИБО РАССМОТРЮ!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: ; метка конца программы
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 1 guest