commit 026dede6bcecf4a235b645b0369684fd3cfaa6cc Author: Константин Косарев Date: Fri Jul 31 22:31:28 2026 +0300 main Попытка написать видеопроигрыватель для Sprinter computer Есть еще над чем поработать. diff --git a/source/main3.asm b/source/main3.asm new file mode 100644 index 0000000..bb6d054 --- /dev/null +++ b/source/main3.asm @@ -0,0 +1,854 @@ + device zxspectrum128 +; ============================================================ +; КОНСТАНТЫ +; ============================================================ +VMODE: +.T40: EQU #02 +.T80: EQU #03 +.V320: EQU #81 +.V640: EQU #82 +.background: EQU #50 +.sprite: EQU #50 + +BANKSIZE EQU #0A + +; ---- Константы портов ---- +CTC_CH2: EQU #12 +CTC_CH3: EQU #13 + +; ---- Порты управления страницами фастрам ---- +FastRAM: +.ON EQU #FB +.OFF EQU #7B +.SLOT0 EQU #5C +SYS_PORT: +.ON EQU #7C +.OFF EQU #3C + +; ---- Коды частоты звука ---- +SOUND_8KHZ EQU 0 +SOUND_11KHZ EQU 1 +SOUND_16KHZ EQU 2 +SOUND_22KHZ EQU 3 + +; ============================================================ +; ПОДКЛЮЧАЕМ INCLUDE-ФАЙЛЫ +; ============================================================ + include "include\head.asm" + include "include\keyboard.asm" + include "include\dss_equ.asm" + include "include\bios_equ.asm" + include "include\sp_equ.asm" + + +; ============================================================ +; ТОЧКА ВХОДА +; ============================================================ +begin: jp main + + +; ============================================================ +; ДАННЫЕ +; ============================================================ + +; ============================================================ +; ЗАГОЛОВОК .SPR +; ============================================================ + +HEAD_SIGN EQU 0 ; 3 bytes "SPR" +HEAD_WIDTH EQU 3 ; 2 bytes ширина +HEAD_HEIGHT EQU 5 ; 1 byte высота +HEAD_OFFSET_Y EQU 6 ; 1 byte отступ Y +HEAD_OFFSET_X EQU 7 ; 1 byte отступ X +HEAD_FPS EQU 8 ; 1 byte FPS +HEAD_SOUNDRATE EQU 9 ; 1 byte код частоты звука +HEAD_PALETTE EQU 10 ; 1024 байта палитра +HEAD_AUDIO_OFF EQU 1034 ; 4 bytes смещение до аудио + +HEAD_PART_SIZE EQU 1038 ; 2 bytes размер 1/5 части кадра +HEAD_MFP_SIZE EQU 1040 ; 2 bytes размер таблицы смещений +HEAD_MFP_PAGES EQU 1042 ; 1 byte страниц под таблицу +HEAD_MFP_LAST EQU 1043 ; 2 bytes размер последней страницы + +HEADER_SIZE EQU 1045 ; размер заголовка + +MFP_START = HEADER_SIZE ; = 1045 - здесь начинается таблица смещений + +; ============================================================ +; БУФЕР ЗАГОЛОВКА +; ============================================================ +header: +.signature: db "SPR" +.width: dw 0 +.height: db 0 +.offset_y: db 0 +.offset_x: db 0 +.fps: db 0 +.soundrate: db 0 +.palette: ds 1024 +.sound_off: dw 0,0 +.part_size: dw 0 ; размер 1/5 части +.mfp_size: dw 0 ; размер таблицы +.mfp_pages: db 0 ; страниц под таблицу +.mfp_last: dw 0 ; размер последней страницы + + + +; ============================================================ +; Переменные файлового ввода-вывода +; ============================================================ +idfile: db 0 ; временный ID файла +scr_id: db 0 ; ID файла видео +snd_id: db 0 ; ID файла звука +buffer: db 0 ; базовая страница выделенной памяти +SavePage: db 0 ; сохранённая страница окна 0 +win1: db 0 ; сохранённая страница окна 1 +sound_load: db 0 ; флаг: нужно ли загружать звук +counter_notes: dw #1000 ; счётчик записей в таблице смещений. После каждой загрузки #1000 + +addres_wav: dw #4000 ; текущий адрес звуковых данных в окне #4000 + + +; ---- Строки для вывода ---- +About: db #0d, #0a, "(c) Sprinter Video Player v0.15.035 Alpha by kostya261. 09.07.2026", #0d, #0a, #00 +new_line: db #0a, #0d, #00 +cmd: ds #100 +commandLine: dw #8082 + +; ---- Основной цикл ---- +main: + +; ---- Выводим информацию о плеере ---- + ld hl,About + ld c,Dss.PChars + rst DssRst + +; ---- Разбираем командную строку ---- + ld hl,(commandLine) + ld de,cmd + ld bc,#0745 + rst DssRst + + +; ---- Выводим информацию командной строки ---- + ld hl,cmd + ld c,Dss.PChars + rst DssRst + + +; ============================================ +; Нужно продумать какие страницы куда пойдут. +; ============================================ +; Немного переборщил. Нужно раза в два меньше. +; но пока пускай будут. Мало ли, пригодяться... + + ; Запрашиваем память (11 страниц) + ld b,BANKSIZE + 1 + ld c,Dss.GetMem + rst DssRst + ld (buffer),a + + ld b,0 + +metka_p: djnz metka_p + +; ---- Устанавливаем графический режим ---- + ld a,#5c: ld (Graphics.video_page),a + ld a,#81: call Graphics + + call LoadHeader + + ld hl,header.palette + call SetPalette + call Copy_Palette + call ExtractMemoryPage + call ClearSound + call SetUp_CovoxBL +; call SetUp_Interrupt + + + +; ---- Ищем самый тёмный цвет ---- + ld hl, header.palette + call FindDarkestColor + ld (clrscr.color), a ; сохраняем номер цвета + +; ---- Очищаем экран ---- + + call clrscr + call LoadHeader + + +; ============================================ +; Открываем видеопоток. +; ============================================ + ld hl,cmd + call OpenFile + ld (LoadMoveFP.move_fp),a + call LoadMoveFP + + ld hl,cmd + call OpenFile + ld (scr_id),a + ld (DrawFrame.idfile1),a + ld (DrawFrame.idfile1_2),a + ld (DrawFrame.idfile1_3),a + ld (DrawFrame.idfile1_4),a + ld (DrawFrame.idfile1_5),a + +;============================================== + + ld hl, cmd + call OpenFile + ld (snd_id),a + ld (LoadBlockWav.snd_id),a + ld (LoadBlockWav_.snd_id),a + call Move_FP_Sound + + call LoadBlockWav ; загружаем первую половину + call LoadBlockWav_ ; загружаем вторую половину + call SetUp_Interrupt + + +metka_cinema: + di: IM 2: ei; Свои прерывания + + call Flip + call DrawFrame + +; ---- решаем, нужно ли загружать звук ---- + ld a,(sound_load): cp 0: jr nz,.no_skip2: + ld a,(next_data.trigger): cp 0: jr nz,.nn1 + call LoadBlockWav: jr .nn2 +.nn1: call LoadBlockWav_ +.nn2: ld a,1: ld (sound_load),a; сбрасываем флаг загрузки звука + +.no_skip2: + + di: IM 1: ei; возвращаем дос прерывания + halt + ld c,Dss.ScanKey: rst DssRst + jp nz,_exit + + ld a,(DrawFrame.exit_video) + cp #ff + jr nz,metka_cinema + + +; ============================================ +; ВЫХОД ИЗ ПРОГРАММЫ +; ============================================ +_exit: + + call clear_covox + + ld a,(LoadMoveFP.move_fp) + ld (idfile),a + call CloseFile + + ld a,(scr_id) + ld (idfile),a + call CloseFile + + + ld a,(snd_id) + ld (idfile),a + call CloseFile + + ld c,Dss.Exit + rst DssRst + ret + + + + +; ============================================================ +; ПОИСК САМОГО ТЁМНОГО ЦВЕТА В ПАЛИТРЕ +; ============================================================ +; Вход: HL = указатель на палитру (header.palette) +; Выход: A = номер самого тёмного цвета (0-255) +; BC = яркость самого тёмного цвета (сумма R+G+B) +; ============================================================ + +FindDarkestColor: + ld b, 0 ; номер текущего цвета (0-255) + ld de, 0xFFFF ; минимальная яркость (пока максимальная) + ld c, 0 ; номер самого тёмного цвета (пока 0) + +.loop: + ; ---- Читаем 4 байта цвета (B, G, R, 0) ---- + ld a, (hl) ; B + inc hl + ld d, a ; сохраняем B в D + ld a, (hl) ; G + inc hl + ld e, a ; сохраняем G в E + ld a, (hl) ; R + inc hl + inc hl ; пропускаем 0 + + ; ---- Считаем яркость = R + G + B (16 бит!) ---- + ld h, 0 + ld l, a ; HL = R + add hl, de ; HL = R + G + ld d, 0 + ld e, d ; DE = 0 + add hl, de ; HL = R + G + B (теперь яркость в HL) + + ; ---- Сравниваем с текущей минимальной яркостью ---- + ld a, h ; сравниваем старшие байты + cp d + jr c, .darker ; если HL < DE, то это темнее + jr nz, .not_darker ; если HL > DE, пропускаем + ld a, l ; сравниваем младшие байты + cp e + jr nc, .not_darker ; если HL >= DE, пропускаем + +.darker: + ; ---- Это самый тёмный цвет на данный момент ---- + ld de, hl ; сохраняем новую минимальную яркость в DE + ld c, b ; сохраняем номер цвета + +.not_darker: + ; ---- Следующий цвет ---- + inc b + ld a, b + cp 255 + jr nz, .loop + + ; ---- Возвращаем результат ---- + ld a, c ; A = номер самого тёмного цвета + ld b, d ; B = старший байт яркости + ld c, e ; C = младший байт яркости + ret + + + + +; ============================================ +; УСТАНОВКА ГРАФИЧЕСКОГО РЕЖИМА +; ============================================ +; в А - номер режима (81 = 320*256б 82 = 640*256) +; ld a,#50 - номер подключаемой видеостраницы, по умолчанию #50 +; Пример вызова: ld a,#5c +; ld (video_page),a +; ld a,#81 +; call Graphics +Graphics: + ld bc,#0050: rst DssRst +.video_page: equ $+1: ld a,#50 + out (EmmWin.P3),a + ret + + +; ============================================ +; Загружаем и отрисовываем кадр частями +; ============================================ +DrawFrame: + +.pageA: equ $+1: ld a,#00: out(#a2),a + + push de +.idfile1: equ $+1: ld a,#00 + ld hl,#4000 +.size_file_1: equ $+1: ld de,#4000 + ld c,Dss.Read + rst DssRst + pop de + + ld de,0 +.buffer_screen: equ $+1: ld hl,#c000 + add hl,de: ld (.x),hl + + ld hl,#4000 + ld b,64; Ширина сегмента +.y1: equ $+1: ld a,55: out (Y_PORT),a +.x: equ $+1: ld de,#0000 + di +.m1: ld l,l: ld a,(hl): ld a,a: ld (de),a: ld b,b: inc de + + push de +.hght1: equ $+1: ld de,50: add hl,de + pop de +.y_1: equ $+1: ld a,55: out (Y_PORT),a + djnz .m1 + ei + + push de +.idfile1_2: equ $+1: ld a,#00 + ld hl,#4000 +.size_file_2: equ $+1: ld de,#4000 + ld c,Dss.Read + rst DssRst + pop de + + ld hl,#4000 + ld b,64; Ширина сегмента +.y2: equ $+1: ld a,55: out (Y_PORT),a +.m2: di + ld l,l: ld a,(hl): ld a,a: ld (de),a: ld b,b: inc de + + push de +.hght2: equ $+1: ld de,50: add hl,de + pop de +.y_2: equ $+1: ld a,55: out (Y_PORT),a + djnz .m2 + ei + + push de +.idfile1_3: equ $+1: ld a,#00 + ld hl,#4000 +.size_file_3: equ $+1: ld de,#4000 + ld c,Dss.Read + rst DssRst + pop de + + ld hl,#4000 + ld b,64; Ширина сегмента +.y3: equ $+1: ld a,55: out (Y_PORT),a +.m3: di + ld l,l: ld a,(hl): ld a,a: ld (de),a: ld b,b: inc de + + push de +.hght3: equ $+1: ld de,50: add hl,de + pop de +.y_3: equ $+1: ld a,55: out (Y_PORT),a + djnz .m3 + ei + + push de +.idfile1_4: equ $+1: ld a,#00 + ld hl,#4000 +.size_file_4: equ $+1: ld de,#4000 + ld c,Dss.Read + rst DssRst + pop de + + ld hl,#4000 + ld b,64; Ширина сегмента +.y4: equ $+1: ld a,55: out (Y_PORT),a +.m4: di + ld l,l: ld a,(hl): ld a,a: ld (de),a: ld b,b: inc de + + push de +.hght4: equ $+1: ld de,50: add hl,de + pop de +.y_4: equ $+1: ld a,55: out (Y_PORT),a + djnz .m4 + ei + + push de +.idfile1_5: equ $+1: ld a,#00 + ld hl,#4000 +.size_file_5: equ $+1: ld de,#4000 + ld c,Dss.Read + rst DssRst + cp #ff + jr nz,.skip + ld (.exit_video),a +.skip: + pop de + + ld hl,#4000 + ld b,64; Ширина сегмента +.y5: equ $+1: ld a,55: out (Y_PORT),a +.m5: di + ld l,l: ld a,(hl): ld a,a: ld (de),a: ld b,b: inc de + + push de +.hght5: equ $+1: ld de,50: add hl,de + pop de +.y_5: equ $+1: ld a,55: out (Y_PORT),a + djnz .m5 + ei + + ret +.exit_video: + db #00 + + + + +; HL = старшие 16 бит +; IX = младшие 16 бит +Move_FP: + ld a,(scr_id) +.hl_reg: equ $+2:ld hl,#0000 +.ix_reg: equ $+2: ld ix,0000 + ld bc,#0015 + rst DssRst + ret + +; ld a,file_id +; HL = старшие 16 бит +; IX = младшие 16 бит +Move_FP_Small: + ld bc,#0015 + rst DssRst + ret + +; HL = старшие 16 бит +; IX = младшие 16 бит +Move_FP_Sound: + ld a,(snd_id) + ld hl,(header.sound_off + 2) + ld ix,(header.sound_off) + ld bc,#0015 + rst DssRst + ret + + + +; ============================================================ +; ПЕРЕКЛЮЧЕНИЕ ЭКРАННЫХ СТРАНИЦ +; ============================================================ +Flip: + ld hl,.flip_s +.flip_s: equ $+1 + ld a,#01 + inc (hl) + and %00000001 + out (RGMOD),a + + cp 1 + jr z,.skip + ld hl,#c140 + ld (DrawFrame.buffer_screen), hl + ret +.skip: ld hl,#c000 + ld (DrawFrame.buffer_screen), hl + + ret + +; ============================================================ +; НАСТРОЙКА COVOX-BLASTER +; ============================================================ +SetUp_CovoxBL: + ld bc,#04e + ld a,%10011001 + out (c),a + ret + +; ============================================================ +; НАСТРОЙКА ПРЕРЫВАНИЙ +; ============================================================ +SetUp_Interrupt: + DI + LD HL,interrupt + ld (#90ff),hl + LD A,#90 + LD I,A + IM 2 + EI + ret + +; ============================================================ +; ОБРАБОТЧИК ПРЕРЫВАНИЯ +; ============================================================ +interrupt: + di + push af + push bc + push de + push hl + xor a + in a,(#fe): and #80 + call nz,next_data + +.next: + pop hl + pop de + pop bc + pop af + ei + ret +.inter: db #00 + + + +next_data: + + in a,(#a2): ld (win1),a +.trigger: equ $+1: ld a,#00 + cp 0: jr nz,.n2 +.page7: equ $+1: ld a,#00: out (#a2),a: jr .n3 +.n2: +.page6: equ $+1: ld a,#00: out (#a2),a +.n3: + ld hl,(addres_wav) + ld c,#4f + ld b,128 + otir + + ld a,#80: cp h: jr nz,.next + ld hl,#4000: ld (addres_wav),hl + ld a,(.trigger) + cpl: ld (.trigger),a +.nn2: xor a: ld (sound_load),a +.next: ld (addres_wav),hl + ld a,(win1): out (#a2),a + ret + +; ============================================================ +; ОЧИСТКА ЗВУКА +; ============================================================ +clear_covox: + ld a,#80 + ld bc,#4f +clear_cbl: out (c),a + djnz clear_cbl + ret + + + +; ============================================================ +; ОЧИСТКА ЭКРАНА +; ============================================================ +clrscr: + push bc + push hl + ld hl,(DrawFrame.buffer_screen) + ld bc,#280 +.m1: push bc + di + ld d,d: ld a,0: ld e,e +.color: equ $+1: ld a,0: ld (hl),a + ld b,b + ei + pop bc + inc hl + dec bc + ld a,b: or c + jr nz,.m1 + pop hl + pop bc + ret + +; ============================================================ +; УСТАНОВКА ПАЛИТРЫ +; ============================================================ +;hl addres palette +SetPalette: + ld de,#0000 + ld bc,#ffa4 + xor a + rst BiosRst + ret + +Copy_Palette: + ld b,0 +.sp_loop: + push bc + ld a,b + out (Y_PORT),a + ld hl,#c3e0 + ld de,#c3e4 + ld bc,#04 + ldir + pop bc + djnz .sp_loop + ret + +; ============================================================ +; ОТКРЫТИЕ/ЗАКРЫТИЕ ФАЙЛА +; ============================================================ +OpenFile: + ld a,#C0 + out (RGADR),a + ld a,1 + ld c,Dss.Open + rst DssRst + ld (idfile),a + ret + +CloseFile: + ld a,(idfile) + ld c,Dss.Close + rst DssRst + ret + + +; ---- Загрузка заголовка ---- +LoadHeader: + ld hl,cmd + call OpenFile + + ld a,(idfile) + ld hl,header + ld de,HEADER_SIZE + ld c,Dss.Read + rst DssRst + + call CloseFile + +; ---- Установка параметров проигрывателя ---- + ld a,(header.offset_y) + ld (DrawFrame.y1),a: ld (DrawFrame.y_1),a + ld (DrawFrame.y2),a: ld (DrawFrame.y_2),a + ld (DrawFrame.y3),a: ld (DrawFrame.y_3),a + ld (DrawFrame.y4),a: ld (DrawFrame.y_4),a + ld (DrawFrame.y5),a: ld (DrawFrame.y_5),a + +; ---- Устанавливаем высоту кадра ---- + di + ld d,d + ld a,(header.height) + ld b,b + ei + ld (DrawFrame.hght1),a + ld (DrawFrame.hght2),a + ld (DrawFrame.hght3),a + ld (DrawFrame.hght4),a + ld (DrawFrame.hght5),a + +; ---- размер загружаемых получастей кадра ---- + ld hl,(header.part_size) + + ld (DrawFrame.size_file_1),hl + ld (DrawFrame.size_file_2),hl + ld (DrawFrame.size_file_3),hl + ld (DrawFrame.size_file_4),hl + ld (DrawFrame.size_file_5),hl + + + ld a,(header.mfp_pages) + inc a + ld (header.mfp_pages),a + ret + + + +LoadMoveFP: + +.move_fp: equ $+1: ld a,#00 + ld hl,#0000 + ld ix,#0415 + call Move_FP_Small +.load: +.page1: equ $+1: ld a,#00: out(#a2),a + ld a,(header.mfp_pages) + dec a + ret z + ld (header.mfp_pages), a + + ld a,(.move_fp) + ld hl,#4000: ld d,h: ld e,l + ld c,Dss.Read + rst DssRst + + ld hl,#1000 + ld (counter_notes),hl + ret + +LoadBlockWav: + +.page6: equ $+1: ld a,#00: out (#a2),a +.snd_id: equ $+1: ld a,#00 + ld hl,#4000: ld d,h: ld e,l + ld c,Dss.Read + rst DssRst + + ld hl, (counter_notes) + dec hl + jr z,.skip + ld (counter_notes),hl + ret +.skip: + call LoadMoveFP.load + jr Move_FP_Small_ + + +LoadBlockWav_: + +.page7: equ $+1: ld a,#00: out (#a2),a +.snd_id: equ $+1: ld a,#00 + ld hl,#4000: ld d,h: ld e,l + ld c,Dss.Read + rst DssRst + + ld hl, (counter_notes) + dec hl + jr z,.skip + ld (counter_notes),hl + ret +.skip: + call LoadMoveFP.load + jp Move_FP_Small_ + + + +Move_FP_Small_: +.current_point: equ $+2: ld ix,(#4000) +.current_point_2: equ $+1: ld hl,(#4002) + + ld a,(scr_id) + ld bc,#0015 + rst DssRst + + ld hl,(.current_point) + inc hl: inc hl: inc hl: inc hl + ld (.current_point),hl + inc hl: inc hl + ld (.current_point_2),hl + ret + + +ClearSound: + ld a,(LoadBlockWav.page6): out (#a2),a + xor a + ld hl, #4000 + ld de, #4001 + ld bc, #3fff + ld (hl), a + ldir + + ld a,(LoadBlockWav_.page7): out (#a2),a + xor a + ld hl, #4000 + ld de, #4001 + ld bc, #3fff + ld (hl), a + ldir + ret + +; ============================================================ +; Облегчаем доступ к страницам памяти +; ============================================================ +ExtractMemoryPage: + ld b,10 + ld a,(buffer) + ld c,Dss.SetWin1 + rst DssRst + in a,(#a2): ld (DrawFrame.pageA),a + + ld b,5 + ld a,(buffer) + ld c,Dss.SetWin1 + rst DssRst + in a,(#a2): ld (next_data.page7),a: ld (LoadBlockWav_.page7),a + ld b,4 + ld a,(buffer) + ld c,Dss.SetWin1 + rst DssRst + in a,(#a2): ld (next_data.page6),a: ld (LoadBlockWav.page6),a + + ld b,3 + ld a,(buffer) + ld c,Dss.SetWin1 + rst DssRst + in a,(#a2): ld (LoadMoveFP.page1),a + ret + + + + + +; ============================================================ +; КОНЕЦ +; ============================================================ +code_end: + + + savebin "player.exe",start_addr,code_end-start_addr + + diff --git a/source/make3.bat b/source/make3.bat new file mode 100644 index 0000000..f61d8f7 --- /dev/null +++ b/source/make3.bat @@ -0,0 +1,18 @@ +@echo off + +if EXIST player.exe ( + del player.exe +) +tools\sjasmplus\sjasmplus.exe main3.asm --lst=main.lst +if errorlevel 1 goto ERR +echo Ok! +goto END + +:ERR +del player.exe +pause +echo Something was happened... +pause +goto END + +:END diff --git a/source/make_image.bat b/source/make_image.bat new file mode 100644 index 0000000..534013c --- /dev/null +++ b/source/make_image.bat @@ -0,0 +1,47 @@ +rem echo OFF +set PROG=FBIRD +mkdir build +echo Unmounting old image ... +osfmount.com -D -m X: + +echo Assembling ... +tools\sjasmplus\sjasmplus.exe %PROG%.asm --lst=%PROG%.lst +if errorlevel 1 goto ERR + +echo Preparing floppy disk image ... +copy /Y image\dss_image.img build\%PROG%.img +rem Delay before copy image +timeout 2 > nul +osfmount.com -a -t file -o rw -f build/%PROG%.img -m X: +if errorlevel 1 goto ERR +mkdir X:\%PROG% +mkdir X:\%PROG%\ASSETS +copy /Y %PROG%.EXE /B X:\%PROG%\ /B +copy /Y assets\*.b* /B X:\%PROG%\ASSETS\ /B + +mkdir build\%PROG% +mkdir build\%PROG%\ASSETS + +copy /Y %PROG%.EXE /B X:\%PROG%\ /B +copy /Y assets\*.b* /B X:\%PROG%\ASSETS /B +copy /Y %PROG%.EXE /B build\%PROG%\ /B +copy /Y assets\*.b* /B build\%PROG%\ASSETS /B + +if errorlevel 1 goto ERR +rem Delay before unmounting image +timeout 2 > nul +echo Unmounting image ... +osfmount.com -d -m X: +goto SUCCESS +:ERR +rem pause +echo Some Building ERRORs!!! +pause 0 +rem exit +goto END +:SUCCESS +echo Copying image to ZXMAK2 Emulator +copy /Y build\%PROG%.img /B %SPRINTER_EMULATOR% /B +echo Done! +:END +pause 0 \ No newline at end of file diff --git a/source/makefast.bat b/source/makefast.bat new file mode 100644 index 0000000..f35009b --- /dev/null +++ b/source/makefast.bat @@ -0,0 +1,18 @@ +@echo off + +if EXIST fastram.bin ( + del fastram.bin +) +tools\sjasmplus\sjasmplus.exe FastRam.asm --lst=FastRam.lst +if errorlevel 1 goto ERR +echo Ok! +goto END + +:ERR +del fastram.bin +pause +echo Something was happened... +pause +goto END + +:END diff --git a/source/player.exe b/source/player.exe new file mode 100644 index 0000000..b7d597f Binary files /dev/null and b/source/player.exe differ