file_id.diz0100664000076500007650000000015307725642373012430 0ustar prool2prool2OS Proolix by Serge Pustovoitoff 2:461/35@Fidonet http://prool.kharkov.org/proolix/ files.bbs0100664000076500007650000000042007725642373012114 0ustar prool2prool2FILE_ID.DIZ description INSTALLD.BAT install Proolix to HDD (D:) INSTALLF.BAT install Proolix to FDD (A:) INSTALLH.BAT install Proolix to HDD (C:) MKBOOT.BAT make proolix boot sector README.1ST read me SUPPORT.TXT proolix support VERSION Proolix SlimeWare version installd.bat0100664000076500007650000000335707725642373012640 0ustar prool2prool2@echo off cls echo ┌────────────────────────────────────────────────────────────────────┐ echo │ Инсталляция ОС Proolix на раздел d: FAT-12 │ echo │ │ echo │ Installator (install.bat) version D-0.0.3.1 24-Feb-98 │ echo │ │ echo │ Каталог, в котором распакован файл slime?.arj │ echo │ должен быть текущим. │ echo │ │ echo │ Учтите, бут-сектор диска и Master Boot Record, а также вся │ echo │ информация, содержащаяся на диске, могут быть запорчены ! │ echo │ Нажмите CTRL BREAK, если Вы передумали. │ echo │ В противном случае нажмите ANY KEY │ echo └────────────────────────────────────────────────────────────────────┘ pause>nul cls src\boot\bp -d@ boot.mbr src\boot\bp -d3 -i -a0 boot.mbr src\boot\bp -d4 -i src\boot\booth12.bin copy src\bm\boot d:\boot > nul echo Kernel to disk d: copy src\kernel\kernel d:\kernel > nul echo on REM REM Doc to disk d: copy *.doc d:\ REM REM Files description to disk d: copy files.bbs d:\ REM REM Utilities to disk d: mkdir d:\bin copy src\command\kernel.ovl d:\ > nul REM a: REM cd \bin REM c: copy src\command\*. d:\bin REM Fonts to disk d: copy src\command\*.fnt d:\bin REM REM Man mkdir d:\usr mkdir d:\usr\man copy man\*.* d:\usr\man REM REM Installation done. REM Reboot, please, from diskette a: REM Press, please, Ctrl Alt Del REM goto End :Error echo ! echo ! Installation error echo ! :End installf.bat0100664000076500007650000000337507725642373012642 0ustar prool2prool2@echo off cls echo ┌────────────────────────────────────────────────────────────────────┐ echo │ Инсталляция ОС Proolix на дискету a: │ echo │ │ echo │ Installator (install.bat) version F-0.0.1.4 10-Mar-98 │ echo │ │ echo │ Каталог, в котором распакован файл slime?.arj │ echo │ должен быть текущим. │ echo │ │ echo │ Учтите, бут-сектор дискеты и вся │ echo │ информация, содержащаяся на дискете, могут быть запорчены !!! │ echo │ Нажмите CTRL BREAK, если Вы передумали связываться с Proolix'ом. │ echo │ В противном случае нажмите ANY KEY │ echo └────────────────────────────────────────────────────────────────────┘ pause>nul cls src\boot\bp -d0 -i -y src\boot\boots.bin if errorlevel 1 goto Error echo Boot manager to diskette a: copy src\bm\bootf a:\boot > nul echo Kernel to diskette a: copy src\kernel\kernel a:\kernel > nul echo on REM REM Files description to diskette a: copy files.bbs a:\ REM REM Utilities to diskette a: mkdir a:\bin copy src\command\kernel.ovl a:\ > nul REM a: REM cd \bin REM c: copy src\command\*. a:\bin REM Fonts to diskette a: copy src\command\*.fnt a:\bin del a:\bin\makefile > nul REM Man to diskette mkdir a:\usr mkdir a:\usr\man copy man\*.* a:\usr\man REM REM Installation done. REM Reboot, please, from diskette a: REM Press, please, Ctrl Alt Del REM goto End :Error echo ! echo ! Installation error echo ! :End installh.bat0100664000076500007650000000350107725642373012633 0ustar prool2prool2@echo off cls echo ┌────────────────────────────────────────────────────────────────────┐ echo │ Инсталляция ОС Proolix на a: и c: (boot manager на a:, ядро на c: )│ echo │ │ echo │ Installator (install.bat) version H-0.0.2.1 30-Sep-98 │ echo │ │ echo │ Каталог, в котором распакован файл slime?.arj │ echo │ должен быть текущим. │ echo │ В устройстве a: должна быть чистая дискета! │ echo │ │ echo │ Учтите, бут-секторы диска и дискеты, а также вся │ echo │ информация, содержащаяся на диске и дискете, могут быть запорчены !│ echo │ Нажмите CTRL BREAK, если Вы передумали. │ echo │ В противном случае нажмите ANY KEY │ echo └────────────────────────────────────────────────────────────────────┘ pause>nul cls src\boot\bp -d0 -i -y src\boot\boots.bin if errorlevel 1 goto Error echo Boot manager to diskette a: copy src\bm\booth a:\boot > nul echo Kernel to disk c: copy src\kernel\kernel c:\kernel > nul echo on REM REM Doc to disk c: copy *.doc c:\ REM REM Files description to disk c: copy files.bbs c:\ REM REM Utilities to disk c: mkdir c:\bin copy src\command\kernel.ovl c:\ > nul REM a: REM cd \bin REM c: copy src\command\*. c:\bin REM Fonts to disk c: copy src\command\*.fnt c:\bin REM REM Man mkdir c:\usr mkdir c:\usr\man copy man\*.* c:\usr\man REM REM Installation done. REM Reboot, please, from diskette a: REM Press, please, Ctrl Alt Del REM goto End :Error echo ! echo ! Installation error echo ! :End man/0040775000076500007650000000000007725642416011102 5ustar prool2prool2man/help.doc0100664000076500007650000000276507725642416012530 0ustar prool2prool2Proolix commands (internal & external): ScrollLock - rus/lat shutdown - shutdown & reboot ver - version clear, cls - clear screen l - list files (internal command). Use l -? for help ls - list files (external). Use ls -? for help mount [digit|dos_drive_letter] - mount new device (new disk) E [arg...] - show arguments (internal) e - show arguments (external) mem - memory map memd - memory dump (use /? subcommand for memd help) fcb - show FCB list alloc - allocate memory block garbage - garbage collection (memory blocks optimize - squeeze) free - free memory block open - open file Cat - copy file (files) to stdout (CATenate files) (internal) cat - (external) vec - show interrupt vectors Xonix - running one xonix on screen (save screen surf) (internal) xonix - (external) int0 - simulate interrupt 0 de - disk editor echo - echo arguments env, set - show environment date - show current date & time timer [-y] [-n] - set time on/off setmore [-y] [-n] - set more on/off buf - show cache buffers' status rm [files...] - delete (ReMove) file (files) mv file1 file2 - rename files: file1 to file2 (MoVe file link) cp file1 file2 - CoPy files: file1 to file2 (external) Cp - (internal cp) cd dir - change directory md dir - make directory pwd - print work directory touch - touch file (external) more file - show file start - start scheduler (with bugs!) Files: files.bbs - all files description (ASCII text) memmap.doc - memory map man/help.src0100664000076500007650000000241307725642416012540 0ustar prool2prool2; Дизассемблированный файл bin/help из пакета Proolix ; комментарий (c) G.Shepelev ; #include ; void main(void) a0100: jmp a0104 ; обход сигнатуры a0102 DB 0DEh,0ADh ; сигнатура Proolix'а a0104: push cs ; никому не нужное здесь a0105: pop ax ; сохранение значения сегмента a0106: mov [a0110],ax ; в памяти программы a0109: call a0112 ; вызов тела программы help a010C: jmp dword ptr [000C] ; выход из программы - межсегментный ; переход на вектор завершения из PSP ; ( в книжке П.Нортона адрес другой! ) a0110 DW ? ; область хранения (cs) ; { ; тело программы... ; printf("Usage `more /usr/man/help.doc' for help\n"); a0112: push ds ; 1-й параметр сегмент текстовой строки a0113: mov ax,a0124 ; смещение текстовой строки a0116: push ax ; 2-й параметр a0117: call a011E ; вызов printf a011A: add sp,4 ; извлечение параметров из стека ; } a011D: ret ; возврат в main ; =printf a011E: mov ax,10h ; номер функции printf прерывания INT_NO a0121: int 84h ; int INT_NO a0123: ret ; текст, выдаваемый на дисплей a0124 DB "Usage `more /usr/man/help.doc' for help",0Ah,0 ; в качестве символа перевода строки используется код 0Ah, а не последова- ; тельность 0Dh 0Ah как в MS-DOS! man/key.src0100664000076500007650000000613407725642416012404 0ustar prool2prool2; Дизассемблированный файл bin/key из пакета Proolix ; комментарий (c) G.Shepelev ; #include ; #include ; #include ; void main() a0100: jmp a0104 ; обход сигнатуры a0102 DB 0DEh,0ADh ; сигнатура Proolix'а a0104: push cs ; никому не нужное здесь a0105: pop ax ; сохранение значения сегмента a0106: mov [a0110],ax ; в памяти программы a0109: call a0112 ; вызов тела программы key a010C: jmp dword ptr [000C] ; выход из программы - межсегментный ; переход на вектор завершения из PSP ; ( в книжке П.Нортона адрес другой! ) a0110 DW ? ; область хранения (cs) ; { ; тело программы... ; int i; ; переменная целого типа, будет использоваться si a0112: push si ; сохраняем si ; printf("View Key Codes\n\nPress Ctrl-D for exit\n\n"); a0113: push ds ; 1-й параметр сегмент текстовой строки a0114: mov ax,a0166 ; смещение текстовой строки a0117: push ax ; 2-й параметр a0118: call a0160 ; вызов printf a011B: add sp,4 ; извлечение параметров из стека ; while(1) ; вечный цикл ;) ; { ; i=getch(); a011E: call a015A ; вызов getch a0121: mov si,ax ; значение i ; printf("%i\n",i); странненькие обозначения... a0123: push si ; численный параметр a0124: push ds ; 1-й параметр сегмент текстовой строки a0125: mov ax,a018E ; смещение текстовой строки a0128: push ax ; 2-й параметр a0129: call a0160 ; вызов printf("%i\n",i) a012C: add sp,6 ; извлечение параметров из стека ; switch(i) ; { ; case 4: printf("\n"); exit(0); a012F: mov ax,si ; численный параметр a0131: cmp ax,4 ; case 4 a0134: jz a0138 ; совпало - перевод строки и выход a0136: jmp a011E ; возврат на while a0138: push ds ; 1-й параметр сегмент текстовой строки a0139: mov ax,a018C ; смещение текстовой строки a013C: push ax ; 2-й параметр a013D: call a0160 ; вызов printf("\n") a0140: add sp,4 ; извлечение параметров из стека a0143: xor ax,ax ; 0 a0145: push ax ; параметр на стек a0146: call a014F ; exit(int) a0149: inc sp ; извлечение параметров из стека :) a014A: inc sp a014B: jmp a011E ; возврат на while ; /* case 0: i=getch(); printf("%i\n",i); */ ; } собственно сюда мы никогда не попадём... ; } ; } a014D: pop si ; восстанавливаем si a014E: ret ; возврат в main - его не будет... ; =exit a014F: add sp,2 ; адрес возврата нам не понадобится... a0152: mov ax,word ptr [bp+4] ; параметр в стеке ; (вот только регистр bp никто не настроил!) a0155: jmp dword ptr [000C] ; выход из программы - межсегментный ; переход на вектор завершения из PSP ; ( в книжке П.Нортона адрес другой! ) a0159 DB 0 ; Акела промахнулся! ;) ; =getch a015A: mov ax,0 ; номер функции getch прерывания INT_NO a015D: int 84h ; int INT_NO a015F: ret ; =printf a0160: mov ax,10h ; номер функции printf прерывания INT_NO a0163: int 84 ; int INT_NO a0165: ret a0166 DB "View Key Codes",0Ah,0Ah ; "\n" - код 0Ah DB "Press Ctrl-D for exit",0Ah,0Ah,0 a018E DB "%i",0Ah,0 ; "%i\n" man/memmap.doc0100664000076500007650000000145707725642416013051 0ustar prool2prool2Memory map for Proolix (80x86 real mode) 00000 Vectors 00400 ROM BIOS data 00500 Kernel PSP 00600 Kernel Begin (see KERNEL_BEGIN in boot.c) 07C00 =0:7C00 (=0070:7500) Boot sector 07E00 Boot sector end xxxxx Kernel end xxxxx+1 Begin of dynamic memory allocate area 30500 (=3050:0000) /boot (boot manager) (see boots.asm, PSPSeg constant) MemTop (f.e. 9FFFF) End of dynamic memory allocate area A0000 EGA (in graph modes) B0000 MDA, Hercules 1st videopage B8000 CGA, EGA, VGA 1st videopage (mode=3, symbol mode) C8000 Additional ROM modules (2K blocks) E0000 End of addtn ROM E0000 Bg AT ROM BIOS EFFFF End AT ROM BIOS F6000 ROM Basic FE000 ROM BIOS, POST FFFF0 JMP - COLD REBOOT FFFF5 BIOS version/date (ASCII) FFFFE PC/XT/AT identefication byte man/cp.src0100664000076500007650000003125407725642416012217 0ustar prool2prool2; Дизассемблированный файл cp из пакета Proolix ; комментарий (c) G.Shepelev ; #include ; #include ; #include ; #include ; #include ; #include ; #include ; Стандартное начало программы. ; На стеке переданы параметры массива символьных строк! a0100: jmp a0104 ; обход сигнатуры a0102 DB 0DEh,0ADh ; сигнатура Proolix'а a0104: push cs ; никому не нужное здесь a0105: pop ax ; сохранение значения сегмента a0106: mov [a0110],ax ; в памяти программы a0109: call a0242 ; вызов main ; в ax возвращается код завершения... a010C: jmp dword ptr [000Ch] ; выход из программы - межсегментный ; переход на вектор завершения из PSP ; ( в книжке П.Нортона адрес другой! ) a0110 DW ? ; область хранения (cs) ; void cp_help(void) ; { ; puts("Uses: cp [file1] [file2]"); выдать подсказку... a0112: push ds ; 1-й параметр сегмент текстовой строки a0113: mov ax,a034C ; смещение текстовой строки ; "Uses: cp [file1] [file2]",0 a0116: push ax ; 2-й параметр a0117: call a031C ; вызов puts a011A: add sp,4 ; } a011D: ret ; int copy(char *path1, char *path2) ; подпрограмма буферизованного копирования из одного файла в другой ; {int h1, h2, i1, i2; long n, m; ; char buf [SECTOR_SIZE]; a011E: push bp ; сохранение содержимого регистра bp a011F: mov bp,sp ; bp - указатель в стеке; ; "сверху" - переданные функции параметры, ; "снизу" - временные буфер и переменные. a0121: sub sp,210h ; резервирование буфера в 200h байт, ; по 4 байта для n и m, ; по 2 байта для h1, h2, i1 и i2 ; if((h1=open(path1,O_RDONLY))==-1) return -1; ; открыть файл1 для чтения a0125: mov ax,1 ; O_RDONLY a0128: push ax ; первый параметр на стек - атрибут доступа a0129: push ds ; второй параметр на стек - seg path1 a012A: push [bp+4] ; второй параметр на стек - offset path1 a012D: call a0328 ; open a0130: add sp,6 ; коррекция указателя стека a0133: mov [bp-210h],ax ; h1 = номер файла1 a0137: cmp ax,-1 ; == -1 a013A: jnz a013F ; нет, продолжим... a013C: jmp a0235 ; выход с признаком заверш. -1 ; if((h2=open(path2,O_WRONLY|O_CREAT|O_TRUNC))==-1) ; открыть и усечь до 0-й длины (а если не существует - создать) ; файл, открытый для записи a013F: mov ax,0302h ; O_WRONLY or O_CREAT or O_TRUNC a0142: push ax ; первый параметр на стек - атрибут доступа a0143: push ds ; второй параметр на стек - seg path2 a0144: push [bp+6] ; второй параметр на стек - offset path2 a0147: call a0328 ; open a014A: add sp,6 ; коррекция указателя стека a014D: mov [bp-20Eh],ax ; h2 = номер файла2 a0151: cmp ax,-1 ; == -1 a0154: jnz a0162 ; нет, продолжим... ; {close(h1); return -1;} a0156: push [bp-210h] ; h1 = номер файла1 a015A: call a033A ; close a015D: inc sp ; коррекция указателя стека a015E: inc sp a015F: jmp a0235 ; выход с признаком заверш. -1 ; while(1) ; почти бесконечный цикл чтения-записи секторов ; { ; if((n=read(h1,buf,SECTOR_SIZE))==-1) break; ; чтение в буфер очередного сектора a0162: xor dx,dx a0164: mov ax,a0200 ; dx ax = длина буфера (= длине сект.) a0167: push dx ; первый параметр на стек - старшее слово длины a0168: push ax ; первый параметр на стек - младшее слово длины ; учитывая, что адресация к памяти в данной модели 16-битная, ; очень сомнительно, чтобы старшее слово длины имело смысл... a0169: push ss ; второй параметр на стек - seg buf a016A: lea ax,[bp-200h] a016E: push ax ; второй параметр на стек - offset buf a016F: push [bp-210h] ; третий параметр на стек - h1 a0173: call a032E ; read a0176: add sp,10 ; коррекция указателя стека a0179: mov [bp-206h],dx ; n = число прочитанных байтов a017D: mov [bp-208h],ax a0181: cmp dx,-1 ; == -1 a0184: jnz a018B a0186: cmp ax,-1 a0189: jz a01E4 ; break ошибка чтения ; if(n==0) {m=0; break;} проверка конца файла a018B: mov ax,[bp-208h] a018F: or ax,[bp-206h] ; n == 0 ? a0193: jnz a01A3 a0195: mov word ptr [bp-202h],0 ; m = 0 a019B: mov word ptr [bp-204h],0 ; ничего не записано a01A1: jmp a01E4 ; break конец файла1 ; if((m=write(h2,buf,n))==-1) break; ; запись из буфера очередного сектора a01A3: push [bp-206h] ; первый параметр на стек - n a01A7: push [bp-208h] ; (число значащих байт в буфере) ; учитывая, что адресация к памяти в данной модели 16-битная, ; очень сомнительно, чтобы старшее слово длины имело смысл... a01AB: push ss ; второй параметр на стек - seg buf a01AC: lea ax,[bp-200h] a01B0: push ax ; второй параметр на стек - offset buf a01B1: push [bp-20Eh] ; третий параметр на стек - h2 a01B5: call a0334 ; write a01B8: add sp,10 ; коррекция указателя стека a01BB: mov [bp-202h],dx ; m = число записанных байтов a01BF: mov [bp-204h],ax a01C3: cmp dx,-1 ; == -1 a01C6: jnz a01CD a01C8: cmp ax,-1 a01CB: jz a01E4 ; break ошибка записи ; if (m!=n) break; проверка правильности длины записи a01CD: mov dx,[bp-202h] ; m a01D1: mov ax,[bp-204h] ; число записанных байт a01D5: cmp dx,[bp-206h] ; == n число прочитанных байт a01D9: jnz a01E4 a01DB: cmp ax,[bp-208h] a01DF: jnz a01E4 ; break не удалось записать ; } a01E1: jmp a0162 ; следующий сектор... ; сюда попадаем когда файл скопирован или в случае ошибки ; гораздо проще было бы иметь разные точки выхода или ; формировать отдельный признак ошибки... ; i1=close(h1); a01E4: push [bp-210h] ; h1 (номер файла1) a01E8: call a033A ; close a01EB: inc sp ; коррекция указателя стека a01EC: inc sp a01ED: mov [bp-20Ch],ax ; i1 - признак успешности закрытия файла1 ; i2=close(h2); a01F1: push [bp-20Eh] ; h2 (номер файла2) a01F5: call a033A ; close a01F8: inc sp ; коррекция указателя стека a01F9: inc sp a01FA: mov [bp-20Ah],ax ; i2 - признак успешности закрытия файла2 ; if (n==-1) return -1; a01FE: cmp word ptr [bp-206h],-1 ; n == -1 a0203: jnz a020C a0205: cmp word ptr [bp-208h],-1 a020A: jz a0235 ; выход с признаком заверш. -1 ; if (m==-1) return -1; a020C: cmp word ptr [bp-202h],-1 ; m == -1 a0211: jnz a021A a0213: cmp word ptr [bp-204h],-1 a0218: jz a0235 ; выход с признаком заверш. -1 ; if (m!=n) return -1; a021A: mov dx,[bp-202h] ; m (число записанных байтов) a021E: mov ax,[bp-204h] a0222: cmp dx,[bp-206h] ; n (число прочитанных байтов) a0226: jnz a0235 a0228: cmp ax,[bp-208h] a022C: jnz a0235 ; выход с признаком заверш. -1 ; if (i1==-1) return -1; a022E: cmp word ptr [bp-20Ch],-1 ; i1 (признак успешности закрытия файла1) a0233: jnz a023A ; =return -1 a0235: mov ax,-1 ; -1 a0238: jmp a023E ; return (i2); a023A: mov ax,[bp-20Ah] ; i2 (признак успешности закрытия файла2) ; гораздо компактнее было бы, если бы все проверки выполнялись на логических ; операциях в одной команде if... ; } ; выход из подпрограммы copy a023E: mov sp,bp ; исходное состояние стека a0240: pop bp ; восстановление содержимого bp a0241: ret ; main(int argc, char *argv[] ) основная процедура ; argc - число передаваемых строк символов ; *argv - указатель на массив символов ; { ; int ii, j, n, Files=0; ; char path[2][PATH_MAX]; a0242: push bp ; сохранение содержимого регистра bp a0243: mov bp,sp ; bp - указатель в стеке; ; "сверху" - переданные программе параметры, ; "снизу" - временные буфер и переменные. a0245: sub sp,206h ; резервирование двойного буфера в 2*FFh байт, ; по 2 байта для ii, j, n и Files a0249: mov word ptr [bp-200h],0 ; Files=0 ; номер половинки буфера для имени файла ; можно было бы обойтись одним индексом ii... ; argc--; a024F: dec word ptr [bp+4] ; argc=argc-1 ; (нулевую строку игнорируем) ; ii=1; a0252: mov word ptr [bp-206h],1 ; ii=1 ; номер строки массива (начали с первой строки) ; do ; копирование текстовых строк из массива во временный буфер ; (хотел бы я знать зачем...) и имитация обработки опций ; { ; if (argc) a0258: cmp word ptr [bp+4],0 ; argc == 0 a025C: jz a02C8 ; нет строк для копирования в буфер... ; { ; if (argv[ii][0]=='-') может признак опции? a025E: mov bx,[bp-206h] ; ii a0262: shl bx,1 ; ii*2 a0264: add bx,[bp+6] ; offset argv + ii*2 ; (адр. указателя на ii-ю строку символов) a0267: mov bx,[bx] ; указатель на 0-й символ ii-й строки a0269: cmp byte ptr [bx],2Dh ; == "-" a026C: jnz a029A ; else ; { ; реакция на опции ; n=(int)strlen(argv[ii]); a026E: push ds ; первый параметр на стек - seg argv[ii] a026F: mov bx,[bp-206h] ; ii a0273: shl bx,1 ; ii*2 a0275: add bx,[bp+6] ; offset argv + ii*2 a0278: push [bx] ; первый параметр на стек - offset argv[ii] a027A: call a0346 ; strlen a027D: add sp,4 ; коррекция указателя стека a0280: mov [bp-202h],ax ; n=длина строки ; for (j=1;j= ; switch (argv[ii][j]) ; { ; case 'N': никаких опций ;) ; default : cp_help(); return 1; a0294: call a0112 ; выдать подсказку... a0297: jmp a0311 ; return 1 ; } ; } ; else ; { ; strcpy(path[Files++],argv[ii]); ; копирование ii-й строки из массива в одну из половинок буфера, ; счётчик Files корректируется для указания на следующую половинку a029A: push ds ; первый параметр seg arg[ii] a029B: mov bx,[bp-206h] ; ii a029F: shl bx,1 ; ii*2 a02A1: add bx,[bp+6] ; offset argv + ii*2 ; (адр. указателя на ii-ю строку символов) a02A4: push [bx] ; первый параметр offset argv[ii] a02A6: push ds ; второй параметр seg path[Files] a02A7: mov ax,[bp-200h] ; Files 0...1 a02AB: inc word ptr [bp-200h] ; Files=Files+1 a02AF: mov dx,0FFh ; длина половинки буфера path a02B2: mul dx ; ax=текущая начальная позиция в буфере a02B4: lea dx,[bp-1FEh] ; адрес начала path a02B8: add ax,dx ; смещение текущей позиции для записи в память a02BA: push ax ; второй параметр offset path[Files] a02BB: call a0340 ; strcpy копирование строки ASCIIZ a02BE: add sp,8 ; коррекция указателя стека ; if (Files>2) {cp_help(); return 3;} a02C1: cmp word ptr [bp-200h],2 a02C6: jg a02DF ; Files>2 ; } ; } ; } ; while (ii++= a02D5: jmp a0258 ; возврат на DO ; if (Files<2) {cp_help(); return 3;} ; проверка того, что были переданы оба имени файла (лишние игнорир.) a02D8: cmp word ptr [bp-200h],2 a02DD: jge a02E7 ; Files>=2 якобы OK ; =cp_help();return 3 a02DF: call a0112 ; выдать подсказку... a02E2: mov ax,3 a02E5: jmp a0318 ; if ((copy(path[0],path[1]))==-1) ; копирование файла с проверкой успешности a02E7: lea ax,[bp-0FFh] a02EB: push ax ; первый параметр path[1] a02EC: lea ax,[bp-1FEh] a02F0: push ax ; второй параметр path[0] a02F1: call a011E ; подпрограмма copy a02F4: add sp,4 ; коррекция указателя стека a02F7: cmp ax,-1 ; == -1 a02FA: jnz a0316 ; нет, наверное файл скопирован упешно... ; { ; printf("Can't copy %s to %s\n",path[0],path[1]); a02FC: lea ax,[bp-0FFh] a0300: push ax ; первый параметр - адрес path[1] a0301: lea ax,[bp-1FEh] a0305: push ax ; второй параметр - адрес path[0] a0306: push ds ; параметр seg строки a0307: mov ax,a0365 ; смещение текстовой строки ; "Can't copy %s to %s",0Ah,0 a030A: push ax ; параметр offset строки ; весьма занятный алгоритм передачи адресов текстовых строк, ; некоторые дополняются значением сегмента, а другие нет... ; А не лажа ли это??? a030B: call a0322 ; printf a030E: add sp,8 ; коррекция указателя стека ; return 1; a0311: mov ax,1 a0314: jmp a0318 ; } ; return 0; a0316: xor ax,ax ; } ; выход из подпрограммы main a0318: mov sp,bp ; исходное состояние стека a031A: pop bp ; восстановление содержимого bp a031B: ret ; =puts a031C: mov ax,7 a031F: int 84h a0321: ret ; =printf a0322: mov ax,10h a0325: int 84h a0327: ret ; =open a0328: mov ax,24h a032B: int 84h a032D: ret ; =read a032E: mov ax,26h a0331: int 84h a0333: ret ; =write a0334: mov ax,27h a0337: int 84h a0339: ret ; =close a033A: mov ax,28h a033D: int 84h a033F: ret ; =strcpy a0340: mov ax,3Ch a0343: int 84h a0345: ret ; =strlen a0346: mov ax,40h a0349: int 84h a034B: ret a034C DB "Uses: cp [file1] [file2]",0 a0365 DB "Can't copy %s to %s",0Ah,0 man/files.bbs0100664000076500007650000000005607725642416012672 0ustar prool2prool2HELP.DOC help MEMMAP.DOC proolix memory map mkboot.bat0100664000076500007650000000203507725642373012311 0ustar prool2prool2@echo off cls echo ┌────────────────────────────────────────────────────────────────────┐ echo │ Создание загрузочного сектора ОС Proolix на дискете a: │ echo │ │ echo │ Boot maker (mkboot.bat) version 0.0.0.24 8-Nov-95 │ echo │ │ echo │ Каталог, в котором распакован файл proolix.arj │ echo │ должен быть текущим. │ echo │ │ echo │ Учтите, бут-сектор дискеты и вся │ echo │ информация, содержащаяся на дискете, могут быть запорчены !!! │ echo │ Нажмите CTRL BREAK, если Вы передумали связываться с Proolix'ом. │ echo │ В противном случае нажмите ANY KEY │ echo └────────────────────────────────────────────────────────────────────┘ pause>nul cls bp -i -y boots.bin readme.1st0100664000076500007650000002756307725642374012232 0ustar prool2prool2 Операционная система Proolix - файл readme Copyright (C) 1993-1999 Serge Pustovoitoff, prool@itl.net.ua, 2:461/35@FidoNet Portions copyright: PKLITE (tm) Executable File Compressor Version 1.15 7-30-92 (C) 1990-1992 PKWARE Inc. All Rights Reserved. Patent No. 5,051,745 PKWARE, Inc. 9025 N. Deerwood Drive Brown Deer, WI 53223 Content 1. PROOLIX not UNIX 2. Warranties & license 3. [skipped] 4. Install (Установка Пруликса) 5. RTFM - Read The F$%& Manual 6. VIRUS! 7. History 8. Trademarks 9. Credits 10. Contact & e-mail support 11. Литература 1. PROOLIX not UNIX Посвящается моей жене и дочери Вам предлагается находящаяся в процессе разработки POSIX-совместимая операционная система Proolix. Hа пути к POSIXу сейчас мы находимся примерно на уровне MSDOS 3.0 (без многозадачности). ;) 2. Warranties & license Я запустил Proolix в DOS-сессии под OS/2 и он сразу повис. Д.Завалишин Разpешается pаспостpанение и использование исходных текстов и самих пpогpамм, в том числе модифициpованных, пpи выполнении следyющих yсловий: Исходный текст pаспостpаняется с сохpанением вышеописанного копиpайта, данного списка yсловий и пpилагающейся деклаpации об ответственности. Все программы,матеpиалы или иные продукты с yпоминанием возможностей или использования этого пpогpаммного пpодyкта, должны выводить следyющее сообщение на русском, украинском и/или английском языках: > Этот пpодyкт включает пpогpаммы, pазpаботанные Сергеем Пустовойтовым > Ось цей продукт у своему складi мае програми, що навiщось розробив > пан Сергiйко Пустовiйтiв > This product includes software developed by the Serge Pustovoitoff Вы не получаете прямой или косвенной прибыли при распространении данного продукта. Мое имя не может использоваться и способствовать pаспостpанению пpодyктов, созданных на базе данного пpогpаммного пpодyкта, без специального письменного pазpешения. Этот пpогpаммный пpодyкт pаспостpаняется мной или назначенными мной лицами по принятому в компьютерной практике принципу "AS IS" ("КАК (ЧТО) ЕСТЬ" - так(то) и предлагаем). Любые гаpантии, подpазyмевающиеся или явно выpаженные, включая (но не огpаничиваясь) подpазyмевающиеся гаpантии товаpного вида и пpигодности для опpеделенных пpименений, не действительны. Автор не дает никаких гарантий, ни явных, ни подразумеваемых, что данный комплекс программ не выведет из строя Ваше аппаратное или программное обеспечение и не причинит прямых или косвенных убытков Вашему благосостоянию или здоровью. Hи в коем слyчае автор не может нести ответственность за любые пpямо, косвенно, слyчайно, особо, типично или логически возникшие повpеждения (включая, но не огpаничиваясь, поставкy сопyтствyющих товаpов и yслyг, потеpю pаботоспособности, данных, пpибыли или пpиостановкy деятельности) в любой тpактовке ответственности, контpакта, стpогой ответственности или пpавонаpyшения (включая небpежность или что-либо), вытекающие из использования данного пpодyкта любым обpазом, даже если заpанее известно о возможности подобного повpеждения. В случае повреждений претензии не принимаются, однако, если Вы сообщите мне условия, при которых произошла авария, я, возможно, смогу помочь: например, советом, как восстановить софт, запорченный моей ОС или консультацией по применению Пруликса или высылкой Вам новой версии или исправлением замеченных Вами ошибок в Пруликсе. Также я постараюсь исправить замеченные баги в ОС, чтобы впредь подобных аварий не повторялось. 4. Install "Make Proolix not war" ОС в минимальном комплекте (без исходников и библиотек) поставляется в виде одного архива (текущей поставкой является Proolix SlimeWare в архиве slime?.arj), запакованного архиватором arj. Для установки ОС необходимо распаковать архив в каталог c:\proolix на Вашем жестком диске и запустить одну из программ install?.bat. (installb.bat инсталлирует Пруликс на дискету A:, откуда он и будет потом грузиться. installh.bat инсталлирует Пруликс на винчестер, диск C: (master boot record и boot-sector винчестера не меняется, загрузка все равно будет с дискеты, с нее загрузится boot-manager и передаст управление находящемуся на винчестере ядру)). Для машин без винчестера Пруликс можно распаковать на диске B: и запускать installb оттуда. Для машин без второго дисковода, чтобы сделать загружаемую Пруликс-дискету, необходимо создать на дискете бут-сектор Пруликса, запустив mkboot.bat и скопировать в корневой каталог дискеты файл kernel.bin, переименовав его в kernel. (Внимание: В файле install.bat была ошибка и он нормально работает только, начиная с версии 0.0.0.8 5-Jan-94, (версия помечена в самом файле install.bat)). После чего можно загружаться с дискеты A: и пытаться работать в ОС Proolix. 5. RTFM - Read The F$%& Manual Что умеет делать эта версия Proolix'а: - MSDOS-программа Boot Processor (bp.com) умеет копировать бут в файл, файл в бут и инсталлировать командный (com) файл в бут сектор дискеты, не меняя параметров дискеты, которые, как известно, находятся в буте. Таким образом, при помощи этой программы Вы сможете делать свои буты. (Только вот зачем? Впрочем, иногда это полезно. Известен антивирусный бут VITAMINB Сессы. Известен бут (где-то в Софтпанораме был), который при попытке загрузки с дискеты производит загрузку с винта - он тоже может иметь антивирусное назначение или просто для удобства служить). - программа boot.asm - это мой личный бут-загрузчик, расположенный в первом секторе дискеты. Он загружает и запускает обычный ДОСовский файл /BOOT (boot manager). При этом файл может быть в корневом каталоге не первым и занимать на диске сколько угодно несмежных кластеров. Мой бут следит по FATу. - /BOOT - автономная программа, загружаемая бут-загрузчиком. Это - boot manager ОС Proolix. Hаписан на С. Boot manager может загружать ядро Пруликса с дискеты A:, раздела винчестера C:, может принудительно загружать MSDOS (или другую ОС) с винчестера при наличии дискеты в A: и т.п. - KERNEL - автономная программа, загружаемая бут-менеджером. Это - ядро ОС Proolix. Hаписано на С. Как компилировать, см. внимательно файл makefile и исходник ядра - файл kernel.c. Так как ядро работает автономно, без МС ДОС, только в присуствии ROM BIOS, то большинство функций языка С, использующих запросы к ДОС, не работает. Я написал на ассемблере и на С некоторый минимум функций. Hабор непрерывно расширяется и почти ежедневно выпускаются новые версии с новыми функциями и исправлением замеченных багов и глюков. - описания других файлов ОС можно найти в файлах dir или files.bbs, а также в других файлах документации. Краткий свод внутренних и внешних команд Пруликса можно получить, используя команду help. (Слово "внутренний" понимается в том же смысле, в котором команды cd/chdir MSDOS и UNIX'а являются внутренними). 6. Антивирусная защита Файловые вирусы, ориентированные на MSDOS операционной системе Proolix не страшны по определению, а против бутовых вирусов имеется проверка в бутсекторе и в начале ядра. (Проверка сделана по идее, предложенной Юрием Белотицким, bela@padco.kharkov.ua). Бут-сектор Пруликса, обнаружив на диске, с которого загружается Пруликс, бутовый вирус, выводит символ V на экран и ждет нажатия любой клавиши. Увидев символ V я рекомендую вставить в дисковод A: заклеенную заведомо стерильную дискету с MSDOS и антивирусными средствами, а затем перезагрузиться с диска A: (но не по Ctrl-Alt-Del, а по reset!) и произвести лечение имеющимися средствами (Aidstest, ADinf Cure Module, Dr.Web, format c: etc). Рекомендую также для профилактики от бутовых вирусов использовать вакцину VitaminB Сессы. 7. История История ведется в файле history.doc 8. Trademarks Пруль, Prool, PROOL, prool, пруль, Proolix, PROOLIX, Пруликс, ПРУЛИКС, Прулих, ПРУЛИХ, XProolix, XPROOLIX, xproolix, ХПрулих, ХПРУЛИХ, ХПруликс, ХПРУЛИКС, хпрулих, хпруликс - торговые марки Пруля JNP, jnp, Джей-Эн-Пи - - торговые марки компьютерного клуба JNP (Харьков) Остальные упомянутые в тексте торговые марки imho кому-нибуль да принадлежат 9. Credits Благодарю лиц, в той или иной степени заинтересовавшихся Пруликсом и/или прямо или косвенно помогавших мне. Вот их неполный список: Валерий Рабинович, Университет им.Вейцмана (Израиль), Игорь Чунихин, Sprint, igor@ktts.kharkov.ua, Вадим Гарбуз, vega@itl.net.ua, Слава Землянский, агентство "Интерфакс", zema@interfax.kiev.ua, Дмитрий Городчанин, Linux Team, Дима Орлов, 2:461/27@Fidonet Андрей Головченко, Андрей Петров, 2:461/35.444@Fidonet, ХАДИ, Саша Селуянов, 2:461/144@Fidonet, Михаил В. Синцов, Юрий Белотицкий, СП "PADCO", Игорь Cазонов (2:461/61.99@Fido), Гена Лапин, Гриша Бочаров, Алекс Семеняка, Университет Флориды, Михаил Щербак, Mike Aizatsky, 2:461/21.100@Fidonet, Хиргий H.И., Харьковский государственный университет, Sergey Goudzenko, 2:461/416, Ральф Браун (Ralf Brown) - его Interrupt List - полнейший и подробнейший справочник по архитектуре PC! Сергей Ивашинников, Владивосток, Tony Perminov, 2:461/200.12@Fidonet PKWARE, Inc за free версию упаковщика PKLITE Егор Егоров, Linux Team, Soft-ICE by Nu-Mega Technologies, MARQUIS DE SOIREE, PartitionMagic by PowerQuest 10. Contact & e-mail support Как связаться с автором, смотри в файле support.txt Автор ОС Proolix - Сергей Пустовойтов, также известный как Serge Pustovoitoff и Пруль (Prool). Его адреса: Internet prool@infocom.kharkov.ua FidoNet 2:461/35 WWW http://www.infocom.kharkov.ua/~prool Voice phone +380(572)235102, 123445 11. Литература [Бах] "АРХИТЕКТУРА ОПЕРАЦИОННОЙ СИСТЕМЫ UNIX" Морис Дж. Бах (Перевод с английского к.т.н. Крюкова А.В.) ("THE DESIGN OF THE UNIX OPERATING SYSTEM" by Maurice J. Bach) Copyright c 1986 Корпорация Bell Telephone Laboratories. Издано корпорацией Prentice-Hall. Отделение Simon & Schuster Энглвуд Клиффс, Нью-Джерси 07632 Серия книг по программному обеспечению издательства Prentice Hall. Консультант Брайан В. Керниган ISBN 0-13-201757-1 025 [Готье] Готье Р. Руководство по операционной системе UNIX / Пер. с англ. - М.: Финансы и статистика, 1985. - 232 с. [МОС] Мобильная операционная система: Справочник. - М.: Радио и связь, 1991. - 208 с. ISBN 5-256-00581-2 [Керниган и Пайк] Керниган Б.В., Пайк Р. UNIX - универсальная среда программирования. - М.: Финансы и статистика, 1992 [Hикитенко] Hикитенко Александр, "PTS-DOS или MS-DOS?". - "Computer World Киев", 28 декабря 1994, No 23(23), с.6. [Amstrad] Amstrad personal computer PC 1640. User instructions. Second edition, 1987 [Interrupt List] Interrupt List, Release 48, Last change 10/29/95 This compilation is Copyright (c) 1989,1990,1991,1992,1993,1994,1995 Ralf Brown [TECH Help!] TECH Help! ver 1.2 Copyright (c) 1985,1986,1987 by Dan Rollins and Flambeaux Software Перевод на русский С.М.Абель [PC Help] [Help PC] HelpPC 2.10 Quick Reference Utility Copyright (c) 1991, David Jurgens readme.2nd0100664000076500007650000001513107725642374012172 0ustar prool2prool2 Как инсталлировать Пруликс на винт (для загрузки с винта) ver.2 24.Feb.98 --------------------------------------------------------- Инсталлировать мой бутсектор в бутсектор винта, не повредив таблицу параметров, можно при помощи BP.C (Boot Processor). Правда, в использовании утилиты BP хрен разберешься. Пока нет подробного описания, которое удовлетворило бы взыскательный вкус Георгия Шепелева, дам ряд хинтов: 1. BP написано через жопу 2. BP без параметров делает вид, что выдает хелп 3. Главный параметр командной строки -d<цифра> это номер устройства, а именно: 0 - флоп A: 1 - флоп B: 2 - винт (раздел C:) 3 - ... Вы думаете, что 3 - это раздел D: ? Хрен там! Я не знаю, кто придумал Extended Partition, но похоже, это Microsoft и ему пора за это оборвать... уши. Идея вроде неплохая для своего времени, но сколько она геморрая принесла (в мелкомягком исполнении). Итак, рассмотрим типичную конфигурацию ламерского компьютера: у Вас стоит на C: Windows 95, еще на винте есть Extended partition, состоящий из одного логического диска - D: (например, выделенного для Пруликса). Так вот, программа BP считает extended partition отдельным разделом (нулевой длины), а каждый логический диск - еще одним разделом (более-менее обычным). Поэтому у Вас будет: 2 - раздел C: (Primary partition) 3 - Extended partition 4 - logical disk D: (заметим в скобках, что структура Extended partition очень похожа на структуру главной Partition Table из MBR (Master Boot Record)) Hо это еще не все. Стандартными средствами Windows 95 сделать диск D: загружаемым нельзя! Можно сделать sys d:, можно потом командой fdisk сделать активным раздел D:, но грузиться с него будет нельзя! Почему? Рассмотрим процесс загрузки подробнее. В начале загрузки в память загружается Master Boot Record, содержащая главную Partition Table и ей передается управление. Содержащася в MBR программа определяет активный раздел, загружает в память его бутсектор и передает ему управление, а бутсектор в свою очередь загружает свою операционную систему. Когда у Вас Windows 95 на C: (а она вообще на D: умеет ставиться?), то все работает нормально, как и было задумано. Hо Вы хотите создать еще один раздел, помимо C: Обычный FAT-раздел Windows 95 создать не даст, она может создать толко extended раздел, а на нем - один или несколько логических дисков. Вот ту-то и начинается самое интересное. Активным (загружаемым) Виндовс может сделать только extended раздел (именно он упомянут в Master Partition Table). Hо грузиться с этого раздела нельзя, так как его бутсектор заполнен нулями (а не программой загрузки) и стандартными средствами Windows ничем другим не заполняется). Поэтому надо не только сделать extended partition активным командой fdisk, но и переписать туда копию программы загрузки из MBR (сделать это можно только моей программой BP или нортоновским диск-эдитором, но BP это делает удобнее ;) bp -d@ mbr bp -d3 -i -a0 mbr Теперь можно грузиться с той операционной системы, что установлена на логическом диске D: Туда можно установить MSDOS/MS Windows командой sys d: или format d: /s или Пруликс командами bp -d4 -i booth16 copy a:*.* d: (если распакованный дистрибутив Пруликса у Вас на a:) Приложение. Параметры программы BP. Самый простой вызов BP примерно такой: bp -d0 file При этом бутсектор устройства 0 копируется в файл file и заодно отображается на экране в форме таблицы. О соответствии цифр реальным дискам уже говорилось выше, замечу только, что псевдоустройство @ - это Master Boot Record. Обратный процесс (копирование из файла в бутсектор) осуществляется добавлением флага -r ("реверс"). Так, скопировать нечто в MBR можно командой bp -d@ -r nechto ВHИМАHИЕ! Я очень не рекомендую копировать что-либо в MBR своего винчестера, если Вы не уверены в корректности и необходимости этих действий. Можно легко и сразу потерять всю информацию, содержащуюся на винте (дискете). (Впрочем, Windows может и не разрешить Вам это сделать...) Еще я не рекомендую вообще использовать ключ -r , так как он перезаписывает _весь_ бутсектор, в том числе таблицу параметров и при этом тоже возможны достаточно неприятные глюки (тоже можно потерять всю информацию с диска) Для инсталляции своей программы загрузки в бутсектор рекомендуется ключ -i ("инсталляция"), который копирует в бутсектор только программный код, оставляя таблицу параметров или таблицу разделов не изменившейся. Вот так можно проинсталлировать пруликсный бутсектор на дискету A: bp -d0 -i boots.bin И, наконец, параметр -a<цифра> используется при инсталляции программы загрузки на MBR-подобное псевдоустройство (MBR (-d@) или extended partition). Используя этот параметр, можно указать активный (загружаемый) раздел - например, активный логический диск на Extended партиции. (Играться параметром -a с MBR я настоятельно не рекомендую, для этого есть системная программа fdisk. Впрочем, по-моему, в коде программы BP у меня есть защита от сочетания флагов -d@ -a и -i или -r . А может и нет такой защиты...) И еще, программа BP в процессе работы выдает таблицу всех разделов на вашем винте. Советую смотреть на эту таблицу. Вот пример такой таблицы для винта, имеющего разделы c:, d:, e: Boot Processor 0.1.4 24-Feb-98 (C) 1993-1998, S.Pustovoitoff Dev Head Sec Trk/cyl Partition ------------------------------- 0 floppy drive 1 floppy drive 2 1 1 0 LARGE (06) 3 0 193 15 EXTENDL (0F) 4 1 193 15 FAT-12 (01) 5 0 193 18 EXTEND (05) 6 1 193 18 FAT-12 (01) Как видите, 2 - это раздел c: (primary partition), 3 - первая extended partition, 4 - раздел (логический диск) d:, 5 - вторая extended partition, 6 - раздел (логический диск) e: Как видите, каждому логическому диску предшествует extended partition Просьба ко всем, кто это читает: Если вам не облом, потестируйте мой бутсектор. Для этого даже не надо инсталлировать на винт полный Пруликс. Инсталлируйте, скажем на D:, бутсектор (файл src/boot/booth16.bin из дистрибутива, если у Вас FAT-16 и booth12.bin, если FAT-12) и скопируйте на D: в корень бутменежер (файл src/bm/boot) (при необходимости инсталлируйте в Extended partition программу загрузки из MBR, как все это делать, описано выше). Сделав D: (Extended partition) активным попробуйте перегрузиться (заранее приготовив загрузочную rescue дискету!). О результатах напишите: E-mail prool@prool.kharkov.ua Fido 2:461/35 src/0040775000076500007650000000000007725643123011112 5ustar prool2prool2src/gist.doc0100664000076500007650000000257207725642462012557 0ustar prool2prool2 19│Prool's activity for Proolix development 18│ ██████ 17│ ██████ 16│ ██████ 15│ ██████ 14│ ██████ 13│ ██████ 12│ ████████████ ███ 11│ ████████████ ███ ███ 10│ ██████████████████ ███ ███ 9│ ███ ██████████████████ ███ ███ 8│ ███ █████████████████████ ███ ███ 7│ ███ ███ █████████████████████ █████████ 6│ ███ ██████ █████████████████████ █████████ 5│ ███ ██████ ████████████████████████ █████████ 4│ ███ ██████ ████████████████████████ █████████ 3│ █████████ █████████ ███████████████████████████ █████████ 2│ █████████ █████████ ███████████████████████████ █████████ 1│████████████ █████████ ██████████████████████████████ █████████ 1993───1994────────────────────────────────1995───────────────────────────── DecJanFebMarAprMayJunJulAugSepOctNovDecJanFebMarAprMayJunJulAugSepOctNov src/bm/0040775000076500007650000000000007725643473011520 5ustar prool2prool2src/bm/files.bbs0100664000076500007650000000021507725643472013304 0ustar prool2prool2CB.ASM Boot manager CRT file (asm) MAKEFILE Makefile BOOT.OLD Boot manager (src) MAKEFILE.OLD Makefile src/bm/msdos.asm0100664000076500007650000000143607725643473013350 0ustar prool2prool2_TEXT segment byte public 'CODE' assume cs:_TEXT _msdos proc extrn _RestoreVec:near ; вернуть старые прерывания cli call _RestoreVec sti xor ax,ax mov ES,ax ; Read MBR mov dl,80h ; drive mov dh,0 ; head mov cl,1 ; sec mov ch,0 ; trk mov al,1 ; sec count mov ah,2 ; Fn read mov bx,7c00h int 13h nop jc @@reboot ;jmp 0:7c00 db 0eah dw 7c00h dw 0 @@reboot:; jmp ffff:0 db 0eah dw 0 dw 0ffffh _msdos endp public _msdos _TEXT ends end src/bm/hdd2.asm0100664000076500007650000000143307725643472013040 0ustar prool2prool2_TEXT segment byte public 'CODE' assume cs:_TEXT _hdd2 proc extrn _RestoreVec:near ; вернуть старые прерывания cli call _RestoreVec sti xor ax,ax mov ES,ax ; Read MBR mov dl,81h ; drive mov dh,0 ; head mov cl,1 ; sec mov ch,0 ; trk mov al,1 ; sec count mov ah,2 ; Fn read mov bx,7c00h int 13h nop jc @@reboot ;jmp 0:7c00 db 0eah dw 7c00h dw 0 @@reboot:; jmp ffff:0 db 0eah dw 0 dw 0ffffh _hdd2 endp public _hdd2 _TEXT ends end src/bm/out_mbr.c0100664000076500007650000000170407725643473013332 0ustar prool2prool2#include void outMBR (char far *buf) { int i; struct MBRstru far *MBR; MBR=(void far *)buf; printf("System ----Begin---- ----End----- Preceding sec Total sec\n"); printf(" head sec cyl head sec cyl\n"); /* "A FAT 12 iiii ii iiii iiii ii iiii iiiiiiiiii iiiiiiiiii\n" */ for (i=0;i<4;i++) {unsigned int j; if (MBR->Partition[i].indicator==0) printf(" "); else printf("A"); printf(" "); out_os(MBR->Partition[i].system_indicator); printf(" %4i ",MBR->Partition[i].begin_head); printf("%2i ",(j=MBR->Partition[i].begin_sec) & 0x3F); j = (j & 0xC0)<<2; printf("%4i ",MBR->Partition[i].begin_cyl | j); printf("%4i ",MBR->Partition[i].end_head); printf("%2i ",(j=MBR->Partition[i].end_sec) & 0x3F); j = (j & 0xC0)<<2; printf("%4i ",MBR->Partition[i].end_cyl | j); printf("%10lu ",MBR->Partition[i].preceding_sec); printf("%10lu\n",MBR->Partition[i].total_sec); } } src/bm/tlib.cmd0100664000076500007650000000045007725643473013133 0ustar prool2prool2bootl/C/E-+printf-+sec4clu2-+mem-+tolower-+conv-+ctype-+strchr-+char_in-+char_out-+string-+putch0-+getch0-+kbhit-+txtattr-+hdd2-+msdos-+cold-+reboot-+bootread-+out_os-+cursor-+videopag-+int86-+out_mbr & -+int13err-+readsec-+bootred0-+vector-+out_iv-+viewexe-+nextclu2-+cluread-+strlen-+absread src/bm/cb.asm0100664000076500007650000001220707725643472012604 0ustar prool2prool2; Startup module for Proolix /boot (similar c0t.obj from Turbo C 2.0 and ; similar crt.o from UNIXs) ; Version 0.0.1.7 23-Apr-97 ; History ; 0.0.1.7 23-Apr-97 ; 0.0.1.6 22-Apr-97 ; 0.0.1.5 20-Apr-97 отловлен большой глюк с mov SP, ... ; 0.0.1.4 10-May-96 add internal stack ; 0.0.1.3 9-Mar-96 ; 0.0.1.2 27-Feb-96 ... ; 0.0.1.1 26-Feb-96 cb.arj ; 0.0.1.1 25-Feb-96 cb.arj ; 0.0.1.0 11-Jan-96 cb.arj ; ; 0.0.0.15 5-Nov-95 c0.asm ; 0.0.0.15 4-Nov-95 ... ; 0.0.0.14 15-Jan-95 c0.asm sayr macro str ; В графических режимах не работает push si lea si,str ; Было mov si,offset str call sayr_proc pop si endm sayr chr macro sym ; via BIOS ; Not worked in graph mode (bl - bg color!) ; NO SAVE REG mov al,sym mov ah,0eh int 10h endm chr KernPSP equ 50h _TEXT segment byte public 'CODE' DGROUP group _TEXT,_DATA,_BSS org 100h assume cs:DGROUP,ds:DGROUP ; ,ss:DGROUP .8086 _Begin: mov ax,CS mov DS,ax mov ES,ax ; mov DGROUP@,ax cli mov SS,ax mov SP,offset 0FFECH ; StackEnd ; 0fffeh sti ; chr 'A' ; call _saycsip extrn _main:near jmp _main _kernel_start: public _kernel_start ; mov ax,KernPSP mov DS,ax mov ES,ax cli mov SS,ax mov SP,0fffeh sti db 0eah ; /* KERNEL START: JMP 50:100 */ dw 100h,KernPSP ; ;DGROUP@ dw 0 ;public DGROUP@ ; comment | _saycsip proc near ; REG SAVED push ax push DS chr 'i' chr 'p' chr '=' push CS pop ax call ohw chr ':' call ll ll: pop ax call ohw chr ' ' chr 'd' chr 's' chr '=' push DS pop ax call ohw push CS pop DS sayr s_ax pop ax push ax call ohw sayr s_bx mov ax,bx call ohw sayr s_cx mov ax,cx call ohw sayr s_dx mov ax,dx call ohw sayr s_si mov ax,si call ohw sayr s_di mov ax,di call ohw sayr s_ss mov ax,SS call ohw sayr s_sp mov ax,SP call ohw sayr s_es mov ax,ES call ohw sayr s_bp mov ax,BP call ohw pop DS pop ax ret ;s0 db 13,10,"CS:IP=",0 s_ax db ' ax=',0 s_bx db ' bx=',0 s_cx db ' cx=',0 s_dx db ' dx=',0 s_si db ' si=',0 s_di db ' di=',0 s_ss db ' SS=',0 s_sp db ' SP=',0 s_ds db ' DS=',0 s_es db ' ES=',0 s_bp db ' BP=',0 _saycsip endp ohw proc ; Вывод слова в HEX-виде. Вход: слово в ax. ; Все регистры сохраняются. ; Вызывает подпрограмму ohb push ax ; Сохр. ради al. mov al,ah call ohb pop ax ; Восст. al. call ohb ret ohw endp sayr_proc proc ; Процедура вывода строки при помощи функций BIOS ; Вход: DS:SI - ASCIIZ строка. ; All registers saved ; В графических режимах не работает ; ALL REGS SAVED! push ax push si PUSHF cld sayr_l1: lodsb or al,al jz sayr_ret mov ah,0eh int 10h jmp short sayr_l1 sayr_ret: POPF pop si pop ax ret sayr_proc endp ohb proc ; Procedure output hex byte Ver 0.1.1 6 Dec 93 via BIOS ; Input: AL - byte ; All regs. reserved ;) ; Not worked in graph mode. bl - bg color !!! push ax push cx push dx mov dl,al mov cl,4 shr al,cl call ohb1 mov al,dl and al,0fh call ohb1 pop dx pop cx pop ax ret ohb endp ohb1 proc ; Regs not saved !!! push ax cmp al,9 ja @@_1 ; al > 9 ; al <= 9 add al,'0' jmp @@_out @@_1: add al,'A'-10 @@_out: mov ah,0eh int 10h pop ax ret ohb1 endp ; | _TEXT ends _DATA segment byte public 'DATA' _DATA ends _BSS segment byte public 'BSS' _BSS ends end _Begin src/bm/boot.h0100664000076500007650000000012107725643472012622 0ustar prool2prool2#define EXTEND 5 #define EXTEND2 0xF #define _HDD_ 0x80 #define MAX_LINES 22 src/bm/boot.c0100664000076500007650000006067507725643472012641 0ustar prool2prool2#define VERSION "Proolix boot manager ver. 0.0.1.2 26-Aug-99" /* #define DEBUG */ /* History in reverse order 0.0.1.2 26-Aug-99 - 0.0.1.1, compile by Turbo C 2.01 (all previous compiled by TC 2.0) 0.0.1.1 23-Feb-99 - add NumLock off, anykey for interrupt boot sec. 0.0.1.0 10-Mar-98 0.0.0.29 15-Feb-98 0.0.0.28 4-Feb-98 0.0.0.27 18-Aug-97 0.0.0.26 10-Aug-97 0.0.0.25 31-May-97 0.0.0.24 31-May-97 0.0.0.23W 12-May-97 - add command MORE and NOMORE 0.0.0.22 11-May-97 - F1 - boot from 1st HDD 0.0.0.21 6-May-97 - сделана работа с кластерами до 32К включительно 0.0.0.20 1-May-97 - fixed case Cylinder>255 in HDD 0.0.0.19 27-Apr-97 - booted from A:, B:, C:, D:, etc... 0.0.0.18 26-Apr-97 0.0.0.17 23-Apr-97 0.0.0.16 22-Apr-97 0.0.0.15 21-Apr-97 0.0.0.14 20-Apr-97 - отловлен большой глюк с mov SP, ... 0.0.0.13 19-Apr-97 - add boot.h and AUTOSTART preprocessor variable 0.0.0.12 12-May-96 - вынес Cluster в static 0.0.0.11 21-Apr-96 0.0.0.10 20-Apr-96 - /boot теперь сжат PKLite'ом 0.0.0.9 15-Apr-96 - делаю загрузку с любого раздела винчеcтера (а не только с C: как это было раньше) 0.0.0.8 11-Apr-96 - сделал работу с FAT размером больше, чем 64К 0.0.0.7 6-Apr-96 0.0.0.7 5-Apr-96 0.0.0.6 4-Apr-96 0.0.0.5 31-Mar-96 0.0.0.5 30-Mar-96 - HDD... 0.0.0.4 27-Mar-96 - add "dump" command 0.0.0.3 25-Mar-96 0.0.0.2 18-Mar-96 - работало только с кластерами 1024к (работало с 3" 720k дискетами и не работало с 3" 1.2M) 0.0.0.1 13-Mar-96 0.0.0.1 12-Mar-96 0.0.0.1 9-Mar-96 0.0.0.0 27-Feb-96 */ #include #include #include #include #include #include #include #include #include #include #include "boot.h" #define AUTOSTART #ifndef DEF_BOOT #define DEF_BOOT 0 /* default boot device 0 - a: 1 - b: 2 - c: */ #endif #define CLUSTER_ADDR MK_FP(0x4050, 0) #define FAT_ADDR MK_FP(0x5050, 0) #define COMMAND_LINE 80 #define KERNEL_BEGIN_SEG 0x60 #define EXE_HEADER_SIZE 0x1c #define MAX_CLU_SEC 64 /* 64 */ /* 16 */ #define PSP KERNEL_BEGIN_SEG-0x10 #ifdef _HERCULES_ #define MAIN_COLOR 7 #else #define MAIN_COLOR 11 #endif #define ReadPhysSec2 ReadPhysSec unsigned char NearBuffer [SECTOR_SIZE]; char far * pCluster; unsigned long RootBeg; unsigned long RootEnd; int CurrentDevice; int FATMode; struct BootStru *B; char huge *FAT ; int NextDrive=2; /* disk C: */ int NextDOSDrive='C'; void kernel_start (void); struct DeviceStruct Devices [LASTDRIVE]; /* Devices [0] - disk A: sec=0 if not present Devices [1] - disk B: sec=0 if not present Devices [2] - disk C: sec=0 if not present Devices [3] - disk D: sec=0 if not present ... */ /*--------------------------------------------------------------------------*/ int TextAttr=MAIN_COLOR; char far *KbdStatus; char Russian [256]; char Buf [SECTOR_SIZE]; char Buf2 [SECTOR_SIZE]; char MBRBuf [SECTOR_SIZE]; char command [COMMAND_LINE]; int errno; int SectorsOnCyl; unsigned long MaxSectors; int TrkSecs; int HeadCnt; int CluSize; unsigned int CluSizeBytes; int FatSize; int FatCnt; unsigned long ResSecs; unsigned long DataStart; unsigned int TargetForBugs; unsigned int MaxClusters; int More=0; int NLine=0; /****************************************************************************/ void cold (void); void hdd2 (void); void out_os (int c); #include "..\kernel\ppt.c" /****************************************************************************/ void ident (void) { printf("\n\n%s\n\n",VERSION); #ifdef AUTOSTART printf("Press ESC fastly for interrupt boot sequence\n"); #endif printf("help - help\n\n\ Enter - load standard Proolix kernel\n\n\ F1 - forced boot from 1st HDD\n\n\ "); } /****************************************************************************/ void help (void) { ident(); printf("\ help - this help\n\ 0:\n\ 1: - set FDD\n\ 2:\n\ 3:\n\ ... - set HDD\n\ reboot - hot reboot\n\ cold - cold reboot\n\ msdos - load OS from HDD 0\n\ hdd2 - load OS from HDD 1 (if present)\n\ ls - ls\n\ more - set more on\n\ nomore - set more off\n\ dump filename - hex dump of filename\n\ "); } /****************************************************************************/ int TR (int curdev) { if (curdev>1) return _HDD_; /* HDD */ else return curdev; /* FDD */ } /****************************************************************************/ void RestoreVec (void) { } /****************************************************************************/ int sema_lock (void /* ;) */ ) { return 0; } /****************************************************************************/ void sema_unlock (void /* ;) */ ) { } /****************************************************************************/ int putch__(char c) { switch (c) { case 0: c=' '; break; default: if (c<' ') c='.'; } return putch(c); } /****************************************************************************/ #ifdef DEBUG void out_boot(void far *buf) {int i; unsigned long DiskSize; unsigned long TrueSectors; struct BootStru far *b; b=buf; printf("\n\ ----------------------------------Disk parameters:------------------------------\n"); printf("Jump command %02X %02X %02X \n",(*b).Jmp[0],(*b).Jmp[1],(*b).Jmp[2]); printf("OEM name %-8s\n\ OEM name ",(*b).OEM); for(i=0;i<8;) printf("%02X ",(*b).OEM[i++]); #if 1 printf("\nSector size %4i bytes Cluster size %1i sect\n",(*b).SectSiz,(*b).ClustSiz); printf("Reserved sectors (before 1st FAT) %2i FAT counter %1i\n",(*b).ResSecs,(*b).FatCnt); printf("Root directory entries %4i Total sectors %7u\n",(*b).RootSiz,(*b).TotSecs); printf("Media descr %02X FAT size %5i sect\n",(*b).Media,(*b).FatSize); printf("Track size %2i sec Heads %2i\n",(*b).TrkSecs,(*b).HeadCnt); printf("Hidden sectors %7li Big Number Of Sectors %7li\n",(*b).HidnSec,(*b).BigSect); printf("Physical Drive No %02X Extended Boot Signature %02X\n",(*b).DriveNo,(*b).BootSign); printf("Volume Serial No %04X-%04X\n", (*b).SerialNo[1], (*b).SerialNo[0]); #endif printf("\nVolume Label (in boot) "); for(i=0;i<11;)putch__((*b).VolLbl[i++]); printf("\n "); for(i=0;i<11;)printf("%02X ",(*b).VolLbl[i++]); printf("\nFile system Id "); for(i=0;i<8;)putch__((*b).FileSysId[i++]); printf("\n "); for(i=0;i<8;)printf("%02X ",(*b).FileSysId[i++]); if ((*b).TotSecs==0) TrueSectors=(*b).BigSect; else TrueSectors=(*b).TotSecs; DiskSize=((long) (*b).SectSiz * TrueSectors)/1024l; if (DiskSize>5000) { DiskSize/=1024; printf("\nDisk size %li Mb\n",DiskSize); } else { printf("\nDisk size %li Kb\n",DiskSize); } } #endif /****************************************************************************/ void setdisk (int NewDevice) {int sec, head, trk, olddevice, oldpart; unsigned long i; olddevice=CurrentDevice; CurrentDevice=NewDevice; if (NewDevice>1) { /* HDD */ if (Devices[NewDevice].sec==0) { printf("bootman: invalid device\n"); CurrentDevice=olddevice; return; } head=Devices[NewDevice].head; sec=Devices[NewDevice].sec; trk=Devices[NewDevice].trk; if (ReadPhysSec (_HDD_, sec, head, trk, Buf)) { printf ("boot: partition boot sector read error\n"); CurrentDevice=olddevice; return; } /* printf("========================================================\n"); */ B = (void *) Buf; #if 0 out_boot((void far *) Buf); #endif HeadCnt=B->HeadCnt; TrkSecs=B->TrkSecs; SectorsOnCyl=HeadCnt*TrkSecs; #if 0 ResSecs=(unsigned long)Devices[NewDevice].sec+ (unsigned long)Devices[NewDevice].head*(unsigned long)TrkSecs+ (unsigned long)Devices[NewDevice].trk*SectorsOnCyl; #else ResSecs=(unsigned long)(Devices[NewDevice].sec & 0x3F)+ (unsigned long)Devices[NewDevice].head*(unsigned long)TrkSecs+ (unsigned long)(Devices[NewDevice].trk|((int)(Devices[NewDevice].sec & 0xC0)<<2))* SectorsOnCyl; #endif #ifdef DEBUG printf("ResSecs=%lu\n",ResSecs); #endif MaxSectors=Devices[NewDevice].MaxSectors+ResSecs; FATMode=Devices[NewDevice].FileSystem; } else { /* FDD */ if (Devices[NewDevice].sec==0) { printf("bootman: invalid device\n"); CurrentDevice=olddevice; return; } if (bootread0 (CurrentDevice, Buf)) { printf ("boot: boot sector read error :( \n"); CurrentDevice=olddevice; return; } B = (void *) Buf; #if defined (DEBUG) out_boot((void far *) Buf); #endif if ((i=B->ResSecs)!=0) ResSecs=i; ResSecs=B->HidnSec+1; if ((i=B->TotSecs)!=0) MaxSectors=i; else MaxSectors=B->BigSect+B->HidnSec; #ifdef DEBUG printf("MaxSectors=%li\n",MaxSectors); #endif HeadCnt=B->HeadCnt; TrkSecs=B->TrkSecs; SectorsOnCyl=HeadCnt*TrkSecs; FATMode=FAT12; } CluSize=B->ClustSiz; if (CluSize>MAX_CLU_SEC) printf("\nPANIC!!! Cluster size=%i sec - is too large for this realization\n\n\ Max supported cluster size=%i sec\n\n",CluSize,MAX_CLU_SEC); CluSizeBytes=CluSize * SECTOR_SIZE; FatSize=B->FatSize; FatCnt=B->FatCnt; RootBeg = ResSecs + B->FatCnt * B->FatSize; RootEnd = RootBeg + ( ( B->RootSiz * 32 ) / B->SectSiz ) - 1; DataStart = RootEnd+1; MaxClusters=(unsigned int)((MaxSectors-DataStart)/CluSize+1); #ifdef DEBUG printf("RootBeg =%lu\n",RootBeg); printf("RootEnd =%lu ",RootEnd); printf("ResSecs =%lu ",ResSecs); printf("MaxSectors =%lu =%08lX MaxClusters =%u\n", MaxSectors,MaxSectors,MaxClusters); printf("\nHeadCnt =%2i TrkSecs =%2i FatSize =%2i FatCnt =%1i\n", HeadCnt,TrkSecs,FatSize,FatCnt); printf("B->SectSiz =%i ", B->SectSiz ); printf("B->ClustSiz=%i ", B->ClustSiz); printf("B->ResSecs =%u ", B->ResSecs ); printf("B->FatCnt =%i ", B->FatCnt ); printf("B->RootSiz =%i ", B->RootSiz ); printf("B->TotSecs =%u ", B->TotSecs ); printf("B->Media =%02X ", B->Media ); printf("B->FatSize =%i ", B->FatSize ); printf("B->TrkSecs =%i ", B->TrkSecs ); printf("B->HeadCnt =%i ", B->HeadCnt ); printf("B->HidnSec =%lu ",B->HidnSec ); printf("B->BigSect =%lu ",B->BigSect ); printf("B->DriveNo =%02X ", B->DriveNo ); printf("B->BootSign=%02X ", B->BootSign); printf("DataStart = %lu ",DataStart); printf("\nCluster size = %u bytes\n",CluSizeBytes); #endif } /****************************************************************************/ void ls (void) {int i, k; unsigned long j; struct dirent *Ent; for (j=RootBeg;j<=RootEnd;j++) { if (absread (TR(CurrentDevice), 1, j, Buf2)) printf ("boot: sector %lu absread error\n", j); else { for (k=0;k<16;k++) { Ent = (void *) (Buf2+k*32); if ((*Ent).d_name[0]==0) continue; if ((*Ent).d_name[0]==0xE5) continue; #if 0 if ((*Ent).Attr.B.Label) continue; if ((*Ent).Attr.B.Dir) continue; #endif for (i=0;i<11; i++) printf("%c",Ent->d_name[i]); printf(" %u\n",Ent->d_fileno); } } } } /****************************************************************************/ void load_and_run (char *KernelName) {int i, k; unsigned int Clu; unsigned long j; unsigned len, len1; struct dirent *Ent; char DirectoryRecord [11]; char huge * Adr; struct exe_header far * H; unsigned int far * Rel; unsigned int I_OFF, I_SEG, RELO_SEG; for (i=0;i<11;i++)DirectoryRecord[i]=' '; memcpy(DirectoryRecord,KernelName,strlen(KernelName)); for (j=RootBeg;j<=RootEnd;j++) if (absread (TR(CurrentDevice), 1, j, Buf2)) printf ("boot: sector %lu absread error\n", j); else { for (k=0;k<16;k++) { Ent = (void *) (Buf2+k*32); if (Ent->d_name[0] && ((*Ent).d_name[0]!=0xE5)) { if (Ent->Attr.B.Label) continue; if (Ent->Attr.B.Dir) continue; if (memcmp(Ent->d_name,DirectoryRecord,11)==0) { printf("Kernel `%s' found. First cluster=%u Size=%lu\n", KernelName,Ent->d_fileno,Ent->Size); printf("Loading to %04X:0000\n",KERNEL_BEGIN_SEG); /* Load FAT */ j=ResSecs; FAT = FAT_ADDR; #if 1 for (i=0; id_fileno; Adr = MK_FP (KERNEL_BEGIN_SEG,0); CluRead(TR(CurrentDevice),Clu,(char far *)Adr); if (memcmp((char far *)Adr,"MZ",2)) { /* COM */ printf("COM KERNEL\n"); Adr += CluSizeBytes; Clu=NextClu2(Clu); while (Clu!=0xFFFFU) { CluRead(TR(CurrentDevice),Clu,(char far *)Adr); putch('#'); Adr += CluSizeBytes; Clu=NextClu2(Clu); }; kernel_start(); } else { #if 1 memcpy(pCluster,(char far *)Adr,CluSizeBytes); #else {int ii; for (ii=0;iiHdrSize) > 0x20) {printf ("boot: illegal HdrSize = %04X",len1); goto l1; } /* загрузка файла в ОЗУ */ Adr = MK_FP (KERNEL_BEGIN_SEG,0); #if 1 memcpy((char far *)Adr,pCluster+(len1<<4), len=CluSizeBytes-(len1<<4)); #else {int ii, jj; jj=len1<<4; for (ii=0;ii<(len=CluSizeBytes-jj);ii++) *(Adr+ii)=*(pCluster+jj+ii); } #endif Adr += len; Clu=NextClu2(Clu); #if !defined(_HERCULES_) textattr(9); #endif while (Clu!=0xFFFFU) { CluRead(TR(CurrentDevice),Clu,(char far *)Adr); #ifdef DEBUG putch('#'); /* printf(" %08lX",Adr); */ #endif Adr += CluSizeBytes; Clu=NextClu2(Clu); }; /* настройка перемещаемых адресов */ puts(""); Rel=(unsigned int far *)(pCluster + (H->TablOff)); for (i=0; iReloCnt; i++) { /* printf(" #%02X",i); */ I_OFF=*Rel++; /* printf(" I_OFF=%04X",I_OFF); */ I_SEG=*Rel++; /* printf(" I_SEG=%04X",I_SEG); */ RELO_SEG=KERNEL_BEGIN_SEG+I_SEG; /* printf(" RELO_SEG=%04X",RELO_SEG); */ *(unsigned int far *)MK_FP(RELO_SEG,I_OFF) = *(unsigned int far *)MK_FP(RELO_SEG,I_OFF)+KERNEL_BEGIN_SEG; putch('@'); } #if !defined(_HERCULES_) textattr(4); #endif puts("\nEXEC! "); *(int far *)MK_FP(PSP,0)=0x20CD; /* INT 20H :) */ *(int far *)MK_FP(PSP,2)=0x9FFF; /* для LZEXE */ *(int far *)MK_FP(PSP,4)=CurrentDevice; /* EXEC ! */ /* ES = DS = PSP */ /* SS = START_SEG+ReloSS, SP = ExeSP */ /* CS = START_SEG+ReloCS, IP = ExeIP */ /* (команды: PUSH seg; PUSH offset; RETF) */ i=H->ReloSS+KERNEL_BEGIN_SEG; asm mov cx,i; i=H->ReloCS+KERNEL_BEGIN_SEG; asm mov dx,i; i=H->ExeSP; asm mov si,i; i=H->ExeIP; asm mov di,i; asm mov bx,PSP; asm mov DS,bx; asm mov ES,bx; asm cli; asm mov SS,cx; asm mov SP,si; asm sti; asm push dx; asm push di; asm retf; } } } } } printf("Kernel `%s' not found\n",KernelName); l1:; } /****************************************************************************/ void dump (char far *Command) {int i, k, Clu; unsigned long j; unsigned len, len1; struct dirent *Ent; char DirectoryRecord [11]; char far *FileName; char far *ppp; if ((FileName=strchr(Command,' '))==NULL) return; FileName++; if (*FileName==0) return; printf("Dump %Fs\n",FileName); for (i=0;i<11;i++)DirectoryRecord[i]=' '; memcpy(DirectoryRecord,FileName,strlen(FileName)); for (j=RootBeg;j<=RootEnd;j++) if (absread (TR(CurrentDevice), 1, j, Buf2)) printf ("boot: sector %lu absread error\n", j); else { for (k=0;k<16;k++) { Ent = (void *) (Buf2+k*32); if ((*Ent).d_name[0] && ((*Ent).d_name[0]!=0xE5)) { if ((*Ent).Attr.B.Label) continue; if ((*Ent).Attr.B.Dir) continue; if (memcmp(Ent->d_name,DirectoryRecord,11)==0) { printf("File `%Fs' found. Cluster %u\n",FileName,Ent->d_fileno); #ifdef DEBUG printf(" press any key "); getch(); #endif /* Load FAT */ j=ResSecs; FAT = FAT_ADDR; for (i=0; id_fileno; #ifdef DEBUG printf("FAT loaded\n"); printf(" press any key "); getch(); #endif while (Clu!=-1) { CluRead(TR(CurrentDevice),Clu,pCluster); ppp=pCluster; for (i=0;i>6)+1; if (i) Devices[0].sec=-1; if (i>1) Devices[1].sec=-1; if (*(char far *)MK_FP(0,0x475)) /* 40h:75h - number of fixed disk drives */ if (bootread0 (_HDD_, MBRBuf)) /* [Interrupt List] */ printf ("boot: MBR read error\n"); else { /* printf("# head sec trk ResSecs MaxSectors\n"); */ process_partition_table (MBRBuf); } else ; /* outMBR(MBRBuf); */ } /****************************************************************************/ char *gets (char *s) { int i; char buf[MAX_LEN_STR]; char c; for(i=0;i'); gets(command); strupr(command); /* printf("\ncom=`%s'\n",command); */ if (command[0]==0) { load_and_run ("KERNEL"); } else if (strcmp(command,"HELP")==0) help(); else if (strcmp(command,"REBOOT")==0) reboot(); else if (strcmp(command,"COLD")==0) cold(); else if (strcmp(command,"MSDOS")==0) msdos(); else if (strcmp(command,"HDD2")==0) hdd2(); else if (strcmp(command,"LS")==0) ls(); else if (strcmp(command,"MORE")==0) More=1; else if (strcmp(command,"NOMORE")==0) More=0; else if (memcmp(command,"DUMP ",5)==0) dump(command); else if (command[1]==':') { setdisk(command[0]-'0'); } else { load_and_run (command); } } }src/bm/sec4clu2.c0100664000076500007650000000142507725643473013307 0ustar prool2prool2#include #include #include #include "kernel.h" /****************************************************************************/ /* #define DEBUG */ /****************************************************************************/ unsigned long SecForClu (unsigned int CluNo) {unsigned long l; /* Sector=ResSecs + FatCnt*FatSize + (RootSiz*32)/SectSiz + ((CluNo-2)*ClustSiz) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ DataStart */ #if 0 if ((CluNo>MaxClusters)||(CluNo<2)) { printf("SecForClu: Invalid cluster number. CluNo=%i, MaxClusters=%i", CluNo,MaxClusters); return -1; } #endif l=DataStart + ( ((unsigned long)CluNo-2) * CluSize ); #ifdef DEBUG printf("sec4clu: return %li ",l); #endif return l; } src/bm/nextclu2.c0100664000076500007650000000165407725643473013433 0ustar prool2prool2#include #include #include /* NextClu(), NextClu2() - next cluster number compute and load to Cache) */ /* NextClu() - kernel's internal module */ /* NextClu2() - boot manager internal module */ /* Согласовывать NextClu() с NextClu2() ! */ extern unsigned int MaxClusters; extern int FATMode; extern char huge * FAT; unsigned int NextClu2 (unsigned int CluNo) /* -1 for eof or error */ { /* for FAT12 */ unsigned int i; if ((CluNo>MaxClusters)||(CluNo==0)) { printf("NextClu: Invalid cluster number. CluNo=%u, MaxClusters=%u", CluNo, MaxClusters); return -1; } if (FATMode==FAT12) { /* FAT 12 */ i=*(unsigned int huge *)(FAT+ (((unsigned long)CluNo) * 3)/2); if (CluNo & 1) i>>=4; else i&=0xfff; if (i>0xff0) return -1; } else { /* FAT 16 */ i=*(unsigned int far *)(FAT+ ((unsigned long)CluNo) * 2); if (i>0xfff0) return -1; } return i; }src/bm/makefile0100664000076500007650000001721607725643473013224 0ustar prool2prool2# OS Proolix. Boot manager makefile. # Use Turbo C 2.0 make.exe TasmFlags = /q /t /w2 /m4 #TasmFlags = /t /w2 /m4 /l # LinkFlag = /c/t/d/m/s LinkFlag = /c/d/m/s TCOpt = -K -wcln -wsig -wucp -wrvl -N- # -wstv # TCFlag = -mt -I..\include -I..\kernel -DKERNEL -DProolix $(TCOpt) CPPFlag = -I..\include TC = \tc # Proc = \usr\prool\proc Commands = ..\command Include = ..\include Kernel = ..\kernel KernelFiles = kernel.c progname.c alloc.c process.c syscall.c ConfFiles = $(Include)\conf.c $(Include)\limits.h $(Include)\unistd.h \ $(Include)\struct.h $(Include)\prool.h $(Include)\proto.h $(Kernel)\kernel.h .a.obj: tasm /ml /z $(TasmFlags) /jjumps $&.a .c.obj: tcc -c $(TCFlag) -o $& $& .asm.obj: tasm /ml /z $(TasmFlags) $& .c.asm: tcc -c -S $(TCFlag) $& .asm.a: app $&.asm $&.a .c.i: cpp $(CPPFlag) $& ############################################################################## boot: boot.com ..\kernel\pklite -o boot.com boot. boot.com: boot.obj cb.obj bootl.lib $(Kernel)\cs0.lib tlink /c/d/m/s/t cb boot,boot,boot,bootl $(Kernel)\cs0 boot.obj: boot.c boot.h $(Include)\struct.h $(Kernel)\ppt.c tcc -c -B -mt -I..\include $(TCOpt) \ -DKERNEL -DProolix -DBOOT $& ############################################################################## bootf: bootf.com ..\kernel\pklite -o bootf.com bootf. bootf.com: bootf.obj cb.obj bootl.lib $(Kernel)\cs0.lib tlink /c/d/m/s/t cb bootf,bootf,bootf,bootl $(Kernel)\cs0 bootf.obj: boot.c boot.h $(Include)\struct.h tcc -c -B -mt -I..\include $(TCOpt) -obootf \ -DKERNEL -DProolix -DBOOT -DAUTO -DDEF_BOOT=0 boot ############################################################################## booth: booth.com ..\kernel\pklite -o booth.com booth. booth.com: booth.obj cb.obj bootl.lib $(Kernel)\cs0.lib tlink /c/d/m/s/t cb booth,booth,booth,bootl $(Kernel)\cs0 booth.obj: boot.c boot.h $(Include)\struct.h tcc -c -B -mt -I..\include $(TCOpt) -obooth \ -DKERNEL -DProolix -DBOOT -DAUTO -DDEF_BOOT=2 boot ############################################################################## boot.asm: boot.c boot.h $(Include)\struct.h tcc -c -S -mt -I..\include $(TCOpt) \ -DKERNEL -DProolix -DBOOT $& a:\boot: boot copy boot a:\boot bootl.lib: tlib.cmd printf.obj sec4clu2.obj mem.obj tolower.obj \ conv.obj ctype.obj strchr.obj char_in.obj char_out.obj \ string.obj bootread.obj out_iv.obj viewexe.obj nextclu2.obj \ putch0.obj getch0.obj out_os.obj cursor.obj videopag.obj \ kbhit.obj txtattr.obj int86.obj out_mbr.obj \ hdd2.obj msdos.obj cold.obj \ reboot.obj bootred0.obj \ vector.obj readsec.obj \ int13err.obj \ cluread.obj strlen.obj absread.obj tlib @ tlib.cmd out_mbr.obj: out_mbr.c tcc -c $(TCFlag) $(Kernel)\out_mbr.c out_os.obj: $(Kernel)\out_os.c $(ConfFiles) tcc -c -oout_os.obj $(TCFlag) $(Kernel)\out_os.c strlen.obj: $(Kernel)\strlen.c $(ConfFiles) tcc -c -ostrlen.obj $(TCFlag) $(Kernel)\strlen.c absread.obj: $(Kernel)\absread.c $(ConfFiles) $(Kernel)\kernel.h tcc -c -oabsread.obj $(TCFlag) $(Kernel)\absread.c cluread.obj: $(Kernel)\cluread.c $(ConfFiles) $(Kernel)\kernel.h tcc -c -ocluread.obj $(TCFlag) $(Kernel)\cluread.c nextclu2.obj: nextclu2.c $(ConfFiles) tcc -c -onextclu2.obj $(TCFlag) nextclu2.c viewexe.obj: $(Kernel)\viewexe.c tcc -c -oviewexe.obj $(TCFlag) $(Kernel)\viewexe.c out_iv.obj: $(Kernel)\out_iv.c $(ConfFiles) $(Kernel)\kernel.h tcc -c -oout_iv.obj $(TCFlag) $(Kernel)\out_iv.c bootread.obj: $(Kernel)\bootread.c $(ConfFiles) $(Kernel)\kernel.h tcc -c -obootread.obj $(TCFlag) $(Kernel)\bootread.c string.obj: $(Kernel)\string.c $(ConfFiles) tcc -c -ostring.obj $(TCFlag) $(Kernel)\string.c char_in.obj: $(Kernel)\char_in.c $(ConfFiles) tcc -c -ochar_in.obj $(TCFlag) $(Kernel)\char_in.c char_out.obj: $(Kernel)\char_out.c $(ConfFiles) tcc -c -ochar_out.obj $(TCFlag) $(Kernel)\char_out.c strchr.obj: $(Kernel)\strchr.c $(ConfFiles) tcc -c -ostrchr.obj $(TCFlag) $(Kernel)\strchr.c ctype.obj: $(Kernel)\ctype.c $(ConfFiles) tcc -c -octype.obj $(TCFlag) $(Kernel)\ctype.c conv.obj: $(Kernel)\conv.c $(ConfFiles) tcc -c -oconv.obj $(TCFlag) $(Kernel)\conv.c printf.obj: $(Kernel)\printf.c $(ConfFiles) tcc -c -B -DBOOT $(TCFlag) -oprintf.obj $(Kernel)\printf.c printf.asm: $(Kernel)\printf.c $(ConfFiles) tcc -c -S -DBOOT $(TCFlag) -oprintf.asm $(Kernel)\printf.c #printf.obj: printf.asm # tasm /ml /z $(TasmFlags) $& sec4clu2.obj: sec4clu2.c $(ConfFiles) $(Kernel)\kernel.h tcc -c $(TCFlag) sec4clu2.c mem.obj: $(Kernel)\mem.c $(ConfFiles) tcc -c $(TCFlag) -omem.obj $(Kernel)\mem.c tolower.obj: $(Kernel)\tolower.c $(ConfFiles) tcc -c $(TCFlag) -otolower.obj $(Kernel)\tolower.c videopag.obj: $(Kernel)\videopag.c $(ConfFiles) tcc -c $(TCFlag) -ovideopag.obj $(Kernel)\videopag.c int13err.obj: $(Kernel)\int13err.c $(ConfFiles) tcc -c $(TCFlag) -oint13err.obj $(Kernel)\int13err.c putch0.obj: $(Kernel)\putch0.asm tasm /ml /z $(TasmFlags) $(Kernel)\putch0.asm; getch0.obj: $(Kernel)\getch0.asm tasm /ml /z $(TasmFlags) $(Kernel)\getch0.asm; kbhit.obj: $(Kernel)\kbhit.asm tasm /ml /z $(TasmFlags) $(Kernel)\kbhit.asm; txtattr.obj: $(Kernel)\txtattr.asm tasm /ml /z $(TasmFlags) $(Kernel)\txtattr.asm; hdd2.obj: $(Kernel)\hdd2.asm tasm /ml /z $(TasmFlags) $(Kernel)\hdd2.asm; msdos.obj: $(Kernel)\msdos.asm tasm /ml /z $(TasmFlags) $(Kernel)\msdos.asm; cold.obj: $(Kernel)\cold.asm tasm /ml /z $(TasmFlags) $(Kernel)\cold.asm; reboot.obj: $(Kernel)\reboot.asm tasm /ml /z $(TasmFlags) $(Kernel)\reboot.asm; bootred0.obj: $(Kernel)\bootred0.asm tasm /ml /z $(TasmFlags) $(Kernel)\bootred0.asm; vector.obj: $(Kernel)\vector.asm tasm /ml /z $(TasmFlags) $(Kernel)\vector.asm; readsec.obj: $(Kernel)\readsec.asm tasm /ml /z $(TasmFlags) $(Kernel)\readsec.asm; cursor.obj: $(Kernel)\cursor.asm tasm /ml /z $(TasmFlags) $(Kernel)\cursor.asm; int86.obj: $(Kernel)\int86.asm tasm /ml /z $(TasmFlags) $(Kernel)\int86.asm; install: boot copy boot a:\boot all: boot booth bootf cb.obj: cb.asm bak: del *.bak del *.map del *.tmp del *.lst del *.dic del *.i del norton.ini clean: bak del *.obj del *.lib del boot del tcpick.pck reboot: reboot src/boot/0040775000076500007650000000000007725643752012065 5ustar prool2prool2src/boot/bp.c0100664000076500007650000003450507725643752012636 0ustar prool2prool2#define VER "Boot Processor 0.1.6 2-Nov-99 (C) 1993-1999, S.Pustovoitoff" /* История: 0.1.6 2-Nov-99 - несущественные (косметические) модификации 0.1.5 10-Mar-98 0.1.4 24-Feb-98 - сделана работа с многочисленными extended partition 0.1.3 16-Jan-98 - сделана работа с extended partition 0.1.2 11-Jan-98 0.1.1 7-Jan-98 0.1.0 28-Dec-97 - add bootread() instead of absread(), add outMBR, add bootwrite() instead of abswrite() 0.0.20 32-Aug-97 - fixed small bug 0.0.19 24-Aug-97 - MSDOS/Proolix version 0.0.18 22-Aug-97 0.0.17 27-Apr-97 0.0.16 26-Apr-97 0.0.15 3-Apr-96 0.0.14 24-Sep-95 0.0.14 24-Sep-95 0.0.13 16-Sep-95 0.0.13 15-Sep-95 - исправлены некоторые ошибки при работе с жесткими дисками 0.0.12 21-Mar-95 - некоторая косметика по совету Mike Aizatsky, 2:461/21.100 0.0.11 26-Nov-94 - убрал progname(). Hафига она была нужна!? 0.0.10 19-Nov-94 - после -d возможен любой символ 0.0.9 5-Sep-94 - -y switch 0.0.8 3-Sep-94 - вывод имени файла InName 0.0.7 26-Jan-94 0.0.6 10-Jan-94 putch__() 0.0.5 23-Dec-93 0.0.4 11 Dec 93 rename to BP - Boot Processor 0.0.3 0.0.2 7 Dec 93 0.0.1 6 Dec 93 add out_boot(), -d switch 0.0.0 2 dec 93 до этого по Buffered MonoPIP 2.04 22 Nov 93 */ #include #include #include #include #include #include #include #define FAT12 0 #define FAT16 1 #define NO_FAT 2 #undef OPEN_MAX #undef TMP_MAX #include "..\include\prool.h" #define __TIME_DATE_ #define _FTIME_ #include "..\include\conf.c" #include "..\include\limits.h" #include "..\include\struct.h" #define SECSIZE 512 #define _HDD_ 0x80 /* Global definitions */ char FlagR = 0; char FlagI = 0; char FlagY = 0; char dev = 0xF0; int NextDrive=2; int NextDOSDrive='C'; struct DeviceStruct Devices [LASTDRIVE]; /* Devices [0] - disk A: sec=0 if not present Devices [1] - disk B: sec=0 if not present Devices [2] - disk C: sec=0 if not present Devices [3] - disk D: sec=0 if not present ... */ int active=-1; int bootread0 (int dev, void far * buf); int bootwrite (int dev, void far * buf); int ReadPhysSec (unsigned char drive, unsigned char sec, unsigned char head, unsigned char trk /* or cyl */, char *Buffer); int WritePhysSec (unsigned char drive, unsigned char sec, unsigned char head, unsigned char trk /* or cyl */, char *Buffer); #include "..\kernel\out_os.c" #include "..\kernel\out_mbr.c" int bootread (int Dev, void *Buf) {int i, err; char InternalBuffer [SECTOR_SIZE]; for (i=0; i [filename] [-r] [-i] [-a] [-y]\n\ -r - reverse copy (file->boot/master boot sector),\n\ DEFAULT (without '-r') - boot/master boot sector->file\n\ \n\ -i - install file to boot/master boot sector,\n\ BPB and partition table not change!\n\ -d - drive:\n\ @ - master boot record of 1st HDD\n\ Boot records:\n\ 0 - drive 0 (floppy drive A:)\n\ 1 - drive 1 (floppy drive B:)\n\ 2 - drive 2 (1st partition of 1st HDD)\n\ ...\n\ -a - set active partition (for extended partition only)\n\ -y - assume 'y' on all queries\n"); } putch__(char c) { switch (c) { case 0: c=' '; break; default: if (c<' ') c='.'; } return putch(c); } void out_devices() {int i; printf("\nDev Head Sec Trk/cyl Partition"); printf("\n-------------------------------"); for (i=0;i5000) { DiskSize/=1024; printf("\nDisk size %li Mb\n",DiskSize); } else { printf("\nDisk size %li Kb\n",DiskSize); } } #define EXTEND 5 #define EXTEND2 0xF int extended_partition(int dev) { if (dev==0xFF) return 1; if ((Devices[dev].system_indicator==EXTEND ) || (Devices[dev].system_indicator==EXTEND2) ) return 1; return 0; } void out_boot_or_mbr (int dev, void far *buf) { if (extended_partition(dev)) outMBR(buf); else out_boot(buf); } #include "..\kernel\ppt.c" void test_devices (void) {unsigned int i; struct MBRstru *MBR; char MBRBuf [SECTOR_SIZE]; for (i=0;i 0: 0 = нет дисковых устройств (AX & 0001H) ║ ║ ║ ║ ║ ║ ║ ║ ╚═══> 1: 8087 сопроцессор (ненадежно) ║ ║ ║ ║ ║ ║ ║ ╚══════> 2-3: материнская плата RAM (AX & 0eH) ║ ║ ║ ║ ║ ║ ║ 01H=16K; 04H=32K; 0eH=64K (или больше) ║ ║ ║ ║ ║ ║ ╚══════════> 4-5: начальный/активный режим (AX & 0030H) ║ ║ ║ ║ ║ ║ 10H=40-кол цветн; 20H=80-кол цветн; ║ ║ ║ ║ ║ ║ 30H=TTL монохромная плата ║ ║ ║ ║ ║ ╚══════════════> 6-7: всего дисководов -1 (AX & 00c0H) ║ ║ ║ ║ ║ 00H=1; 40H=2; 80H=3; c0H=4 ║ ║ ║ ║ ╚═════════════════> 8: DMA присутствует (AX & 0100H) ║ ║ ║ ╚═════════════════════> 9-11: RS232 порты (AX & 0e00H) ║ ║ ║ 000H=нет; 200H=1; 400H=2; ... e00H=7 ║ ║ ╚═════════════════════════>12: 1=игровой адаптер присутствует(AX & 1000H) ║ ╚═══════════════════════════>13: 1=послед.принтер (PC/Jr только) ╚══════════════════════════════>14-15: установлено принтеров (AX & c000H) 0000H=нет; 4000H=1; 8000H=2; c000H=3 Замеч: Часто используется для проверки режима видео. Если (AX & 30H) = 30H, то адаптер монохромный──видео сегмент RAM по адресу 0b000H, иначе 0b800H. */ i=((*(unsigned int far *)MK_FP(0,0x410) & 0xC0)>>6)+1; if (i) Devices[0].sec=-1; if (i>1) Devices[1].sec=-1; if (bootread0 (_HDD_, MBRBuf)) printf ("test_devices: MBR read error\n"); process_partition_table (MBRBuf); } int read_boot_or_mbr (int dev, char *buf) { int sec; if ((dev==0)||(dev==1)) { /* A: or B: */ return bootread(dev,buf); } if (dev==0xFF) { return bootread(_HDD_,buf); } sec=Devices[dev].sec; if (sec==0) return -1; return ReadPhysSec (_HDD_,sec,Devices[dev].head,Devices[dev].trk,buf); } int write_boot_or_mbr (int dev, void *buf) { int sec; if ((dev==0)||(dev==1)) { /* A: or B: */ return bootwrite(dev,buf); } if (dev==0xFF) { return bootwrite(_HDD_,buf); } sec=Devices[dev].sec; if (sec==0) return -1; return WritePhysSec (_HDD_,sec,Devices[dev].head,Devices[dev].trk,buf); } char buf [SECSIZE], bufboot[SECSIZE]; int main (int argc, char *argv[] /* , char *env[] */) { int i; int FileNameCounter; char InName [80]; int h; struct MBRstru *mbr_p; #if 1 clrscr(); #else for (i=0;i<25;i++)puts(""); #endif ident(); FileNameCounter=0; for(i=1;i=SECSIZE) printf(" or more\n"); else printf("\n"); if (i>SECSIZE) {printf("Not enough memory in boot sector\n");return 2;} else if (i>510) printf("Warning! Last 1-2 bytes lost!\n"); close(h); if (extended_partition(dev)) { /* MBR or extended partition */ for (i=0;i<0x1BE;i++)bufboot[i]=buf[i]; /* bootloader */ if ((active>=0)&&(active<4)) { /* set active partition */ mbr_p=(void *)bufboot; mbr_p->Partition[active].indicator=0x80; out_boot_or_mbr(dev,bufboot); } } else { /* plain boot sector */ for (i=0;i<3+8;i++)bufboot[i]=buf[i]; /* JMP and OEM name */ for (i=0x26; i %s sector %i:\n\nOverwrite %s sector (y/n) ? ", InName,sector_type(dev),dev,sector_type(dev)); if (reply("YN")!=1) return 1; } printf("\nFile %s -> %s sector %i: !\n", InName,sector_type(dev),dev); if (write_boot_or_mbr(dev,bufboot)){printf("Disk write error\n"); return 2;} } else if (!FlagR) { /* boot -> file */ printf("%s sector %i: -> file %s\n",sector_type(dev),dev,InName); if(read_boot_or_mbr(dev,buf)==-1){printf("Disk read error\n"); return 2;} out_boot_or_mbr(dev,buf); if((h=open(InName,O_CREAT|O_WRONLY|O_BINARY,S_IWRITE))==-1) {printf("Boot image open/creat error in file %s\n",InName); return 2;} if(write(h,buf,SECSIZE)!=SECSIZE) {printf("Boot image write error\n"); return 2;} if(close(h)) {printf("Boot image close error\n"); return 2;} } else { /* file -> boot */ if (!FlagY) { printf("File %s -> %s sector %i:\n\nOverwrite %s sector (y/n) ? ", InName,sector_type(dev),dev,sector_type(dev)); if(reply("YN")!=1)return 1; } printf("\nFile %s -> %s sector %i: !\n", InName,sector_type(dev),dev); if((h=open(InName,O_RDONLY|O_BINARY))==-1) {printf("Boot image open error in file %s\n",InName); return 2;} if(read(h,buf,SECSIZE)!=SECSIZE) {printf("Boot image read error\n"); return 2;} out_boot_or_mbr(dev,buf); if(close(h)) {printf("Boot image close error\n"); return 2;} if(write_boot_or_mbr(dev,buf)){printf("Disk write error\n"); return 2;} } return 0; }src/boot/fat12.asm0100664000076500007650000000201507725643752013477 0ustar prool2prool2; for FAT-12 NextClu proc ; Input: ax - cluster no ; Output: ax - next cluster from FAT ; cf=1 if EOF ; REGS SAVED ! push bx push cx push dx push di push ES mov di,ax mov bx,3 mul bx ; dx:ax := ax * bx shr ax,1 ; ax := ax /2 ; ax - addr in FAT mov bx,FATseg mov ES,bx mov bx,ax mov ax,word ptr ES:[bx] test di,1 jz @@1 mov cl,4 shr ax,cl jmp @@2 @@1: and ax,0fffh @@2: ; cmp ax,0fffh ; je @@cf ; cmp ax,0ff7h ; je @@cf cmp ax,word ptr MaxClusters+off ja @@cf clc @@ret: pop ES pop di pop dx pop cx pop bx ret @@cf: stc jmp @@ret NextClu endp src/boot/boot0.asm0100664000076500007650000003420007725643752013606 0ustar prool2prool2 PAGE ,79 ; Boot sector ver. 0.0.0.8 7-Nov-94 from Proolix operating system ; Copyright (C) Serge Pustovoitoff, 1993, 1994 off equ 7c00h - 100h Drive equ 0 ModifyParams equ 'Yes' PSPSeg equ 50h ; 70h LoadAddr equ (PSPSeg shl 4)+100h include macros.asm sayr macro str ; NO SAVE REGS !!! ; Макрокоманда, аналогичная макрокоманде say. Только say использует функцию 9h ; ДОС, а sayr - функцию BIOS (функция 0eh прерывания 10h) ; В графических режимах не работает mov si,offset str call sayr_proc endm sayr locals jumps .model tiny .code org 100h Begin: jmp short l db 90h ; '12345678' OEM db 'KERNEL',0,0 SectSiz dw 512 ClustSiz db 2 ResSecs dw 1 FatCnt db 2 RootSiz dw 112 TotSecs dw 720 Media db 0fdh FatSize dw 2 TrkSecs dw 9 HeadCnt dw 2 HidnSec dd 0 BigNo dd 0 ; Big total no of sectors dw 0 ; Physical drive no db 9 ; Extended boot signature ;dd 1 ; Volume serial no FATaddr dw 0 ; ! internal vars StartClu dw 0 ; ! Lbl db 'No_Kernel',0,0 ; Volume label db 'FAT12 ' ; File system ID RootSize dw ' '; use 2 last bytes of File system id OldVec dw 2 dup (0) l: ; Table 11 bytes - drive param cli xor ax,ax mov es,ax ifdef ModifyParams mov bx,78h ; вот до сих пор будет таблица в 11 байт lds si,dword ptr es:[bx] ; ds:si - vector diskette param mov word ptr OldVec+off,si mov word ptr OldVec+off+2,ds ; push ds ; push si ; push ss ; push bx mov di,offset l+off mov cx,0Bh cld rep movsb ;11 bytes from diskette param tble to begin of pgm ; Bytes: ; 0 - bit 0-3 - SRT (step rate time), 4-7 head unload time ; 1 - bit 0: 1 if DMA, 2-7 head load time ; 2 - motor wait (in 55 ms) ; 3 - sec size (0 - 128, 1 - 256, 2 - 512, 3 - 1024) ; 4 - EOT (finish sector on track) ; 5 - interval length for ReadWrite ; 6 - DTL - Data Transfer Length (maximal) ; 7 - interval length for formatting ; 8 - Filler ; 9 - head settle time (in ms) ; a - motor start time (in 1/8 s) push es pop ds mov byte ptr [di-2],0Fh ; head settle := f mov cx,ds:TrkSecs+off ; TrkSecs mov [di-7],cl ; Data Transfer Length mov [bx+2],ax mov word ptr [bx],offset l+off ; new diskette table endif sti mov dl,Drive int 13h ; Disk dl=drive ah=func 00h ; reset disk, al=return status comment | jc l_err xor ax,ax cmp TotSecs+off,ax ; TotSecs cmp with 0 je loc_3 mov cx,TotSecs+off ; TotSecs mov word ptr BigNo+off,cx ; Big total no of sec | loc_3: sayr Ident+off mov al,byte ptr FatCnt+off cbw mov cx,word ptr FatSize+off mul cx ; ax*cx -> dx:ax add ax,word ptr ResSecs+off ; ax - Root Beginning Sector mov word ptr StartClu+off,ax PUSH ax mov ax,word ptr RootSiz+off mov cx,32 mul cx mov cx,word ptr SectSiz+off div cx ; dx:ax / cx -> ax; mod -> dx ; ax - Root Size in Sectors add word ptr StartClu+off,ax mov cx,ax mov word ptr RootSize+off,ax POP ax ; ax - Root Bg Sec @@loop: ; load root directory push cx push ax mov bx,offset Buff+off mov dl,Drive call SecRead jc l_err ; chr1 '#' mov cx,16 ; root entryes in 1 sector @@l: push cx mov cx,6 mov si,bx mov di,offset OEM+off rep cmpsb je l_found pop cx add bx,32 loop @@l pop ax inc ax pop cx loop @@loop ; end of load root dir ; inkey2 l_err: sayr Lbl+off @@ll: jmp short @@ll ; include ohb1.asm ; include ohw.asm l_found: pop cx ;sayr Ver+off ; Found kernel ; bx - kernel dir record ; word ptr [bx+1ah] - 1st cluster mov ax,word ptr [bx+1ah] ; ax - 1st cluster ;LoadFAT PUSH ax ; save ax with 1st clu no mov bx,offset Buff+off mov ax,word ptr RootSize+off mov cx,word ptr SectSiz+off mul cx ; ax - RootSize in bytes add bx,ax ; Addr buf for FAT mov word ptr FATaddr+off,bx mov ax,word ptr ResSecs+off mov cx,word ptr FatSize+off @@l: mov dl,Drive call SecRead jc l_err add bx,512 loop @@l mov al,byte ptr ClustSiz+off cbw mov dx,word ptr SectSiz+off mul dx mov cx,ax ; Cluster Size in Bytes POP ax ; restore ax (1st clu no) mov bx,LoadAddr l2: mov dl,Drive call CluRead add bx,cx cmp bx,off jae l3 call NextClu ; set ax jnc l2 ; EXEC! ; mov ax,PSPSeg ; mov DS,ax ; mov ES,ax ; cli ; mov SS,ax ; mov SP,0fffeh ; sti db 0eah ; JMP PSPSeg:100 dw 100h,PSPSeg l3: sayr L_err+off l4: jmp l4 ;ssize db 'SIZE',0 NextClu proc ; Input: ax - cluster no ; Output: ax - next cluster from FAT ; cf=1 if EOF ; Use global var: ; FATaddr dw 0 ; REGS SAVED ! push bx push cx push dx push si push di mov di,ax mov bx,3 mul bx ; dx:ax := ax * bx shr ax,1 ; ax := ax /2 ; ax - addr in FAT mov si,ax mov bx,word ptr FATaddr+off mov ax,word ptr [bx+si] test di,1 jz @@1 mov cl,4 shr ax,cl jmp @@2 @@1: and ax,0fffh @@2: ; cmp ax,0fffh ; je @@cf ; cmp ax,0ff7h ; je @@cf cmp ax,word ptr TotSecs+off ja @@cf clc @@ret: pop di pop si pop dx pop cx pop bx ret @@cf: stc jmp @@ret NextClu endp SecRead proc ; ver 0.0.1 3-Nov-94 (for boot) ; Read absolute sectors ; Input: ax - abs sec number ; dl - drive (for int 13h Fn=2) ; ES:bx - buffer ; BP - autobase register ; DS - data segment reg ; Use global variables (based on BP!): ; word ptr HeadCnt+off ; word ptr TrkSecs+off ; Output: cf=1 if error ; ALL REGS SAVED !!! push ax push cx push dx push si push di mov si,bx ; save bx & dx mov di,dx PUSH ax mov ax,word ptr HeadCnt+off mov cx,word ptr TrkSecs+off mul cx ; dx:ax := HeadCnt * TrkSecs mov bx,ax POP ax xor dx,dx ; dx:ax - Abs Sec No div bx ; ax - Trk; dx - mod mov bx,ax ; bx - track no mov ax,dx xor dx,dx ; dx:ax - module div cx ; dx:ax / TrkSecs; ax - Head; dx - Sec on Head-1 inc dx ; dx - Sec on Head mov cx,5 l_loop: push cx mov cl,dl ; sector mov ch,bl ; track ; Warning: track < 255 !!! mov bx,si ; Restore dl - drive no mov dx,di ; Restore bx - offset for buff mov dh,al ; head mov ax,0201h; Fn=02, Read 1 sector int 13h jnc l_break pop cx loop l_loop jmp short l_ret l_break: pop cx l_ret: pop di pop si pop dx pop cx pop ax ret SecRead endp CluRead proc ; Read cluster ; Input: ax - cluster number ; dl - drive (for int 13h Fn=2) ; ES:bx - buffer ; BP - autobase register ; DS - data segment reg ; Use global variables (based on BP!): ; StartClu dw 0 ; Number sector of 1st cluster ; ClustSiz db 2 ; SectSiz dw ; ALL REGS SAVED !!! push ax push bx push cx push bx mov bl,1 chr1 '#' pop bx ; Sector = StartClu + ((Clu-2) * ClustSiz) PUSH bx PUSH dx sub ax,2 mov bx,ax mov al,byte ptr ClustSiz+off cbw mov cx,ax mul bx add ax,word ptr StartClu+off ; ax - sector POP dx ; Restore dl POP bx ; cx - ClustSiz @@l: call SecRead jc l_err add bx,word ptr SectSiz+off inc ax loop @@l pop cx pop bx pop ax ret CluRead endp comment | reada1 proc ; Regs no save !!! xor ax,ax xor dl,dl mov bx,offset Buff+off call SecRead jc l_err sayr Buff-base+3[bp] ret reada1 endp | comment | reada proc ; Reg no save !!! mov ah,2 ; Fn read mov al,1 ; num sec mov dl,Drive ; drive mov dh,0 ; head mov cx,1 ; cyl/sec mov bx,offset Buff+off int 13h jc l_err sayr Buff-base+3[bp] ret reada endp | comment | saycsip proc ; REG SAVED push ax sayr s0+off push CS pop ax call ohw chr1 ':' mov ax,Begin+off call ohw ; sayr s_ax+off ; pop ax ; push ax ; call ohw ; sayr s_bx+off ; mov ax,bx ; call ohw ; sayr s_cx+off ; mov ax,cx ; call ohw ; sayr s_dx+off ; mov ax,dx ; call ohw ; sayr s_si+off ; mov ax,si ; call ohw ; sayr s_di+off ; mov ax,di ; call ohw sayr s_ss+off mov ax,SS call ohw sayr s_sp+off mov ax,SP call ohw sayr s_ds+off mov ax,DS call ohw sayr s_es+off mov ax,ES call ohw ; sayr s_bp+off ; mov ax,BP ; call ohw pop ax ret s0 db 13,10,"Bg CS:IP=",0 ;s_ax db ' ax=',0 ;s_bx db ' bx=',0 ;s_cx db ' cx=',0 ;s_dx db ' dx=',0 ;s_si db ' si=',0 ;s_di db ' di=',0 s_SS db ' SS=',0 s_SP db ' SP=',0 s_DS db ' DS=',0 s_ES db ' ES=',0 ;s_bp db ' BP=',0 saycsip endp | comment | ints proc ; Reg no saved !!! sayr s1+off mov cx,0ffh mov bp,0 l1: mov al,0ffh sub al,cl call ohb chr1 ' ' mov ax,[bp+2] call ohw chr1 ':' mov ax,[bp] call ohw chr1 13 chr1 10 add bp,4 test cx,0fh jnz l3 inkey2 l3: loop l1 ret s1 db 13,10,"ints",13,10,0 ints endp | comment | Int21 proc sayr Ver+off iret Int21 endp | comment | dump proc mov cx,520 xor si,si @@l: mov ax,byte ptr Begin-base[bp+si] call ohb inc si loop @@l ret dump endp | sayr_proc proc ; Ver 0.0.1 9-Dec-93 ; Процедура вывода строки при помощи функций BIOS ; Вход: DS:SI - ASCIIZ строка. ; NO REG SAVED !!! ; В графических режимах не работает ; cld sayr_l1: lodsb or al,al jz sayr_ret mov ah,0eh int 10h jmp short sayr_l1 sayr_ret: ret sayr_proc endp Ident db 'PILO',0 ;Ident db 'Proolix by Prool. Load ',0 L_err db 'Error',0 Buff label byte ; for 512 byte space end Begin  src/boot/bootd.asm0100664000076500007650000001444107725643752013677 0ustar prool2prool2 PAGE ,79 ; Debugging boot sector 0.0.0.4 25-Feb-96 ; Copyright (C) Serge Pustovoitoff 1994, 1995 ; History ; 0.0.0.4 25-Feb-96 ; 0.0.0.3 16-Sep-95 ; 0.0.0.3 15-Sep-95 ; 0.0.0.2 8-Nov-94 off equ 7c00h - 100h ; Макрос. Вывод одного символа через ROM BIOS. chr1 macro sym ; Not worked in graph mode (registr bl - background color!) ; NO SAVED REGS !!! mov ax,0e00h+sym int 10h endm chr1 sayr macro str ; NO SAVE REGS !!! ; Макрокоманда, аналогичная макрокоманде say. Только say использует функцию 9h ; ДОС, а sayr - функцию BIOS (функция 0eh прерывания 10h) ; В графических режимах не работает mov si,offset str call sayr_proc endm sayr locals jumps .model tiny .code org 100h Begin: jmp short l db 90h ; '12345678' OEM db 'KERNEL',0,0 SectSiz dw 512 ClustSiz db 2 ResSecs dw 1 FatCnt db 2 RootSiz dw 112 TotSecs dw 720 Media db 0fdh FatSize dw 2 TrkSecs dw 9 HeadCnt dw 2 HidnSec dd 0 BigNo dd 0 ; Big total no of sectors dw 0 ; Physical drive no db 9 ; Extended boot signature ;dd 1 ; Volume serial no FATaddr dw 0 ; ! internal vars StartClu dw 0 ; ! Lbl db 'No_Kernel',0,0 ; Volume label db 'FAT12 ' ; File system ID RootSize dw ' '; use 2 last bytes of File system id OldVec dw 2 dup (0) l: ; Table 11 bytes - drive param push CS pop DS call saycsip sayr s1+off mov ax,FatSize+off call ohw sayr s2+off xor ax,ax mov ES,ax mov ax,word ptr ES:[13h*4+2] call ohw l0: jmp l0 saycsip proc ; REG SAVED push ax PUSHF sayr s0+off push CS pop ax call ohw chr1 ':' call l1 l1: pop ax PUSH BX mov bx,offset l1-Begin sub ax,bx call ohw POP BX sayr s_ax+off pop ax push ax call ohw sayr s_bx+off mov ax,bx call ohw sayr s_cx+off mov ax,cx call ohw sayr s_dx+off mov ax,dx call ohw sayr s_f+off POP ax ; flags (from stack) -> ax ; (see PUSHF) call ohw sayr s_si+off mov ax,si call ohw sayr s_di+off mov ax,di call ohw sayr s_ss+off mov ax,SS call ohw sayr s_sp+off mov ax,SP call ohw sayr s_ds+off mov ax,DS call ohw sayr s_es+off mov ax,ES call ohw sayr s_bp+off mov ax,BP call ohw pop ax ret s0 db 13,10,"Bg CS:IP=",0 s1 db " FatSize=",0 s2 db " int 13h =",0 s_ax db ' ax=',0 s_bx db ' bx=',0 s_cx db ' cx=',0 s_dx db ' dx=',0 s_si db ' si=',0 s_di db ' di=',0 s_ss db ' SS=',0 s_sp db ' SP=',0 s_ds db ' DS=',0 s_es db ' ES=',0 s_bp db ' BP=',0 s_f db ' Flags=',0 saycsip endp comment | ints proc ; Reg no saved !!! sayr s1+off mov cx,0ffh mov bp,0 l1: mov al,0ffh sub al,cl call ohb chr1 ' ' mov ax,[bp+2] call ohw chr1 ':' mov ax,[bp] call ohw chr1 13 chr1 10 add bp,4 test cx,0fh jnz l3 inkey2 l3: loop l1 ret s1 db 13,10,"ints",13,10,0 ints endp | comment | Int21 proc sayr Ver+off iret Int21 endp | comment | dump proc mov cx,520 xor si,si @@l: mov ax,byte ptr Begin-base[bp+si] call ohb inc si loop @@l ret dump endp | sayr_proc proc ; Ver 0.0.1 9-Dec-93 ; Процедура вывода строки при помощи функций BIOS ; Вход: DS:SI - ASCIIZ строка. ; NO REG SAVED !!! ; В графических режимах не работает ; cld sayr_l1: lodsb or al,al jz sayr_ret mov ah,0eh int 10h jmp short sayr_l1 sayr_ret: ret sayr_proc endp ohw proc ; Вывод слова в HEX-виде. Вход: слово в ax. ; Все регистры сохраняются. ; Вызывает подпрограмму ohb push ax ; Сохр. ради al. mov al,ah call ohb pop ax ; Восст. al. call ohb ret ohw endp ohb proc ; Procedure output hex byte Ver 0.1.1 6 Dec 93 via BIOS ; Input: AL - byte ; All regs. reserved ;) ; Not worked in graph mode. bl - bg color !!! push ax push cx push dx mov dl,al mov cl,4 shr al,cl call ohb1 mov al,dl and al,0fh call ohb1 pop dx pop cx pop ax ret ohb endp ohb1 proc ; Regs not saved !!! push ax cmp al,9 ja @@_1 ; al > 9 ; al <= 9 add al,'0' jmp @@_out @@_1: add al,'A'-10 @@_out: mov ah,0eh int 10h pop ax ret ohb1 endp Buff label byte ; for 512 byte space end Begin src/boot/booth.asm0100664000076500007650000002410507725643752013701 0ustar prool2prool2 PAGE ,79 jumps ; HDD Boot sector ver. 0.0.0.0 2-Feb-98 from Proolix operating system ; При отладке бута учитывались многочисленные полезные замечания, которые ; сделал Алекс Семеняка и Юрий Белотицкий, bela@interfax.kharkov.ua off equ 7C00h-100h ; Смещение, связанное с тем, что во время компиляции ; адресом начала является 100h, а во время ; выполнения 7C00 PSPSeg equ 3050h ; Сегментный адрес, куда будет ; загружен бутменеджер ; (точнее, его PSP) FATseg equ 7E0h ; Макрос. Вывод одного символа через ROM BIOS. chr macro sym ; Not worked in graph mode (registr bl - background color!) ; NO SAVED REGS !!! mov ax,0e00h+sym int 10h endm chr locals .model tiny .code org 100h Begin: jmp start ; Таблица параметров диска db 90h ; NOP ; '12345678' OEM db 'Proolix ' SectSiz dw 512 ClustSiz db 4 ResSecs dw 1 FatCnt db 2 RootSiz dw 512 TotSecs dw 0 Media db 0f8h FatSize dw 43 TrkSecs dw 50 HeadCnt dw 2 HidnSec dd 40200 BigNo dd 0 ; Big total no of sectors db 0 ; Head No FirstClu label word DriveNo_ db 80h ; Physical drive no db 29h ; Extended boot signature StartCluHi dw 0 ; dd Volume serial no StartCluLo dw 0 Lbl db 'BOOT ' ; Volume label MaxClusters label word db 'FAT16 ' ; File system ID RootSize dw ' '; use 2 last bytes of File system id OldVec dw 2 dup (0) Sector_ db 0 HeadNo db 0 TrackNo_ dw 0 RootSectLow dw 0 RootSectHi dw 0 start: ; Значения регистров после загрузки boot-сектора ; CS:IP = 0:7C00 SS=30 SP=F6 ES=0 ; 0:0 - 0:200 - таблица прерываний ; Стек: c 30:F6 (0:3F6) растет к 0 (0:200-0:400 - стек) ; ROM BIOS area 0:400-0:500 ; mov dl,80h ; int 13h ; Disk dl=drive ah=func 00h ; ; reset disk, al=return status ; jc l_err loc_3: push CS pop DS push CS pop ES ; chr '0' ; Вычисления mov al,byte ptr FatCnt+off cbw mul word ptr FatSize+off ; FatCnt * FatSize -> dx:ax add ax,word ptr HidnSec+off ; low adc dx,word ptr HidnSec+2+off ; high add ax,word ptr ResSecs+off adc dx,0 ; dx:ax - Root 1st Sector mov RootSectLow+off,ax mov RootSectHi+off,dx ; Сохраняем ; обьем корня в секторах=(RootSiz*32)/512=RootSiz/16; mov word ptr StartCluHi+off,dx mov word ptr StartCluLo+off,ax ; MaxClusters=(unsigned int)((MaxSectors-DataStart)/CluSize+1); mov ax,word ptr BigNo+off mov dx,word ptr BigNo+2+off add ax,word ptr HidnSec+off ; low adc dx,word ptr HidnSec+2+off ; high sub ax,word ptr StartCluLo+off sbb dx,word ptr StartCluHi+off mov cl,ClustSiz+off xor ch,ch div cx inc ax mov MaxClusters+off,ax mov ax,word ptr RootSiz+off ; dx:ax - объем корня в байтах cwd mov cx,16 div cx ; ax <- объем корня в секторах ; dx <- остаток or dx,dx ; добавление последнего неполного сектора jz l_zero inc ax l_zero: ; ax - объем корня в секторах add word ptr StartCluLo+off,ax adc word ptr StartCluLo+off,0 ; Загрузка корневого каталога посекторно и посекторный поиск в нем ; имени ядра mov cx,ax ; - объем корня в секторах mov ax,RootSectLow+off mov dx,RootSectHi+off l_loop_1: mov bx,offset Buff+off push cx push ax push dx call ReadSector ; read sector (dx:ax)-> ES:bx jc l_err ; Поиск ядра в корне mov cx,16 ; root entryes in 1 sector @@l: push cx mov cx,11 mov di,bx mov si,offset Lbl+off rep cmpsb je l_found pop cx add bx,32 loop @@l pop dx pop ax pop cx inc ax adc dx,0 loop l_loop_1 l_err: chr 'E' Vis: jmp short Vis l_found: ; HАШЛИ ! ; chr 'O' ; Found kernel ; bx - kernel dir record ; word ptr [bx+1ah] - 1st cluster mov ax,word ptr [bx+1ah] ; ax - 1st cluster mov FirstClu+off,ax mov ax,word ptr HidnSec+off mov dx,word ptr HidnSec+2+off add ax,word ptr ResSecs+off adc dx,0 ; dx:ax - 1st FAT sector mov bx,FATseg mov ES,bx ; ES=FATseg xor bx,bx mov cx,word ptr FatSize+off ; Загрузка ядра покластерно (по цепочке из FATа) ; Загрузка FAT @@l: call ReadSector ; read sec dx:ax -> ES:bx jc l_err mov si,ES add si,20h mov ES,si ; ES+=20h inc ax ; Next sector! adc dx,0 loop @@l mov al,byte ptr ClustSiz+off cbw mov dx,word ptr SectSiz+off mul dx mov cx,ax ; Cluster Size in Bytes mov ax,FirstClu+off mov bx,PSPSeg+10h mov ES,bx ; ES=PSPSeg+10h xor bx,bx l2: call CluRead ; push ax ; chr '.' ; pop ax add bx,cx call NextClu ; set ax jnc l2 ; chr 'X' ; EXEC! Запуск ядра ; *(int far *)MK_FP(PSP,2)=0x9FFF; /* для LZEXE */ mov ax,PSPSeg mov DS,ax mov ES,ax cli mov SS,ax mov SP,0fffeh sti db 0eah ; JMP PSPSeg:100 dw 100h,PSPSeg CluRead proc ; Read cluster ; Input: ax - cluster number ; ES:bx - buffer ; DS - data segment reg ; Use global variables: ; StartCluHi:StartCluLo - Number sector of 1st cluster ; ClustSiz db 2 ; SectSiz dw ; ALL REGS SAVED !!! push ax push bx push cx push dx ; Sector = StartClu + ((Clu-2) * ClustSiz) PUSH bx dec ax ; ax:=ax-2 dec ax ; mov bx,ax mov al,byte ptr ClustSiz+off cbw mov cx,ax mul bx add ax,word ptr StartCluLo+off adc dx,word ptr StartCluHi+off POP bx ; dx:ax - sector @@lll: call ReadSector jc l_err inc ax adc dx,0 add bx,512 loop @@lll pop dx pop cx pop bx pop ax ret CluRead endp ifdef FAT12 include fat12.asm else include fat16.asm endif ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ; Читает 1 сектор dx:ax в es:bx. CF, если ошибка. ReadSector proc near push ax push cx push dx ; Заполняет внутренние переменные Sector_, HeadNo и TrackNo_ значениями, ; соответствующими абс. сектору dx:ax. div word ptr TrkSecs+off ; dx:ax / TrkSecs -> (dx,ax) inc dl ; dl - # сектора mov Sector_+off,dl xor dx,dx ; dx=0 div word ptr HeadCnt+off mov HeadNo+off,dl ; # стороны mov TrackNo_+off,ax ; # дорожки mov cx,10 @@loop: PUSH CX mov dx,TrackNo_+off ; dx=TrackNo_ mov cl,6 ; cl=6 shl dh,cl ; dh=tt000000 B or dh,Sector_+off ; dh=ttssssss B mov cx,dx ; cx=ttsssssstttttttt xchg ch,cl ; cx=ttttttttttssssss mov dl,80h ; drive mov dh,HeadNo+off mov ax,0201h int 13h ; read sectors to memory es:bx ; al=#,ch=cyl,cl=sectr,dh=head jnc @@ok POP CX loop @@loop stc @@ret: pop dx pop cx pop ax retn @@ok: POP CX jmp @@ret ReadSector endp ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ Buff label byte end Begin src/boot/bootrw.asm0100664000076500007650000000760407725643752014107 0ustar prool2prool2; read/write boot/master boot sector modules for bp.c locals _TEXT segment byte public 'CODE' assume cs:_TEXT ; bootread0 (int dev, void far * buf) return 0 or ErrorCode _bootread0 proc near push bp mov bp,sp ; word ptr [bp+4] - argument 1 ; word ptr [bp+6] - argument 2 ... push bx push cx push dx push ES mov dx,word ptr [bp+4] mov bx,word ptr [bp+6] mov ES,word ptr [bp+8] mov cx,1 mov dh,0 mov ax,0201h ; Fn=02, Read 1 sector int 13h jc @@err xor ax,ax jmp @@ret @@err: @@ret: pop ES pop dx pop cx pop bx ; mov sp,bp pop bp ret _bootread0 endp public _bootread0 ; bootwrite (int dev, void far * buf) return 0 or ErrorCode _bootwrite proc near push bp mov bp,sp ; word ptr [bp+4] - argument 1 ; word ptr [bp+6] - argument 2 ... push bx push cx push dx push ES mov dx,word ptr [bp+4] mov bx,word ptr [bp+6] mov ES,word ptr [bp+8] mov cx,1 mov dh,0 mov ax,0301h ; Fn=03, Write 1 sector int 13h jc @@err xor ax,ax jmp @@ret @@err: @@ret: pop ES pop dx pop cx pop bx ; mov sp,bp pop bp ret _bootwrite endp public _bootwrite _ReadPhysSec proc ; int ReadPhysSec (unsigned char drive, unsigned char sec, unsigned char head, ; unsigned char trk /* or cyl */, char *Buffer); ; /* ; 2 bytes are combined to a word similar to INT 13: ; ; │7│6│5│4│3│2│1│0│ 1st byte (sector) ; │ │ └─┴─┴─┴─┴─┴── Sector offset within cylinder ; └─┴───────────── High order bits of cylinder # ; ; │7│6│5│4│3│2│1│0│ 2nd byte (cylinder) ; └─┴─┴─┴─┴─┴─┴───── Low order bits of cylinder # ; */ ; ALL REGS SAVED push bp mov bp,sp push bx push cx push dx push ES push DS pop ES mov dl,byte ptr [bp+ 4] ; drive mov cl,byte ptr [bp+ 6] ; sec mov dh,byte ptr [bp+ 8] ; head mov ch,byte ptr [bp+10] ; trk mov bx,word ptr [bp+12] ; Buffer mov ax,0201h; Fn=02, Read 1 sector int 13h jc @@err xor ax,ax jmp @@ret @@err: ; mov ax,-1 @@ret: pop ES pop dx pop cx pop bx ; mov sp,bp pop bp ret _ReadPhysSec endp public _ReadPhysSec _WritePhysSec proc ; int WritePhysSec (unsigned char drive, unsigned char sec, unsigned char head, ; unsigned char trk, char *Buffer); ; ALL REGS SAVED push bp mov bp,sp push bx push cx push dx push ES push DS pop ES mov dl,byte ptr [bp+ 4] ; drive mov cl,byte ptr [bp+ 6] ; sec mov dh,byte ptr [bp+ 8] ; head mov ch,byte ptr [bp+10] ; trk mov bx,word ptr [bp+12] ; Buffer mov ax,0301h; Fn=03, Write 1 sector int 13h jc @@err xor ax,ax jmp @@ret @@err: ; mov ax,-1 @@ret: pop ES pop dx pop cx pop bx ; mov sp,bp pop bp ret _WritePhysSec endp public _WritePhysSec _TEXT ends end src/boot/makefile0100664000076500007650000000663407725643752013573 0ustar prool2prool2# OS Proolix. Boot record makefile. # Use Turbo C 2.0 make.exe for make Proolix kernel TasmFlags = /i..\..\..\proc /q /t /w2 /ml /z /m3 /l LinkFlag = /c/t/d/m/s/x # LinkFlag = /c/t/d/x TCFlag = -N- -K -C -mt -I..\include -DKERNEL # TCFlag = -K -C -mt -I..\include -DKERNEL -g1 -j1 # TCFlag = -K -C -O- -G- -Z- -d- -mt -r- -u+ -v- -y- CPPFlag = -I..\include TC = \tc # Proc = \usr\prool\proc Commands = ..\command Include = ..\include Kernel = ..\kernel .c.obj: tcc -c $(TCFlag) $& .asm.obj: tasm $(TasmFlags) $& .c.asm: tcc -c -S $(TCFlag) $& .c.i: cpp $(CPPFlag) $& all: bp.com boots.bin booth12.bin booth16.bin boots.bin: boots.obj tlink $(LinkFlag) boots,boots.bin booth12: booth12.bin bp.com bp -d4 -i -y booth12.bin booth16: booth16.bin bp.com bp -d4 -i -y booth16.bin boot: boots.bin bp.com bp -d0 -i -y boots.bin booth12.bin: booth12.obj tlink $(LinkFlag) booth12,booth12.bin booth16.bin: booth16.obj tlink $(LinkFlag) booth16,booth16.bin boots.obj: boots.asm booth12.obj: booth.asm fat12.asm tasm $(TasmFlags) /dFAT12 booth,booth12,booth12 booth16.obj: booth.asm fat16.asm tasm $(TasmFlags) /dFAT16 booth,booth16,booth16 bootrw.obj: bootrw.asm bp.com: bp.c $(Include)\struct.h $(Include)\limits.h bootrw.obj \ $(Kernel)\out_os.c $(Kernel)\out_mbr.c tcc -mt -lt bp.c bootrw.obj copy bp.com \bin herccomp: msherc.com msherc.bin comp msherc.bin msherc.com msherc.com: msherc.asm tasm $(TasmFlags) $& tlink /t/x msherc boot_p.bin: boot_p.obj tlink $(LinkFlag) boot_p,boot_p.bin csipboot: bootd.bin bp.com bp -da -i -y bootd.bin bootd.bin: bootd.obj tlink $(LinkFlag) bootd,bootd.bin i install: boot mbr.obj: mbr.asm mbr.com: mbr.obj bootcomp: mbr.com comp mbr.bin mbr.com boot360k.2nd: boot360k.asm tasm $(TasmFlag) -i\etc\sr boot360k tlink $(LinkFlag) boot360k,boot360k.2nd arh arj: pix_boot.arj arj f -jm pix_boot makefile arj f -r -t1g pix_boot *.c arj f -r -jm pix_boot save: a:\pix_boot.arj a:\proolix.arj a:\pix_boot.arj: pix_boot.arj copy pix_boot.arj a:\pix_boot.arj a:\proolix.arj: ..\proolix.arj copy ..\proolix.arj a:\proolix.arj ..\proolix.arj: pix_boot.arj arj f -r -jm -xfile_id.diz ..\proolix bak: del *.bak del *.map del *.tmp del *.lst del *.i del norton.ini clean: bak del *.obj del delete: clean pix_boot.arj arj f -jm pix_boot makefile arj f -r -jm -d -xmakefile pix_boot del tcpick.tcp test disktest: arj t a:\pix_boot.arj arj t a:\proolix.arj normalboot: boot360k bp -r -da boot360k reboot: hboot src/boot/boots.asm0100664000076500007650000003310507725643752013714 0ustar prool2prool2 PAGE ,79 jumps ; FDD Boot sector ver. 0.0.4.0 20-Apr-96 from Proolix operating system ; Copyright (C) Serge Pustovoitoff, 1993-1996 ; При отладке бута учитывались многочисленные полезные замечания, которые ; сделал Алекс Семеняка и Юрий Белотицкий (bela@padco.kharkov.ua) ; History in stack order ; 0.0.4.0 20-Apr-96 загружаемый файл /boot может быть сжат pklite'ом ; 0.0.3.1 24-Mar-96 replace chr1 '.' -> char1 176 ; 0.0.3.1 12-Mar-96 PSPSeg = 3050h ; 0.0.3.0 25-Feb-96 PSPSeg = 1050h ; 0.0.3.0 10-Jan-96 - загружаем не /kernel, а /boot (см. файл history, ; запись 0.0.1.4 10-Jan-96 ; 0.0.2.3 16-Sep-95 ; 0.0.2.2 15-Sep-95 - разветвление на FDD и HDD бут сектора ; 0.0.2.1 25-Feb-95 - до этого история не велась... (см. также общую историю ; в файле kernel/history.doc ; Смещение, связанное с тем, что во время компиляции ; адресом начала является 100h, а во время ; выполнения 7c00h off equ 7c00h-100h Drive equ 0 ; Загрузочный диск A: (FDD 0) PSPSeg equ 3050h ; Сегментный адрес, куда будет ; загружен /boot (точнее, его PSP) FATaddr equ Buff ; Макрос. Вывод одного символа через ROM BIOS. chr1 macro sym ; Not worked in graph mode (registr bl - background color!) ; NO SAVE REGS !!! mov ax,0e00h+sym int 10h endm chr1 sayr macro str ; NO SAVE REGS !!! ; Макрокоманда, аналогичная макрокоманде say. Только say использует функцию 9h ; ДОС, а sayr - функцию ROM BIOS (функция 0eh прерывания 10h) ; В графических режимах не работает mov si,offset str call sayr_proc endm sayr locals .model tiny .code org 100h Begin: jmp short start ; Таблица параметров диска db 90h ; NOP ; '12345678' OEM db 'Proolix ' SectSiz dw 512 ClustSiz db 2 ResSecs dw 1 FatCnt db 2 RootSiz dw 112 TotSecs dw 720 Media db 0fdh FatSize dw 2 TrkSecs dw 9 HeadCnt dw 2 HidnSec dd 0 BigNo dd 0 ; Big total no of sectors db 0 ; Head No db 0h ; Physical drive no db 29h ; Extended boot signature ;dd 1 ; Volume serial no ;FATaddr label word ; ! dw 0 ; ! internal vars StartClu dw 0 ; ! Lbl db 'BOOT ' ; Volume label db 'FAT12 ' ; File system ID RootSize dw ' '; use 2 last bytes of File system id OldVec dw 2 dup (0) start: ; push CS ; pop DS ; sayr OEM+off ; Значения регистров после загрузки boot-сектора ; CS:IP = 0:7C00 SS=30 SP=F6 ES=0 ; 0:0 - 0:200 - таблица прерываний ; Стек: c 30:F6 (0:3F6) растет к 0 (0:200-0:400 - стек) ; ROM BIOS area 0:400-0:500 ; cli ; Модификация diskette param table (взято из бута MSDOS 6.0) ; нужен ли в нижеследующей команде префикс ES: ? lds si,dword ptr ES:[78h] ; DS:si - vector diskette param table ; diskette param tble ; Bytes: ; 0 - bit 0-3 - SRT (step rate time), 4-7 head unload time ; 1 - bit 0: 1 if DMA, 2-7 head load time ; 2 - motor wait (in 55 ms) ; 3 - sec size (0 - 128, 1 - 256, 2 - 512, 3 - 1024) ; 4 - EOT (finish sector on track) ; 5 - interval length for ReadWrite ; 6 - DTL - Data Transfer Length (maximal) ; 7 - interval length for formatting ; 8 - Filler ; 9 - head settle time (in ms) ; a - motor start time (in 1/8 s) mov byte ptr [si+9],0Fh ; head settle := f mov cx,TrkSecs+off ; TrkSecs mov [si+6],cl ; Data Transfer Length ; sti mov dl,Drive xor ax,ax int 13h ; Disk dl=drive ah=func 00h ; reset disk, al=return status jc l_err push CS pop ES push CS pop DS ; Вычисления mov al,byte ptr FatCnt+off cbw mov cx,word ptr FatSize+off mul cx ; ax*cx -> dx:ax add ax,word ptr ResSecs+off ; ax - Root Beginning Sector mov word ptr StartClu+off,ax PUSH ax mov ax,word ptr RootSiz+off mov cx,32 mul cx mov cx,word ptr SectSiz+off div cx ; dx:ax / cx -> ax; mod -> dx or dx,dx ; Если остаток ненулевой, то прибавляем еще один jz l_ll ; сектор (последний неполный сектор root'а) inc ax l_ll: ; ax - Root Size in Sectors add word ptr StartClu+off,ax mov cx,ax mov word ptr RootSize+off,ax POP ax ; ax - Root Bg Sec @@loop: ; Загрузка корневого каталога посекторно и посекторный поиск в нем ; имени ядра push cx push ax mov bx,offset Buff+off mov dl,Drive push ax call SecRead jc l_err pop ax ; push ax ; chr1 'R' ; pop ax mov cx,16 ; root entryes in 1 sector @@l: push cx mov cx,11 mov di,bx mov si,offset Lbl+off rep cmpsb je l_found pop cx add bx,32 loop @@l pop ax inc ax pop cx loop @@loop ; end of load root dir ; HЕ HАШЛИ ЯДРА l_err: ; chr1 'E' call ohw xor ah,ah int 16h int 19h ;Vis: jmp short Vis sayr_proc proc ; Ver 0.0.1 9-Dec-93 ; Процедура вывода строки при помощи функций BIOS ; Вход: DS:SI - ASCIIZ строка. ; NO REG SAVED !!! ; В графических режимах не работает ; cld sayr_l1: lodsb or al,al jz sayr_ret mov ah,0eh int 10h jmp short sayr_l1 sayr_ret: ret sayr_proc endp l_found: ; HАШЛИ ! pop cx ; Found kernel ; bx - kernel dir record ; word ptr [bx+1ah] - 1st cluster mov ax,word ptr [bx+1ah] ; ax - 1st cluster ; Загрузка FAT в ОЗУ PUSH ax ; save ax with 1st clu no mov ax,word ptr ResSecs+off mov bx,offset FATaddr+off mov cx,word ptr FatSize+off ; Загрузка ядра покластерно (по цепочке из FATа) ; Загрузка FAT @@l: mov dl,Drive push ax call SecRead jc l_err pop ax add bx,512 inc ax ; Next sector! ; push ax ; chr1 'F' ; pop ax loop @@l mov al,byte ptr ClustSiz+off cbw mov dx,word ptr SectSiz+off mul dx mov cx,ax ; Cluster Size in Bytes POP ax ; restore ax (1st clu no) mov bx,PSPSeg mov ES,bx mov bx,100h l2: mov dl,Drive call CluRead push ax chr1 176 pop ax add bx,cx call NextClu ; set ax jnc l2 ; EXEC! Запуск ядра ; mov ax,PSPSeg ; mov DS,ax ; mov ES,ax ; cli ; mov SS,ax ; mov SP,0fffeh ; sti ; sayr OEM+off ; *(int far *)MK_FP(PSP,2)=0x9FFF; /* для LZEXE */ mov ax,PSPSeg mov DS,ax cli mov SS,ax mov SP,0fffeh sti ; mov ES,ax ; mov word ptr ES:[2],9FFFh db 0eah ; JMP PSPSeg:100 dw 100h,PSPSeg NextClu proc ; Input: ax - cluster no ; Output: ax - next cluster from FAT ; cf=1 if EOF ; Use global var: ; FATaddr dw 0 ; REGS SAVED ! push bx push cx push dx push si push di mov di,ax mov bx,3 mul bx ; dx:ax := ax * bx shr ax,1 ; ax := ax /2 ; ax - addr in FAT mov si,ax mov bx,offset FATaddr+off mov ax,word ptr [bx+si] test di,1 jz @@1 mov cl,4 shr ax,cl jmp @@2 @@1: and ax,0fffh @@2: ; cmp ax,0fffh ; je @@cf ; cmp ax,0ff7h ; je @@cf cmp ax,word ptr TotSecs+off ja @@cf clc @@ret: pop di pop si pop dx pop cx pop bx ret @@cf: stc jmp @@ret NextClu endp SecRead proc ; ver 0.0.1 3-Nov-94 (for FDD boot) ; Read absolute sectors ; Input: ax - abs sec number ; dl - drive (for int 13h Fn=2) ; ES:bx - buffer ; DS - data segment reg ; Use global variables: ; word ptr HeadCnt+off ; word ptr TrkSecs+off ; Output: cf=1 if error ; NO ALL REGS SAVED !!! ; push ax push bx push cx push dx push si push di mov si,bx ; save bx & dx mov di,dx PUSH ax mov ax,word ptr HeadCnt+off mov cx,word ptr TrkSecs+off mul cx ; dx:ax := HeadCnt * TrkSecs mov bx,ax ; bx = HeadCnt * TrkSecs POP ax xor dx,dx ; dx:ax - Abs Sec No div bx ; ax=Track=AbsSec/(HeadCnt*TrkSecs); dx - mod (Sec on Cyl) mov bx,ax ; bx - track no mov ax,dx xor dx,dx ; dx:ax - module (Sec on Cyl) div cx ; Head=[dx:ax]/TrkSecs;ax - Head; mod (dx) - Sec on Head-1 inc dx ; dx - Sec on Head mov cx,5 l_loop: push cx mov cl,dl ; sector mov ch,bl ; track ; Warning: track < 255 !!! mov bx,si ; Restore bx - offset for buff mov dx,di ; Restore dl - drive no mov dh,al ; head mov ax,0201h; Fn=02, Read 1 sector int 13h jnc l_break pop cx loop l_loop jmp short l_ret l_break: pop cx l_ret: pop di pop si pop dx pop cx pop bx ; pop ax ret SecRead endp CluRead proc ; Read cluster ; Input: ax - cluster number ; dl - drive (for int 13h Fn=2) ; ES:bx - buffer ; DS - data segment reg ; Use global variables: ; StartClu dw 0 ; Number sector of 1st cluster ; ClustSiz db 2 ; SectSiz dw ; ALL REGS SAVED !!! push ax push bx push cx ; Sector = StartClu + ((Clu-2) * ClustSiz) PUSH bx PUSH dx dec ax ; ax:=ax-2 dec ax ; mov bx,ax mov al,byte ptr ClustSiz+off cbw mov cx,ax mul bx add ax,word ptr StartClu+off ; ax - sector POP dx ; Restore dl POP bx ; cx - ClustSiz @@l: push ax call SecRead jc l_err pop ax add bx,word ptr SectSiz+off inc ax loop @@l pop cx pop bx pop ax ret CluRead endp ohw proc ; Вывод слова в HEX-виде. Вход: слово в ax. ; Все регистры сохраняются. ; Вызывает подпрограмму ohb push ax ; Сохр. ради al. mov al,ah call ohb pop ax ; Восст. al. call ohb ret ohw endp ohb proc ; Procedure output hex byte Ver 0.1.1 6 Dec 93 via BIOS ; Input: AL - byte ; All regs. reserved ;) ; Not worked in graph mode. bl - bg color !!! push ax push cx push dx mov dl,al mov cl,4 shr al,cl call ohb1 mov al,dl and al,0fh call ohb1 pop dx pop cx pop ax ret ohb endp ohb1 proc ; Regs not saved !!! push ax cmp al,9 ja @@_1 ; al > 9 ; al <= 9 add al,'0' jmp @@_out @@_1: add al,'A'-10 @@_out: mov ah,0eh int 10h pop ax ret ohb1 endp Buff label byte end Begin src/boot/files.bbs0100664000076500007650000000003007725643752013645 0ustar prool2prool2BOOTRW.ASM bootread0() src/boot/fat16.asm0100664000076500007650000000145707725643752013514 0ustar prool2prool2; for FAT-16 NextClu proc ; Input: ax - cluster no ; Output: ax - next cluster from FAT ; cf=1 if EOF ; REGS SAVED ! push bx push dx push ES mov bx,2 mul bx ; dx:ax := ax * bx ; dx:ax - relative address in FAT add dx,FATseg ; dx:ax - absolute address in FAT mov ES,dx mov bx,ax mov ax,word ptr ES:[bx] ; cmp ax,0fffh ; je @@cf ; cmp ax,0ff7h ; je @@cf cmp ax,word ptr MaxClusters+off ja @@cf clc @@ret: pop ES pop dx pop bx ret @@cf: stc jmp @@ret NextClu endp src/command/0040775000076500007650000000000007725644160012532 5ustar prool2prool2src/command/cp.c0100664000076500007650000000506507725644157013311 0ustar prool2prool2/*-------------------------------------------------------------------------*/ /* external cp utility (like UNIX' cp) */ /* for OS Proolix, MSDOS */ /* by Serge Pustovoitoff (Prool), prool@itl.net.ua */ /* WWW http://www.users.itl.net.ua/~prool/ */ /*-------------------------------------------------------------------------*/ #ifdef Proolix #include #else #define SECTOR_SIZE 512 #define PATH_MAX 128 #endif #include #include #include #include #include #include void cp_help(void) { puts("usage: cp [file1] [file2]"); } int copy(char *path1, char *path2) {int h1, h2, i1, i2; long n, m; char buf [SECTOR_SIZE]; #ifdef Proolix if((h1=open(path1,O_RDONLY))==-1) #else if((h1=open(path1,O_RDONLY|O_BINARY))==-1) #endif { printf("cp: can't open source\n"); return -1; } if (access(path2,2)==0) if (unlink(path2)) {printf("cp: can't unlink target\n"); return -1; } #ifdef Proolix if((h2=open(path2,O_WRONLY|O_CREAT|O_EXCL))==-1) #else if((h2=open(path2,O_WRONLY|O_CREAT|O_EXCL|O_BINARY,S_IWRITE))==-1) #endif { printf("cp: can't open target\n"); close(h1); return -1; } while(1) { if((n=read(h1,buf,SECTOR_SIZE))==-1) break; if(n==0) {m=0; break;} if((m=write(h2,buf,n))==-1) break; if (m!=n) break; } i1=close(h1); i2=close(h2); if (n==-1) {printf("cp: can't read source\n"); return -1;} if (m==-1) {printf("cp: can't write target\n"); return -1;} if (m!=n) {printf("cp: write error (device full or not ready?)\n"); return -1;} if (i1==-1) {printf("cp: can't close source\n");return -1;} if (i2==-1) { printf( "cp: can't close target (device or directory full or device not ready)\n" ); return -1; } return 0; /* OK! */ } main(int argc, char *argv[] ) { int ii, j, n, Files=0; char path[2][PATH_MAX]; argc--; ii=1; do { if (argc) { if (argv[ii][0]=='-') { n=(int)strlen(argv[ii]); for (j=1;j2) {cp_help(); return 3;} } } } while (ii++ #include #include void saycsip(void); void main (void) {int i=0xAAAA,j=0xBBBB; j=fork(); if (j==-1) puts("fork error"); else if (j) { /* parent */ while (1) { putch('P'); for (i=0;i<30000;i++) j++; /* L: goto L; */ } } else { /* child */ while (1) { putch('c'); for (i=0;i<30000;i++) j++; /* L1: goto L1; */ } } } src/command/banner.c0100664000076500007650000001755607725644157014164 0ustar prool2prool2/* banner - print a banner Author: Brian Wallis */ /***************************************************************** * * SYSVbanner.c * * This is a PD version of the SYS V banner program (at least I think * it is compatible to SYS V) which I wrote to use with the clock * program written by: ** DCF, Inc. ** 14623 North 49th Place ** Scottsdale, AZ 85254 * and published in the net comp.sources.misc newsgroup in early July * since the BSD banner program works quite differently. * * There is no copyright or responsibility accepted for the use * of this software. * * Brian Wallis, brw@jim.odr.oz, 4 July 1988 * *****************************************************************/ #include #include /* Make under MSDOS tcc -DMSDOS -mt -lt banner.c Serge Pustovoitoff, prool@infocom.kharkov.ua, 13-03-97г. 23:29:45 */ #if defined(MSDOS) || defined (Proolix) int main (int argc, char **argv); #else _PROTOTYPE(int main, (int argc, char **argv)); #endif char *glyphs[] = { " @@@ @@ @@ @ @ @@@@@ @@ @@@ ", " @@@ @@ @@ @ @ @ @ @@@ @ @ @ @@@ ", " @@@ @ @ @@@@@@@@ @ @@ @ @@ @ ", " @ @ @ @@@@@ @ @@@ @ ", " @@@@@@@ @ @ @ @ @ @ ", " @@@ @ @ @ @ @ @ @@ @ @ ", " @@@ @ @ @@@@@ @ @@ @@@@ @ ", " @@ @@ @", " @ @ @ @ @ @ ", " @ @ @ @ @ @ ", " @ @ @@@@@@@ @@@@@ @@@ @@@@@ @ ", " @ @ @ @ @ @@@ @ ", " @ @ @ @ @ @ @@@ @ ", " @@ @@ @ @@@ @ ", " @@@ @ @@@@@ @@@@@ @ @@@@@@@ @@@@@ @@@@@@@", " @ @ @@ @ @@ @@ @ @ @ @@ @ ", "@ @ @ @ @ @ @@ @ @ @ @ ", "@ @ @ @ @@@@@ @@@@@ @@@@@@@ @@@@@ @@@@@@ @ ", "@ @ @ @ @ @ @ @@ @ @ ", " @ @ @ @ @ @ @ @ @@ @ @ ", " @@@ @@@@@ @@@@@@@ @@@@@ @ @@@@@ @@@@@ @ ", " @@@@@ @@@@@ @@@ @ @ @@@@@ ", "@ @@ @ @@@ @@@ @ @ @ @", "@ @@ @ @@@ @ @@@@@ @ @", " @@@@@ @@@@@@ @@@ @ @ @@ ", "@ @ @ @@@ @ @@@@@ @ @ ", "@ @@ @ @@@ @ @ @ ", " @@@@@ @@@@@ @@@ @ @ @ @ ", " @@@@@ @ @@@@@@ @@@@@ @@@@@@ @@@@@@@@@@@@@@ @@@@@ ", "@ @ @ @ @ @@ @@ @@ @ @ @", "@ @@@ @ @ @ @ @@ @ @@ @ @ ", "@ @ @ @@ @@@@@@@ @ @ @@@@@@ @@@@@ @ @@@@", "@ @@@@ @@@@@@@@ @@ @ @@ @ @ @", "@ @@ @@ @@ @@ @@ @ @ @", " @@@@@ @ @@@@@@@ @@@@@ @@@@@@ @@@@@@@@ @@@@@ ", "@ @ @*@ @@ @ @ @ @@ @@@@@@@@", "@ @ @ @@ @ @ @@ @@@@ @@ @", "@ @ @ @@ @ @ @ @ @ @@ @ @@ @", "@@@@@@@ @ @@@@ @ @ @ @@ @ @@ @", "@ @ @ @ @@ @ @ @ @@ @ @@ @", "@ @ @ @ @@ @ @ @ @@ @@@ @", "@ @ @@@ @@@@@ @ @ @@@@@@@@ @@ @@@@@@@@", "@@@@@@ @@@@@ @@@@@@ @@@@@ @@@@@@@@ @@ @@ @", "@ @@ @@ @@ @ @ @ @@ @@ @ @", "@ @@ @@ @@ @ @ @@ @@ @ @", "@@@@@@ @ @@@@@@@ @@@@@ @ @ @@ @@ @ @", "@ @ @ @@ @ @ @ @ @ @ @ @ @ @", "@ @ @ @ @ @ @ @ @ @ @ @ @ @ @", "@ @@@@ @@ @ @@@@@ @ @@@@@ @ @@ @@ ", "@ @@ @@@@@@@@ @@@@@ @ @@@@@ @ ", " @ @ @ @ @ @ @ @ @ @ ", " @ @ @ @ @ @ @ @ @ @ ", " @ @ @ @ @ @ ", " @ @ @ @ @ @ @ ", " @ @ @ @ @ @ @ ", "@ @ @ @@@@@@@ @@@@@ @ @@@@@ @@@@@@@", " @@@ ", " @@@ @@ @@@@@ @@@@ @@@@@ @@@@@@ @@@@@@ @@@@ ", " @ @ @ @ @ @ @ @ @ @ @ @ @", " @ @ @ @@@@@ @ @ @ @@@@@ @@@@@ @ ", " @@@@@@ @ @ @ @ @ @ @ @ @@@", " @ @ @ @ @ @ @ @ @ @ @ @", " @ @ @@@@@ @@@@ @@@@@ @@@@@@ @ @@@@ ", " ", " @ @ @ @ @ @ @ @ @ @ @ @@@@ ", " @ @ @ @ @ @ @ @@ @@ @@ @ @ @", " @@@@@@ @ @ @@@@ @ @ @@ @ @ @ @ @ @", " @ @ @ @ @ @ @ @ @ @ @ @ @ @", " @ @ @ @ @ @ @ @ @ @ @ @@ @ @", " @ @ @ @@@@ @ @ @@@@@@ @ @ @ @ @@@@ ", " ", " @@@@@ @@@@ @@@@@ @@@@ @@@@@ @ @ @ @ @ @", " @ @ @ @ @ @ @ @ @ @ @ @ @ @", " @ @ @ @ @ @ @@@@ @ @ @ @ @ @ @", " @@@@@ @ @ @ @@@@@ @ @ @ @ @ @ @ @@ @", " @ @ @ @ @ @ @ @ @ @ @ @ @@ @@", " @ @@@ @ @ @ @@@@ @ @@@@ @@ @ @", " @@@ @ @@@ @@ @ @ @ @", " @ @ @ @ @@@@@@ @ @ @ @ @ @ @ @ @ ", " @ @ @ @ @ @ @ @ @@ @ @ @ @", " @@ @ @ @@ @@ @ @ @ ", " @@ @ @ @ @ @ @ @ @ @", " @ @ @ @ @ @ @ @ @ @ ", " @ @ @ @@@@@@ @@@ @ @@@ @ @ @ @" }; int main(argc, argv) int argc; char *argv[]; { int a, b, c, len, ind; char line[80]; for (argv++; --argc; argv++) { #ifdef Proolix len = (int) strlen(*argv); #else len = strlen(*argv); #endif if (len > 10) len = 10; for (a = 0; a < 7; a++) { for (b = 0; b < len; b++) { if ((ind = (*argv)[b] - ' ') < 0) ind = 0; for (c = 0; c < 7; c++) { line[b * 8 + c] = glyphs[(ind / 8 * 7) + a][(ind % 8 * 7) + c] == '@' ? ind + ' ' : ' '; } line[b * 8 + 7] = ' '; } for (b = len * 8 - 1; b >= 0; b--) { if (line[b] != ' ') break; line[b] = '\0'; } printf("%s\n", line); } printf("\n"); } return(0); } src/command/000.asm0100664000076500007650000000022207725644157013532 0ustar prool2prool2; Do not edit this file. ; This file is automatically generated model tiny .code _getch: mov ax,0 int 084h ret public _getch end src/command/pg.c0100664000076500007650000000154407725644160013305 0ustar prool2prool2#include #include #include #include #include #include #define MAX_S 256 void main(argc, argv) int argc; char *argv[]; {FILE *fp; char s[MAX_S]; long pos, oldpos; int i; if (argc==1) {printf("usage: pg filename\n"); exit(0); } #pragma warn -sus fp=fopen(argv[1],"r"); #pragma warn +sus L0: pos=ftell(fp); for(i=0;i<24;i++) { if (fgets(s,MAX_S,fp)==NULL) break; printf("%s",s); } oldpos=pos; pos=ftell(fp); L1: printf( "\n%li: Space - next page, Minus - prev. page, 1 - Begin, ` - End, ESC - exit" ,pos); i=getch(); putch('\r'); switch(i) { case ' ': goto L0; case '-': fseek(fp,oldpos,SEEK_SET); goto L0; case '1': fseek(fp,0,SEEK_SET); goto L0; case '`': fseek(fp,0,SEEK_END); goto L0; case ESC: break; default: goto L1; } fclose(fp); } src/command/ls.c0100664000076500007650000001032207725644160013307 0ustar prool2prool2#include #include #include #include #include #include #include #include char *DirToPath(struct dirent far *Dir, char *path); /****************************************************************************/ void help(void) { puts("Uses: ls [-l] [-L] [-U] [-H] [-T] [-M] [-S]\n\n\ Switches:\n\n\ -l - long info\n\ -L - very long info\n\ -U - list unused dir records\n\ -H - hex output (default - dec output)\n\ -T - title\n\ -S - type summa of filesizes\n\ -M - more"); } /****************************************************************************/ #if 0 /* сохранено для истории */ void OutAttr(char a) {char Letter [] = "ADLSHR"; char Mask; int i; Mask=0x20; for (i=0;i<6;i++){if(a&Mask)putch(Letter[i]); else putch('.');Mask>>=1;} } void OutTime(unsigned int t) { printf("%2i:%02i:%02i",t>>11,(t&0x7ff)>>5, (unsigned int)(t & (unsigned int) 0x1f)*2); } void OutDate(unsigned int t) { printf("%2i-%02i-%02i",t&0x1f,(t&0x1e0)>>5,1980+(t>>9)); } #endif /****************************************************************************/ /****************************************************************************/ #if 1 void OutAttr(struct AttrField Attr) { if (Attr.Attr1) putch('*'); else putch('.'); if (Attr.Attr2) putch('*'); else putch('.'); if (Attr.Archive) putch('A'); else putch('.'); if (Attr.Dir) putch('D'); else putch('.'); if (Attr.Label) putch('L'); else putch('.'); if (Attr.System) putch('S'); else putch('.'); if (Attr.Hidden) putch('H'); else putch('.'); if (Attr.ReadOnly) putch('R'); else putch('.'); } void OutTimeDate(struct ftime t) { printf("%2i:%02i:%02i %2i-%02i-%02i", t.ft_hour, t.ft_min, t.ft_tsec*2, t.ft_day, t.ft_month,1980+t.ft_year); } #endif /****************************************************************************/ int main (int argc, char *argv[]) {int i, j, k, n; long l; struct dirent far *D; char Path [NAME_MAX+1]; int FlagL=0; int FlagU=0; int FlagLL=0; int FlagH=0; int FlagT=0; int FlagS=0; unsigned long size; unsigned long SumSize=0; DIR far *dir; argc--; i=1; do { if (argc) { if (argv[i][0]=='-') { n=(int)strlen(argv[i]); for (j=1;j #include #include "prool.h" void main (int argc) {int i; char c; for (i=0;i<256;i++) { c=i; switch (c) { /* case 7: */ /* case 8: */ /* case 9: */ case 10: case 13: c='.'; } if (argc==2) textattr(c); putch (c); putch (' '); if (i&&((i&15)==15)) {textattr (7); puts("");} } textattr (7); } src/command/s.c0100664000076500007650000000173407725644160013142 0ustar prool2prool2#include #include #define SIZE_S 254 void main(int argc, char *argv[]) { int i, n, m; FILE far *fp; char s [SIZE_S]; char *cc; if (argc<2) printf("usage: s [ string_no [string_count] ]\n"); fp=fopen(argv[1],"r"); if (fp==NULL) {perror("s: fopen"); return; } if (argc>2) if (argv[2][0]=='$') n=htoi(argv[2]+1); else n=atoi(argv[2]); else n=0; if (argc>3) if (argv[3][0]=='$') m=htoi(argv[2]+1); else m=atoi(argv[2]); else m=1; if (n==0) { for(i=1;;i++) { if (fgets(s,SIZE_S,fp)==NULL) break; cc=s; if (cc[0]=='\n') cc++; printf("\n%i:0x%04X: %s",i,i,cc); } } else { for (i=1;i #include #include #include #include #include #include "prool.h" void help(void) { puts("Uses: touch [-c] [files...]"); } int main(int argc, char *argv[] ) { int i, j, h, n, Files=0, Flagc=0; struct time t; struct date d; struct ftime ft; argc--; i=1; do { if (argc) { if (argv[i][0]=='-') { n=(int)strlen(argv[i]); for (j=1;j #include #include #include #include #include #include #define Prec 2 #define Zero 0 /*--------------------------------------------------------------------------*/ /* E M A I N */ /*--------------------------------------------------------------------------*/ void main (int argc, char *argv[]) { int i, j; struct date d; struct time t; char curdir [PATH_MAX+1]; union REGS regs; j=argc; getdate(&d); gettime(&t); printf("Date is %2i-%02i-%02i %2i:%02i:%02i\n\n", d.da_day,d.da_mon,d.da_year+1980, t.ti_hour,t.ti_min,t.ti_sec); printf("pwd=%Fs\n",getcwd(curdir,PATH_MAX+1)); regs.h.ah=15; regs.x.flags=0; int86(0x10,®s,®s); printf("Current videomode = %i, page = %i\n",regs.h.al,regs.h.bh); printf("argc = %i\n",j); printf("Prog name = %s\n",argv[0]); for (i=0; i<=j; i++) { printf("Argument # %i ",i); if (argv[i]!=NULL) puts(argv[i]); else puts("(null)"); } printf("\nEnvironment:\n\n"); for (i=0; *(environ+i) != NULL; i++) { printf("environ.string=%Fs\n",*(environ+i)); } } src/command/unarj.c0100664000076500007650000006015707725644160014023 0ustar prool2prool2/* UNARJ.C, UNARJ, R JUNG, 02/17/93 * Main Extractor routine * Copyright (c) 1991-93 by Robert K Jung. All rights reserved. * * This code may be freely used in programs that are NOT ARJ archivers * (both compress and extract ARJ archives). * * If you wish to distribute a modified version of this program, you * MUST indicate that it is a modified version both in the program and * source code. * * I am holding the copyright on the source code, so please do not * delete my name from the program files or from the documentation. * * I wish to give credit to Haruhiko Okumura for providing the * basic ideas for ARJ and UNARJ in his program AR. Please note * that UNARJ is significantly different from AR from an archive * structural point of view. * * Modification history: * Date Programmer Description of modification. * 04/05/91 R. Jung Rewrote code. * 04/23/91 M. Adler Portabilized. * 04/29/91 R. Jung Added l command. Removed 16 bit dependency in * fillbuf(). * 05/19/91 R. Jung Fixed extended header skipping code. * 05/25/91 R. Jung Improved find_header(). * 06/03/91 R. Jung Changed arguments in get_mode_str() and * set_ftime_mode(). * 06/19/81 R. Jung Added two more %c in printf() in list_arc(). * 07/07/91 R. Jung Added default_case_path() to extract(). * Added strlower(). * 07/20/91 R. Jung Changed uint ratio() to static uint ratio(). * 07/21/91 R. Jung Added #ifdef VMS. * 08/28/91 R. Jung Changed M_DIFFHOST message. * 08/31/91 R. Jung Added changes to support MAC THINK_C compiler * per Eric Larson. * 10/07/91 R. Jung Added missing ; to THINK_C additions. * 11/11/91 R. Jung Added host_os test to fwrite_txt_crc(). * 11/24/91 R. Jung Added more error_count processing. * 12/03/91 R. Jung Added backup file processing. * 02/17/93 R. Jung Added archive modified date support. * */ #include "unarj.h" #ifdef MODERN #include #include #include #ifdef Proolix #include #define EXIT_FAILURE (1) #define EXIT_SUCCESS (0) #define stdout (0) #endif /* Proolix */ #else /* !MODERN */ extern void free(); void exit(); extern char FAR *strcat(); extern char FAR *strcpy(); extern char FAR *strncpy(); extern char FAR *strchr(); extern char FAR *strrchr(); extern int strlen(); extern int strcmp(); #ifdef VMS #include #define EXIT_FAILURE SS$_ABORT #define EXIT_SUCCESS SS$_NORMAL #else #define EXIT_FAILURE (1) #define EXIT_SUCCESS (0) #endif #define toupper(c) ((c)>='a'&&(c)<='z'?(c)-('a'-'A'):(c)) #define tolower(c) ((c)>='A'&&(c)<='Z'?(c)+('a'-'A'):(c)) #endif /* ?MODERN */ #ifdef THINK_C #include #endif /* Global variables */ UCRC crc; FILE FAR *arcfile; FILE FAR *outfile; ushort bitbuf; long compsize; long origsize; uchar subbitbuf; uchar header[HEADERSIZE_MAX]; char arc_name[FNAME_MAX]; int command; int bitcount; int file_type; int no_output; int error_count; /* Messages */ static char *M_USAGE [] = { "Usage: UNARJ archive[.arj] (list archive)\n", " UNARJ e archive (extract archive)\n", " UNARJ l archive (list archive)\n", " UNARJ t archive (test archive)\n", " UNARJ x archive (extract with pathnames)\n", "\n", "This is an ARJ demonstration program and ** IS NOT OPTIMIZED ** for speed.\n", "You may freely use, copy and distribute this program, provided that no fee\n", "is charged for such use, copying or distribution, and it is distributed\n", "ONLY in its original unmodified state. UNARJ is provided as is without\n", "warranty of any kind, express or implied, including but not limited to\n", "the implied warranties of merchantability and fitness for a particular\n", "purpose. Refer to UNARJ.DOC for more warranty information.\n", "\n", "ARJ Software Internet address : robjung@world.std.com\n", "Robert and Susan Jung CompuServe userid: 72077,445\n", "2606 Village Road West\n", "Norwood, Massachusetts 02062\n", "USA\n", NULL }; char M_VERSION [] = "UNARJ (Demo version) 2.41 Copyright (c) 1991-93 Robert K Jung\n\n"; char M_ARCDATE [] = "Archive created: %s"; char M_ARCDATEM[] = ", modified: %s"; char M_BADCOMND[] = "Bad UNARJ command: %s"; char M_BADCOMNT[] = "Invalid comment header"; char M_BADHEADR[] = "Bad header"; char M_BADTABLE[] = "Bad Huffman code"; char M_CANTOPEN[] = "Can't open %s"; char M_CANTREAD[] = "Can't read file or unexpected end of file"; char M_CANTWRIT[] = "Can't write file. Disk full?"; char M_CRCERROR[] = "CRC error!\n"; char M_CRCOK [] = "CRC OK\n"; char M_DIFFHOST[] = " Binary file!"; char M_ENCRYPT [] = "File is password encrypted, "; char M_ERRORCNT[] = "%sFound %5d error(s)!"; char M_EXTRACT [] = "Extracting %-25s"; char M_FEXISTS [] = "%-25s exists, "; char M_HEADRCRC[] = "Header CRC error!"; char M_NBRFILES[] = "%5d file(s)\n"; char M_NOMEMORY[] = "Out of memory"; char M_NOTARJ [] = "%s is not an ARJ archive"; char M_PROCARC [] = "Processing archive: %s\n"; char M_SKIPPED [] = "Skipped %s\n"; char M_SUFFIX [] = ARJ_SUFFIX; char M_TESTING [] = "Testing %-25s"; char M_UNKNMETH[] = "Unsupported method: %d, "; char M_UNKNTYPE[] = "Unsupported file type: %d, "; char M_UNKNVERS[] = "Unsupported version: %d, "; #define get_crc() get_longword() #define fget_crc(f) fget_longword(f) #define setup_get(PTR) (get_ptr = (PTR)) #define get_byte() ((uchar)(*get_ptr++ & 0xff)) #define BUFFERSIZE 4096 #define ASCII_MASK 0x7F #define CRCPOLY 0xEDB88320L #define UPDATE_CRC(r,c) r=crctable[((uchar)(r)^(uchar)(c))&0xff]^(r>>CHAR_BIT) /* Local functions */ #ifdef MODERN static void make_crctable(void); static void crc_buf(char FAR *str, int len); static void strparity(uchar *p); static FILE FAR *fopen_msg(char *name, char *mode); static int fget_byte(FILE FAR *f); static uint fget_word(FILE FAR *f); static ulong fget_longword(FILE FAR *f); static void fread_crc(uchar FAR *p, int n, FILE FAR *f); static void decode_path(char *name); static void get_date_str(char *str, ulong tstamp); static int parse_path(char *pathname, char *path, char *entry); static void strncopy(char *to, char *from, int len); static uint get_word(void); static ulong get_longword(void); static long find_header(FILE FAR *fd); static int read_header(int first, FILE FAR *fd, char *name); static void skip(void); static void unstore(void); static int check_flags(void); static int extract(void); static int test(void); static uint ratio(long a, long b); static void list_start(void); static void list_arc(int count); static void execute_cmd(void); static void help(void); #endif /* MODERN */ /* Local variables */ static char filename[FNAME_MAX]; static char comment[COMMENT_MAX]; static char *hdr_filename; static char *hdr_comment; static ushort headersize; static uchar first_hdr_size; static uchar arj_nbr; static uchar arj_x_nbr; static uchar host_os; static uchar arj_flags; static short method; static uint file_mode; static ulong time_stamp; static short entry_pos; static ushort host_data; static uchar *get_ptr; static UCRC file_crc; static UCRC header_crc; static long first_hdr_pos; static long torigsize; static long tcompsize; static int clock_inx; static char *writemode[2] = { "wb", "w" }; static UCRC crctable[UCHAR_MAX + 1]; /* Functions */ static void make_crctable() { uint i, j; UCRC r; for (i = 0; i <= UCHAR_MAX; i++) { r = i; for (j = CHAR_BIT; j > 0; j--) { if (r & 1) r = (r >> 1) ^ CRCPOLY; else r >>= 1; } crctable[i] = r; } } static void crc_buf(str, len) char FAR *str; int len; { while (len--) UPDATE_CRC(crc, *str++); } void disp_clock() { static char clock_str[4] = { '|', '/', '-', '\\' }; printf("(%c)\b\b\b", clock_str[clock_inx]); clock_inx = (clock_inx + 1) & 0x03; } void error(fmt, arg) char *fmt; char *arg; { #ifdef Proolix putch('\n'); #else putc('\n', stdout); #endif printf(fmt, arg, error_count); #ifdef Proolix putch('\n'); #else putc('\n', stdout); #endif #ifndef Proolix exit(EXIT_FAILURE); #endif } static void strparity(p) uchar *p; { while (*p) { FIX_PARITY(*p); p++; } } static FILE FAR * fopen_msg(name, mode) char *name; char *mode; { FILE FAR*fd; fd = file_open(name, mode); if (fd == NULL) error(M_CANTOPEN, name); return fd; } static int fget_byte(f) FILE FAR *f; { int c; if ((c = getc(f)) == EOF) error(M_CANTREAD, ""); return c & 0xFF; } static uint fget_word(f) FILE FAR *f; { uint b0, b1; b0 = fget_byte(f); b1 = fget_byte(f); return (b1 << 8) + b0; } static ulong fget_longword(f) FILE FAR *f; { ulong b0, b1, b2, b3; b0 = fget_byte(f); b1 = fget_byte(f); b2 = fget_byte(f); b3 = fget_byte(f); return (b3 << 24) + (b2 << 16) + (b1 << 8) + b0; } static void fread_crc(p, n, f) uchar FAR *p; int n; FILE FAR *f; { n = file_read((char FAR *)p, 1, n, f); origsize += n; crc_buf((char FAR *)p, n); } void fwrite_txt_crc(p, n) uchar FAR *p; int n; { uchar c; crc_buf((char FAR *)p, n); if (no_output) return; if (file_type == TEXT_TYPE) { while (n--) { c = *p++; if (host_os != OS) { FIX_PARITY(c); } if (putc((int) c, outfile) == EOF) error(M_CANTWRIT, ""); } } else { if (file_write((char FAR *)p, 1, n, outfile) != n) error(M_CANTWRIT, ""); } } void init_getbits() { bitbuf = 0; subbitbuf = 0; bitcount = 0; fillbuf(2 * CHAR_BIT); } void fillbuf(n) /* Shift bitbuf n bits left, read n bits */ int n; { bitbuf = (bitbuf << n) & 0xFFFF; /* lose the first n bits */ while (n > bitcount) { bitbuf |= subbitbuf << (n -= bitcount); if (compsize != 0) { compsize--; subbitbuf = (uchar) getc(arcfile); } else subbitbuf = 0; bitcount = CHAR_BIT; } bitbuf |= subbitbuf >> (bitcount -= n); } ushort getbits(n) int n; { ushort x; x = bitbuf >> (2 * CHAR_BIT - n); fillbuf(n); return x; } static void decode_path(name) char *name; { for ( ; *name; name++) { if (*name == ARJ_PATH_CHAR) *name = PATH_CHAR; } } static void get_date_str(str, tstamp) char *str; ulong tstamp; { sprintf(str, "%04u-%02u-%02u %02u:%02u:%02u", ts_year(tstamp), ts_month(tstamp), ts_day(tstamp), ts_hour(tstamp), ts_min(tstamp), ts_sec(tstamp)); } static int parse_path(pathname, path, entry) char *pathname; char *path; char *entry; { char *cptr, *ptr, *fptr; short pos; fptr = NULL; for (cptr = PATH_SEPARATORS; *cptr; cptr++) { #ifdef Proolix if ((ptr = (char *)strrchr(pathname, *cptr)) != NULL && #else if ((ptr = strrchr(pathname, *cptr)) != NULL && #endif (fptr == NULL || ptr > fptr)) fptr = ptr; } if (fptr == NULL) pos = 0; else pos = fptr + 1 - pathname; if (path != NULL) { strncpy(path, pathname, pos); path[pos] = NULL_CHAR; } if (entry != NULL) strcpy(entry, &pathname[pos]); return pos; } static void strncopy(to, from, len) char *to; char *from; int len; { int i; for (i = 1; i < len && *from; i++) *to++ = *from++; *to = NULL_CHAR; } void strlower(s) char *s; { while (*s) { *s = (char) tolower(*s); s++; } } void strupper(s) char *s; { while (*s) { *s = (char) toupper(*s); s++; } } voidp FAR * malloc_msg(size) int size; { char FAR *p; if ((p = (char FAR *)xmalloc(size)) == NULL) error(M_NOMEMORY, ""); return (voidp FAR *)p; } static uint get_word() { uint b0, b1; b0 = get_byte(); b1 = get_byte(); return (b1 << 8) + b0; } static ulong get_longword() { ulong b0, b1, b2, b3; b0 = get_byte(); b1 = get_byte(); b2 = get_byte(); b3 = get_byte(); return (b3 << 24) + (b2 << 16) + (b1 << 8) + b0; } static long find_header(fd) FILE FAR *fd; { long arcpos, lastpos; int c; arcpos = file_tell(fd); file_seek(fd, 0L, SEEK_END); lastpos = file_tell(fd) - 2; if (lastpos > MAXSFX) lastpos = MAXSFX; for ( ; arcpos < lastpos; arcpos++) { file_seek(fd, arcpos, SEEK_SET); c = fget_byte(fd); while (arcpos < lastpos) { if (c != HEADER_ID_LO) /* low order first */ c = fget_byte(fd); else if ((c = fget_byte(fd)) == HEADER_ID_HI) break; arcpos++; } if (arcpos >= lastpos) break; if ((headersize = fget_word(fd)) <= HEADERSIZE_MAX) { crc = CRC_MASK; fread_crc(header, (int) headersize, fd); if ((crc ^ CRC_MASK) == fget_crc(fd)) { file_seek(fd, arcpos, SEEK_SET); return arcpos; } } } return -1; /* could not find a valid header */ } static int read_header(first, fd, name) int first; FILE FAR *fd; char *name; { ushort extheadersize, header_id; header_id = fget_word(fd); if (header_id != HEADER_ID) { if (first) error(M_NOTARJ, name); else error(M_BADHEADR, ""); } headersize = fget_word(fd); if (headersize == 0) return 0; /* end of archive */ if (headersize > HEADERSIZE_MAX) error(M_BADHEADR, ""); crc = CRC_MASK; fread_crc(header, (int) headersize, fd); header_crc = fget_crc(fd); if ((crc ^ CRC_MASK) != header_crc) error(M_HEADRCRC, ""); setup_get(header); first_hdr_size = get_byte(); arj_nbr = get_byte(); arj_x_nbr = get_byte(); host_os = get_byte(); arj_flags = get_byte(); method = get_byte(); file_type = get_byte(); (void)get_byte(); time_stamp = get_longword(); compsize = get_longword(); origsize = get_longword(); file_crc = get_crc(); entry_pos = get_word(); file_mode = get_word(); host_data = get_word(); hdr_filename = (char *)&header[first_hdr_size]; strncopy(filename, hdr_filename, sizeof(filename)); if (host_os != OS) strparity((uchar *)filename); if ((arj_flags & PATHSYM_FLAG) != 0) decode_path(filename); hdr_comment = (char *)&header[first_hdr_size + strlen(hdr_filename) + 1]; strncopy(comment, hdr_comment, sizeof(comment)); if (host_os != OS) strparity((uchar *)comment); /* if extheadersize == 0 then no CRC */ /* otherwise read extheader data and read 4 bytes for CRC */ while ((extheadersize = fget_word(fd)) != 0) file_seek(fd, (long) (extheadersize + 4), SEEK_CUR); return 1; /* success */ } static void skip() { file_seek(arcfile, compsize, SEEK_CUR); } static void unstore() { int n; long pos; char FAR *buffer; buffer = (char FAR *)malloc_msg(BUFFERSIZE); pos = file_tell(arcfile); disp_clock(); n = (int)(BUFFERSIZE - (pos % BUFFERSIZE)); n = compsize > (long)n ? n : (int)compsize; while (compsize > 0) { if (file_read(buffer, 1, n, arcfile) != n) error(M_CANTREAD, ""); disp_clock(); compsize -= n; fwrite_txt_crc((uchar FAR *)buffer, n); n = compsize > BUFFERSIZE ? BUFFERSIZE : (int)compsize; } free(buffer); } static int check_flags() { if (arj_x_nbr > ARJ_X_VERSION) { printf(M_UNKNVERS, arj_x_nbr); printf(M_SKIPPED, filename); skip(); return -1; } if ((arj_flags & GARBLE_FLAG) != 0) { printf(M_ENCRYPT); printf(M_SKIPPED, filename); skip(); return -1; } if (method < 0 || method > MAXMETHOD || (method == 4 && arj_nbr == 1)) { printf(M_UNKNMETH, method); printf(M_SKIPPED, filename); skip(); return -1; } if (file_type != BINARY_TYPE && file_type != TEXT_TYPE) { printf(M_UNKNTYPE, file_type); printf(M_SKIPPED, filename); skip(); return -1; } return 0; } static int extract() { char name[FNAME_MAX]; if (check_flags()) { error_count++; return 0; } no_output = 0; if (command == 'E') strcpy(name, &filename[entry_pos]); else { strcpy(name, DEFAULT_DIR); strcat(name, filename); } if (host_os != OS) default_case_path(name); if (file_exists(name)) { printf(M_FEXISTS, name); printf(M_SKIPPED, name); skip(); error_count++; return 0; } outfile = file_open(name, writemode[file_type & 1]); if (outfile == NULL) { printf(M_CANTOPEN, name); putchar('\n'); skip(); error_count++; return 0; } printf(M_EXTRACT, name); if (host_os != OS && file_type == BINARY_TYPE) printf(M_DIFFHOST); printf(" "); crc = CRC_MASK; if (method == 0) unstore(); else if (method == 1 || method == 2 || method == 3) decode(); else if (method == 4) decode_f(); fclose(outfile); set_ftime_mode(name, time_stamp, file_mode, (uint) host_os); if ((crc ^ CRC_MASK) == file_crc) printf(M_CRCOK); else { printf(M_CRCERROR); error_count++; } return 1; } static int test() { if (check_flags()) return 0; no_output = 1; printf(M_TESTING, filename); printf(" "); crc = CRC_MASK; if (method == 0) unstore(); else if (method == 1 || method == 2 || method == 3) decode(); else if (method == 4) decode_f(); if ((crc ^ CRC_MASK) == file_crc) printf(M_CRCOK); else { printf(M_CRCERROR); error_count++; } return 1; } static uint ratio(a, b) long a, b; { int i; for (i = 0; i < 3; i++) if (a <= LONG_MAX / 10) a *= 10; else b /= 10; if ((long) (a + (b >> 1)) < a) { a >>= 1; b >>= 1; } if (b == 0) return 0; return (uint) ((a + (b >> 1)) / b); } static void list_start() { printf("Filename Original Compressed Ratio DateTime modified CRC-32 AttrBTPMGVX\n"); printf("------------ ---------- ---------- ----- ----------------- -------- -----------\n"); } static void list_arc(count) int count; { uint r; int garble_mode, path_mode, volume_mode, extfil_mode, ftype, bckf_mode; char date_str[20], fmode_str[10]; static char mode[5] = { 'B', 'T', '?', 'D', 'V' }; static char pthf[2] = { ' ', '+' }; static char pwdf[2] = { ' ', 'G' }; /* plain, encrypted */ static char volf[2] = { ' ', 'V' }; static char extf[2] = { ' ', 'X' }; static char bckf[2] = { ' ', '*' }; if (count == 0) list_start(); garble_mode = ((arj_flags & GARBLE_FLAG) != 0); volume_mode = ((arj_flags & VOLUME_FLAG) != 0); extfil_mode = ((arj_flags & EXTFILE_FLAG) != 0); bckf_mode = ((arj_flags & BACKUP_FLAG) != 0); path_mode = (entry_pos > 0); r = ratio(compsize, origsize); torigsize += origsize; tcompsize += compsize; ftype = file_type; if (ftype != BINARY_TYPE && ftype != TEXT_TYPE && ftype != DIR_TYPE && ftype != LABEL_TYPE) ftype = 3; get_date_str(date_str, time_stamp); strcpy(fmode_str, " "); if (host_os == OS) get_mode_str(fmode_str, (uint) file_mode); if (strlen(&filename[entry_pos]) > 12) printf("%-12s\n ", &filename[entry_pos]); else printf("%-12s ", &filename[entry_pos]); printf("%10ld %10ld %u.%03u %s %08lX %4s%c%c%c%u%c%c%c\n", origsize, compsize, r / 1000, r % 1000, &date_str[2], file_crc, fmode_str, bckf[bckf_mode], mode[ftype], pthf[path_mode], method, pwdf[garble_mode], volf[volume_mode], extf[extfil_mode]); } static void execute_cmd() { int file_count; char date_str[22]; uint r; first_hdr_pos = 0; time_stamp = 0; first_hdr_size = FIRST_HDR_SIZE; arcfile = fopen_msg(arc_name, "rb"); printf(M_PROCARC, arc_name); first_hdr_pos = find_header(arcfile); if (first_hdr_pos < 0) error(M_NOTARJ, arc_name); file_seek(arcfile, first_hdr_pos, SEEK_SET); if (!read_header(1, arcfile, arc_name)) error(M_BADCOMNT, ""); get_date_str(date_str, time_stamp); printf(M_ARCDATE, date_str); if (arj_nbr >= ARJ_M_VERSION) { get_date_str(date_str, (ulong) compsize); printf(M_ARCDATEM, date_str); } printf("\n"); file_count = 0; while (read_header(0, arcfile, arc_name)) { switch (command) { case 'E': case 'X': if (extract()) file_count++; break; case 'L': list_arc(file_count++); skip(); break; case 'T': if (test()) file_count++; break; } } if (command == 'L') { printf("------------ ---------- ---------- ----- -----------------\n"); r = ratio(tcompsize, torigsize); printf(" %5d files %10ld %10ld %u.%03u %s\n", file_count, torigsize, tcompsize, r / 1000, r % 1000, &date_str[2]); } else printf(M_NBRFILES, file_count); fclose(arcfile); } static void help() { int i; for (i = 0; M_USAGE[i] != NULL; i++) printf(M_USAGE[i]); } #ifdef Proolix void #else int #endif main(argc, argv) int argc; char *argv[]; { int i, j, lastc; char *arc_p; #ifdef THINK_C argc = ccommand(&argv); #endif printf(M_VERSION); if (argc == 1) { help(); #ifdef Proolix goto l_exit; #else return EXIT_SUCCESS; #endif } else if (argc == 2) { command = 'L'; arc_p = argv[1]; } else if (argc == 3) { if (strlen(argv[1]) > 1) error(M_BADCOMND, argv[1]); command = toupper(*argv[1]); if (strchr("ELTX", command) == NULL) error(M_BADCOMND, argv[1]); arc_p = argv[2]; } else { help(); #ifdef Proolix goto l_exit; #else return EXIT_FAILURE; #endif } strncopy(arc_name, arc_p, FNAME_MAX); case_path(arc_name); i = strlen(arc_name); j = parse_path(arc_name, (char *)NULL, (char *)NULL); lastc = arc_name[i - 1]; if (lastc == ARJ_DOT) arc_name[i - 1] = NULL_CHAR; else if (strchr(&arc_name[j], ARJ_DOT) == NULL) strcat(arc_name, M_SUFFIX); make_crctable(); error_count = 0; clock_inx = 0; arcfile = NULL; outfile = NULL; execute_cmd(); if (error_count > 0) error(M_ERRORCNT, ""); #ifdef Proolix l_exit:; #else return EXIT_SUCCESS; #endif } /* end UNARJ.C */ src/command/xonix.c0100664000076500007650000000376207725644160014050 0ustar prool2prool2#include #include #include #define MaxX 79 #define MaxY 24 #define MinX 1 #define MinY 1 #define Slowly 3000 /* #define Trace */ #define NX 100 #define NoStatic /* #define BackGround */ /* #define ClrScr */ /* #define Fish */ #define Ice /* #define Blink */ #define XONIX0 1 #define XONIX1 255 #define FRONTIER '~' #ifndef XONIX1 #define XONIX1 XONIX0 #endif int main(argc) int argc; { int i, j; int x[NX],y[NX]; int dx[NX],dy[NX]; int Color [NX]; char Xonix[NX]; #ifndef Trace int oldx,oldy; #endif #ifdef Slowly int ii; #endif clrscr(); if (argc==1) { gotoxy(20,10); printf("Press any key"); for (i=0;!kbhit();i++)if(!i)putch('.'); i+=getch(); srand(i); puts(""); } #ifdef BackGround for (i=0;i<24;i++) { for (j=0;j<79;j++) putch('█'); puts(""); } #endif #ifdef ClrScr clrscr(); #endif #ifdef FRONTIER if(MinY>0) for(i=1;i<=MaxX;i++) {gotoxy(i,MinY #ifndef Ice -1 #endif );putch(FRONTIER);} #endif for (j=0;j #include #include #include #define PRINTF_DEBUG #ifdef PRINTF_DEBUG /* char far *far_global_init = "far_global_init"; */ char far *far_global_uninit; char *near_global_init = "near_global_init"; char *near_global_uninit; #endif void main(void) { #ifdef PRINTF_DEBUG char far *far_local_init = "far_local_init"; char far *far_local_uninit; char *near_local_init = "near_local_init"; char *near_local_uninit; #endif #ifdef PRINTF_DEBUG far_global_uninit="far_global_uninit"; far_local_uninit="far_local_uninit"; near_global_uninit="near_global_uninit"; near_local_uninit="near_local_uninit"; #if 1 printf("printf(literal)\n"); printf("local far init"); printf(far_local_init); printf("local far uninit"); printf(far_local_uninit); /* printf("global far init"); printf(far_global_init); */ printf("global far uninit"); printf(far_global_uninit); #endif printf("\nprintf():\n\n"); printf("local far str initialized %%Fs %Fs\n", far_local_init); printf("local far str uninitialized %%Fs %Fs\n", far_local_uninit); printf("global far str uninitialized %%Fs %Fs\n", far_global_uninit); printf("local near str initialized %%s %s\n", near_local_init); printf("local near str uninitialized %%s %s\n", near_local_uninit); printf("global near str initialized %%s %s\n", near_global_init); printf("global near str uninitialized %%s %s\n", near_global_uninit); printf("Printf 0 = %i\n",0); exit(0); printf("Printf 1 = %i\n",1); #endif } src/command/c1.asm0100664000076500007650000001156607725644157013553 0ustar prool2prool2; Main module (CRT) for Proolix external C-utilities 0xDEAD (.com) ; V 0.0.2.0 14-Dec-1997 ; History in stack order ; V 0.0.2.0 14-Dec-1997 - изменен формат исполнимого файла ; V 0.0.1.0 3-Mar-1997 ; V 0.0.0.14 2-Feb-1997 sayr macro str ; NO SAVE REGS !!! ; Макрокоманда, аналогичная макрокоманде say. Только say использует функцию 9h ; ДОС, а sayr - функцию BIOS (функция 0eh прерывания 10h) ; В графических режимах не работает mov si,offset str call sayr_proc endm sayr chr macro sym ; via BIOS ; Not worked in graph mode (bl - bg color!) push ax mov al,sym mov ah,0eh int 10h pop ax endm chr extrn _main:near _TEXT segment byte public 'CODE' DGROUP group _TEXT,_DATA,_BSS org 0 include ..\include\psp.inc Revert = Int22 _environ = aEnv _More = DOS401 ; dw _NLine = DOS401+2; dw public Revert public _environ public _More public _NLine org 100h assume cs:DGROUP,ds:DGROUP start: db 0deh, 0adh ; signature (magick) ; mov bp,sp push CS pop ax mov DGROUP@,ax ; call saycsip call _main ; Вызов main-функции С ; Возврат в Пруликс jmp dword ptr Revert DGROUP@ dw ? public DGROUP@ comment | saycsip proc ; REG SAVED push ax PUSHF sayr s0 push CS pop ax call ohw chr ':' call l1 l1: pop ax PUSH BX ; mov bx,offset l1-Begin ; sub ax,bx call ohw POP BX sayr s_ax pop ax push ax call ohw sayr s_bx mov ax,bx call ohw sayr s_cx mov ax,cx call ohw sayr s_dx mov ax,dx call ohw sayr s_f POP ax ; flags (from stack) -> ax ; (see PUSHF) call ohw sayr s_si mov ax,si call ohw sayr s_di mov ax,di call ohw sayr s_ss mov ax,SS call ohw sayr s_sp mov ax,SP call ohw sayr s_ds mov ax,DS call ohw sayr s_es mov ax,ES call ohw sayr s_bp mov ax,BP call ohw pop ax ret s0 db 13,10,"Bg CS:IP=",0 s1 db " FatSize=",0 s2 db " int 13h =",0 s_ax db ' ax=',0 s_bx db ' bx=',0 s_cx db ' cx=',0 s_dx db ' dx=',0 s_si db ' si=',0 s_di db ' di=',0 s_ss db ' SS=',0 s_sp db ' SP=',0 s_ds db ' DS=',0 s_es db ' ES=',0 s_bp db ' BP=',0 s_f db ' Flags=',0 saycsip endp sayr_proc proc ; Ver 0.0.1 9-Dec-93 ; Процедура вывода строки при помощи функций BIOS ; Вход: DS:SI - ASCIIZ строка. ; NO REG SAVED !!! ; В графических режимах не работает ; cld sayr_l1: lodsb or al,al jz sayr_ret mov ah,0eh int 10h jmp short sayr_l1 sayr_ret: ret sayr_proc endp ohw proc ; Вывод слова в HEX-виде. Вход: слово в ax. ; Все регистры сохраняются. ; Вызывает подпрограмму ohb push ax ; Сохр. ради al. mov al,ah call ohb pop ax ; Восст. al. call ohb ret ohw endp ohb proc ; Procedure output hex byte Ver 0.1.1 6 Dec 93 via BIOS ; Input: AL - byte ; All regs. reserved ;) ; Not worked in graph mode. bl - bg color !!! push ax push cx push dx mov dl,al mov cl,4 shr al,cl call ohb1 mov al,dl and al,0fh call ohb1 pop dx pop cx pop ax ret ohb endp ohb1 proc ; Regs not saved !!! push ax cmp al,9 ja @@_1 ; al > 9 ; al <= 9 add al,'0' jmp @@_out @@_1: add al,'A'-10 @@_out: mov ah,0eh int 10h pop ax ret ohb1 endp | _TEXT ends _DATA segment word public 'DATA' _DATA ends _BSS segment word public 'BSS' _BSS ends end start src/command/environ.c0100664000076500007650000003300707725644157014364 0ustar prool2prool2/* ENVIRON.C, UNARJ, R JUNG, 09/01/91 * Implementation dependent routines * Copyright (c) 1991 by Robert K Jung. All rights reserved. * * This code may be freely used in programs that are NOT ARJ archivers * (both compress and extract ARJ archives). * * If you wish to distribute a modified version of this program, you * MUST indicate that it is a modified version both in the program and * source code. * * If you modify this program, I would appreciate a copy of the new * source code. I am holding the copyright on the source code, so * please do not delete my name from the program files or from the * documentation. * * The UNIX file date-time stamping code is derived from ZOO by * Rahul Dhesi. * * Modification history: * Date Programmer Description of modification. * 04/09/91 R. Jung Rewrote code. * 04/23/91 M. Adler Portabilized. * 04/29/91 R. Jung Added get_mode_str(). * 05/08/91 R. Jung Combined set_ftime() and set_fmode(). * 06/03/91 R. Jung Changed arguments in get_mode_str() and * set_ftime_mode(). * 07/07/91 R. Jung Added default_case_path() and UNIX section. * 07/24/91 R. Jung Fixed use of _chmod to handle directories. * 08/27/91 R. Jung Added date/time handling to Coherent. * 09/01/91 R. Jung Added #include to vanilla section. * Added file date-time stamping to UNIX section. * */ #include "unarj.h" #ifdef __TURBOC__ #define SUBS_DEFINED #include #include #include #include #include FILE FAR * file_open(name, mode) char *name; char *mode; { return fopen(name, mode); } int file_read(buf, size, nitems, stream) char FAR *buf; int size; int nitems; FILE FAR *stream; { return fread(buf, (size_t) size, (size_t) nitems, stream); } int file_seek(stream, offset, mode) FILE FAR *stream; long offset; int mode; { return fseek(stream, offset, mode); } long file_tell(stream) FILE FAR *stream; { return ftell(stream); } int file_write(buf, size, nitems, stream) char FAR *buf; int size; int nitems; FILE FAR *stream; { return fwrite(buf, (size_t) size, (size_t) nitems, stream); } voidp FAR * xmalloc(size) int size; { return (voidp FAR *)malloc((size_t) size); } void case_path(name) char *name; { strupper(name); } void default_case_path(name) char *name; { strupper(name); } int file_exists(name) char *name; { return (access(name, 0) == 0); } void get_mode_str(str, mode) char *str; uint mode; { strcpy(str, "---W"); if (mode & FA_ARCH) str[0] = 'A'; if (mode & FA_SYSTEM) str[1] = 'S'; if (mode & FA_HIDDEN) str[2] = 'H'; if (mode & FA_RDONLY) str[3] = 'R'; } int set_ftime_mode(name, tstamp, attribute, host) char *name; ulong tstamp; uint attribute; uint host; { FILE FAR *fd; int code; if ((fd = fopen(name, "r+b")) == NULL) return -1; code = setftime(fileno(fd), (struct ftime *) &tstamp); fclose(fd); if (host == OS) { attribute &= 0x27; if (_chmod(name, 1, attribute) == -1) return -1; } return code; } #endif #ifdef _QC #define SUBS_DEFINED #include #include #include #include #include FILE FAR * file_open(name, mode) char *name; char *mode; { return fopen(name, mode); } int file_read(buf, size, nitems, stream) char FAR *buf; int size; int nitems; FILE FAR *stream; { return fread(buf, (size_t) size, (size_t) nitems, stream); } int file_seek(stream, offset, mode) FILE FAR *stream; long offset; int mode; { return fseek(stream, offset, mode); } long file_tell(stream) FILE FAR *stream; { return ftell(stream); } int file_write(buf, size, nitems, stream) char FAR *buf; int size; int nitems; FILE FAR *stream; { return fwrite(buf, (size_t) size, (size_t) nitems, stream); } voidp FAR * xmalloc(size) int size; { return (voidp FAR *)malloc((size_t) size); } void case_path(name) char *name; { strupper(name); } void default_case_path(name) char *name; { strupper(name); } int file_exists(name) char *name; { return (access(name, 0) == 0); } void get_mode_str(str, mode) char *str; uint mode; { strcpy(str, "---W"); if (mode & FA_ARCH) str[0] = 'A'; if (mode & FA_SYSTEM) str[1] = 'S'; if (mode & FA_HIDDEN) str[2] = 'H'; if (mode & FA_RDONLY) str[3] = 'R'; } int set_ftime_mode(name, tstamp, attribute, host) char *name; ulong tstamp; uint attribute; uint host; { FILE FAR *fd; int code; uint date_stamp, time_stamp; date_stamp = (uint)(tstamp >> 16); time_stamp = (uint)(tstamp & 0xFFFF); if ((fd = fopen(name, "r+b")) == NULL) return -1; code = _dos_setftime(fileno(fd), date_stamp, time_stamp); fclose(fd); if (host == OS) { if (_dos_setfileattr(name, attribute)) return -1; } return code; } #endif #ifdef _OS2 #define SUBS_DEFINED #include #define INCL_DOSFILEMGR #include #include #include FILE FAR * file_open(name, mode) char *name; char *mode; { return fopen(name, mode); } int file_read(buf, size, nitems, stream) char FAR *buf; int size; int nitems; FILE FAR *stream; { return fread(buf, (size_t) size, (size_t) nitems, stream); } int file_seek(stream, offset, mode) FILE FAR *stream; long offset; int mode; { return fseek(stream, offset, mode); } long file_tell(stream) FILE FAR *stream; { return ftell(stream); } int file_write(buf, size, nitems, stream) char FAR *buf; int size; int nitems; FILE FAR *stream; { return fwrite(buf, (size_t) size, (size_t) nitems, stream); } voidp FAR * xmalloc(size) int size; { return (voidp FAR *)malloc((size_t) size); } void case_path(name) char *name; { strupper(name); } void default_case_path(name) char *name; { strupper(name); } int file_exists(name) char *name; { return (access(name, 0) == 0); } void get_mode_str(str, mode) char *str; uint mode; { strcpy(str, "---W"); if (mode & FA_ARCH) str[0] = 'A'; if (mode & FA_SYSTEM) str[1] = 'S'; if (mode & FA_HIDDEN) str[2] = 'H'; if (mode & FA_RDONLY) str[3] = 'R'; } int set_ftime_mode(name, tstamp, attribute, host) char *name; ulong tstamp; uint attribute; uint host; { int code; FDATE date_stamp; FTIME time_stamp; HFILE handle; FILESTATUS info; USHORT action; date_stamp.day = ts_day (tstamp); date_stamp.month = ts_month (tstamp); date_stamp.year = ts_year (tstamp) - 1980; time_stamp.twosecs = ts_sec (tstamp) / 2; time_stamp.minutes = ts_min (tstamp); time_stamp.hours = ts_hour (tstamp); if (DosOpen (name, &handle, &action, 0L, 0, FILE_OPEN, OPEN_ACCESS_READWRITE|OPEN_SHARE_DENYREADWRITE, 0L) != 0) return -1; info.fdateCreation = date_stamp; info.ftimeCreation = time_stamp; info.fdateLastAccess = date_stamp; info.ftimeLastAccess = time_stamp; info.fdateLastWrite = date_stamp; info.ftimeLastWrite = time_stamp; info.cbFile = 0; info.cbFileAlloc = 0; info.attrFile = 0; code = (int)DosSetFileInfo (handle, 1, (PBYTE)&info, sizeof (info)); (void)DosClose (handle); if (host == OS) { if (DosSetFileMode (name, attribute, 0L)) return -1; } return code; } #endif #ifdef UNIX #define SUBS_DEFINED #include #ifndef time_t #define time_t long #endif extern struct tm *localtime(); extern time_t time(); extern char FAR *strcpy(); extern voidp FAR *malloc(); FILE FAR * file_open(name, mode) char *name; char *mode; { return fopen(name, mode); } int file_read(buf, size, nitems, stream) char FAR *buf; int size; int nitems; FILE FAR *stream; { return fread(buf, (int) size, (int) nitems, stream); } int file_seek(stream, offset, mode) FILE FAR *stream; long offset; int mode; { return fseek(stream, offset, mode); } long file_tell(stream) FILE FAR *stream; { return ftell(stream); } int file_write(buf, size, nitems, stream) char FAR *buf; int size; int nitems; FILE FAR *stream; { return fwrite(buf, (int) size, (int) nitems, stream); } voidp FAR * xmalloc(size) int size; { return (voidp FAR *)malloc((uint) size); } void case_path(name) char *name; { (char *) name; } void default_case_path(name) char *name; { strlower(name); } int file_exists(name) char *name; { FILE FAR *fd; if ((fd = fopen(name, "rb")) == NULL) return 0; fclose(fd); return 1; } void get_mode_str(str, mode) char *str; uint mode; { strcpy(str, "---W"); if (mode & FA_ARCH) str[0] = 'A'; if (mode & FA_SYSTEM) str[1] = 'S'; if (mode & FA_HIDDEN) str[2] = 'H'; if (mode & FA_RDONLY) str[3] = 'R'; } long gettz() /* returns the offset from GMT in seconds */ { #define NOONOFFSET 43200L #define SEC_IN_DAY (24L * 60L * 60L) #define INV_VALUE (SEC_IN_DAY + 1L) static long retval = INV_VALUE; long now, noon; struct tm *noontm; if (retval != INV_VALUE) return retval; now = (long) time((long *) 0); /* Find local time for GMT noon today */ noon = now - now % SEC_IN_DAY + NOONOFFSET ; noontm = localtime(&noon); retval = NOONOFFSET - 60 * (60 * noontm->tm_hour - noontm->tm_min); return retval; } long mstonix(tstamp) ulong tstamp; { uint date, time; int year, month, day, hour, min, sec, daycount; long longtime; /* no. of days to beginning of month for each month */ static int dsboy[12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; date = (uint) ((tstamp >> 16) & 0xffff); time = (uint) (tstamp & 0xffff); if (date == 0 && time == 0) return 0L; year = ((date >> 9) & 0x7f) + 1980; month = (date >> 5) & 0x0f; day = date & 0x1f; hour = (time >> 11) & 0x1f; min = (time >> 5) & 0x3f; sec = (time & 0x1f) * 2; daycount = 365 * (year - 1970) + /* days due to whole years */ (year - 1969) / 4 + /* days due to leap years */ dsboy[month-1] + /* days since beginning of this year */ day-1; /* days since beginning of month */ if (year % 4 == 0 && year % 400 != 0 && month >= 3) /* if this is a leap year and month */ daycount++; /* is March or later, add a day */ longtime = daycount * 24L * 60L * 60L + hour * 60L * 60L + min * 60 + sec; return longtime; } int set_ftime_mode(name, tstamp, attribute, host) char *name; ulong tstamp; uint attribute; uint host; { time_t m_time; struct utimbuf { time_t atime; /* New access time */ time_t mtime; /* New modification time */ } tb; (char *) name; (uint) attribute; (uint) host; m_time = mstonix(tstamp) + gettz(); tb.mtime = m_time; /* Set modification time */ tb.atime = m_time; /* Set access time */ /* set the time stamp on the file */ return utime(name, &tb); } #endif /* end of UNIX section */ #ifndef SUBS_DEFINED /* vanilla version for other compilers */ #ifdef MODERN #include #include #else /* !MODERN */ extern char FAR *strcpy(); extern voidp FAR *malloc(); #endif /* ?MODERN */ FILE FAR * file_open(name, mode) char *name; char *mode; { return fopen(name, mode); } int file_read(buf, size, nitems, stream) char FAR *buf; int size; int nitems; FILE FAR *stream; { return fread(buf, (int) size, (int) nitems, stream); } int file_seek(stream, offset, mode) FILE FAR *stream; long offset; int mode; { return fseek(stream, offset, mode); } long file_tell(stream) FILE FAR *stream; { return ftell(stream); } int file_write(buf, size, nitems, stream) char FAR *buf; int size; int nitems; FILE FAR *stream; { return fwrite(buf, (int) size, (int) nitems, stream); } voidp FAR * xmalloc(size) int size; { return (voidp FAR *)malloc((uint) size); } void case_path(name) char *name; { (char *) name; } void default_case_path(name) char *name; { (char *) name; } int file_exists(name) char *name; { FILE FAR *fd; if ((fd = fopen(name, "rb")) == NULL) return 0; fclose(fd); return 1; } void get_mode_str(str, mode) char *str; uint mode; { strcpy(str, "---W"); if (mode & FA_ARCH) str[0] = 'A'; if (mode & FA_SYSTEM) str[1] = 'S'; if (mode & FA_HIDDEN) str[2] = 'H'; if (mode & FA_RDONLY) str[3] = 'R'; } int set_ftime_mode(name, tstamp, attribute, host) char *name; ulong tstamp; uint attribute; uint host; { (char *) name; (ulong) tstamp; (uint) attribute; (uint) host; return 0; } #endif /* end of vanilla section */ /* end ENVIRON.C */ src/command/cpuspeed.asm0100664000076500007650000001503107725644157015047 0ustar prool2prool2; ----------------------------------------------------------------------------- ; CPUSPEED.ASM CPU speed measurement routine Version 1.14 ; ; Too-Much-In-One-So-Don't-Get-Lost(tm) CPU/FPU feature detection library ; ; Copyright(c) 1993,94 by B-coolWare. ; ----------------------------------------------------------------------------- ; History: ; ; 11/11/93 slightly modified to support C/C++, slightly ; optimized for 286/386 instruction sets, ; documented where possible. ; 15/03/94 slightly modified to disable invalid computation for ; unknown CPUs ; 08/06/94 shortened by replacing repeated commands by DUPed ; equate ; 13/06/94 new CPU type addition reflected ; MODEL TPASCAL ; uncomment this to use with Turbo Pascal MODEL TINY,C ; uncomment this to use with C/C++ compilers ; ^^^^^ change to preferred memory model INCLUDE UNIDEF.INC ; macros LOCALS .data EXTRN CPUFix: DWORD ; CPU Type speed fix constant EXTRN Shift : WORD ; current loop length .code ifndef __use_386__ ifdef __use_286__ .286 endif else __use_286__ equ 1 .386 endif PUBLIC Speed _bpcs equ _wp equ clr macro reg sub reg,reg endm ; ----------------------------------------------------------------------- ; Speed modifies CPUFix and Shift and returns value which should b used ; as follows: ; ; CPUSpeed_In_MHz := (((CPUFix*Shift)/Speed)+5)/10; ; ; This formulae is taken from Norton SysInfo unchanged. I've no idea why ; computations done this way, but it works ok. ; I dinna insert floating point here, but to use with assembler you'll have to ; do so. ; Shift should be converted to DWORD prior to multiplication. ; Resulting value may be rounded to nearest integer, or may be left unchanged ; if you want exact CLK frequency value. ; function Speed( CPUid : Byte ) : Word; ; unsigned int Speed( unsigned short CPUid ); ; CPUid is value from 0 to 0Eh identifying processor we're running on ; 8088 = 00h ; 8086 = 01h ; V20 = 02h ; V30 = 03h ; 188 = 04h ; 186 = 05h ; 286 = 06h ; 386sx = 07h ; 386dx = 08h ; 386sl = 09h ; 486sx = 0Ah ; 486dx = 0Bh ; 486slc = 0Ch ; 486dlc = 0Dh ; P5 = 0Eh ; CxM1 = 0Fh ; It is lower byte of the result of CPU_Type routine defined in CPU_TYPE.ASH MaxCPUid equ 0Fh ; change this if you added new CPU types Speed PROC ARG CPUid:BYTE cmp CPUid,MaxCPUid ; checking if we know this CPU jbe @@okcpu mov CPUid,MaxCPUid ; fixing CPU id @@okcpu: mov cx,2 mov _bpcs[Indic],0 @@1: mov Shift,cx call Speed_Test cmp ax,1000h jnb @@2 mov cx,Shift shl cx,1 jmp @@1 @@2: push ax mov cx,Shift mov _bpcs[Indic],1 call Speed_Test pop dx sub dx,ax xchg ax,dx ifdef __use_386__ movzx bx,CPUid else mov bl,CPUid sub bh,bh endif ifdef __use_286__ shl bx,2 else shl bx,1 shl bx,1 endif ifdef __use_386__ mov edx,cs:CPUFixes[bx] mov CPUFix,edx else mov dx,_wp cs:CPUFixes[bx] mov _wp CPUFix,dx mov dx,_wp cs:CPUFixes[2][bx] mov _wp CPUFix[2],dx endif ret ENDP Speed_Test PROC NEAR ; returns number of tick-tacks spent performing known instruction? ; or difference between time taken by plain group of similar instructions and ; time taken by loop of that instructions? I dinna find out what exactly it ; does, but it works - what else do i (and u) need? PUSH SI DI clr DX,DX ; CLR DX,DX MOV SI,0AAAAH MOV BX,05555H IN AL,61h JMP $+2 AND AL,0FCH OUT 61h,AL JMP $+2 MOV AL,0B4h OUT 43h,AL JMP $+2 SUB AL,AL OUT 42h,AL JMP $+2 OUT 42h,AL JMP $+2 IN AL,61h MOV DI,AX OR AL,01 CMP _bpcs[Indic],0 JZ @@1 JMP @@2 @@1: CLI OUT 61h,AL @@3: Sprite equ <8Bh, 0C6h, 0F7h, 0F3h> ; MOV AX,SI ; DIV BX db 101 dup(Sprite) DEC CX JZ @@4 JMP @@3 @@2: CLI OUT 61h,AL NOP ; well, maybe this is the right place for ; NOP, so i left it here. Try to kill it and ; see what will happen... @@5: db Sprite DEC CX JZ @@4 JMP @@5 @@4: MOV AX,DI OUT 61h,AL JMP $+2 STI IN AL,42h JMP $+2 XCHG AH,AL IN AL,42h JMP $+2 XCHG AH,AL NEG AX PUSH AX IN AL,61h JMP $+2 AND AL,0FDh OUT 61h,AL POP AX DI SI RET ENDP Indic db ? CPUFixes: ; For on different processors the same instruction takes different number of ; CPU clocks, we should adjust absolute timer value using our knowledge of ; known CPU's timings. dd 2AD26h ; 8088 dd 2AD26h ; 8086 dd 0E90Bh ; V20 dd 0DFB9h ; V30 dd 0BA6Fh ; 188 dd 0BA6Fh ; 186 dd 06FDCh ; 286 dd 07486h ; 386sx dd 07486h ; 386dx dd 07486h ; 386sl ??? - ain't checked yet dd 07486h ; 486sx dd 07486h ; 486dx dd 0668Ah ; Cx486slc dd 0668Ah ; Cx486dlc dd 0668Ah ; Pentium ??? this value should be adjusted dd 0668Ah ; CxM1 ??? this value should be adjusted include cpu_type.ash END src/command/hello.c0100664000076500007650000000031407725644160013774 0ustar prool2prool2#include #include #include #include #include #include void main(void) { char wd [NAME_MAX+3]; printf("%Fs\n",getcwd(wd,NAME_MAX+3)); } src/command/cat2.c0100664000076500007650000000150007725644157013526 0ustar prool2prool2/* Программа для отладки вызовов open и read */ #include #include #include #include #include #include void main(int argc, char *argv[]) {int h1, h2, n; char c; if (argc<2) {puts("Use cat2 []");exit(1);} puts(argv[1]); puts(argv[2]); if ((h1=open(argv[1],O_RDONLY))==-1) { printf("Can't open %s\n",argv[1]); return; } if ((h2=open(argv[2],O_RDONLY))==-1) { printf("Can't open %s\n",argv[2]); } while(1) { while(1) { n=(int)read(h1,&c,1); if (n!=1) {puts("Can't read 1");exit(2);} else putch(c); if(c=='\n') break; } if(getch()==3)exit(0); while(1) { n=(int)read(h2,&c,1); if (n!=1) puts("Can't read 2"); else putch(c); if(c=='\n') break; } if(getch()==3)exit(0); } } src/command/makefile.10100664000076500007650000000252607725644160014373 0ustar prool2prool2# Do not edit this file. # This file is automatically generated Members=\ 000.obj 001.obj 002.obj 003.obj 004.obj 005.obj 006.obj 007.obj 008.obj \ 009.obj 010.obj 011.obj 012.obj 013.obj 014.obj 015.obj 016.obj 017.obj \ 018.obj 019.obj 020.obj 021.obj 022.obj 023.obj 024.obj 025.obj 026.obj \ 027.obj 028.obj 029.obj 030.obj 031.obj 032.obj 033.obj 034.obj 035.obj \ 036.obj 037.obj 038.obj 039.obj 040.obj 041.obj 042.obj 043.obj 044.obj \ 045.obj 046.obj 047.obj 048.obj 049.obj 050.obj 051.obj 052.obj 053.obj \ 054.obj 055.obj 056.obj 057.obj 058.obj 059.obj 060.obj 061.obj 062.obj \ 063.obj 064.obj 065.obj 066.obj 067.obj 068.obj 069.obj 070.obj 071.obj \ 072.obj 073.obj 074.obj 075.obj 076.obj 077.obj 078.obj 079.obj 080.obj \ 081.obj 082.obj 083.obj 084.obj 085.obj 086.obj 087.obj 088.obj 089.obj \ 090.obj 091.obj 092.obj 093.obj 094.obj 095.obj 096.obj 097.obj 098.obj \ 099.obj 100.obj 101.obj 102.obj 103.obj 104.obj 105.obj 106.obj 107.obj \ 108.obj 109.obj 110.obj 111.obj 112.obj 113.obj 114.obj 115.obj 116.obj \ 117.obj 118.obj 119.obj 120.obj 121.obj 122.obj 123.obj 124.obj 125.obj \ 126.obj 127.obj 128.obj 129.obj 130.obj 131.obj 132.obj 133.obj 134.obj \ 135.obj 136.obj 137.obj 138.obj 139.obj 140.obj 141.obj 142.obj 143.obj \ 144.obj 145.obj 146.obj 147.obj 148.obj 149.obj 150.obj 151.obj 152.obj \ 153.obj src/command/more.c0100664000076500007650000000227707725644160013645 0ustar prool2prool2/* more - command from OS Proolix (C) Serge Pustovoitoff, 07.11.95 make for Proolix make more make for MSDOS tcc more */ /* сюда надо добавить листание на экран по пробелу и на строку по вводу */ #include #include #ifdef Proolix #include #else #define MAX_LINE 24 #endif #define STR_LEN 256 void main (int argc, char *argv[]) {char str [STR_LEN]; FILE far *ff; int l, nl=1, counter=0; if (argc!=2) puts("Usage: more filename"); else { if ((ff=fopen(argv[1],"r"))==NULL) printf("more: Can't open %s\n",argv[1]); else while (fgets(str,STR_LEN,ff)!=NULL) { l=(int)strlen(str); if (str[l-1]=='\n') str[l-1]=0; /* ohs(str); */ #ifdef Proolix if (str[0]==10) puts(str+1); else puts(str); #else puts(str); #endif counter++; if (++nl>MAX_LINE) { printf("%s, %i-%i",argv[1],counter-(MAX_LINE-1),counter); #ifdef Proolix if (getchar()=='q') break; #else if (getch()=='q') break; #endif puts(""); nl=1; } } } } src/command/syscall.h0100664000076500007650000000500207725644160014347 0ustar prool2prool2; Do not edit this file. ; This file is automatically generated INT_NO equ 084h getch equ 000 getchar equ 001 getche equ 002 kbhit equ 003 gets equ 004 putch equ 005 putchar equ 006 puts equ 007 htoi equ 008 htol equ 009 atoi equ 010 atol equ 011 itoa equ 012 ltoa equ 013 ultoa equ 014 ohs equ 015 printf equ 016 sprintf equ 017 fprintf equ 018 vsprintf equ 019 vprintf equ 020 clrscr equ 021 inport equ 022 inportb equ 023 outport equ 024 outportb equ 025 textattr equ 026 gotoxy equ 027 inicom_ equ 028 getcom_ equ 029 putcom_ equ 030 getcomstat_ equ 031 getvect equ 032 setvect equ 033 geninterrupt equ 034 end equ 035 open equ 036 creat equ 037 read equ 038 write equ 039 close equ 040 lseek equ 041 filelength equ 042 tell equ 043 unlink equ 044 rename equ 045 dup equ 046 shutdown equ 047 perror equ 048 memccpy equ 049 memchr equ 050 memcmp equ 051 memcpy equ 052 memicmp equ 053 memmove equ 054 memset equ 055 stpcpy equ 056 strcat equ 057 strchr equ 058 strcmp equ 059 strcpy equ 060 strcspn equ 061 strdup equ 062 stricmp equ 063 strlen equ 064 strlwr equ 065 strncat equ 066 strncmp equ 067 strncpy equ 068 strnicmp equ 069 strnset equ 070 strpbrk equ 071 strrchr equ 072 strrev equ 073 strset equ 074 strspn equ 075 strstr equ 076 strtok equ 077 strupr equ 078 tolower equ 079 toupper equ 080 isgraph equ 081 isprint equ 082 isalnum equ 083 isalpha equ 084 iscntrl equ 085 isdigit equ 086 islower equ 087 ispunct equ 088 isspace equ 089 isupper equ 090 isxdigit equ 091 malloc equ 092 calloc equ 093 realloc equ 094 free equ 095 div equ 096 ldiv equ 097 chmod equ 098 _chmod equ 099 access equ 100 fopen equ 101 freopen equ 102 fdopen equ 103 fileno equ 104 fgetc equ 105 fgets equ 106 fputc equ 107 fputs equ 108 fread equ 109 fwrite equ 110 vfprintf equ 111 fclose equ 112 fflush equ 113 ftell equ 114 fseek equ 115 fgetpos equ 116 fsetpos equ 117 rewind equ 118 int86 equ 119 getcwd equ 120 chdir equ 121 opendir equ 122 readdir equ 123 telldir equ 124 seekdir equ 125 rewinddir equ 126 closedir equ 127 mkdir equ 128 rmdir equ 129 getenv equ 130 stat equ 131 fstat equ 132 isatty equ 133 qsort equ 134 getftime equ 135 setftime equ 136 gettime equ 137 getdate equ 138 time equ 139 ctime equ 140 rand equ 141 srand equ 142 getcolor equ 143 wherex equ 144 wherey equ 145 absread equ 146 abswrite equ 147 exit equ 148 strtoul equ 149 fork equ 150 service equ 151 exec equ 152 wait equ 153 src/command/cat.c0100664000076500007650000000610307725644157013450 0ustar prool2prool2/*-------------------------------------------------------------------------*/ /* external cat */ /*-------------------------------------------------------------------------*/ /* #define DEBUG */ #include #include #include #include #include #include "prool.h" int FlagH=0; int FlagA=0; int FlagT=0; int FlagN=0; int Flag_s=1; int Col=0; int Line=0; void help(void) { puts("Uses: cat [-sHMATN] [-Ooffset] [files...]\n\ Flags:\n\ -H - hex output\n\ -M - more\n\ -A - hex & ascii output\n\ -T - address titles\n\ -N - output to /dev/null\n\ -Ooffset - hex offset\n\ -s - don't print error messages"); } #ifdef MSDOS long int htol(char *s) { sscanf(s,"%X",htol); } #endif int main(int argc, char *argv[] ) { unsigned char c[512]; int i, ii, j, h, n, Files=0; unsigned long offset=0; unsigned long adr=0; argc--; ii=1; do { if (argc) { if (argv[ii][0]=='-') { n=(int)strlen(argv[ii]); for (j=1;j=' ') {if (putchar(c[i])==EOF) goto L_close; } else putchar(' '); } } if (puts("")==EOF) goto L_close; } else for (i=0;i #include #include #include #include #include #include #include #include #include #include #include #include #include #include /****************************************************************************/ char Sec1 [SECTOR_SIZE]; char huge *aPSP=0; jmp_buf return_point; char string [MAX_COMMAND_STRING]; char osmajor=DOS_MAJOR, osminor=DOS_MINOR, osbreak; struct DTAfind far * DTAaddr; struct country_structure Ukraine; char far * pEnv, far * curEnv; int TSR=0; char wd [PATH_MAX+1]; /****************************************************************************/ char allow_dos_functions [255]; char verbose_dos_functions [255]; char allow_change_int [255]; int msdos_verbose=0; int msdos_pause=0; char OldInt [INTERRUPT_TABLE_SIZE]; /****************************************************************************/ void hexdump(char *header, char huge *adr, int ctr) {int i; printf(header); for (i=0;i - change dir\n\ setpause [0|1] - set MSDOS debuggin' pause\n\ verbose [0|1] - set MSDOS debuggin' verbose mode\n\ "); } /****************************************************************************/ void far cpm (void) { printf("\nCalled CP/M entry!\n"); } /****************************************************************************/ int ViewEXE (struct exe_header far *Buf) {int c; #ifndef _HERCULES_ textattr(EMULATOR_COLOR); #endif printf("Bytes on last page %04X\n",Buf->PartPag ); printf("Pages in file %04X\n",Buf->PageCnt ); printf("Relocations %04X\n",Buf->ReloCnt ); printf("Paragraphe in header %04X\n",Buf->HdrSize ); printf("MinMem %04X par\n",Buf->MinMem ); printf("MaxMem %04X par\n",Buf->MaxMem ); printf("SS:SP %04X:%04X\n",Buf->ReloSS,Buf->ExeSP); printf("CheckSum %04X\n",Buf->ChkSum ); printf("CS:IP %04X:%04X\n",Buf->ReloCS,Buf->ExeIP); printf("Relocation table addr %04X\n",Buf->TablOff ); printf("Overlay No. %1X\n",Buf->Overlay); #if 0 printf("\n1.Press ESC for quit, other key for continue\n"); c=getch(); #ifndef _HERCULES_ textattr(DOS_COLOR); #endif if (c==ESC) return 1; #endif return 0; } /****************************************************************************/ int execdos (char *argv0, char *params) { char ExeHeader [HEADER_SIZE]; int i, j, h, argc, nenv, restos, segment, offset_s; long int FileLen, l, sec; unsigned int len; size_t SizeMemoryBlock; char huge *mem, far *ptr, far *adr, far *EnvAdr; struct exe_header far * H; unsigned int RelocTable [2], BEGIN_SEG, I_OFF, I_SEG, RELO_SEG; struct sPSP far *PSP; char FlagCOM; unsigned int MemTop; jmp_buf Pointer; long ExeLen, ReadLen; if ((h=open(argv0,O_RDONLY))==-1) return 1; FileLen=filelength(h); /*** Чтение первого сектора и проверка на сигнатуру MZ ***/ restos = (SECTOR_SIZE>FileLen) ? (int)FileLen : SECTOR_SIZE; if (read(h,Sec1,restos) != restos) goto R3; printf("restos=%i\n",restos); hexdump("Sec1=",Sec1,16); if (!memcmp(Sec1,"MZ",2)) { /* EXE */ FlagCOM=0; memcpy((char far *)ExeHeader,(char far *)Sec1,HEADER_SIZE); H=(void far *)ExeHeader; printf(".EXE file. File length=%li\n",FileLen); if (ViewEXE(H)) { close(h); return 1; } ExeLen=(H->PageCnt*512)-(16*H->HdrSize)-(H->PartPag); printf("Image length=%li bytes\n",ExeLen); SizeMemoryBlock=-1L; /*(H->PageCnt*(512/16)-H->HdrSize+H->MinMem)<<4-(H->PartPag)*/ } else { /* COM */ FlagCOM=1; SizeMemoryBlock=((ComMemory -1U)<<4)+1; } #if 0 printf("2.Press ESC for quit or other key for continue\n"); if (getch()==27) return 1; #endif #ifdef DEBUG printf("SizeMemoryBlock=%08lX\n",SizeMemoryBlock); #endif if ( (void far *)(aPSP=malloc(SizeMemoryBlock)) == NULL ) { printf("execdos: no memory. (Required %04X bytes)\n",SizeMemoryBlock); return 2; } #ifdef DEBUG printf("aPSP=%04X:%04X\n",FP_SEG(aPSP),FP_OFF(aPSP)); #endif mem=aPSP+0x100; #ifdef DEBUG printf("mem=%04X:%04X\n",FP_SEG(mem),FP_OFF(mem)); #endif if (FlagCOM==0) BEGIN_SEG=FP_SEG(aPSP)+0x10; PSP=(void far *)aPSP; PSP->CD20=0x20CDU; /* int 20 h */ asm push CS; asm pop ax; asm mov i,ax; asm mov ax,offset Int20; asm mov j,ax; PSP->Int22=(((unsigned long)i << 16) | j); asm push CS; asm pop ax; asm mov i,ax; asm mov ax,offset Int23; asm mov j,ax; PSP->Int23=(((unsigned long)i << 16) | j); asm push CS; asm pop ax; asm mov i,ax; asm mov ax,offset Int24; asm mov j,ax; PSP->Int24=(((unsigned long)i << 16) | j); MemTop = (*((unsigned int far *)MK_FP(0,0x413)))<<6; PSP->TopMemPar=MemTop; PSP->op=0x9A; PSP->Avail=0xFEF0; PSP->cpm_segment=FP_SEG(cpm); PSP->ParentSeg=0x50; PSP->aEnv=FP_SEG(pEnv); PSP->prevPSP=0xFFFFFFFFUL; PSP->SS_SP=(long)MK_FP(FP_SEG(aPSP),_SP); PSP->pHandle=(long)MK_FP(FP_SEG(aPSP),0x18); PSP->sHandle=20; PSP->FnCB[0]=0xCD; PSP->FnCB[1]=0x21; PSP->FnCB[2]=0xCB; for (i=0;i<20;i++) PSP->aHandle[i]=0xFF; DTAaddr=(void far *)((char far *)aPSP+0x80); /* command string to PSP */ if (params==NULL) { /* комстрока пустая (только имя_программы) */ /* l_bug: */ l=1; strcpy((char far *)aPSP+0x81,"\r"); } else { l=(int)strlen(params); if (l>127) l=127; strcpy((char far *)aPSP+0x81,params); } *(unsigned char far *)(aPSP+0x80)=l; *(unsigned char far *)(aPSP+0x81+l)='\r'; if (FlagCOM) { memcpy((void far *)mem,Sec1,restos); mem+=restos; } else { /* EXE */ if(lseek(h,(H->HdrSize)<<4,SEEK_SET)==-1L) {R3:close(h); free((void far *)aPSP); return 3; } } /* Чтение остальных секторов */ if (FlagCOM) { /* COM */ ReadLen=FileLen-restos; } else { /* EXE */ ReadLen=ExeLen; } sec=ReadLen/SECTOR_SIZE; for (l=1;lTablOff,SEEK_SET)==-1L) goto R3; for (i=0; iReloCnt; i++) { if(read(h,RelocTable,4)!=4) goto R3; I_OFF=RelocTable[0]; I_SEG=RelocTable[1]; RELO_SEG=BEGIN_SEG+I_SEG; *(unsigned int far *)MK_FP(RELO_SEG,I_OFF) = *(unsigned int far *)MK_FP(RELO_SEG,I_OFF)+BEGIN_SEG; } } if (close (h)) {free((void far *)aPSP); return 3;} len=2; strcpy(curEnv,argv0); /* EXEC ! */ if (FlagCOM) printf("EXEC!\n"); #if 1 {char far *mmm; printf("Start point %04X:%04X ",H->ReloCS+BEGIN_SEG,H->ExeIP); mmm=MK_FP(H->ReloCS+BEGIN_SEG,H->ExeIP); for (i=0;i<16;i++) printf("%02X ",*mmm++); printf("\n"); } #endif Pointer[0].j_flag=0x7202; if (FlagCOM) { /* COM */ Pointer[0].j_sp=0xFFFEU-len; Pointer[0].j_ss=FP_SEG(aPSP); Pointer[0].j_cs=FP_SEG(aPSP); Pointer[0].j_ip=0x100; Pointer[0].j_es=FP_SEG(aPSP); Pointer[0].j_ds=FP_SEG(aPSP); } else { /* EXE */ Pointer[0].j_sp=H->ExeSP; Pointer[0].j_ss=H->ReloSS+BEGIN_SEG; Pointer[0].j_cs=H->ReloCS+BEGIN_SEG; Pointer[0].j_ip=H->ExeIP; Pointer[0].j_es=FP_SEG(aPSP); Pointer[0].j_ds=FP_SEG(aPSP); } longjmp (Pointer, 0); return 0; } /****************************************************************************/ void main (void) { char argv0 [ARGV0LEN]; int i; initialization(); printf(VER); printf("\n\nUse `help` for help\n"); setjmp(return_point); printf("\n"); while (1) {char *cc; printf("C>"); gets(string); if (!string[0]) continue; for (i=0;iARGV0LEN) l=ARGV0LEN; memcpy(argv0,string,l); } /* printf("argv0=`%s'\n",argv0); */ if (!strcmp(argv0,"ver")) { printf("%s\nsetver=%i.%i\n",VER,osmajor,osminor); printf("msdos_pause=%i\n",msdos_pause); printf("msdos_verbose=%i\n",msdos_verbose); } else if (!strcmp(argv0,"help")) help(); else if (!strcmp(argv0,"exit")) goto l_exit; else if (!strcmp(argv0,"cd")) { if (cc==NULL) { if (getcwd(wd,PATH_MAX+1)==NULL) puts("pwd error"); else puts(wd); } else if (chdir(cc+1)) printf("Can't chdir %s\n",cc+1); } else if (!strcmp(argv0,"setver")) { osmajor=atoi(cc+1); cc=(char *)strchr(cc,'.'); if (cc!=NULL) osminor=atoi(cc+1); printf("New version %i.%i\n",osmajor,osminor); } else if (!strcmp(argv0,"setpause")) { if ((*(cc+1))=='0') msdos_pause=0; else msdos_pause=1; printf("msdos_pause=%i\n",msdos_pause); } else if (!strcmp(argv0,"verbose")) { if ((*(cc+1))=='0') msdos_verbose=0; else msdos_verbose=1; printf("msdos_verbose=%i\n",msdos_verbose); } else { printf("\nmse: "); switch (execdos(argv0, cc)) { case 0: /* printf("OK"); */ break; case 1: printf("not found\n"); break; case 2: printf("no memory\n"); break; case 3: printf("I/O error\n"); break; default: printf("invalid error\n"); break; } } } printf("\n"); l_exit: deinitialization(); } src/command/ce.asm0100664000076500007650000000227707725644157013636 0ustar prool2prool2; Main module (CRT) for Proolix external C-utilities 0xDEAF (.exe) ; V 0.0.3.0 14-Feb-98 ; Макрос. Вывод одного символа через ROM BIOS. chr macro sym ; Not worked in graph mode (registr bl - background color!) ; NO SAVED REGS !!! mov ax,0e00h+sym int 10h endm chr ; History in stack order ; V 0.0.3.0 14-Feb-98 ; V 0.0.2.0 14-Dec-97 - изменен формат исполнимого файла ; V 0.0.1.0 3-Mar-97 ; V 0.0.0.14 2-Feb-97 extrn _main:near _TEXT segment byte public 'CODE' DGROUP group _DATA,_BSS assume cs:_TEXT,ds:DGROUP start: ; chr 'B' ;l: jmp l mov ax,DGROUP mov DS,ax mov DGROUP@,ax call _main ; Вызов main-функции С ; Возврат в Пруликс xor ax,ax push ax extrn _exit:near call near ptr _exit DGROUP@ dw ? public DGROUP@ _TEXT ends _DATA segment word public 'DATA' _DATA ends _BSS segment word public 'BSS' _BSS ends _STACK segment word public stack 'STACK' db 60 dup ('stack') _STACK ends end start src/command/chess.c0100664000076500007650000000672007725644157014013 0ustar prool2prool2/* * Вот программа, занявшая первое место ("Best of Show") в этом году. Она * вызывается с необязательным числовым параметром (по умолчанию 2) и играет * в шахматы. Параметр определяет глубину просмотра (при глубине большей, * чем 3, она будет думать очень долго). Ходы задаются двумя восьмеричными * числами (откуда куда - см. доску в начале игры, например, "e2-e4" нужно * будет вводить как "64 44"), в приглашении к приему указывается количество * просмотренных ходов и оценка позиций - своей и противника, т.е. Вас). * * Правила игры несколько упрощены - пешки превращаются только в ферзей, нет * взятия на проходе и длинной рокировки (мне и короткую сделать не удалось), * а также контроля правил повторения позиций и 50 ходов. */ #include #include #define m(x)(x<0?-1:!!x) #define g tj()-J #define a(x)(x<0?-x:x) #define h(x)((x)<=K?x:N-(x)) #define f 9999 #define A return #define H printf( #define R double #define U int #define V for #define b else #define u while #define B if U v,w,Y= -1,W,J,p,F,o=f,M,N,K,X,YY,_,P[f],s(); typedef U(*L)(); L q[f]; tj(){ U S=m(v)+(m(w)<1||w-Y||!q[J]:(w-Y&&(w-Y*2||q[W+Y*(N+1)]|| (J>>K)-K+(Y-1)/ 2))||q[J]; } z(){ _=5; A v*w||g; } e(){ _= -2; A(v*v*v-v||w*w*w-w)&&(J-W-2||(W&N)-4||(W>>K!=(Y-1?N:0))|| q[W+1]||q[W+2]||q[W+K]!=z||P[W+K]*Y<0); } R VR(){ int PZ=0x7fff; A(R)(rand()&PZ)/(R)PZ; } l(){ _=K+1; A(v*w&&a(v)-a(w))||g; } R UC(){ R i=0,d; u((i+=d=VR())<1.0); A d; } c(){ _= -11; A a(v)-a(w)||g; } I(ur,n,x){ W=ur; J=n; B(P[W]!=Y||P[J]==Y)A J+1; v=(J&N)-(W&N); w=(J>>K)-(W>>K); A q[W]()||(x&&QL(W,J,s)); } TT(W){ v=w=0; A q[W]()+K; } s(){ U j= -1,i; Y= -Y; V(i=0; i=0&&!I(i,j,0))A Y= -Y; } A!(Y= -Y); } bb(){ _=1; A a(v*w)-2; } uv(){ V(v=0; v>K)==0){ U S=h(v&N); q[v]=!S?z:(S==1?bb:(S==2?c:(v&N>K?l:e))); } b B(h(v>>K)==1)q[v]=k; b q[v]=0; P[v]=!!q[v]*(28-v); } } y(){ U G=Y,i; J=0; V(i=0; i>K)==0)q[J]=l; B(q[W]==e)B(J-W==2)O(J+1,J-1); b B(W-J==2)O(W-1,W+1); P[J]=P[W]; q[W]=0; P[W]=0; } QL(W,J,D)L D; { U HQ=P[J],YX; L AJ=q[J],XY=q[W]; O(W,J); YX=D(); O(J,W); q[J]=AJ; q[W]=XY; P[J]=HQ; A YX; } C(){ U i,j,BZ=0; V(i=0; i>K)+h(i&N),G=Y, S=Z==z?88:(Z==k?11 +r+(P[i]<0?N-(i>>K):(i>>K)): (Z==l?124-((YY<8&&((i&N)!=K|| (i>>K)!=(P[i]>0?0:N)))?M:0): (Z==c?41+r:(Z==e?f-r-r:36+r+r)))); Y=P[i]; V(j=0; j>K+K,i&M-1,1)){ Y= -Y; o= -E; t= -QL(i>>K+K,i&M-1,PX); Y= -Y; B(t>E){ ++XP; Q=i; E=t; B(E>=S) A++F,E; } } B(!XP)E=s()?-f+1:0; p=Q; A++F,E; } RZ(){ U i,j,T=0; V(; ; ){ y(); o=f; do{ H"\n%d %d %d %s ",X,T,C(),s()?"!":">"); fflush(stdout); } u(scanf("%o%o",&i,&j)!=2||I(i,j,1)); O(i,j); y(); X=0; ++YY; Y= -Y; T=PX(); i=p>>(K<<1); j=p&(M-1); B(I(i,j,1)){ H"Rats!\n"); A; } O(i,j); Y= -Y; B(T>M*M)H"\nHar har.\n"); } } main(ac,av)char**av; { long time(),j=time(&j); R i=0; srand((U)j); V(M=0; M<=f; ++M)i+=UC(); M=i/100; B(M&3)++M; B(M&1)--M; V(N=1; N*N1?atoi(av[1]):2; uv(); RZ(); } src/command/cpu_type.ash0100664000076500007650000006272707725644157015100 0ustar prool2prool2; ---------------------------------------------------------------------------- ; CPU_TYPE.ASH Too-Much-In-One-So-Don't-Get-Lost(tm) ; CPU/FPU feature detection library Version 1.14 ; ; Copyright(c) 1992,93,94 by B-coolWare. Written by Bobby Z. ; Portions copyright(c) 1990 by 2B Programmers ; All rights reserved. ; ---------------------------------------------------------------------------- ; Uses: ; UNIDEF.INC universal macros and defines ; LSTRING.ASH Lstring macro ; DOSINOUT.ASH WriteStr routine ; ; History: ; ; Dec 17 1992 initially written ; Jun 10 1993 added distinguish between 80386 and i486 ; Sep 14 1993 added Pentium and above CPUs detection ; added 386sx and 386dx distinguishing ; added i486sx, i486dx and Cyrix 486 distinguishing ; added FPU distinguishing routine ; Sep 16 1993 added i486slc distinguishing ; Nov 23 1993 fixed Pentium fixup bug ; fixed i386step bug (i hope so) ; Jan 10 1994 added IIT xC87 math coprocessors detection ; Jan 12 1994 added some comments and fixed spelling errors - no ; changes to code made ; Jan 18 1994 fixed bug that causes fpu_type routine to hang on 486s ; Mar 23 1994 distinguish between 486dx and 486sx made reliable ; added 386SL detection routine (ain't been tested yet) ; Jun 07 1994 Test_Buffer made reentrant - I just forgot to do ; that before... ; Jun 20 1994 added Cyrix M1 (586) identification, FPU_Type routine ; slightly corrected. EF_AC equ 00040000h ; AC bit in EFLAGS register EF_ID equ 00200000h ; ID bit in EFLAGS register MSW_ET equ 00000010h ; ET bit in MSW register MSW_NE equ 00000020h ; NE bit in MSW register ; following constants are returned in AX by CPU_Type routine cpu8088 equ 0000h ; 8088 cpu8086 equ 0001h ; 8086 cpuNECV20 equ 0002h ; NEC V20 cpuNECV30 equ 0003h ; NEC V30 cpu80188 equ 0004h ; 188 cpu80186 equ 0005h ; 186 cpu80286 equ 0006h ; 286 cpu286 equ 06h ; 286 cpu80386sxv equ 0107h ; 386sx in V86 mode cpu80386sxr equ 0007h ; 386sx in real mode cpu386dx equ 08h ; 386dx cpu80386dxv equ 0108h ; 386dx in V86 mode cpu80386dxr equ 0008h ; 386dx in real mode cpu80386slv equ 0109h ; 386sl in V86 mode cpu80386slr equ 0009h ; 386sl in real mode cpui486sxv equ 010Ah ; 486sx in V86 mode cpui486sxr equ 000Ah ; 486sx in real mode cpu486dx equ 0Bh ; 486dx cpui486dxv equ 010Bh ; 486dx in V86 mode cpui486dxr equ 000Bh ; 486dx in real mode cpuCx486 equ 0Ch ; Cyrix 486 cpu486slcv equ 010Ch ; Cyrix 486slc in V86 cpu486slcr equ 000Ch ; Cyrix 486slc in real mode cpu486dlc equ 0Dh cpu486dlcv equ 010Dh ; Cyrix 486dlc in V86 cpu486dlcr equ 000Dh ; Cyrix 486dlc in real mode cpuPentium equ 0Eh cpuPentiumr equ 000Eh ; Pentium in real mode cpuPentiumv equ 010Eh ; Pentium in V86 mode cpuCxM1 equ 0Fh cpuCxM1r equ 000Fh ; Cyrix M1 (586) in real mode cpuCxM1v equ 010Fh ; Cyrix M1 (586) in V86 mode cpuP6 equ 0010h ; add new CPUs here LOCALS JUMPS cpuid equ ; Pentium instruction public CPU_Type CPU_Type proc LOCAL ETFlipped : BYTE ; entry - none ; returns AL = CPU code (see above constants) ; AH = 1 if in V86, 0 otherwise ; DL = FPU code (see below constants) push bx cx si clr bx push sp ; this code uses bug in chips prior to pop ax ; 80286: when push sp performed, value cmp ax,sp ; of sp is first decremented and then ; placed onto the stack. 286 and up ; handle this instruction correctly, ; saving value which sp have upon issue ; of this command, not after. jnz @@000 ; if not equal that it is <286 mov ax,7000h pushf push ax popf pushf pop ax popf mov bl,6 and ax,7000h ; check for flag - only 386+ has it jz @@200 ; if ax=0 than this is 286 inc bx ; distinguish between 386SX/Cx486SLC and 386DX/Cx486DLC chips ; This one uses the fact, that 386sx/Cx486SLC has 16-bit data bus and thus ; uses only 16-bit bus interchange format to communicate with coprocessor. ; Due to this limitation the ET bit in MSW is always zero and can't be ; changed, but on 386dx/Cx486DLC it can be flipped. .386p clr si mov eax,cr0 mov ecx,eax xor eax,MSW_ET ; flipping ET bit mov cr0,eax mov eax,cr0 mov cr0,ecx ; restoring previous value of CR0 xor eax,ecx ; did it flip ok? jz @@L100 inc si ; DX/DLC @@L100: ;This code that distinguishes a 386 from a 486 depends on ;the 386's inability to toggle the AC bit in the EFLAGS register, ;but the 486 can. This technique is apparently blessed by Intel. ;Distinguish between 386 and 486 ;Placed into public domain by Compaq Computers. .386 mov ax,sp and sp,0FFFCh ;round down to a dword boundary pushfd pushfd pop edx mov ecx,edx xor edx,EF_AC ;toggle AC bit and ecx,EF_AC push edx popfd pushfd pop edx popfd ;restore original flags mov sp,ax ;restore original stack pointer and edx,EF_AC cmp edx,ecx jnz @@486 ;it's a 486 or si,si ; SX/SLC? ; jz @@386sl jz @@L1 inc bx ; 386DX jmp @@L1 ;@@386sl: ; tested as SX - checking if SL ; call check386sl ; jnc @@L1 ; inc bx ; inc bx ; jmp @@L1 @@486: ; distinguish between Cyrix 486 and Intel 486+ mov bx,cpui486sxr push bx mov cx,8D5h clr ax,ax mov dx,ax cmp ax,ax pushf mov ax,0FFFFh mov bx,4 div bx pushf pop ax dx bx and ax,cx and dx,cx cmp ax,dx jnz @@586 inc bx ; Cyrix 486SLC inc bx or si,si jz @@586 inc bx ; Cyrix 486DLC @@586: ; Check for Pentium or later by attempting to toggle the Id bit in EFLAGS reg: ; if we can't, it's an i486. ; Pentium detection routine ; Placed in public domain by Dr. Dobbs Journal pushfd ; get current flags pop eax mov ecx,eax xor eax,EF_ID ; attempt to toggle ID bit push eax popfd pushfd ; get new EFLAGS pop eax push ecx ; restore original flags popfd and eax,EF_ID ; if we couldn't toggle ID, and ecx,EF_ID ; then this is i486 cmp eax,ecx jz @@486sdx ; do not alter BX ; It's Pentium or later. Use CPUID to get processor family. sub eax,eax ; get processor info inc al cpuid and ah,0Fh ; 5 means Pentium cmp ah,4 jb @@386dx ; CPUID also works on later models of 386dx je @@486dx ; and 486dx. Though we shouldn't come here on ; a 386 it's better to make an extra check for ; the case we occasionally did. cmp bl,cpuCx486 ; was Cyrix microcode detected ? jb @@P5 cmp bl,cpuCx486+1 ja @@P5 mov bl,cpuCxM1 ; yes - this is Cyrix M1 chip jmp @@L1 @@P5: mov bl,ah add bl,cpuPentium-5 jmp @@L1 @@386dx: mov bx,cpu80386dxr jmp @@L1 @@486sdx: ; distinguish between i486dx and i486sx processors ; based on 486sx's inability to toggle NE bit of MSW .486p mov eax,cr0 mov ecx,eax db 66h,83h,0E0h,0DFh ; and eax,0FFFFFFDFh ; flip off NE bit of MSW mov cr0,eax mov eax,cr0 cmp eax,ecx jnz @@486dx or eax,MSW_NE ; flip on NE bit of MSW mov cr0,eax mov eax,cr0 cmp eax,ecx jnz @@486dx dec bx @@486dx: inc bx mov eax,ecx mov cr0,eax @@L1: .286p smsw ax and al,1 mov bh,al ; get the VM flag into bh jmp @@200 @@000: mov bl,4 ; assume this is 186/188 mov cl,33 clr ax dec ax shl ax,cl jnz @@100 ; 186/188 does not actually shift ; more that 32 bits. It shifts only ; n mod 32 bits, where n is number of ; bits to shift. mov bl,2 ; assume NEC family clr cx dec cx ; rep es: lodsb - incorrect order of prefixes and thus would ; not work as repeated command on Intel's CPUs. ; 8086/88 accepts only es: rep lodsb order. But ; NEC Vxx CPUs process multiple prefix repeated ; instructions correctly regardless of their ; order. db 0F3h,26h,0ACh ; rep es: lodsb jcxz @@100 ; was repeated cx times -> NEC V20/V30 sub bx,bx ; good old 88/86 @@100: call Test_Buffer jcxz @@200 ; prefetch buffer length < 6 bytes -> 88 / V20 inc bx ; prefetch buffer length = 6 bytes -> 86 / V30 @@200: call FPU_Type mov ax,bx pop si cx bx ret endp ;check386sl proc ; CF = 1 if 386SL ; meaning of this code is unclear for me, but Diagsoft states this works ; ok. ; cli ; in ax,22h ; mov cx,ax ; test cl,1 ; jnz @@1 ; mov ax,8000h ; out 23h,al ; xchg ah,al ; out 22h,al ; out 22h,ax ; jmp $+2 ; in ax,22h ; test al,1 ; jz @@2 ;@@1: ; mov ax,cx ; or ah,1 ; out 22h,ax ; jmp $+2 ; jmp $+2 ; in ax,22h ; test al,1 ; jnz @@2 ; mov ax,8000h ; out 23h,al ; xchg ah,al ; out 22h,al ; out 22h,ax ; jmp $+2 ; in ax,22h ; test al,1 ; jz @@2 ; mov ax,cx ; test al,1 ; jnz @@3 ; or ah,1 ; out 22h,ax ; stc ; jmp @@Q ;@@2: ; mov ax,cx ; out 22h,ax ;@@3: ; clc ;@@Q: ; sti ; ret ; endp Test_Buffer proc ; (C) 2B Programmers push es di mov _bpcs[@@0],41h ; to make this routine reentrant std push cs pop es ldi @@2 mov al,_bpcs[@@1] mov cx,3 cli rep stosb cld ; 1 nop ; 2 nop ; 3 nop ; 4 <- 80x88 will cut here and inc cx instruction @@0: inc cx ; 5 will be overwritten by sti, else we'll get @@1: ; cx = 1, which indicates 80x86 sti ; 6 @@2: sti pop di es ret endp ; db 13,10 ; db ' Too much is not enough...',13,10 ; db ' (Deep Purple)',13,10 ; db 13,10 ; db 'TMIOSDGL(tm) CPU/FPU feature detection library Version 1.14',13,10 ; db 'Copyright(c) 1992,93,94 by B-coolWare. Released as freeware.',13,10 fsbp0 equ ; IIT xC87 specific instruction: ; select register bank #0 fsbp1 equ ; IIT xC87 specific instruction: ; select register bank #1 fsbp2 equ ; IIT xC87 specific instruction: ; select register bank #2 fmul4x4 equ ; IIT xC87 specific instruction: ; matrix multiplication FPU_Type proc ; ; on entry : BL = CPU code !! Required !! ; .8086 .8087 ; check for coprocessor mov dl,2 ; assume no coprocessor present finit clr cx mov fpubuf_w,5A5Ah fnstsw fpubuf_w fwait mov ax,fpubuf_w or al,al ; FPU wasn't initialized - no FPU at all jnz @@L15 fnstcw fpubuf_w ; check the control word also fwait mov ax,fpubuf_w and ax,103Fh cmp ax,3Fh jne @@L15 mov dl,4 ; assume 8087 fstenv fpuenv fwait and fpubuf_w,0FF7Fh fldcw fpubuf_w fwait fdisi fstcw fpubuf_w fwait test fpubuf_w,80h jnz @@L15 mov dl,8 ; assume 80287 .286 .287 finit ; checking if -Inf <> +Inf fld1 ; 287 erroneously claim that they are equal fldz fdivp st(1),st fld st fchs fcompp fstsw fpubuf_w fwait mov ax,fpubuf_w sahf jz @@L15 ; -Inf <> +Inf -> 287XL or 387 and up mov dl,0Ch ; assume 80387 @@L14: .286 .287 cmp bl,09h ; 486 or up? jb @@checkIIT ; IIT x87's bank switching instructions causes jmp @@L35 ; 486s to hang... don't know why. @@checkIIT: ; testing for IIT ?C87 finit ; trying to perform a matrix multiplication fsbp1 wait fldz ; loading matrix coeffs in bank #1 fld1 fldz fldz fld1 fldz fldz fldz wait finit fsbp2 fldz ; loading matrix coeffs in bank #2 fldz fldz fld1 fldz fldz fld1 fldz wait finit fsbp0 wait fldz ; generating vector fld1 fld st(0) fadd st,st(0) fld st(0) fadd st,st(2) fmul4x4 ; do the multiplication wait fstp iit1 ; store resulting vector... fstp iit2 fstp iit3 fstp iit4 wait ; ...and check the result cmp _wp [iit4+2],4040h jnz @@L35 cmp _wp [iit3+2],4000h jnz @@L35 cmp _wp [iit2+2],3F80h jnz @@L35 cmp _wp [iit1],0 jnz @@L35 ; wow! it works - IIT chip cmp dl,0Ch ; tested as 80387? jnz @@300 mov dl,24 ; this is IIT 3C87 jmp @@L15 @@300: mov dl,22 ; this is IIT 2C87 jmp @@L15 @@L35: finit fldpi f2xm1 fstp fpubuf_d cmp word ptr [fpubuf_d+2],3FC9h jne @@L15 or dl,2 ; this is Cyrix ?C87 @@L15: cmp bl,7 jb @@L16 .386 clr eax int 11h test eax,1000000h .8086 jz @@L16 or dl,1 ; Weitek 1167 present @@L16: cmp bl,cpu486dx ; 486dx? jne @@L17 @@builtin: and dl,3 or dl,10h ; built-in coprocessor jmp @@nobuilt @@L17: cmp bl,cpu486dlc ; 486dlc and Pentium-like CPUs got built-in jae @@builtin ; FPUs @@nobuilt: cmp bl,cpu286 ; 286...? jnz @@20 cmp dl,0Ch ; ...and FPU tested as 387...? jz @@21 cmp dl,0Dh jnz @@20 @@21: add dl,8 ; then assume 80287XL - tricky @@20: cmp bl,cpuPentium jb @@30 and dl,3 or dl,10h ; built-in coprocessor @@30: cmp dl,4 ; any 87 present? jb @@L18 fldenv fpuenv ; yes - restore 87 environment @@L18: ret endp fpubuf_w dw ? fpubuf_d dd ? fpuenv db 14 dup(?) iit1 dd 6F772049h ; this is just a message - anything iit2 dd 7265646Eh ; can be here. iit3 dd 20666920h iit4 dd 00544949h ifdef __PRINT_CPU__ CPUs dw offset I88 dw offset I86 dw offset V20 dw offset V30 dw offset I188 dw offset I186 dw offset I286 dw offset I386SX dw offset I386DX dw offset I386SL dw offset I486SX dw offset I486DX dw offset Cyr486SLC dw offset Cyr486DLC dw offset I586 dw offset CxM1 Lstring I88, Lstring I86, Lstring V20, Lstring V30, Lstring I188, Lstring I186, Lstring I286, Lstring I386SX, Lstring I386DX, Lstring I386SL, Lstring I486SX, Lstring I486DX, Lstring Cyr486SLC, Lstring Cyr486DLC, Lstring I586, Lstring CxM1, Lstring RealMode,< in real mode> Lstring VirtMode,< in V86 mode> FPUType dw ? print_CPU proc .8086 call CPU_Type clr dh mov FPUType,dx push ax ifdef __use_386__ movzx bx,al else mov bl,al clr bh endif shl bx,1 mov dx,CPUs[bx] call WriteStr pop ax cmp al,7 jb @@Exit push ax or ah,ah jnz @@Virt ldx RealMode jmp @@Pr @@Virt: ldx VirtMode @@Pr: call WriteStr pop ax ifdef __PRINT_STEP__ cmp al,cpu386dx ; 386dx ? jnz @@Exit call print_Step endif ; __PRINT_STEP__ @@Exit: ldx EndLine call WriteStr ifdef __PRINT_FPU__ call print_FPU ldx EndLine call WriteStr endif ret endp endif ; __PRINT_CPU__ ifdef __PRINT_STEP__ __386STEP__ EQU 1 endif ifdef __386STEP__ stepB0 EQU 0 stepB1 EQU 1 stepD0 EQU 2 ifdef __PRINT_STEP__ stepTable label word dw offset B0Str dw offset B1Str dw offset D0Str Lstring B0Str, Lstring B1Str, Lstring D0Str, Lstring stepStr,<, 386 chip step is > print_Step proc .8086 ldx stepStr call WriteStr call i386step ifdef __use_386__ movzx bx,al else mov bl,al clr bh endif shl bx,1 mov dx,stepTable[bx] call WriteStr ret endp endif ; this routine determines 386DX chip stepping. ; ripped from Phar Lap TellMe utility. ; returns: ; ax = 0 -> chip is step B0 or earlier ; ax = 1 -> chip is step B1 ; ax = 2 -> chip is step D0 or later i386step proc .386 push bx cx dx si di es ds mov ax,3506h int 21h push cs pop ds mov dx,offset @@int06h mov ax,2506h int 21h clr cx inc cx ; .486 ; cmpxchg ds:[bx+si],al ; this command sequence cause INT 06 db 0Fh,0A6h,00h ; to occur on 386s later than step B0. ; TASM does not generate this code when ; using mnemonics. Generated code ; differs from that specified in db ; but decodes in the same instruction. @@B0: mov dx,bx push es pop ds mov ax,2506h int 21h jcxz @@checkB1 clr ax jmp @@Qstep @@int06h: clr cx add sp,4 popf jmp @@B0 @@buf dw 0 @@checkB1: mov di,offset @@buf mov dx,80h inc cx ; cx = 0 if we got here mov ax,cx inc ax cld push ax rep insb ; repeating insb 1 times on B1 step chip does ; not reset cx to zero. pop ax jcxz @@Qstep dec ax @@Qstep: pop ds es di si dx cx bx ret endp endif ifdef __PRINT_FPU__ FPUs dw offset fpuUnknown ; ? dw offset fpuUnknown ; ? dw offset fpuNone ; --- dw offset fpuWeitek ; Weitek 1167 dw offset fpu87 ; 8087 dw offset fpu87W ; 8087 + Weitek 1167 dw offset fpuUnknown ; ? dw offset fpuUnknown ; ? dw offset fpu287 ; 80287 dw offset fpu287W ; 80287 + Weitek 1167 dw offset fpu2C87 ; Cyrix 2C87 dw offset fpu2C87W ; Cyrix 2C87 + Weitek 1167 dw offset fpu387 ; 80387 dw offset fpu387W ; 80387 + Weitek 1167 dw offset fpu3C87 ; Cyrix 3C87 dw offset fpu3C87W ; Cyrix 3C87 + Weitek 1167 dw offset fpuBuiltIn ; 486 internal dw offset fpuBuiltInW ; 486 internal + Weitek 1167 dw offset fpu4C87 ; Cyrix 4C87 dw offset fpu4C87W ; Cyrix 4C87 + Weitek 1167 dw offset fpu287XL ; Intel 80287XL dw offset fpu287XLW ; Intel 80287XL + Weitek 1167 dw offset fpuIIT2C87 ; IIT 2C87 dw offset fpuIIT2C87W ; IIT 2C87 + Weitek 1167 dw offset fpuIIT3C87 ; IIT 3C87 dw offset fpuIIT3C87W ; IIT 3C87 + Weitek 1167 Lstring FPUis, Lstring fpuWeitek, Lstring fpuUnknown, Lstring fpuNone, Lstring fpuBuiltIn,<(Built-In)> Lstring fpu87, Lstring fpu287, Lstring fpu287XL, Lstring fpu387, Lstring fpu2C87, Lstring fpu3C87, Lstring fpu4C87, Lstring fpuBuiltInW,<(Built-In) and Weitek 1167> Lstring fpu87W, Lstring fpu287W, Lstring fpu287XLW, Lstring fpuIIT2C87, Lstring fpuIIT2C87W, Lstring fpuIIT3C87, Lstring fpuIIT3C87W, Lstring fpu387W, Lstring fpu2C87W, Lstring fpu3C87W, Lstring fpu4C87W, print_FPU proc .8086 ldx FPUis call WriteStr mov bx,FPUType shl bx,1 mov dx,FPUs[bx] call WriteStr ret endp endif ifndef __use_386__ ifndef __use_286__ .8086 endif endif src/command/decode.c0100664000076500007650000002771107725644157014134 0ustar prool2prool2/* DECODE.C, UNARJ, R JUNG, 02/17/93 * Decode ARJ archive * Copyright (c) 1991 by Robert K Jung. All rights reserved. * * This code may be freely used in programs that are NOT ARJ archivers * (both compress and extract ARJ archives). * * If you wish to distribute a modified version of this program, you * MUST indicate that it is a modified version both in the program and * source code. * * If you modify this program, I would appreciate a copy of the new * source code. I am holding the copyright on the source code, so * please do not delete my name from the program files or from the * documentation. * * Modification history: * Date Programmer Description of modification. * 04/05/91 R. Jung Rewrote code. * 04/23/91 M. Adler Portabilized. * 04/29/91 R. Jung Made GETBIT independent of short size. * 05/04/91 R. Jung Simplified use of start[len]. * 08/28/91 R. Jung Added KEEP_WINDOW for systems with low memory. * 02/17/93 R. Jung Added extra test for bad data to make_table(). * Added PTABLESIZE defines. * */ #include "unarj.h" #ifdef MODERN #include #else /* !MODERN */ extern void free(); #endif /* ?MODERN */ #define THRESHOLD 3 #define DDICSIZ 26624 #define MAXDICBIT 16 #define MATCHBIT 8 #define MAXMATCH 256 #define NC (UCHAR_MAX + MAXMATCH + 2 - THRESHOLD) #define NP (MAXDICBIT + 1) #define CBIT 9 #define NT (CODE_BIT + 3) #define PBIT 5 #define TBIT 5 #if NT > NP #define NPT NT #else #define NPT NP #endif #define CTABLESIZE 4096 #define PTABLESIZE 256 #define STRTP 9 #define STOPP 13 #define STRTL 0 #define STOPL 7 /* Local functions */ #ifdef MODERN static void make_table(int nchar, uchar *bitlen, int tablebits, ushort *table, int tablesize); static void read_pt_len(int nn, int nbit, int i_special); static void read_c_len(void); static ushort decode_c(void); static ushort decode_p(void); static void decode_start(void); static short decode_ptr(void); static short decode_len(void); #endif /* MODERN */ /* Local variables */ static uchar FAR *text = NULL; static short getlen; static short getbuf; static ushort left[2 * NC - 1]; static ushort right[2 * NC - 1]; static uchar c_len[NC]; static uchar pt_len[NPT]; static ushort c_table[CTABLESIZE]; static ushort pt_table[PTABLESIZE]; static ushort blocksize; /* Huffman decode routines */ static void make_table(nchar, bitlen, tablebits, table, tablesize) int nchar; uchar *bitlen; int tablebits; ushort *table; int tablesize; { ushort count[17], weight[17], start[18], *p; uint i, k, len, ch, jutbits, avail, nextcode, mask; for (i = 1; i <= 16; i++) count[i] = 0; for (i = 0; (int)i < nchar; i++) count[bitlen[i]]++; start[1] = 0; for (i = 1; i <= 16; i++) start[i + 1] = start[i] + (count[i] << (16 - i)); if (start[17] != (ushort) (1 << 16)) error(M_BADTABLE, ""); jutbits = 16 - tablebits; for (i = 1; (int)i <= tablebits; i++) { start[i] >>= jutbits; weight[i] = 1 << (tablebits - i); } while (i <= 16) { weight[i] = 1 << (16 - i); i++; } i = start[tablebits + 1] >> jutbits; if (i != (ushort) (1 << 16)) { k = 1 << tablebits; while (i != k) table[i++] = 0; } avail = nchar; mask = 1 << (15 - tablebits); for (ch = 0; (int)ch < nchar; ch++) { if ((len = bitlen[ch]) == 0) continue; k = start[len]; nextcode = k + weight[len]; if ((int)len <= tablebits) { if (nextcode > (uint)tablesize) error(M_BADTABLE, ""); for (i = start[len]; i < nextcode; i++) table[i] = ch; } else { p = &table[k >> jutbits]; i = len - tablebits; while (i != 0) { if (*p == 0) { right[avail] = left[avail] = 0; *p = avail++; } if (k & mask) p = &right[*p]; else p = &left[*p]; k <<= 1; i--; } *p = ch; } start[len] = nextcode; } } static void read_pt_len(nn, nbit, i_special) int nn; int nbit; int i_special; { int i, n; short c; ushort mask; n = getbits(nbit); if (n == 0) { c = getbits(nbit); for (i = 0; i < nn; i++) pt_len[i] = 0; for (i = 0; i < 256; i++) pt_table[i] = c; } else { i = 0; while (i < n) { c = bitbuf >> (13); if (c == 7) { mask = 1 << (12); while (mask & bitbuf) { mask >>= 1; c++; } } fillbuf((c < 7) ? 3 : (int)(c - 3)); pt_len[i++] = (uchar)c; if (i == i_special) { c = getbits(2); while (--c >= 0) pt_len[i++] = 0; } } while (i < nn) pt_len[i++] = 0; make_table(nn, pt_len, 8, pt_table, sizeof(pt_table)); } } static void read_c_len() { short i, c, n; ushort mask; n = getbits(CBIT); if (n == 0) { c = getbits(CBIT); for (i = 0; i < NC; i++) c_len[i] = 0; for (i = 0; i < CTABLESIZE; i++) c_table[i] = c; } else { i = 0; while (i < n) { c = pt_table[bitbuf >> (8)]; if (c >= NT) { mask = 1 << (7); do { if (bitbuf & mask) c = right[c]; else c = left[c]; mask >>= 1; } while (c >= NT); } fillbuf((int)(pt_len[c])); if (c <= 2) { if (c == 0) c = 1; else if (c == 1) c = getbits(4) + 3; else c = getbits(CBIT) + 20; while (--c >= 0) c_len[i++] = 0; } else c_len[i++] = (uchar)(c - 2); } while (i < NC) c_len[i++] = 0; make_table(NC, c_len, 12, c_table, sizeof(c_table)); } } static ushort decode_c() { ushort j, mask; if (blocksize == 0) { blocksize = getbits(16); read_pt_len(NT, TBIT, 3); read_c_len(); read_pt_len(NP, PBIT, -1); } blocksize--; j = c_table[bitbuf >> 4]; if (j >= NC) { mask = 1 << (3); do { if (bitbuf & mask) j = right[j]; else j = left[j]; mask >>= 1; } while (j >= NC); } fillbuf((int)(c_len[j])); return j; } static ushort decode_p() { ushort j, mask; j = pt_table[bitbuf >> (8)]; if (j >= NP) { mask = 1 << (7); do { if (bitbuf & mask) j = right[j]; else j = left[j]; mask >>= 1; } while (j >= NP); } fillbuf((int)(pt_len[j])); if (j != 0) { j--; j = (1 << j) + getbits((int)j); } return j; } static void decode_start() { blocksize = 0; init_getbits(); } void decode() { short i; short j; short c; short r; long count; #ifdef KEEP_WINDOW if (text == (uchar FAR *) NULL) text = (uchar FAR *)malloc_msg(DDICSIZ); #else text = (uchar FAR *)malloc_msg(DDICSIZ); #endif disp_clock(); decode_start(); count = 0; r = 0; while (count < origsize) { if ((c = decode_c()) <= UCHAR_MAX) { text[r] = (uchar) c; count++; if (++r >= DDICSIZ) { r = 0; disp_clock(); fwrite_txt_crc(text, DDICSIZ); } } else { j = c - (UCHAR_MAX + 1 - THRESHOLD); count += j; i = decode_p(); if ((i = r - i - 1) < 0) i += DDICSIZ; if (r > i && r < DDICSIZ - MAXMATCH - 1) { while (--j >= 0) text[r++] = text[i++]; } else { while (--j >= 0) { text[r] = text[i]; if (++r >= DDICSIZ) { r = 0; disp_clock(); fwrite_txt_crc(text, DDICSIZ); } if (++i >= DDICSIZ) i = 0; } } } } if (r != 0) fwrite_txt_crc(text, r); #ifndef KEEP_WINDOW free((char FAR *)text); #endif } /* Macros */ #define BFIL {getbuf|=bitbuf>>getlen;fillbuf(CODE_BIT-getlen);getlen=CODE_BIT;} #define GETBIT(c) {if(getlen<=0)BFIL c=(getbuf&0x8000)!=0;getbuf<<=1;getlen--;} #define BPUL(l) {getbuf<<=l;getlen-=l;} #define GETBITS(c,l) {if(getlen>(CODE_BIT-l);BPUL(l)} static short decode_ptr() { short c; short width; short plus; short pwr; plus = 0; pwr = 1 << (STRTP); for (width = (STRTP); width < (STOPP) ; width++) { GETBIT(c); if (c == 0) break; plus += pwr; pwr <<= 1; } if (width != 0) GETBITS(c, width); c += plus; return c; } static short decode_len() { short c; short width; short plus; short pwr; plus = 0; pwr = 1 << (STRTL); for (width = (STRTL); width < (STOPL) ; width++) { GETBIT(c); if (c == 0) break; plus += pwr; pwr <<= 1; } if (width != 0) GETBITS(c, width); c += plus; return c; } void decode_f() { short i; short j; short c; short r; short pos; long count; #ifdef KEEP_WINDOW if (text == (uchar FAR *) NULL) text = (uchar FAR *)malloc_msg(DDICSIZ); #else text = (uchar FAR *)malloc_msg(DDICSIZ); #endif disp_clock(); init_getbits(); getlen = getbuf = 0; count = 0; r = 0; while (count < origsize) { c = decode_len(); if (c == 0) { GETBITS(c, CHAR_BIT); text[r] = (uchar)c; count++; if (++r >= DDICSIZ) { r = 0; disp_clock(); fwrite_txt_crc(text, DDICSIZ); } } else { j = c - 1 + THRESHOLD; count += j; pos = decode_ptr(); if ((i = r - pos - 1) < 0) i += DDICSIZ; while (j-- > 0) { text[r] = text[i]; if (++r >= DDICSIZ) { r = 0; disp_clock(); fwrite_txt_crc(text, DDICSIZ); } if (++i >= DDICSIZ) i = 0; } } } if (r != 0) fwrite_txt_crc(text, r); #ifndef KEEP_WINDOW free((char FAR *)text); #endif } /* end DECODE.C */ src/command/uasm.asm0100664000076500007650000000170707725644160014203 0ustar prool2prool2; Proolix external asm-utility ; include ..\kernel\macros.asm include syscall.h ; .286 .model tiny .code ; org 0 ;Revert label dword ; org 100h _main proc near ; Это начало главной программы public _main ;extrn _saycsip:near ; call _saycsip ; Точка А. (См. ниже) ; pusha ; popa mov ax,'A' ; Заталкиваем в стек первый (и единственный) параметр push ax ; системного вызова mov ax,0deadh ; Сдвигаем стек на 1 слово для совместимости push ax ; с вызовами из программ на С mov ax,putch ; это системный вызов putch int INT_NO add sp,4 ; Возвращаем стек в исходное состояние, каким он был ; в точке А ret ; Возврат в Пруликс _main endp endsrc/command/unarj.h0100664000076500007650000003306307725644160014024 0ustar prool2prool2/* UNARJ.H, UNARJ, R JUNG, 02/17/93 * Include file * Copyright (c) 1990 by Robert K Jung. All rights reserved. * * This code may be freely used in programs that are NOT ARJ archivers * (both compress and extract ARJ archives). * * If you wish to distribute a modified version of this program, you * MUST indicate that it is a modified version both in the program and * source code. * * If you modify this program, I would appreciate a copy of the new * source code. I am holding the copyright on the source code, so * please do not delete my name from the program files or from the * documentation. * * Modification history: * Date Programmer Description of modification. * 04/05/91 R. Jung Rewrote code. * 04/23/91 M. Adler Portabilized. * 04/29/91 R. Jung Added volume label support. * 05/30/91 R. Jung Added SEEK_END definition. * 06/03/91 R. Jung Changed arguments in get_mode_str() and * set_ftime_mode(). * 06/28/91 R. Jung Added new HOST OS numbers. * 07/08/91 R. Jung Added default_case_path() and strlower(). * 07/21/91 R. Jung Fixed #endif _QC comment. * 08/27/91 R. Jung Added #ifdef for COHERENT. * 09/01/91 R. Jung Added new host names. * 12/03/91 R. Jung Added BACKUP_FLAG. * 04/06/92 R. Jung Added ARCHIMEDES. * 02/17/93 R. Jung Improved ARJ header information. Added ARJ_M_VERSION. * */ #ifndef _ARH_DEF_ #define _ARH_DEF_ /* Use prototypes and ANSI libraries if __STDC__ */ #ifdef __STDC__ # define MODERN #endif /* __STDC__ */ /* Do not use prototypes for COHERENT */ #ifdef COHERENT # undef MODERN # define KEEP_WINDOW #endif /* COHERENT */ /* Use prototypes and ANSI libraries if __TURBOC__ */ #ifdef __TURBOC__ # define MODERN #endif /* __TURBOC__ */ /* Use prototypes and ANSI libraries if _QC */ #ifdef _QC # define MODERN #endif /* _QC */ /* Use prototypes and ANSI libraries if _OS2 */ #ifdef _OS2 # define MODERN #endif /* _OS2 */ /* Used to remove arguments in function prototypes for non-ANSI C */ #ifdef MODERN # define OF(a) a #else /* !MODERN */ # define OF(a) () #endif /* ?MODERN */ #ifdef MODERN typedef void voidp; #else /* !MODERN */ # define void int typedef char voidp; #endif /* ?MODERN */ #include #ifdef MODERN # include #else /* !MODERN */ # ifndef UCHAR_MAX # define UCHAR_MAX (255) # endif # ifndef CHAR_BIT # define CHAR_BIT (8) # endif # ifndef LONG_MAX # define LONG_MAX (0x7FFFFFFFL) # endif #endif /* ?MODERN */ #ifndef SEEK_SET # define SEEK_SET 0 #endif #ifndef SEEK_CUR # define SEEK_CUR 1 #endif #ifndef SEEK_END # define SEEK_END 2 #endif typedef unsigned char uchar; /* 8 bits or more */ typedef unsigned int uint; /* 16 - 32 bits or more */ typedef unsigned short ushort; /* 16 bits or more */ typedef unsigned long ulong; /* 32 bits or more */ #define USHRT_BIT (CHAR_BIT * sizeof(ushort)) /* ********************************************************* */ /* Environment definitions (implementation dependent) */ /* ********************************************************* */ #ifdef _QC #define __MSDOS__ #endif #ifdef __MSDOS__ #define OS 0 #define PATH_SEPARATORS "\\:" #define PATH_CHAR '\\' #define MAXSFX 25000L #define ARJ_SUFFIX ".ARJ" #endif #ifdef _OS2 #define OS 0 /* ??? */ #define PATH_SEPARATORS "\\:" #define PATH_CHAR '\\' #define SWITCH_CHARS "-/" #define MAXSFX 25000L #define ARJ_SUFFIX ".ARJ" #endif #ifdef __CI #define PRIME 1 #define OS 1 #define PATH_SEPARATORS ">" #define PATH_CHAR '>' #define FIX_PARITY(c) c |= ~ASCII_MASK #define DEFAULT_DIR "*>" #define ARJ_SUFFIX ".ARJ" #endif /* Error levels */ #ifndef ERROR_DEFINES #define ERROR_OK 0 /* success */ #define ERROR_WARN 1 /* minor problem (file not found) */ #define ERROR_FAIL 2 /* fatal error */ #define ERROR_CRC 3 /* CRC error */ #define ERROR_SECURE 4 /* ARJ security invalid or not found */ #define ERROR_WRITE 5 /* disk full */ #define ERROR_OPEN 6 /* can't open file */ #define ERROR_USER 7 /* user specified bad parameters */ #define ERROR_MEMORY 8 /* not enough memory */ #endif #ifndef MAXSFX /* size of self-extracting prefix */ #define MAXSFX 500000L #endif #ifndef FNAME_MAX #define FNAME_MAX 512 #endif #ifndef SWITCH_CHARS #define SWITCH_CHARS "-" #endif #ifndef FIX_PARITY #define FIX_PARITY(c) c &= ASCII_MASK #endif #ifndef ARJ_SUFFIX #define ARJ_SUFFIX ".arj" #endif #ifndef ARJ_DOT #define ARJ_DOT '.' #endif #ifndef DEFAULT_DIR #define DEFAULT_DIR "" #endif #ifndef OS #define OS 2 #endif #ifndef PATH_SEPARATORS #define PATH_SEPARATORS "/" #endif #ifndef PATH_CHAR #define PATH_CHAR '/' #endif #ifdef Proolix #define FAR far #else #define FAR #endif /* ********************************************************* */ /* end of environmental defines */ /* ********************************************************* */ /* ********************************************************* */ /* * Structure of archive main header (low order byte first): * * 2 header id (comment and local file) = 0x60, 0xEA * 2 basic header size (from 'first_hdr_size' thru 'comment' below) * = first_hdr_size + strlen(filename) + 1 + strlen(comment) + 1 * = 0 if end of archive * * 1 first_hdr_size (size up to 'extra data') * 1 archiver version number * 1 minimum archiver version to extract * 1 host OS (0 = MSDOS, 1 = PRIMOS, 2 = UNIX, 3 = AMIGA, 4 = MACDOS) * (5 = OS/2, 6 = APPLE GS, 7 = ATARI ST, 8 = NEXT) * (9 = VAX VMS) * 1 arj flags (0x01 = GARBLED_FLAG, 0x02 = OLD_SECURED_FLAG) * (0x04 = VOLUME_FLAG, 0x08 = EXTFILE_FLAG) * (0x10 = PATHSYM_FLAG, 0x20 = BACKUP_FLAG) * (0x40 = SECURED_FLAG) * 1 arj security version (2 = current) * 1 file type (2 = comment header) * 1 ? ] * 4 date time stamp created * 4 date time stamp modified * 4 archive size up to the end of archive marker * 4 file position of security envelope data * 2 entryname position in filename * 2 length in bytes of trailing security data * 2 host data * ? extra data * * ? archive filename (null-terminated) * ? archive comment (null-terminated) * * 4 basic header CRC * * 2 1st extended header size (0 if none) * ? 1st extended header * 4 1st extended header's CRC * ... * * * Structure of archive file header (low order byte first): * * 2 header id (comment and local file) = 0x60, 0xEA * 2 basic header size (from 'first_hdr_size' thru 'comment' below) * = first_hdr_size + strlen(filename) + 1 + strlen(comment) + 1 * = 0 if end of archive * * 1 first_hdr_size (size up to 'extra data') * 1 archiver version number * 1 minimum archiver version to extract * 1 host OS (0 = MSDOS, 1 = PRIMOS, 2 = UNIX, 3 = AMIGA, 4 = MACDOS) * (5 = OS/2, 6 = APPLE GS, 7 = ATARI ST, 8 = NEXT) * (9 = VAX VMS) * 1 arj flags (0x01 = GARBLED_FLAG, 0x02 = NOT USED) * (0x04 = VOLUME_FLAG, 0x08 = EXTFILE_FLAG) * (0x10 = PATHSYM_FLAG, 0x20 = BACKUP_FLAG) * (0x40 = NOT USED) * 1 method (0 = stored, 1 = compressed most ... 4 compressed fastest) * 1 file type (0 = binary, 1 = text, 2 = comment header, 3 = directory) * (4 = label) * 1 garble password modifier * 4 date time stamp modified * 4 compressed size * 4 original size * 4 original file's CRC * 2 entryname position in filename * 2 file access mode * 2 host data * ? extra data * 4 bytes for extended file position * * ? filename (null-terminated) * ? comment (null-terminated) * * 4 basic header CRC * * 2 1st extended header size (0 if none) * ? 1st extended header * 4 1st extended header's CRC * ... * ? compressed file */ /* ********************************************************* */ /* ********************************************************* */ /* */ /* Time stamp format: */ /* */ /* 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 */ /* |<---- year-1980 --->|<- month ->|<--- day ---->| */ /* */ /* 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 */ /* |<--- hour --->|<---- minute --->|<- second/2 ->| */ /* */ /* ********************************************************* */ #define CODE_BIT 16 #define NULL_CHAR '\0' #define MAXMETHOD 4 #define ARJ_VERSION 3 #define ARJ_M_VERSION 6 /* ARJ version that supports modified date. */ #define ARJ_X_VERSION 3 /* decoder version */ #define ARJ_X1_VERSION 1 #define DEFAULT_METHOD 1 #define DEFAULT_TYPE 0 /* if type_sw is selected */ #define HEADER_ID 0xEA60 #define HEADER_ID_HI 0xEA #define HEADER_ID_LO 0x60 #define FIRST_HDR_SIZE 30 #define FIRST_HDR_SIZE_V 34 #define COMMENT_MAX 2048 #define HEADERSIZE_MAX (FIRST_HDR_SIZE + 10 + FNAME_MAX + COMMENT_MAX) #define BINARY_TYPE 0 /* This must line up with binary/text strings */ #define TEXT_TYPE 1 #define COMMENT_TYPE 2 #define DIR_TYPE 3 #define LABEL_TYPE 4 #define GARBLE_FLAG 0x01 #define VOLUME_FLAG 0x04 #define EXTFILE_FLAG 0x08 #define PATHSYM_FLAG 0x10 #define BACKUP_FLAG 0x20 typedef ulong UCRC; /* CRC-32 */ #define CRC_MASK 0xFFFFFFFFL #define ARJ_PATH_CHAR '/' #define FA_RDONLY 0x01 /* Read only attribute */ #define FA_HIDDEN 0x02 /* Hidden file */ #define FA_SYSTEM 0x04 /* System file */ #define FA_LABEL 0x08 /* Volume label */ #define FA_DIREC 0x10 /* Directory */ #define FA_ARCH 0x20 /* Archive */ #define HOST_OS_NAMES1 "MS-DOS","PRIMOS","UNIX","AMIGA","MAC-OS","OS/2" #define HOST_OS_NAMES2 "APPLE GS","ATARI ST","NEXT","VAX VMS" #define HOST_OS_NAMES { HOST_OS_NAMES1, HOST_OS_NAMES2, NULL } /* Timestamp macros */ #define get_tx(m,d,h,n) (((ulong)m<<21)+((ulong)d<<16)+((ulong)h<<11)+(n<<5)) #define get_tstamp(y,m,d,h,n,s) ((((ulong)(y-1980))<<25)+get_tx(m,d,h,n)+(s/2)) #define ts_year(ts) ((uint)((ts >> 25) & 0x7f) + 1980) #define ts_month(ts) ((uint)(ts >> 21) & 0x0f) /* 1..12 means Jan..Dec */ #define ts_day(ts) ((uint)(ts >> 16) & 0x1f) /* 1..31 means 1st..31st */ #define ts_hour(ts) ((uint)(ts >> 11) & 0x1f) #define ts_min(ts) ((uint)(ts >> 5) & 0x3f) #define ts_sec(ts) ((uint)((ts & 0x1f) * 2)) /* unarj.c */ extern long origsize; extern long compsize; extern UCRC crc; extern FILE FAR *arcfile; extern FILE FAR *outfile; extern ushort bitbuf; extern uchar subbitbuf; extern uchar header[HEADERSIZE_MAX]; extern char arc_name[FNAME_MAX]; extern int bitcount; extern int file_type; extern int error_count; /* Global functions */ /* unarj.c */ void strlower OF((char *str)); void strupper OF((char *str)); voidp FAR *malloc_msg OF((int size)); void disp_clock OF((void)); void error OF((char *fmt, char *arg)); void fillbuf OF((int n)); ushort getbits OF((int n)); void fwrite_txt_crc OF((uchar FAR *p, int n)); void init_getbits OF((void)); /* environ.c */ FILE FAR *file_open OF((char *name, char *mode)); int file_read OF((char FAR *buf, int size, int nitems, FILE FAR *stream)); int file_seek OF((FILE FAR *stream, long offset, int mode)); long file_tell OF((FILE FAR *stream)); int file_write OF((char FAR *buf, int size, int nitems, FILE FAR *stream)); voidp FAR *xmalloc OF((int size)); void case_path OF((char *name)); void default_case_path OF((char *name)); int file_exists OF((char *name)); void get_mode_str OF((char *str, uint fmode)); int set_ftime_mode OF((char *name, ulong timestamp, uint fmode, uint host)); /* decode.c */ void decode OF((void)); void decode_f OF((void)); /* Message strings */ extern char M_VERSION []; extern char M_ARCDATE []; extern char M_ARCDATEM[]; extern char M_BADCOMND[]; extern char M_BADCOMNT[]; extern char M_BADHEADR[]; extern char M_BADTABLE[]; extern char M_CANTOPEN[]; extern char M_CANTREAD[]; extern char M_CANTWRIT[]; extern char M_CRCERROR[]; extern char M_CRCOK []; extern char M_DIFFHOST[]; extern char M_ENCRYPT []; extern char M_ERRORCNT[]; extern char M_EXTRACT []; extern char M_FEXISTS []; extern char M_HEADRCRC[]; extern char M_NBRFILES[]; extern char M_NOMEMORY[]; extern char M_NOTARJ []; extern char M_PROCARC []; extern char M_SKIPPED []; extern char M_SUFFIX []; extern char M_TESTING []; extern char M_UNKNMETH[]; extern char M_UNKNTYPE[]; extern char M_UNKNVERS[]; #endif /* end UNARJ.H */ src/command/cputype.doc0100664000076500007650000002416007725644157014720 0ustar prool2prool2┌───────────┬──────────────────┬─────────────────────────────────────────────┐ │╔════════╗ │File: CPUTYPE.DOC │Subject: CPU/FPU feature detection library. │ │╠════════╩╗├───────────────┬──┴─────────────────────────────────────────────┤ │║╓─╓─╥─╥╖ ║│Date: 20/06/94 │ Copyright(c) 1993,94 by B-coolWare. │ │║╙─╨─╨─╜╙─║│Version: 1.14 │ This document should not be changed in any way │ │╚═════════╝│Revision:01/11 │and should be distributed with related software.│ └───────────┴───────────────┴────────────────────────────────────────────────┘ Document no.: LR-0006.94.93M01.11 Contents License Agreement. Appendix A. Library Features and Notes. Appendix B. Credits. Appendix C. Authenticity check. Appendix D. History of changes. Too-Much-In-One-So-Don't-Get-Lost(tm) CPU/FPU feature detection library License. This license regards to the Too-Much-In-One-So-Don't-Get-Lost(tm) CPU/FPU detection library version 1.14 dated 20/06/94, mentioned hereafter as "source code". It describes your rites, obligations and liabilities as for this source code. It took much time to gather all information used to produce this code, so the main purpose of this license is to grant anyone free access to it. Use it free, give away to anyone, but please do not sell or lease it - it's my work, and if you think someone should be paid for it, you're not the rite person anyway. This one goes like this: This source code is freeware and thus you have legal rites to copy, distribu- te, modify and use entire code or parts of it in either commercial or non- commercial software, provided that you do not charge additional fee for distribution/incorporation of this code or its parts in your own products. If you do so, your rites automatically void and you'll be liable for violation of the Russian Copyright Law for Computer Programs and Databases as well as other laws and international provisions. Parties that acquire this source code from you will still have their rites for the source code as long as they comply with this license. The source code SHOULD be distributed along with this license and you should document any changes made to it either in source files or in additional documents. The code cannot be distributed partially, you should include all files that builds the library plus any additional files needed to compile it in the distribution archive/set. Regardless of the extent of modifications made by you to this source code, it will remain freeware, and you should provide a way for anyone to obtain his own copy as of original, so as of modified code. This source code is provided AS IS with no express or implied warranties, including any implied warranties of fitness for particular purpose. If you modify the source code included herein, please add a notification about it and complete description of what and how you modified, so that subsequent users of this code will know that they use not original but rather modified version of the code. In case of any damage caused by use or misuse of this code or any other kind of decease including loss of business profits or valuable information, author shall not be liable for it. I expressly disclaim any warranties regarding to the quality of this code, or its errorlessness. Author reserves the rite to change this code entirely or partially without notification to its users. He also reserves the rite to use this code in any manner in any commercial or non-commercial software of any kind and give it away to anyone who ask. If you have any questions, suggestions or usable information on how to improve this product, feel free to contact author at e-mail (preferrable): 2:5028/52.6@fidonet bob@ymz.yaroslavl.su (Relcom@Internet) do ye think me should arrive on CompuServe? :) phones: +7-(0852)-276-548 (9:00am to 6:00pm, Moscow Time) voice\data 14400/V.32b +7-(0852)-238-663 (8:00pm to 10:00pm,Moscow Time) voice please don't call earlier or later - gimme a break... paper mail: 150031, 10/4/13, Dobrynina Str., Yaroslavl, Russia Vladimir M. Zakharychev (Владимир Захарычев) Calls and letters both in English and in Russian are welcome. Please do not speak/write in any other language if you want to be answered. Letter bombs will be returned to sender :) Appendix A. Library Features and Notes. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The Too-Much-In-One-So-Don't-Get-Lost(tm) CPU/FPU feature detection library allows you to distinguish between following CPUs: Intel 8088,8086,80188,80186,80286,80386DX,80386SX,i486DX,i486SX,Pentium and any succeeding CPUs (when they become available), NEC V20 and V30, Cyrix 486SLC, 486DLC and M1 (586), IBM 386SL - I was told that this chip's identification doesn't work :(. FPUs: Intel 8087,80287,80287XL - not 100% reliable,80387 and 487 internal, Cyrix 2C87,3C87 and 4C87, IIT 2C87 and 3C87, Weitek 1167; determine whether or not the processor is in V86 mode (for DOS programs only)- generally this one just tests for PM flag and assumes V86 if it is set for DOS + PM combination automatically leads to V86; determine 386dx chip step (B0 or earlier,B1,D0 or later) - this one tests for known bugs in chips of these steps, it does not reset CPU to look at EAX value; determine CPU clock speed (for all listed processors, was not checked on some models and may require some adjustments). Note 1: AMD Am386SX/40 and Am386DX/40 - can be identified as such by using CPU_Type in conjunction with Speed: if CPU is identified as Intel 386 and its clock is more than 33MHz then this is definitely an AMD chip - Intel doesn't produce 40MHz 386s while AMD does. However this method is not implemented in CPU_Type routine because speed computing requires some floating point calculations and I don't want to insert FPU instructions in the code because there may be no FPU... You may implement this method in your high-level routine reporting CPU type if you want (and as I did :). Also you may conclude i486DX2 if it is identified as 486DX and has CPU clock of 66 MHz - afaik Intel do not produce DX chips with such clock frequencies. However I cannot quarantee this is true and don't use this method by myself. Note 2: The source code is commented so I didn't include its description here. I think there'll be no problem using it. You might encounter problems adapting the source code to use it in languages other than assembler, but that depends on your qualification. I wrote this one for professionals... Appendix B. Credits. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This appendix contains names and netmail addresses of people who contributed to this product in any way, either by adding any methods or by fixing existing methods given incorrect results. If you do such additions or fixes, please contact me and send modified version of the code so that I'll be able to incorporate it in next releases. 1. Igor Dral of 50/321@fidonet who helped me lot in cleaning the code of bugs, testing, etc. Thanx, pal! 2. YOUR NAME MIGHT BE HERE... Appendix C. Authenticity check. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Original issue of the source code as of version 1.13c include: File Size Description ------------ ------ ---------------------------------------------------------- CPU_TYPE.ASH 18035 Main library module DOSINOUT.ASH 1049 DOS Input/Output routines LSTRING.ASH 1057 Lstring macro to define Pascal-style length,data strings UNIDEF.INC 5593 Macros CPU.ASM 1148 Sample program demonstrating usage of CPU_TYPE.ASH CPUSPEED.ASM 4876 CPU clock speed determination routine Appendix D. History of changes. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TMIOSDGL(tm) version 1.10d was the first version publicly released. Differences between version 1.10d and version 1.11: - changed 80287XL determination logic: now this conclusion is made if CPU is 80286 and FPU tests as 80387; - added IIT (Integrated Information Technology, Inc.) xC87 math coprocessors detection; - fixed bug in 386 stepping detection routine. Differences between versions 1.11 and 1.11b: - fixed bug that caused FPU_Type routine to hang on 486s: they don't handle IIT bank switching instructions at all, stopping CPU. Differences between versions 1.11b and 1.12: - distinguish between Cyrix 486SLC and 486DLC made reliable; - code distinguishing between 386sx and 386dx that used bug in dx chips deleted (it was commented out in previous versions) - current method is absolutely reliable; - code slightly optimized to reduce size. Differences between versions 1.12 and 1.12b: - some slight modifications made to CPUSPEED.ASM module to prevent invalid computation of clock frequency for unknown CPUs. Differences between versions 1.12b and 1.13: - added 386sl detection routine, but wasn't checked yet: at least it doesn't hang the PC :); - distinguishing between i486sx and i486dx finally made reliable; - code slightly optimized; - CPUSPEED.ASM enhanced and recommented to reflect new CPU type addition. Differences between versions 1.13 and 1.14: - reduced source file size of CPUSPEED.ASM; - Test_Buffer routine made reentrant ( at last! :); - added newer 386dx and 486dx recognition ( ID flag of EFLAGS is flippable and CPUID instruction works on new 386dx's and 486dx's so I took precaution of this situation); - described method of identifying AMD's 40MHz 386s and a little bit tricky method of identifying i486DX2/66 chips; - added method of identifying Cyrix M1 (586) chip - was not checked yet; - 386SL detection code commented out, but still present - maybe it works on some chipsets... << end of CPUTYPE.DOC >> src/command/dosfn.c0100664000076500007650000001471107725644157014016 0ustar prool2prool2#include void dos_fn_man (char fn) { printf("\n"); switch (fn) { case 0: printf("Program terminate"); break; case 1: printf("Keyboard input with echo"); break; case 2: printf("Display output"); break; case 3: printf("Wait for auxiliary device input"); break; case 4: printf("Auxiliary output"); break; case 5: printf("Printer output"); break; case 6: printf("Direct console I/O"); break; case 7: printf("Wait for direct console input without echo"); break; case 8: printf("Wait for console input without echo"); break; case 9: printf("Print string"); break; case 0xA: printf("Buffered keyboard input"); break; case 0xB: printf("Check standard input status"); break; case 0xC: printf("Clear keyboard buffer, invoke keyboard function"); break; case 0xD: printf("Disk reset"); break; case 0xE: printf("Select disk"); break; case 0xF: printf("Open file using FCB"); break; case 0x10:printf("Close file using FCB"); break; case 0x11:printf("Search for first entry using FCB"); break; case 0x12:printf("Search for next entry using FCB"); break; case 0x13:printf("Delete file using FCB"); break; case 0x14:printf("Sequential read using FCB"); break; case 0x15:printf("Sequential write using FCB"); break; case 0x16:printf("Create a file using FCB"); break; case 0x17:printf("Rename file using FCB"); break; case 0x18:printf("DOS dummy function (CP/M) (not used/listed)"); break; case 0x19:printf("Get current default drive"); break; case 0x1A:printf("Set disk transfer address"); break; case 0x1B:printf("Get allocation table information"); break; case 0x1C:printf("Get allocation table info for specific device"); break; case 0x1D:printf("DOS dummy function (CP/M) (not used/listed)"); break; case 0x1E:printf("DOS dummy function (CP/M) (not used/listed)"); break; case 0x1F:printf("Get pointer to default drive parameter table (undocumented)"); break; case 0x20:printf("DOS dummy function (CP/M) (not used/listed)"); break; case 0x21:printf("Random read using FCB"); break; case 0x22:printf("Random write using FCB"); break; case 0x23:printf("Get file size using FCB"); break; case 0x24:printf("Set relative record field for FCB"); break; case 0x25:printf("Set interrupt vector"); break; case 0x26:printf("Create new program segment"); break; case 0x27:printf("Random block read using FCB"); break; case 0x28:printf("Random block write using FCB"); break; case 0x29:printf("Parse filename for FCB"); break; case 0x2A:printf("Get date"); break; case 0x2B:printf("Set date"); break; case 0x2C:printf("Get time"); break; case 0x2D:printf("Set time"); break; case 0x2E:printf("Set/reset verify switch"); break; case 0x2F:printf("Get disk transfer address"); break; case 0x30:printf("Get DOS version number"); break; case 0x31:printf("Terminate and stay resident"); break; case 0x32:printf("Get pointer to drive parameter table (undocumented)"); break; case 0x33:printf("Get/set Ctrl-Break check state & get boot drive"); break; case 0x34:printf("Get address to DOS critical flag (undocumented)"); break; case 0x35:printf("Get interrupt vector"); break; case 0x36:printf("Get disk free space"); break; case 0x37:printf("Get/set switch character (undocumented)"); break; case 0x38:printf("Get/set country dependent information"); break; case 0x39:printf("Create subdirectory (mkdir)"); break; case 0x3A:printf("Remove subdirectory (rmdir)"); break; case 0x3B:printf("Change current subdirectory (chdir)"); break; case 0x3C:printf("Create file using handle"); break; case 0x3D:printf("Open file using handle"); break; case 0x3E:printf("Close file using handle"); break; case 0x3F:printf("Read file or device using handle"); break; case 0x40:printf("Write file or device using handle"); break; case 0x41:printf("Delete file"); break; case 0x42:printf("Move file pointer using handle"); break; case 0x43:printf("Change file mode"); break; case 0x44:printf("I/O control for devices (IOCTL)"); break; case 0x45:printf("Duplicate file handle"); break; case 0x46:printf("Force duplicate file handle"); break; case 0x47:printf("Get current directory"); break; case 0x48:printf("Allocate memory blocks"); break; case 0x49:printf("Free allocated memory blocks"); break; case 0x4A:printf("Modify allocated memory blocks"); break; case 0x4B:printf("EXEC load and execute program (func 1 undocumented)"); break; case 0x4C:printf("Terminate process with return code"); break; case 0x4D:printf("Get return code of a sub-process"); break; case 0x4E:printf("Find first matching file"); break; case 0x4F:printf("Find next matching file"); break; case 0x50:printf("Set current process id (undocumented)"); break; case 0x51:printf("Get current process id (undocumented)"); break; case 0x52:printf("Get pointer to DOS 'INVARS' (undocumented)"); break; case 0x53:printf("Generate drive parameter table (undocumented)"); break; case 0x54:printf("Get verify setting"); break; case 0x55:printf("Create PSP (undocumented)"); break; case 0x56:printf("Rename file"); break; case 0x57:printf("Get/set file date and time using handle"); break; case 0x58:printf("Get/set memory allocation strategy (3.x+, undocumented)"); break; case 0x59:printf("Get extended error information (3.x+)"); break; case 0x5A:printf("Create temporary file (3.x+)"); break; case 0x5B:printf("Create new file (3.x+)"); break; case 0x5C:printf("Lock/unlock file access (3.x+)"); break; case 0x5D:printf("Critical error information (undocumented 3.x+)"); break; case 0x5E:printf("Network services (3.1+)"); break; case 0x5F:printf("Network redirection (3.1+)"); break; case 0x60:printf("Get fully qualified file name (undocumented 3.x+)"); break; case 0x62:printf("Get address of program segment prefix (3.x+)"); break; case 0x63:printf("Get system lead byte table (MSDOS 2.25 only)"); break; case 0x64:printf("Set device driver look ahead (undocumented 3.3+)"); break; case 0x65:printf("Get extended country information (3.3+)"); break; case 0x66:printf("Get/set global code page (3.3+)"); break; case 0x67:printf("Set handle count (3.3+)"); break; case 0x68:printf("Flush buffer (3.3+)"); break; case 0x69:printf("Get/set disk serial number (undocumented DOS 4.0+)"); break; case 0x6A:printf("DOS reserved (DOS 4.0+)"); break; case 0x6B:printf("DOS reserved"); break; case 0x6C:printf("Extended open/create (4.x+)"); break; case 0xF8: case 0xF9: case 0xFA: case 0xFB: case 0xFC: case 0xFD: case 0xFE: case 0xFF: printf("OEM INT 21 handler (undocumented)"); break; default :printf("unknown"); } } src/command/ladder.c0100664000076500007650000000036007725644160014125 0ustar prool2prool2#include #include "prool.h" main() {int i,j; for (;;) { for (i=0;i<80;i++) { for (j=0;j int main (void) {int i,j; j=0; while (1) { putch('2'); /* asm int 85H; */ for (i=0;i<30000;i++) j++; } return j; } src/command/reply.c0100664000076500007650000000027307725644160014030 0ustar prool2prool2int reply(char *str) { int c,i; while (1) {c=getche() & 0xdf; for (i=0; str[i]!='\0';) if ((char)c==str[i++]) {putch(13);putch(10);return i;} putch(7); } } src/command/ping.c0100664000076500007650000000357007725644160013635 0ustar prool2prool2/* $Id: ping.c,v 1.2 1996/04/17 09:47:39 axl Exp axl $ $Log: ping.c,v $ Revision 1.2 1996/04/17 09:47:39 axl Specially for Proolix - removed TCP/IP support and hostname resolving Revision 1.1 1996/04/11 14:35:54 axl Initial revision */ #include #ifdef Proolix #include #include #endif #ifdef Proolix #define DELAY_TIME 300000L #else #define DELAY_TIME 300000 #endif #define PONG_COUNT 100 version() { printf("Proolix PING version 0.1\n"); printf("TCP/IP _N0T_ REQURIED !!!\n"); printf("(c) Copyright Dmitry A.Deineka, axl@infocom.kharkov.ua\n"); printf(" http://www.infocom.kharkov.ua/~axl\n"); printf("======================================================\n"); } usage() { version(); printf("Usage: ping -- Ping specified host\n"); printf(" ping -h -- Display this help\n"); printf(" ping -v -- Display version\n"); } do_ping(const char *host_to_ping) { unsigned long seq=0; unsigned long dl; unsigned long count; version(); printf("PING %s: 56 data bytes, MAX %lu packets will be sent\n", host_to_ping, PONG_COUNT); for (count=0; count<=PONG_COUNT; count++) { printf ("64 bytes from %s: icmp_seq=%lu ttl=255 time=0.718 ms\n", host_to_ping, seq); seq++; for (dl=0; dl #include #include void out_os (int c); void outMBR (char far *buf) { int i; struct MBRstru far *MBR; MBR=(void far *)buf; printf("System ----Begin---- ----End----- Preceding sec Total sec\n"); printf(" head sec cyl head sec cyl\n"); /* "A FAT 12 iiii ii iiii iiii ii iiii iiiiiiiiii iiiiiiiiii\n" */ for (i=0;i<4;i++) {unsigned int j; if (MBR->Partition[i].indicator==0) printf(" "); else printf("A"); printf(" "); out_os(MBR->Partition[i].system_indicator); printf(" %4i ",MBR->Partition[i].begin_head); printf("%2i ",(j=MBR->Partition[i].begin_sec) & 0x3F); j = (j & 0xC0)<<2; printf("%4i ",MBR->Partition[i].begin_cyl | j); printf("%4i ",MBR->Partition[i].end_head); printf("%2i ",(j=MBR->Partition[i].end_sec) & 0x3F); j = (j & 0xC0)<<2; printf("%4i ",MBR->Partition[i].end_cyl | j); printf("%10lu ",MBR->Partition[i].preceding_sec); printf("%10lu\n",MBR->Partition[i].total_sec); } } int main (int argc, char *argv[]) {char buf [512]; int dev=0; int hdd; if (argc>1) switch (dev=argv[1][0]) { case '0': case '1': dev-='0'; break; default: printf("usage: `vmbr 0' for view of HDD 0 partition\n\ or `vmbr 1' for view of HDD 1 partition\n\n"); return 1; } hdd=*(char far *)MK_FP(0,0x475); printf("\nTotal HDD devices %i\n\n",hdd); if (hdd) { if (dev void main(void) { printf("Usage `more /usr/man/help.doc' for help\n"); } src/command/files.bbs0100664000076500007650000000047407725644157014334 0ustar prool2prool2ASCII.C Write ascii table BETA.C C-program for Proolix testing CAT.C UNIX's cat CAT2.C double cat (for debug) E.C Show arguments & environment (for debug). See e.com in Prool Utilities HELP.C Help LADDER.C Screen saver UASM.ASM Assembler utility for Proolix VEC.C vec - int.command (show interrupt vectors) src/command/int21.c0100664000076500007650000005527407725644160013645 0ustar prool2prool2#include "mse.h" #include #include #include #include #include #include #include #include #include #include #include /****************************************************************************/ void dos_fn_man (char fn); /****************************************************************************/ char str [STRLEN]; /****************************************************************************/ void dosname2pix(char *pix_name,char far *dos_name,int pix_len) { #if 0 if (msdos_verbose) { #ifndef _HERCULES_ textattr(EMULATOR_COLOR); #endif printf(" `%Fs'->",dos_name); } #endif /* MSDOS reserved names */ if (strcmp(dos_name,"lpt1")) {strncpy(pix_name,"/dev/lpt",pix_len); return; } if (strcmp(dos_name,"lpt2")) {strncpy(pix_name,"/dev/lpt",pix_len); return; } if (*(dos_name+1)==':') dos_name+=2; strncpy(pix_name,dos_name,pix_len); strlwr(pix_name); while (*pix_name) { if (*pix_name=='\\') *pix_name='/'; pix_name++; } #if 0 if (msdos_verbose) { printf(" `%s'->",pix_name); #ifndef _HERCULES_ textattr(DOS_COLOR); #endif } #endif } /****************************************************************************/ void puts_dos (const char far *str) { char c; while((c=*str++)!='$') putch(c); } /****************************************************************************/ void interrupt Int27(void) /* TSR */ { TSR=1; Int20(); } /****************************************************************************/ void interrupt Int20(void) { if (aPSP) if (TSR==0) free((void far *)aPSP); longjmp(return_point, 0); } /****************************************************************************/ void interrupt Int23(void) { printf("\bBREAK\n"); Int20(); } /****************************************************************************/ void interrupt Int24(void) { printf("\bFatal error\n"); Int20(); } /****************************************************************************/ void interrupt Int29(void) { printf("Int29 called\n"); } /****************************************************************************/ void interrupt Int21(void) { char huge * Pointer; char far * far_ptr, far * far_ptr2; unsigned long ll; DIR far *d; struct dirent far * Rec; char *cc; unsigned int iax, ibx, icx, idx, ids, ies, isi, ifl, i, dos_fn; void interrupt (*Vec) (void); struct DTAfind far * DTA2; /* flags ; [BP+22] From [HelpPC]: │11│10│F│E│D│C│B│A│9│8│7│6│5│4│3│2│1│0│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─── CF Carry Flag │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─── 1 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─── PF Parity Flag │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─── 0 │ │ │ │ │ │ │ │ │ │ │ │ │ └─── AF Auxiliary Flag │ │ │ │ │ │ │ │ │ │ │ │ └─── 0 │ │ │ │ │ │ │ │ │ │ │ └─── ZF Zero Flag │ │ │ │ │ │ │ │ │ │ └─── SF Sign Flag │ │ │ │ │ │ │ │ │ └─── TF Trap Flag (Single Step) │ │ │ │ │ │ │ │ └─── IF Interrupt Flag │ │ │ │ │ │ │ └─── DF Direction Flag │ │ │ │ │ │ └─── OF Overflow flag │ │ │ │ └─┴─── IOPL I/O Privilege Level (286+ only) │ │ │ └───── NT Nested Task Flag (286+ only) │ │ └───── 0 │ └───── RF Resume Flag (386+ only) └────── VM Virtual Mode Flag (386+ only) return addr ; offset == [BP+20] ; segment == [BP+18] push ax ; AX == [BP+16] push bx ; BX == [BP+14] push cx ; CX == [BP+12] push dx ; DX == [BP+10] push es ; ES == [BP+8] push ds ; DS == [BP+6] push si ; SI == [BP+4] push di ; DI == [BP+2] push bp ; BP == [BP] mov bp,DGROUP mov DS,bp mov bp,sp sub sp,6 */ asm mov iax,ax; asm mov ibx,bx; asm mov icx,cx; asm mov idx,dx; asm mov ies,es; asm mov isi,si; asm mov ax,word ptr [BP+22]; asm mov ifl,ax; asm mov ax,word ptr [BP+6]; asm mov ids,ax; dos_fn=(iax>>8)&0xFF; if (allow_dos_functions[dos_fn]) { if (msdos_verbose) if (verbose_dos_functions[dos_fn]) { #ifndef _HERCULES_ textattr(EMULATOR_COLOR); #endif dos_fn_man(dos_fn); #ifndef _HERCULES_ textattr(DOS_COLOR); #endif } switch (dos_fn) { case 1: i=getch(); putch(i); asm mov ax,i; asm mov byte ptr [BP+16],al; break; case 2: putch((char)idx); break; case 6: if (((unsigned char)idx)==0xFFU) { if (kbhit()) { /* ZF = 0 */ ifl=ifl & ~0x40; asm mov ax,ifl; asm mov word ptr [BP+22],ax; i=getch(); asm mov ax,i; asm mov byte ptr [BP+16],al; } else { /* ZF = 1 */ ifl=ifl | 0x40; asm mov ax,ifl; asm mov word ptr [BP+22],ax; } } else putch((char)idx); break; case 7: case 8: i=getch(); asm mov ax,i; asm mov byte ptr [BP+16],al; break; case 9: puts_dos(MK_FP(ids,idx)); break; case 0xB: if (kbhit()) i=0xFF; else i=0; asm mov ax,i; asm mov byte ptr [BP+16],al; break; case 0xE: /* */ asm mov byte ptr [BP+16],3; break; case 0x19:asm mov word ptr [BP+16],2; break; case 0x1A:DTAaddr=MK_FP(ids,idx); break; case 0x25:if (allow_change_int[(char)iax]) { if (msdos_verbose) printf(" int %02X vec ",(char)iax); setvect((char)iax,(void interrupt(*)(void))MK_FP(ids,idx)); } else if (msdos_verbose) printf("\nDisallow change int %02X vec",(char)iax); else ; break; case 0x29:/* Parse a Filename for FCB */ printf("Parse=%Fs\n",MK_FP(ids,isi)); break; case 0x2A:/* get date */ {struct date datep; getdate(&datep); i=datep.da_year; asm mov ax,i; asm mov word ptr [BP+12],ax; i=datep.da_day; asm mov ax,i; asm mov byte ptr [BP+10],al; i=datep.da_mon; asm mov ax,i; asm mov byte ptr [BP+11],al; } break; case 0x2B:/* set date */ /* nothing does */ asm mov byte ptr [BP+16],0; break; case 0x2C: /* get time */ {struct time timep; gettime(&timep); i=timep.ti_min; asm mov ax,i; asm mov byte ptr [BP+12],al; i=timep.ti_hour; asm mov ax,i; asm mov byte ptr [BP+13],al; i=timep.ti_sec; asm mov ax,i; asm mov byte ptr [BP+11],al; i=timep.ti_hund; asm mov ax,i; asm mov byte ptr [BP+10],al; } break; case 0x2F:i=FP_OFF(DTAaddr); asm mov ax,i; asm mov word ptr [BP+14],ax; i=FP_SEG(DTAaddr); asm mov ax,i; asm mov word ptr [BP+8],ax; break; case 0x30:i=((osminor*10)<<8)+osmajor; asm mov ax,i; asm mov word ptr [BP+16],ax; asm mov word ptr [BP+14],0; break; case 0x31:/* TSR */ TSR=1; printf("TSR\n"); Int20(); case 0x33:/* Get/set Ctrl-Break check & get boot drive */ switch ((char)iax) { case 1 : /* set Ctrl-Break checking flag */ osbreak=(char)idx; case 0 : /* get Ctrl-Break checking flag */ asm mov al,osbreak; asm mov byte ptr [BP+10],al; break; case 2 : /* set extended Ctrl-Break checking */ break; case 5 : /* get boot drive (DOS 4.x) */ asm mov byte ptr [BP+10],3; default:; } break; case 0x35:/* get vector */ if (msdos_verbose) printf(" int %02X vec ",(char)iax); Vec=getvect((char)iax); i=FP_SEG(Vec); asm mov ax,i; asm mov [BP+8],ax; i=FP_OFF(Vec); asm mov ax,i; asm mov [BP+14],ax; break; case 0x37:switch((char)iax) { case 2 : case 0 : asm mov byte ptr [BP+10],'-'; break; case 1 : case 3 : default: printf("DOS Fn 37, subfn=%02X\n",(char)iax); } break; case 0x38: #if 0 switch((char)iax) { case 0: /* get contry info */ asm mov word ptr [BP+16],0; /* err code=0 */ asm mov word ptr [BP+14],0; /* country code=0 */ /* ds:dx - contry info */ i=FP_OFF(&Ukraine); asm mov ax,i; asm mov word ptr [BP+10],ax; /* dx */ asm push DS; asm pop ax; asm mov word ptr [BP+6],ax; /* DS */ goto l_no_error; default:printf("Get/set country information. Fn=%i\n", (char)iax); } #endif break; case 0x3B:if (msdos_verbose) printf("chdir %Fs",MK_FP(ids,idx)); dosname2pix(str,MK_FP(ids,idx),STRLEN); if (chdir(str)==-1) goto l_error; goto l_no_error; case 0x3C:/* Create */ dosname2pix(str,MK_FP(ids,idx),100); if (msdos_verbose) { #ifndef _HERCULES_ textattr(EMULATOR_COLOR); #endif printf("`%s'\n",str); #ifndef _HERCULES_ textattr(DOS_COLOR); #endif } if ((i=open(str,O_WRONLY|O_CREAT))==-1U) {/* error */ l_error: asm mov word ptr [BP+16],1; /* errno=1 */ /* CF = 1 */ ifl=ifl | 1; asm mov ax,ifl; asm mov word ptr [BP+22],ax; } else {/* no error */ asm mov ax,i; asm mov [BP+16],ax; l_no_error: /* CF = 0 */ ifl=ifl & 0xFFFE; asm mov ax,ifl; asm mov word ptr [BP+22],ax; } break; case 0x3D:/* Open */ if (msdos_verbose) printf(" open. mode=%04X ",(char)iax); dosname2pix(str,MK_FP(ids,idx),100); switch ((char)iax) { case 1: i=O_WRONLY; break; case 2: i=O_RDWR; break; case 0: i=O_RDONLY; break; default:i=O_RDONLY; } if (msdos_verbose) { #ifndef _HERCULES_ textattr(EMULATOR_COLOR); #endif printf("`%s'\n",str); #ifndef _HERCULES_ textattr(DOS_COLOR); #endif } if ((i=open(str,i))==-1U) goto l_error; else {/* no error */ asm mov ax,i; asm mov [BP+16],ax; goto l_no_error; } case 0x3E:/* close */ switch(ibx) { case 0 : /* stdin */ case 1 : /* stdout */ case 2 : /* stderr */ case 3 : /* stdaux */ case 4 : /* stdprn */ printf("close handle 0-4\n"); default: ; } if (close(ibx)) goto l_error; else goto l_no_error; case 0x3F:/* read */ if (msdos_verbose) printf("read h=%i len=%i\n",ibx,icx); Pointer=MK_FP(ids,idx); switch(ibx) { case 0 : /* stdin */ for (i=0;i>16); asm mov ax,i; asm mov word ptr [BP+10],ax; goto l_no_error; } case 0x44:if (msdos_verbose) printf("IOCTL Fn=%02X handle=%04X\n",(char)iax,ibx); switch((char)iax) { case 0: switch (ibx) { case 0 : case 1 : case 2 :asm mov word ptr [BP+10],0x80d3; break; case 3 :asm mov word ptr [BP+10],0x80c0; break; case 4 :asm mov word ptr [BP+10],0xa0c0; break; default: asm mov word ptr [BP+10],3; } break; case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 0xa: case 0xb: case 0xc: case 0xd: case 0xe: case 0xf: #ifndef _HERCULES_ textattr(EMULATOR_COLOR); #endif printf("IOCTL Fn=%02X\n",(char)iax); #ifndef _HERCULES_ textattr(DOS_COLOR); #endif break; default : #ifndef _HERCULES_ textattr(EMULATOR_COLOR); #endif printf("IOCTL invalid Fn=%02X\n",(char)iax); #ifndef _HERCULES_ textattr(DOS_COLOR); #endif } goto l_no_error; case 0x47:if (getcwd(str,64)) goto l_error; else {/* no error */ strupr(str); for (i=1;i<64;i++)if (str[i]=='/') str[i]='\\'; #if 0 if (str[0]=='\\') strncpy(MK_FP(ids,isi),str+1,64); else strncpy(MK_FP(ids,isi),str,64); #endif asm mov ax,i; asm mov [BP+16],ax; goto l_no_error; } case 0x48:far_ptr=malloc(((long)ibx)<<4); i=FP_SEG(far_ptr); if (far_ptr==NULL) goto l_error; else {/* no error */ asm mov ax,i; asm mov [BP+16],ax; goto l_no_error; } case 0x49:if (msdos_verbose) printf("free %04X\n",ies); break; case 0x4A:/* sbrk */ if(realloc(MK_FP(ies,0),(long)ibx<<4)==NULL) goto l_error; else goto l_no_error; case 0x4E:/* Find First */ if (msdos_verbose) printf(" find first `%Fs'",MK_FP(ids,idx)); dosname2pix(str,MK_FP(ids,idx),STRLEN); cc=(char *)strstr(str,"*.*"); if (cc!=NULL) *cc=0; i=(int)strlen(str); if (i!=0) i--; if (i!=0) if (str[i]=='/') str[i]=0; if (str[0]==0) { if (msdos_verbose) printf("L1"); memcpy(str,".",2); } /* if (msdos_verbose) printf("=>`%s' ",str); */ if ((d=opendir(str))==NULL) goto l_error; ids=FP_SEG(DTAaddr); idx=FP_OFF(DTAaddr); case 0x4F:/* Find Next */ DTA2=MK_FP(ids,idx); while (1) { if ((Rec=readdir(d))==NULL) {closedir(d); goto l_error; } if ((Rec->d_name[0]!=0)&&(Rec->d_name[0]!=0xE5)) break; } DirToPath(Rec, str); strupr(str); strncpy(DTA2->filename,str,13); /* if (msdos_verbose) printf(" str=%s->%Fs ",str,DTA2->filename); */ DTA2->attr=Rec->Attr.U; goto l_no_error; case 0: iax=0; case 0x4C:TSR=0; Int20(); case 0x58:if ((char)iax) { if (!ibx) { printf("\nSet strategy - "); switch (ibx) { case 0 : printf("1st "); break; case 1 : printf("best "); break; case 2 : printf("last "); break; default: printf("? "); break; } } } else { if (msdos_verbose) printf("\nGet strategy"); asm mov word ptr [BP+16],0; } /* getch(); */ break; case 0x62:/* get PSP addr */ i=FP_SEG(aPSP); asm mov ax,i; asm mov word ptr [BP+14],ax; break; default :if (1 /*msdos_verbose*/) { #ifndef _HERCULES_ textattr(EMULATOR_COLOR); #endif printf("\nNot realized MSDOS Fn %02X ",dos_fn); dos_fn_man(dos_fn); #ifndef _HERCULES_ textattr(DOS_COLOR); #endif } } } else { #ifndef _HERCULES_ textattr(EMULATOR_COLOR); #endif printf("\nDisallow fn %02X ",dos_fn); dos_fn_man(dos_fn); #ifndef _HERCULES_ textattr(DOS_COLOR); #endif } if (msdos_pause) getch(); } src/command/key.c0100664000076500007650000000047207725644160013466 0ustar prool2prool2#include #include #include void main() { int i; printf("View Key Codes\n\nPress Ctrl-D for exit\n\n"); while(1) { i=getch(); printf("%i\n",i); switch(i) { case 4: printf("\n"); exit(0); /* case 0: i=getch(); printf("%i\n",i); */ } } } src/command/makefile0100664000076500007650000002444107725644160014234 0ustar prool2prool2# OS Proolix - library makefile # Use Turbo C 2.0 make TasmFlags = /w2 /t /q /ml /z /m4 # '-v+ -y+' is debug switches # TCFlag = -I..\include -DProolix -v+ -y+ TCFlag = -N- -I..\include -DProolix -wcln -wsig -wucp -wrvl -wamp -wamb -wnod \ -wpro -K TCFlag = $(TCFlag) -g1 -j1 CPPFlag = -I..\include -DProolix TC = \tc Kernel = ..\kernel Include = ..\include !include "makefile.1" .c.obj: tcc -mt -c $(TCFlag) $& .asm.obj: tasm $(TasmFlags) $& .c.asm: tcc -mt -c -S $(TCFlag) $& .c.i: cpp $(CPPFlag) $& all: lib1.lib uasm cp e ascii cat cat2 xonix kernel.ovl touch \ s page videomod key ls pg vred more setcolor banner beta \ ping help vec vmbr ce.obj p1 lib1.lib: $(Members) tlib.cmd cpuspeed.obj $(Kernel)\syserr.obj del lib1.lib tlib lib1 /C/E -+cpuspeed -+$(Kernel)\syserr @tlib.cmd,lib1.dic kernel.ovl: ovl.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 ovl,kernel.ovl,,lib1 $(Kernel)\cs0 $(Kernel)\kernel unarj: unarj.obj decode.obj environ.obj lib1.lib tlink /c/t/m/s/x c1 unarj decode environ,unarj.,,lib1 $(Kernel)\cs0 unarj.obj: unarj.c unarj.h tcc -mt -c $(TCFlag) -w-sig $& environ.obj: environ.c unarj.h tcc -mt -c $(TCFlag) -w-sig $& decode.obj: decode.c unarj.h cp: cp.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 $&,$&.,,lib1 cp.obj: cp.c ovl.obj: ovl.c $(Kernel)\kernel.h $(Include)\conf.c \ $(Include)\limits.h $(Include)\unistd.h $(Include)\prool.h tcc -mt -c -B $(TCFlag) $& xonix: xonix.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 $&,$&.,,lib1 xonix.obj: xonix.c fork: fork.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 $&,$&.,,lib1 fork.obj: fork.c ascii: ascii.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 $&,$&.,,lib1 ascii.obj: ascii.c gets: gets.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 $&,$&.,,lib1 gets.obj: gets.c $(Include)\conf.c cat2: cat2.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 $&,$&.,,lib1 cat2.obj: cat2.c hello: hello.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 $&,$&.,,lib1 hello.obj: hello.c hello.asm: hello.c cat: cat.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 $&,$&.,,lib1 $(Kernel)\cs0 cat.obj: cat.c cat.asm: cat.c touch: touch.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 $&,$&.,,lib1 touch.obj: touch.c e: e.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 $&,$&.,,lib1 e.obj: e.c ladder: ladder.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 $&,$&.,,lib1 ladder.obj: ladder.c uasm.obj: uasm.asm uasm: uasm.obj c1.obj tlink /c/t/m/s/x c1 $(Kernel)\regdump $(Kernel)\ohw \ $(Kernel)\ohb $(Kernel)\sayr $&,$&.,,lib1 a:\uasm: uasm copy uasm a:\uasm cpuspeed.obj: cpuspeed.asm UNIDEF.INC cpu_type.ash tasm /t/ml cpuspeed install: all mkdir a:\bin copy kernel.ovl a:\kernel.ovl copy *. a:\bin copy *.fnt a:\bin del a:\bin\makefile ############################################################################## ping: ping.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 $&,$&.,,lib1 ping.obj: ping.c tcc -mt -c -N- -I..\include -DProolix -wcln -wsig -wucp -wrvl -wamp -wamb -wnod \ -wpro $& # ping.asm: ping.c ping.lst: ping.asm tasm $(TasmFlags) /l ping.asm del ping.obj ############################################################################## t: t.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 $&,$&.,,lib1 t.obj: t.c t.asm: t.c t.lst: t.asm tasm $(TasmFlags) /l t.asm del t.obj ############################################################################## help: help.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 $&,$&.,,lib1 help.obj: help.c help.asm: help.c help.lst: help.asm tasm $(TasmFlags) /l help.asm del help.obj ############################################################################## beta: beta.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 $&,$&.,,lib1 beta.obj: beta.c beta.asm: beta.c beta.lst: beta.asm tasm $(TasmFlags) /l beta.asm del beta.obj ############################################################################## banner: banner.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 banner,banner.,,lib1 banner.obj: banner.c ############################################################################## more: more.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 more,more.,,lib1 more.obj: more.c ############################################################################## mse: mse.obj c1.obj lib1.lib $(Kernel)\setjmp.obj int21.obj dosfn.obj tlink /c/t/m/s/x c1 int21 dosfn $(Kernel)\setjmp $(Kernel)\d2p \ mse ,mse.,,lib1 $(Kernel)\cs0 mse.obj: mse.c mse.h tcc -mt -c -B $(TCFlag) $& int21.asm: int21.c mse.h tcc -mt -c -S $(TCFlag) $& int21.obj: int21.c tcc -mt -c -B $(TCFlag) $& ############################################################################## iostone: iostone.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 iostone,iostone.,,lib1 iostone.obj: iostone.c ############################################################################## setcolor: setcolor.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 setcolor,setcolor.,,lib1 setcolor.obj: setcolor.c ############################################################################## vec: vec.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 vec,vec.,,lib1 vec.obj: vec.c ############################################################################## m: m.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 m,m.,,lib1 m.obj: m.c chess: chess.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 chess,chess.,,lib1 chess.obj: chess.c vred: vred.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 vred,vred.,,lib1 vred.obj: vred.c ls: ls.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 ls,ls.,,lib1 $(Kernel)\kernel ls.obj: ls.c pg: pg.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 pg,pg.,,lib1 pg.obj: pg.c key: key.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 $&,$&.,,lib1 key.obj: key.c videomod: videomod.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 $&,$&.,,lib1 videomod.obj: videomod.c page: page.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 $&,$&.,,lib1 page.obj: page.c s: s.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 $&,$&.,,lib1 s.obj: s.c a:\kernel.ovl: kernel.ovl copy kernel.ovl a:\kernel.ovl c1.obj: c1.asm ce.obj: ce.asm arh arj: pix_kit.arj arj f pix_kit makefile -jm arj f pix_kit *.c -t1g arj f pix_kit -jm save: a:\pix_kit.arj a:\proolix.arj a:\pix_kit.arj: pix_kit.arj copy pix_kit.arj a:\pix_kit.arj a:\proolix.arj: ..\proolix.arj copy ..\proolix.arj a:\proolix.arj ..\proolix.arj: pix_kit.arj arj f ..\proolix -xfile_id.diz -xreadme.1st clean bak: del *.bak del *.map del *.tmp del *.lst del hello.asm del m.asm del m.obj del m.com del m.exe del *.dic del *.i del norton.ini del delete: clean pix_kit.arj arj f pix_kit -jm makefile arj f pix_kit -jm -d -xmakefile del tcpick.tcp disktest: arj t a:\pix_kit.arj arj t a:\proolix.arj reboot: reboot screen: xonix -NoWait ############################################################################## vmbr: vmbr.obj c1.obj lib1.lib out_os.obj tlink /c/t/m/s/x c1 vmbr out_os,vmbr.,,lib1 vmbr.obj: vmbr.c tcc -mt -c $(TCFlag) vmbr.c c:\bin\vmbr: vmbr copy vmbr c:\bin\vmbr out_os.obj: $(Kernel)\out_os.c $(ConfFiles) tcc -c -oout_os.obj $(TCFlag) $(Kernel)\out_os.c ############################################################################## bp: bp.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 bp ..\boot\bootrw,bp.,,lib1 $(Kernel)\cs0 bp.obj: ..\boot\bp.c tcc -mt -c $(TCFlag) ..\boot\bp.c c:\bin\bp: bp copy bp c:\bin\bp ############################################################################## p1: p1.obj c1.obj lib1.lib tlink /c/t/m/s c1 p1 $(Kernel)\regdump $(Kernel)\ohw \ $(Kernel)\sayr $(Kernel)\ohb,p1.,,lib1 $(Kernel)\cs0 p1.obj: p1.c tcc -mt -c -B $(TCFlag) p1.c c:\bin\p1: p1 copy p1 c:\bin\p1 ############################################################################## p2: p2.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 p2,p2.,,lib1 $(Kernel)\cs0 p2.obj: p2.c tcc -mt -c -B $(TCFlag) p2.c c:\bin\p2: p2 copy p2 c:\bin\p2 ############################################################################## p3: p3.obj c1.obj lib1.lib tlink /c/t/m/s/x c1 p3,p3.,,lib1 $(Kernel)\cs0 p3.obj: p3.c tcc -mt -c -B $(TCFlag) p3.c c:\bin\p3: p3 copy p3 c:\bin\p3 ############################################################################## src/command/mse.h0100664000076500007650000000336307725644160013471 0ustar prool2prool2#define ENV_SIZE 300 #define MAX_COMMAND_STRING 120 #define ARGV0LEN 13 #define STRLEN 100 #define DOS_MAJOR 3 #define DOS_MINOR 20 #define EMULATOR_COLOR 12 #define DOS_COLOR 7 #define INTERRUPT_TABLE_SIZE 256*4 #include void interrupt Int20(void); void interrupt Int21(void); void interrupt Int23(void); void interrupt Int24(void); void interrupt Int29(void); struct DTAfind { int dir_handle; char reserv [0x13]; char attr; int time; int date; long size; char filename [13]; }; struct country_structure { int date_time; /* 0 = month day year, hh:mm:ss (USA) 1 = day month year, hh:mm:ss (Europe) 2 = year month day, hh:mm:ss (Japan) */ char currency [5]; char thousands_sep [2]; char decimal_sep [2]; char date_sep [2]; char time_sep [2]; char currency_lead; /* 0 = symbol leads, without space 1 = symbol follows, without space 2 = symbol leads, one space 3 = symbol follows, one space 4 = symbol replace decimal separator */ char digital_after_dec; char time_format; /* Bit 0 = 0 12 hour clock = 1 24 hour clock */ long case_map_call; char asciiz_sep; char Reserved [10]; }; extern struct country_structure Ukraine; extern char far * pEnv; extern char allow_dos_functions [255]; extern char verbose_dos_functions [255]; extern char allow_change_int [255]; extern int msdos_verbose, msdos_pause; extern jmp_buf return_point; extern char huge *aPSP; extern char osmajor, osminor, osbreak; extern struct DTAfind far * DTAaddr; extern int TSR; src/command/ovl.c0100664000076500007650000001167607725644160013506 0ustar prool2prool2/* Kernel's overlay */ /* #define DEBUG */ #define ARGC 0 /* 0 1 */ #define FONT_LEN 4096 /* #define _DAYTIME_ */ /* daytime color scheme */ #include #include #include #include #include "..\kernel\kernel.h" #ifdef B_COOLWARE unsigned int Speed( unsigned short CPUid ); long CPU_Type(void); int Shift; long CPUFix; char *Processor [] = { "8088", "8086", "V20", "V30", "188", "186", "286", "386SX", "386DX", "386SL", "486SX", "486DX", "Cyrix 486", "486DLC", "P5", "Cyrix M1 (586)", "IMHO, 686 (P6, Pentium Pro)" }; char *CoProcessor [] = { "unknown", "unknown", "none", "Weitek 1167", "8087", "8087 + Weitek 1167", "unknown", "unknown", "80287", "80287 + Weitek 1167", "Cyrix 2C87", "Cyrix 2C87 + Weitek 1167", "80387", "80387 + Weitek 1167", "Cyrix 3C87", "Cyrix 3C87 + Weitek 1167", "486 internal", "486 internal + Weitek 1167", "Cyrix 4C87", "Cyrix 4C87 + Weitek 1167", "Intel 80287XL", "Intel 80287XL + Weitek 1167", "IIT 2C87", "IIT 2C87 + Weitek 1167", "IIT 3C87", "IIT 3C87 + Weitek 1167" }; #endif /****************************************************************************/ void main( #if ARGC int argc, char *argv[] #endif ) {int i; char hour, min, secund, flag; struct date d; struct time t; long l; int F; union REGS inregs; #ifndef CMOS long Tick; #endif #if defined(_VGA_) && CODETABLE==_RUSSIAN_ int font_lines; char *FontName; int h; #endif #if ARGC if (argc!=2) goto l; if (argv[1][0]!='\r') {l: printf("This is overlay. Not executable\n"); exit(1);} #endif #ifdef _HERCULES_ #ifdef _DAYTIME_ textattr(10); #else textattr(7); #endif #endif puts("Copyright (C) by Serge Pustovoitoff, http://prool.kharkov.org, prool@itl.net.ua\n" #if 0 "Proolix comes with ABSOLUTELY NO WARRANTY.\n\ This is free software, and you are welcome to redistribute it.\n\n\ E-mail support: FidoNet 2:461/35, Internet prool@itl.net.ua\n\ anonymous ftp://ftp.itl.net.ua/pub/proolix\n\ WWW http://prool.kharkov.org/proolix/\n\ Voice phone +380(572)206-574\n" #endif ""); #if 1 /* Numlock off */ asm mov ax,40h; asm mov es,ax; /* ES:=40h */ asm and byte ptr es:17h,0DFh; #endif printf("Scroll Lock - russian keyboard mode\n\ Alt-F1 -- Alt-F8 - switch videopages\n"); #ifdef CMOS /* puts("CMOS support enabled"); */ if (readRTC(&hour,&min,&secund,&flag)) { puts("FATAL ERROR: *** No CMOS !!! ***"); } else { #if 0 #if 0 printf("CMOS time "); printf("%2X:%2X:%2X flag= %i\n",hour,min,secund,flag); #endif char *Primary [4] = {"none or EGA/VGA","40 column color","80 column color","monochrome"}; outportb(0x70,0x14); i=(inportb(0x71) & 0x30)>>4; printf("CMOS: Primary display set %s\n",Primary[i]); #endif } #else ReadTick(&Tick,&flag); printf("Ticks %li flag=\n",Tick,flag); #endif #ifdef CLRSCR clrscr(); #endif getdate(&d); gettime(&t); printf("%2i-%02i-%02i %2i:%02i:%02i\n",d.da_day,d.da_mon,d.da_year+1980, t.ti_hour,t.ti_min,t.ti_sec); #ifdef B_COOLWARE F=(int)((((CPUFix*Shift)/Speed(6))+5L)/10L); l=CPU_Type(); printf("CPU: %s, %i MHz, ",Processor[(int)(l&0xFF)],F); printf((l&0xFF00)?"V86 mode":"real mode"); printf(", coprocessor: %s\n",CoProcessor[(int)((l&0xFF0000L)>>16)]); #endif #if defined(_HERCULES_) && defined(_VIDEO_GRAPH_) /* set Hercules to graph mode */ inregs.x.ax=8; inregs.x.flags=0; int86 (0x10, &inregs, &inregs); #endif /* set cursor */ inregs.x.ax=0x0100; inregs.x.cx=0x0C0D; inregs.x.flags=0; int86 (0x10, &inregs, &inregs); /* load russian font */ /* Portions Copyright (C) by G.Shepelev */ /* определить размер литерной матрицы */ #if defined(_VGA_) && CODETABLE==_RUSSIAN_ #if 0 /* font load worked witn bug!!! :((( */ font_lines=*(int far *)MK_FP(0x40,0x85); /* printf("Font size %i lines\n",i); */ switch (font_lines) { case 8: FontName="08.fnt"; break; case 14: FontName="14.fnt"; break; case 16: FontName="16.fnt"; break; default: printf("Invalid font size=%i lines\n",font_lines); } chdir(FONT_DIR); h=open(FontName,O_RDONLY); if (h!=-1) {char font_buf[FONT_LEN]; read(h,font_buf,FONT_LEN); close(h); _ES=_SS; _BH=font_lines; /* bh - число строк в матрице */ _BL=0; /* bl - номер банка знакогенератора */ _AX=0x1100; /* функция 0 - загрузка пользовательского шрифта */ _CX=256; /* число символов в таблице */ _DX=0; /* номер первого определяемого символа */ asm push bp; /* */ _BP=(int)font_buf; /* ES:BP - адрес таблицы */ asm int 10h; asm pop bp; } else printf("Can't open font file %s\n",FontName); #endif /* #if 0 */ #endif /* defined(_VGA_) && CODETABLE==_RUSSIAN_ */ chdir(HOME_DIR); }src/command/vec.c0100664000076500007650000000051007725644160013444 0ustar prool2prool2#include #include #include void OutIntVector (int i) {int far *ff; ff=MK_FP(0,i<<2); printf("%2x %4x:%4x\n",i,*(ff+1),*ff); } void main (int argc, char *argv[]) {int i; if (argc==2) { OutIntVector(htoi(argv[1])); return; } else for (i=0;i<256;i++) OutIntVector(i); } src/command/p3.c0100664000076500007650000000023607725644160013216 0ustar prool2prool2#include int main (void) {int i,j; j=0; while (1) { putch('3'); /* asm int 85H; */ for (i=0;i<30000;i++) j++; } return j; } src/command/page.c0100664000076500007650000000060307725644160013606 0ustar prool2prool2#include #include #include void main(int argc, char *argv[]) { union REGS regs; if (argc==1) { regs.h.ah=15; regs.x.flags=0; int86(0x10,®s,®s); printf("Current videomode = %i, page = %i\n",regs.h.al,regs.h.bh); } else { regs.h.ah=5; regs.h.al=atoi(argv[1]); regs.x.flags=0; int86(0x10,®s,®s); } } src/command/term.c0100664000076500007650000000120307725644160013636 0ustar prool2prool2/*---------------------------------------------------------------------------- T E R M I N A T O R ------------------------------------------------------------------------------ The terminal communication program for OS Proolix ------------------------------------------------------------------------------ Version 0.0.0 16-Oct-97 ------------------------------------------------------------------------------*/ #include int main (void) { int port; char str [80]; printf("terminator\n\n"); printf("Port no.? "); gets(str); scanf(str,"%i",&port); printf("port=%i\n",i); return 0; } src/command/tlib.cmd0100664000076500007650000000145607725644160014154 0ustar prool2prool2-+000-+001-+002-+003-+004-+005-+006-+007-+008-+009-+010-+011-+012-+013-+014 & -+015-+016-+017-+018-+019-+020-+021-+022-+023-+024-+025-+026-+027-+028-+029 & -+030-+031-+032-+033-+034-+035-+036-+037-+038-+039-+040-+041-+042-+043-+044 & -+045-+046-+047-+048-+049-+050-+051-+052-+053-+054-+055-+056-+057-+058-+059 & -+060-+061-+062-+063-+064-+065-+066-+067-+068-+069-+070-+071-+072-+073-+074 & -+075-+076-+077-+078-+079-+080-+081-+082-+083-+084-+085-+086-+087-+088-+089 & -+090-+091-+092-+093-+094-+095-+096-+097-+098-+099-+100-+101-+102-+103-+104 & -+105-+106-+107-+108-+109-+110-+111-+112-+113-+114-+115-+116-+117-+118-+119 & -+120-+121-+122-+123-+124-+125-+126-+127-+128-+129-+130-+131-+132-+133-+134 & -+135-+136-+137-+138-+139-+140-+141-+142-+143-+144-+145-+146-+147-+148-+149 & -+150-+151-+152-+153 src/command/unidef.inc0100664000076500007650000001273107725644160014500 0ustar prool2prool2;--------------------------------------------------------------------------- ; UNIDEF.INC B-coolWare Assembly Language Macro Definitions File ; ; Copyright (c) 1991,94 by B-coolWare. ; Written by Bobby Z. primarily for internal use. ; ; Last modified 27/01/94 ;--------------------------------------------------------------------------- __INC__ EQU 1 ; Do not redefine macros in include files ; Constants for Read- and WriteAbsoluteSectors macros FirstHD EQU 80h SecondHD EQU 81h FirstFD EQU 0 SecondFD EQU 1 ; File attribute constants Archive EQU 00h Normal EQU 20h ReadOnly EQU 01h Hidden EQU 02h SysFile EQU 04h VolumeID EQU 08h Directory EQU 10h AnyFile EQU 3Fh ; Open mode constants fmRead EQU 0 fmWrite EQU 1 fmReadWrite EQU 2 fmDenyReadWrite EQU 10h fmDenyWrite EQU 20h fmDenyRead EQU 30h fmDenyNone EQU 40h fmPrivate EQU 80h ; Type conversion constants _wp equ _bp equ _dp equ _wpcs equ _bpcs equ _dpcs equ _wpds equ _bpds equ _dpds equ _wpes equ _bpes equ _dpes equ ; Useful processor commands prefixes FarJump EQU 0EAh ; followed by dword immediate address FarCall EQU 09Ah ; followed by dword immediate address i386Break EQU 0F1h ; Generates INT 01 on 386+ CPUs ; lxx macros : load register xx with offset to Source lbx macro Source mov bx,offset Source endm ldx macro Source mov dx,offset Source endm ldi macro Source mov di,offset Source endm lsi macro Source mov si,offset Source endm ; clr macro Set register REG's value to 0 clr macro REG sub REG,REG endm ; PUSHALL Save all registers on stack PushAll macro ifdef __use_286__ push ds es pusha else push ds es ax bx cx dx si di bp endif endm ; POPALL Restore all registers PopAll macro ifdef __use_286__ popa pop es ds else pop bp di si dx cx bx ax es ds endif endm ; READCHAR Read character from keyboard ReadChar macro clr ax int 16h endm UpcaseMac macro LOCAL @@Ex cmp al,'a' jb @@Ex cmp al,'z' ja @@Ex and al,11011111B @@Ex: endm ; UPCASESTRMAC Converts string to uppercase. ; REG must be a register containing offset of string, DS should be a data seg ; MaxLen can be a register or an immediate value. The best usage is to define ; a proc with such text: ; ; xxxx proc ; UpcaseStrMac , ; ret ; endp ; and call it with parameters passed by registers or by stack if necessary. UpcaseStrMac macro REG,MaxLen LOCAL __LoopL push si di cx mov si,REG mov di,si ifdifi , mov cx,MaxLen endif __LoopL: lodsb UpcaseMac stosb loop __LoopL pop cx si di endm ; Allocate_Memory Allocate memory block with size SizeInBytes Allocate_Memory macro SizeInBytes ifdifi , mov bx,SizeInBytes endif ifdef __use_286__ shr bx,4 else mov cl,4 shr bx,cl endif inc bx mov ah,48h int 21h endm ; RELEASE_MEMORY Release memory block allocated by Allocate_Memory Release_Memory macro AllocatedSeg ifdifi , push es ifdifi , mov ax,AllocatedSeg endif mov es,ax endif mov ah,49h int 21h ifdifi , pop es endif endm ; MODIFY_BLOCK Modify memory block size Modify_Block macro BlockSeg,NewSizeInBytes ifdifi , push es mov ax,BlockSeg mov es,ax endif mov bx,NewSizeInBytes ifdef __use_286__ shr bx,4 else mov cl,4 shr bx,cl endif inc bx ;; Increasing to paragraph boundary mov ah,4Ah int 21h ifdifi , pop es endif endm OpenFile macro NamePtr,Mode ifnb if &Mode mov ax,3D00h+&Mode else mov ax,3D00h endif else mov ax,3D00h endif ifdifi , ldx endif int 21h endm CreateFile macro NamePtr,Attribute mov ah,3Ch ifnb if &Attribute mov cx,Attribute else clr cx endif endif ifdifi , ldx endif int 21h endm CloseFile macro Handle ifdifi , mov bx,Handle endif mov ah,3Eh int 21h endm ; New DOS 5.0 functions GetUMBLink EQU 5802h ; returns AL = 0 UMB usage disabled ; AL = 1 UMB usage enabled SetUMBLink EQU 5803h ; requires BX = 0 UMB usage disabled ; BX = 1 UMB usage enabled GetMemStrategy EQU 5800h ; returns strategy in AX ( see list below ) SetMemStrategy EQU 5801h ; requires strategy in BX ; New to DOS 5.0 UMBEnabled EQU 0001h UMBDisabled EQU 0000h FIRST_FIT_LOW EQU 0001h ; Allocate the lowest available block BEST_FIT_LOW EQU 0002h ; Allocate the best fitting block LAST_FIT_LOW EQU 0003h ; Allocate the highest available block ; New to DOS 5.0 FIRST_FIT_HIGHONLY EQU 0040h ; same as 0000h but for UMB only BEST_FIT_HIGHONLY EQU 0041h ; --"-- 0001h --"-- LAST_FIT_HIGHONLY EQU 0042h ; --"-- 0002h --"-- FIRST_FIT_HIGH EQU 0080h ; tries UMB first and uses conventional BEST_FIT_HIGH EQU 0081h ; memory if failed. All the rest is as LAST_FIT_HIGH EQU 0082h ; for 0,1,2 strats. GetUpperMemoryLink macro mov ax,GetUMBLink int 21h xchg bx,ax endm SetUpperMemoryLink macro Enable mov ax,SetUMBLink mov bx,Enable int 21h endm GetMemoryStrategy macro mov ax,GetMemStrategy int 21h endm SetMemoryStrategy macro Strategy mov ax,SetMemStrategy mov bx,Strategy int 21h endm src/command/vred.c0100664000076500007650000000105507725644160013634 0ustar prool2prool2#include #include #include #include void main(argc,argv) int argc; char *argv[]; {int h; printf("Vred - Very Restricted EDitor\n\n"); if (argc==1) { printf("Usage: vred \n\n"); exit(1); } if ((h=open(argv[1],O_WRONLY))==-1) {perror(argv[1]); exit(2); } printf("cat stdin to file `%s'\nCtrl-D - end of file\n\n",argv[1]); while(1) {char c; if ((c=getchar())==4) break; if (write(h,&c,1)!=1) break; } if (close(h)==-1) {perror(argv[1]); exit(2); } } src/command/readme.1st0100664000076500007650000001704707725644160014426 0ustar prool2prool2Proolix Development Kit - documentation (C) Serge Pustovoitoff, 1994-1999 1. Введение 2. Программирование на С в Пруликсе 3. Программирование на ассемблере в Пруликсе 4. Адаптация программ на С для ОС Пруликс Что делать, если у вас нет Turbo C 2.0 Как узнать, реализован ли данный системный вызов в Пруликсе 1. Введение Hаконец-то стало возможным написание программ специально для работы в среде Пруликса ! C-компилятора, ни gcc под Пруликсом еще нет, поэтому вместо трансляции программ необходима КРОСС-ТРАHСЛЯЦИЯ, или иначе говоря, трансляция на другой платформе, а именно в среде MS DOS, используя Turbo C 2.0. Hабор системных вызовов пока очень и очень невелик, но постоянно пополняется и сами системные вызовы совершенствуются. Я приглашаю всех желающих поучаствовать в написании утилит для Пруликса или заняться адаптацией к Пруликсу существующих программ. 2. Программирование на С в Пруликсе Файл hello.c - это пример программы на С, написанной для Пруликса. Как видите, это самая обычная С-программа, что и было моей целью - реализовать самый обычный стандартный С. Компиляция без Proolix headers невозможна, так как стандартные хидеры из Turbo C не подходят. (Так, во всех системных вызовах параметры char * заменены на char far *). Идеологией Пруликса является совместимость на уровне исходных текстов с MSDOS и UNIXом, а в идеале - с любой ОС или платформой, где есть компилятор С. Исходные тексты, написанные для Пруликса, будучи перекомпилированы в MSDOS или UNIXе, должны делать ТО ЖЕ САМОЕ. Как компилировать С-программы для Пруликса. Если вы разбираетесь в make- файлах, то все написано в файле makefile. Файлы: c1.obj - главный модуль С-программы, который вызывает функцию main() (в TurboC эти модули имеют имена вида c0.obj, например c0t.obj для модели памяти Tiny). В Пруликсе (временно?) все выполняемые программы имеют модель Tiny, т.е. занимают максимум 1 сегмент (64К). Обьединяя программы в конвейеры и используя распараллеливание (ни того ни другого пока не реализовано ;), можно создавать большие программные комплексы, поэтому необходимость создания выполнимых файлов с виртуальным адресным пространством 1М представляется пока сомнительной. c1.asm - исходный текст модуля c1.obj lib.lib - библиотека поддержки, содержащая заглушки для всех системных вызовов 000.asm и 001.asm - примеры двух первых заглушек 3. Программирование на ассемблере в Пруликсе Слабость набора системных вызовов, реализованных на данный момент, требует использования программ, написанных на ассемблере, что, собственно говоря, является некоторым отступлением от традиций UNIX, но что делать... Разумеется, ассемблерные утилиты будут непереносимы на другие платформы, но без них пока не обойтись. Файл uasm.asm - это пример программы на ассемблере, написанной для Пруликса. Обратите внимание, что главная программа строится в виде far процедуры и выход из нее осуществляется командой ret far. (В com-файлах для MSDOS по умолчанию была бы near-процедура с ret near). Связано это с тем, что вызов выполняемого модуля производится из ядра командой call far. C адреса Signature идет 5-байтовая сигнатура, по которой ядро Пруликса определяет выполимый бинарный файл (Кстати, в главном модуле для С - программе c1.asm сделано то же самое). В файле uasm в качестве примера моделируется системный вызов putch, как это сделал бы компилятор TurboC, компилируя для Пруликса программу на С (например, hello.c). Полезно откомпилировать hello.c в ассемблерный модуль hello.asm и сравнить с uasm.asm. Передача параметров системному вызову осуществляется так, как это делает компилятор TurboC, передавая параметры С-подпрограммам (функциям) через стек в обратном порядке. Именно поэтому для компиляции С- программ нужен только TurboC версии 2.0 (не ++ !), так как в ++ передача параметров может быть реализована по другому, а как на самом деле, я не знаю, так как не использовал BC++ компиляторы. Аналогичные проблемы касаются и других (не борландовских) Скомпиляторов. Zortech или Watcom или HighC возможно сделают более компактный код, но как там с параметрами??? Hе придется ли переделывать всю логику системных вызовов?! Кроме системных вызовов, в ассемблерных программах можно использовать прерывания ROM BIOS (int 10h, int 16h etc) и ячейки памяти ROM BIOS (0040:XXXX). Это тоже не совсем по правилам, ведь по идее пользовательский процесс должен осуществлять системные операции и ввод-вывод ТОЛЬКО через системные вызовы, но никак не в обход ядра. Замечание. Пруликс работает на голой машине, поэтому, разумеется ни о каком int 21h не может быть и речи! Кроме того, нет файла ibmbio.com (io.sys), который, как известно, расширяет некоторые BIOS-прерывания. Поэтому я подчеркиваю, в Пруликсе можно обращаться не к функциям BIOS, а к функциям именно ROM BIOS - т.е. именно к БИОСу, находящемуся в ПЗУ. Функции (или их расширения, реализованные в ibmbio.com, естественно, будут недоступны. 4. Адаптация программ на С для ОС Пруликс Простейший случай адаптации программ, написанных на языке С (и поэтому претендующих на переносимость) в другую ОС (в частности, Пруликс) заключается в их перекомпиляции (сборке) в этой новой операционной среде. Как я уже писал, компиляция программ для Пруликса производится в MSDOS командой make компилятора TurboC или bat-файлом cc. Если вам повезет, то программа нормально соберется в Пруликсе, а потом может быть заработает. В противном случае придется искать причину, почему же программа не собирается и устранять ее (причину), конечно, если она устранима. Как определить, что данный системный вызов в Пруликсе еще не написан? В этом случае у вас ошибка проявится только на стадии редактирования связей (линкования), осуществляемого программой tlink. После обнаружения списка отсуствующих системных вызовов, необходимо свериться с документацией по Пруликсу, где должен быть приведен список реализованных в данной версии вызовов. Затем вы можете попытать обойтись без данного вызова, заменив его чем-либо другим, параллельно вам стоит обратиться по электронной почте к узлам, занимающимся поддержкой Пруликса за новой версией этой ОС, где возможно будут реализованы новые возможности, в частности новые системные вызовы. Кроме того, надо обратиться к автору Пруликса (ко мне) и я, возможно, оперативно реализую необходимый вам системный вызов или помогу каким-либо другим образом. Что делать, если у вас нет такого старья, как TurboC, которым я пользуюсь? Попробуйте новые продукты фирмы Борланд, они imho должны сохранять преемственность со старыми. Многие решения в реализации Прулиха, особенно касающиеся интерфейса между машинно-зависимой частью, написанной на ассемблере и Сишной частью, обработки прерываний, передачи параметров etc связаны с реализацией всего этого в компиляторе (а именно в кодогенераторе) TurboC 2.0 и если уже в TC++ 1.0 это сделано не так, то ничего у вас с новыми компиляторами не получится. Я с интересом прочту сообщения о результатах сборки Пруликса под компиляторами, отличными от моего ТС 2.0. Возможно, вам удастся уговорить меня перейти на другой компилятор. Но, как вы сами понимаете, это все паллиатив, и рано или поздно придется в Пруликсе собирать свой cc (точнее, gcc ;) src/command/setcolor.c0100664000076500007650000000034107725644160014523 0ustar prool2prool2#include #include #include void main(int argc, char *argv[]) { if (argc==1) { printf("Current videoattr = %02X\n", getcolor()); } else { textattr(htoi(argv[1])); } } src/command/videomod.c0100664000076500007650000000056707725644160014511 0ustar prool2prool2#include #include #include void main(int argc, char *argv[]) { union REGS regs; if (argc==1) { regs.h.ah=15; regs.x.flags=0; int86(0x10,®s,®s); printf("Current videomode = 0x%02X, page = %i\n",regs.h.al,regs.h.bh); } else { regs.x.ax=htoi(argv[1]); regs.x.flags=0; int86(0x10,®s,®s); } } src/develop/0040775000076500007650000000000007725644236012556 5ustar prool2prool2src/develop/man.c0100664000076500007650000000336307725644235013476 0ustar prool2prool2/* Man utility for Proolix by Yurii Rashkovskii ( 2:461/11@fidonet.org, yrashk@antisocial.com ) 27.04.98 # Started (1st release) man 0.1 Thanks to Prool for his more.c sources. */ #include #include #include #include #define MAN "/usr/man/" #define MAX_LINE 24 #define STR_LEN 256 #define Proolix char man_d[120]; void getman(char *prog); void main(int argc,char *argv[]) {char str[120]; FILE far *fp; printf("man 0.1 utility, Copyright (c) 1998, Yurii Rashkovskii \n"); if (argc==1) getman("man"); else { strcpy(str,MAN); strcat(str,argv[1]); fp=fopen(str,"r"); if (fp==NULL) { setcolor(0x0F); printf("man: Unable to open %s (help file)\nPlease type 'man man' to get help\n",str); setcolor(0x07); } else { fgets(man_d,1,fp); man_d[29]=0; fclose(fp); getman(argv[1]); } } } void getman(char *prog) { {char str [STR_LEN]; char st[120]; FILE far *ff; int l, z,nl=1, counter=0; strcpy(st,MAN); strcat(st,prog); printf("man: listing %s%s\n",MAN,prog); if ((ff=fopen(st,"r"))==NULL) {printf("man: Can't open %s\n",prog);} else while (fgets(str,STR_LEN,ff)!=NULL) { l=(int)strlen(str); if (str[l-1]=='\n') str[l-1]=0; /* ohs(str); */ #ifdef Proolix if (str[0]==10) puts(str+1); else puts(str); #else puts(str); #endif counter++; if (++nl>MAX_LINE) { printf(" %% ( [ %s ] [%i] of [%i] [ ESC exits ])",man_d,counter-(MAX_LINE-1),counter); if (getchar()==27) { printf("\n"); break; } puts(""); nl=1; for (z=1;z<25;z++) printf("\n"); } } } }src/develop/makefile0100664000076500007650000000532507725644235014257 0ustar prool2prool2# OS Proolix - development kit makefile # Use Turbo C 2.0 make TasmFlags = /w2 /t /q /ml /z /m4 # '-v+ -y+' is debug switches # TCFlag = -I..\include -DProolix -v+ -y+ TCFlag = -N- -I..\include -DProolix -wcln -wsig -wucp -wrvl -wamp -wamb -wnod \ -wpro -K TCFlag = $(TCFlag) -g1 -j1 CPPFlag = -I..\include -DProolix TC = \tc Kernel = ..\kernel Include = ..\include .obj.com: tlink /c/t/m/s/x ..\command\c1 $&,$&,,..\command\lib1 $(Kernel)\cs0 .c.obj: tcc -ms -c $(TCFlag) $& .asm.obj: tasm $(TasmFlags) $& .c.asm: tcc -mt -c -S $(TCFlag) $& .c.i: cpp $(CPPFlag) $& all: hello he bpatch.com hc bpatch.com: bpatch.c tcc -mt -lt bpatch ############################################################################## # memory model small he: he.obj tlink /c/m/s/x ..\command\ce $&,$&.,,..\command\lib1 ..\kernel\cs0 bpatch he 0xAFDE he.obj: he.c tcc -ms -c $(TCFlag) $& he.asm: he.c tcc -ms -c -S $(TCFlag) $& ############################################################################## # memory model small hc: hc.obj tlink /c/m/s/x ..\command\ce $&,$&.,,..\command\lib1 cc0 bpatch hc 0xAFDE hc.obj: hc.c tcc -mc -c $(TCFlag) $& hc.asm: hc.c tcc -mc -c -S $(TCFlag) $& ############################################################################## hello: hello.obj tlink /c/t/m/s/x ..\command\c1 $&,$&.,,..\command\lib1 hello.obj: hello.c hello.asm: hello.c install: all copy hello a:\bin\hello copy he a:\bin\he copy hc a:\bin\hc clean: del *.bak del *.map del *.tmp del *.lst del hello.asm del m.asm del m.obj del m.com del m.exe del *.dic del *.i del norton.ini sh: sh.obj tlink /c/t/m/s/x ..\command\c1 $&,$&.,,..\command\lib1 sh.obj: sh.c zadroka.h $(Include)\conf.c $(Include)\limits.h \ $(Include)\unistd.h $(Include)\struct.h c:\bin\sh: sh copy sh c:\bin\sh t1: t1.obj tlink /c/t/m/s/x ..\command\c1 $&,$&.,,..\command\lib1 t1.obj: t1.c t2: t2.obj tlink /c/t/m/s/x ..\command\c1 $&,$&.,,..\command\lib1 t2.obj: t2.c src/develop/hello.c0100664000076500007650000000031707725644235014022 0ustar prool2prool2#include #include #include #include void main(void) { printf("Hello, world! Ver from 14.02.98, 17:05:03 "); printf("press any key\n"); getch(); exit(0); } src/develop/bpatch.c0100664000076500007650000000101107725644235014150 0ustar prool2prool2#include #include #include int main (int argc, char *argv[]) {int magick, h; if (argc!=3) { printf("usage: bpatch filename magick\n\n\ Par example: bpatch he 0xDEAF\n"); return 1; } sscanf(argv[2],"%X",&magick); printf("name=%s magick=%X",argv[1],magick); if ((h=open(argv[1],O_WRONLY))==-1) {printf("open error\n"); return 2; } if (write(h,&magick,2)!=2) {printf("write error\n"); return 3; } if (close(h)==-1) {printf("close error\n"); return 4; } return 0; } src/develop/files.bbs0100664000076500007650000000014307725644235014342 0ustar prool2prool2HELLO.C Hello, world! HE.C Hello, world! HC.C Hello, world! SH.C Proolix External Simply Shell src/develop/hc.c0100664000076500007650000000044607725644235013314 0ustar prool2prool2/* memory model compact */ #include #include #include #include char s1[]=" static string "; void main(void) { char s2[]=" dynamic string "; printf("Hello,\n"); printf(s1); printf(s2); printf("\npress any key\n"); getch(); exit(0); } src/develop/he.c0100664000076500007650000000044407725644235013314 0ustar prool2prool2/* memory model small */ #include #include #include #include char s1[]=" static string "; void main(void) { char s2[]=" dynamic string "; printf("Hello,\n"); printf(s1); printf(s2); printf("\npress any key\n"); getch(); exit(0); } src/develop/sh.c0100664000076500007650000000653207725644235013336 0ustar prool2prool2/* #define DEBUG */ #include #include #include #include #include #include #include #include "prool.h" #include "conf.c" #include "limits.h" #include "unistd.h" #include "struct.h" #include "zadroka.h" int p; int _argc; char far*_argv [MAX_ARG]; char str[MAX_LEN_STR]; char far * far * _env; char far* __env [MAX_ENV]; /*****************************************************************************/ void date (void) { struct date d; struct time t; getdate(&d); gettime(&t); printf("Date is %2i-%02i-%02i %2i:%02i:%02i\n\n", d.da_day,d.da_mon,d.da_year+1980, t.ti_hour,t.ti_min,t.ti_sec); } /*****************************************************************************/ void echo(void) {int i=1; while (_argv[i]) printf("%s ",_argv[i++]); } /*****************************************************************************/ void put_env(char far*far*_env) { int i; for (i=0; _env[i] != NULL; i++) { puts (_env[i]); } } /*****************************************************************************/ void ladder (void) {int i,j; for (;;) { for (i=0;i<80;i++) { for (j=0;jMAX_ARG) {printf("Too many arguments"); goto l2;} for(;(i 11. Теперь полный путь может занимать PATH_MAX символов (см. include/limits.h, сейчас =255 символов)) Version 0.1.0.29 17-Aug-97 Version 0.1.0.28 11-Jul-97 Version 0.1.0.27 30-Jun-97 Version 0.1.0.26 21-Jun-97 Version 0.1.0.25 9-Jun-97 в kernel.ovl добавлен загрузчик русских шрифтов (portions copyright by G. Shepelev) Version 0.1.0.26 31-May-97 Version 0.1.0.25 31-May-97 исправлен баг, возникавший в случае вызова read(h,buf,len) при len>1024 Version 0.1.0.24 21-May-97 Version 0.1.0.23 18-May-97 Version 0.1.0.23 17-May-97 Version 0.1.0.22 15-May-97 Version 0.1.0.21W 14-May-97 Version 0.1.0.20W 12-May-97 версии с суффиксом "W" собраны не дома, а на работе. Исправлена ошибка при работе с FAT > 64K Version 0.1.0.19 11-May-97 Version 0.1.0.17 2-May-97 Version 0.1.0.17 1-May-97 fixed case Cylinder>255 in HDD Version 0.1.0.16 30-Apr-97 Version 0.1.0.15 28-Apr-97 отловлен большой глюк в связи с тем, что ядро откомпилировано Turbo C 2.0 в модели памяти small, где должно быть DS=SS, а у меня было DS!=SS Version 0.1.0.14 28-Apr-97 Version 0.1.0.14 27-Apr-97 booted from A:, B:, C:, D:, etc... Version 0.1.0.13 26-Apr-97 Version 0.1.0.12 24-Apr-97 add system calls wherex(), wherey() Version 0.1.0.11 23-Apr-97 Version 0.1.0.10 21-Apr-97 Version 0.1.0.9 20-Apr-97 отловлен большой глюк с mov SP, ... (см. c0.asm от 20-Apr-97) Version 0.1.0.8 22-Mar-97 Version 0.1.0.8 21-Mar-97 Version 0.1.0.8 20-Mar-97 Version 0.1.0.7 19-Mar-97 Version 0.1.0.6 13-Mar-97 - проведен частичный аудит всех файлов на предмет копирайтов Version 0.1.0.5 9-Mar-97 Version 0.1.0.5 8-Mar-97 Version 0.1.0.4 3-Mar-97 Version 0.1.0.4 2-Mar-97 Version 0.1.0.4 1-Mar-97 Version 0.1.0.3 23-Feb-97 Version 0.1.0.2 17-Feb-97 Hачиная с версии 0.1.0.0 в Пруликсе, в ДОС-эмуляторе работает отладчик AFD-Pro (c) AdTec GmbH, 1987 Version 0.1.0.1 2-Feb-97 Version 0.1.0.1 1-Feb-97 Version 0.1.0.0 26-Jan-97 0.0.2.4 16-Oct-96 устранена ошибка: ранее вся работа с FAT (LinkClu()) делалась не с обеими копиями FAT 0.0.2.4 15-Oct-96 0.0.2.3 14-Oct-96 исправлена ошибка в связи с DS!=SS (см. src/kernel/c0.asm) 0.0.2.3 13-Oct-96 0.0.2.3 12-Oct-96 0.0.2.2 29-Sep-96 0.0.2.1 16-Sep-96 0.0.2.0 12-Sep-96 0.0.2.0 11-Sep-96 0.0.1.30 10-Jun-96 0.0.1.29 18-May-96 0.0.1.28 16-May-96 0.0.1.27 15-May-96 0.0.1.26 15-May-96 0.0.1.25 12-May-96 0.0.1.24 12-May-96 0.0.1.23 11-May-96 начал делать control-break 0.0.1.22 10-May-96 - fixed несколько bugs... 0.0.1.21 ??? 0.0.1.20 ??? 0.0.1.19 21-Apr-96 0.0.1.19 20-Apr-96 0.0.1.18 19-Apr-96 0.0.1.18 18-Apr-96 - создан Пруликс mailing list proolix@infocom.kharkov.ua 0.0.1.17 17-Apr-96 - собирал Пруликс на работе и затачивал его под винт с разделом формата DOS 4.0. axl написал для Пруликса шуточный ping (TCP/IP пока нет) 0.0.1.17 15-Apr-96 - исправлен баг в функции printf(), возникавший при использовании формата "%lu". исправлена функция ultoa() 0.0.1.17 14-Apr-96 0.0.1.17 13-Apr-96 - исправлен баг в функции getcwd() 0.0.1.16 11-Apr-96 10-Apr-96 7-Apr-96 - мой день рождения 0.0.1.15 6-Apr-96 0.0.1.15 5-Apr-96 - исправляю глюки при работе с винтом... 0.0.1.14 4-Apr-96 - заработал с винтом, правда глюкаво 0.0.1.13 3-Apr-96 0.0.1.13 31-Mar-96 0.0.1.12 30-Mar-96 0.0.1.12 27-Mar-96 - начал делать работу с винтом 0.0.1.12 26-Mar-96 0.0.1.12 25-Mar-96 предыдущая версия не грузилась с дискет с размером кластера 512к. Исправлено. Проверено на дискетах 3" (720k и 1.44 M) и 5" (360 K и 1.2 M) 0.0.1.11 24-Mar-96 0.0.1.11 22-Mar-96 0.0.1.10 21-Mar-96 0.0.1.9 20-Mar-96 0.0.1.8 19-Mar-96 0.0.1.7 18-Mar-96 0.0.1.6 17-Mar-96 ядро типа EXE в общем работает. Сделана упаковка ядра при помощи программы PKLITE by PKWARE Corp. 0.0.1.6 16-Mar-96 0.0.1.5 14-Mar-96 0.0.1.5 13-Mar-96 0.0.1.5 12-Mar-96 0.0.1.5 10-Mar-96 0.0.1.5 9-Mar-96 Boot-manager теперь может загружать не только ядро OS Proolix, но и другие автономные программы типа COM (например автономные игры Arcanoid (ar.com) и Last Mission (mission.com) из пакета Proolix Games (см. доку в каталоге games) 0.0.1.4 7-Mar-96 0.0.1.4 6-Mar-96 0.0.1.4 5-Mar-96 начал делать ядро типа EXE 0.0.1.4 27-Feb-96 промежуточный загрузчик, он же вторичный загрузчик, он же Boot Manager ver. 0.0.0.0 заработал !!! (грузит ядро типа COM) 0.0.1.4 26-Feb-96 0.0.1.4 25-Feb-96 0.0.1.4 22-Feb-96 0.0.1.4 21-Jan-96 0.0.1.4 20-Jan-96 0.0.1.4 19-Jan-96 0.0.1.4 15-Jan-96 0.0.1.4 11-Jan-96 0.0.1.4 10-Jan-96 начал делать промежуточный загрузчик /boot (до этого boot сектор версии 0.0.2.3 16-Sep-95 грузил прямо ядро (файл /kernel)). А теперь boot-сектор будет грузить промежуточный загручик /boot, а /boot будет грузить ядро /kernel 0.0.1.3 29-Dec-95 0.0.1.3 28-Dec-95 0.0.1.2 27-Dec-95 - fork() ??? 0.0.1.1 25-Dec-95 - zarabotal perviy variant novogo systemnogo vyzova exec() 0.0.1.1 24-Dec-95 0.0.1.0 14-Dec-95 HОВЫЙ ЭТАП В ПРУЛИКСЕ. Ранее я делал очень многое как в MSDOS. Теперь многие части переделываются для большей совместимости с идеологией UNIX. Вводится таблица процессов (struct processes в include/struct.h), процесс 1, сделан новый вариант syscall (с использованием таблицы процессов). Далее будут переписаны заново exec() и exit(). Будет написан fork(). Возможно сразу будет диспетчеризация по таймеру. Широко используются идеи Linux8086 by Chad Page, Minix, BSD, идеи, высказанные В.Hехаевым (vovik@glutton.uanet.kharkov.ua). Поставка Пруликса будет осуществляться одним файлом proolixN.arj (proolixN.z/proolixN.tgz), где N - последняя цифра номера версии (0.0.1.0 -> proolix0.arj, 0.0.1.1 -> proolix1.arj, 0.0.1.10 -> proolixa.arj etc). 0.0.0.112 13-Dec-95 11-Dec-95 - оказывается, Пруликс нормально грузится с винта 3" (720 и 1.44), с какой версии это началось, неизвестно, но текущая версия грузится нормально. Hа ftp выложены 3" образы image720.gz и image144.gz 0.0.0.111 10-Dec-95 - из функций групп mem.h и string.h убраны начальные проверки 'if (dest==NULL) return NULL'. Они мешали работать с таблицей векторов прерываний (адрес которой равен NULL). В Minix'е Таненбаума в аналогичных функциях тоже нет таких проверок. К тому же сэкономится немного памяти. (Ядро с проверками занимало 50820, а теперь - 50340, delta=480 bytes) 0.0.0.111 9-Dec-95 8-Dec-95 7-Dec-95 0.0.0.110 6-Dec-95 сд. images 360K и 1.2M, несущ. изм. в ls и Ls 5-Dec-95 сд. pix.tgz 20-Nov-95 19-Nov-95 Перенесены из Minix в Proolix хидеры ansi.h, утилиты: banner 15-Nov-95 0.0.0.109 12-Nov-95 - то же, что и 11-Nov-95, несущественные изменения в OS Proolix. В результате тестов установлено, что причина всех глюков - баги в модуле execve(). До адаптации модуля к EXE файлам (пока незаконченной) этих багов не было. (Адапьация к EXE файлам была начата в версии 0.0.0.102 от 23-Mar-95) 11-Nov-95 - экспериментировал с ядром Linux8086 0.00.3, пытался его собрать под ОС Minix, пытался собрать под Minix bcc (это подмножество gcc из Linux8086 0.00.3) 10-Nov-95 - отдал VGA карту. Теперь Proolix будет делаться на Геркулесе. ("Цветные" вызовы setcolor/getcolor отлажены ранее, на VGA) 0.0.0.108 8-Nov-95 0.0.0.107 8-Nov-95 0.0.0.106 7-Nov-95 - сд. команду more, испр. баг в ohs() 0.0.0.106 6-Nov-95 - возился со сборкой программы yap/more из ОС Minix. В Пруликсе нет curses и некоторых подпрограмм общего характера (signal(), wait() etc...) 0.0.0.106 5-Nov-95 - в программах группы printf при использовании буфера printf_buf, выделяемого по malloc, происходят зависания. А использование локального массива new_printf_buf (см. в printf.c), как и было раньше (до версии 0.0.0.106 7-Oct-95) работает нормально. 0.0.0.106 4-Nov-95 0.0.0.106 25-Oct-95 0.0.0.106 15-Oct-95 0.0.0.106 12-Oct-95 0.0.0.106 11-Oct-95 0.0.0.106 8-Oct-95 - переделаны ф-ции группы printf, дабы они исользовали буфер не из стека, а извне адресного пространства ядра. Драйвер консоли переписан на С. Виснет... :( 0.0.0.106 7-Oct-95 - опять создается впечатление, что функции группы printf очень сильно используют стек, стек наезжает на код и происходят глюки. (Код+стек занимает один сегмент - 64К, при превышении размера кода предел 55-56К и выводе длинных строк через printf начинают возникать непонятные глюки, которые исчезают, когда число printf и длина выводимых им строк уменьшаются). Hеобходимо переписать printf так, чтобы в качестве буферов для строк использовались не локальные массивы, размещающиеся в стеке, а массивы, выделяемые по alloc/malloc (это выделение происходит не из сегмента ядра, а из общего пула conventional memory и требует только far pointers) 0.0.0.106 1-Oct-95 - под Пруликсом заработали игры arcanoid и mission из дистрибутива ОС АТОМ Ивашинникова 0.0.0.106 28-Sep-95 0.0.0.106 24-Sep-95 - делал работу с винтом 0.0.0.107 24-Sep-95 - делал загрузку с винта 0.0.0.107 23-Sep-95 - делал загрузку с винта 0.0.0.107 22-Sep-95 - делал загрузку с винта 0.0.0.107 17-Sep-95 - делал загрузку с винта 0.0.0.107 16-Sep-95 - делал загрузку с винта 0.0.0.107 15-Sep-95 - делал загрузку с винта 0.0.0.107 3-Sep-95 - Сд. сис. вызов getcolor 0.0.0.107 1-Sep-95 - после перерыва опять взялся за Пруликс. Сд. сис. вызовы rand, srand, setcolor 0.0.0.106 6-Jun-95 0.0.0.105 25-May-95 0.0.0.105 14-May-95 0.0.0.104 14-May-95 0.0.0.104 23-Apr-95 0.0.0.104 19-Apr-95 0.0.0.104 16-Apr-95 0.0.0.104 10-Apr-95 0.0.0.104 6-Apr-95 0.0.0.103 25-Mar-95 - исправлена ошибка при cp /bin/e /1/ee malloc мoжет распределять блоки памяти более 64к 0.0.0.102 24-Mar-95 - исправлен баг в mkdir() 0.0.0.102 23-Mar-95 - для облегчения переноса GNU утилит и других утилит в Пруликс нужен формат .exe. Дело не только в том, что нек-рые утилиты не влезают в 64к. Все pointers (*), передаваемые системным вызовам ядра, должны быть far (far *). Чтобы не вбивать вручную везде слово far (FAR), лучше вести компиляцию утилит не в модели tiny, как раньше, а в модели compact, large или huge - а это даст не файл образа памяти .com (aka .bin aka .sav), а файл .exe Hачал делать работу с форматом .exe 0.0.0.101 19-Mar-95 0.0.0.101 18-Mar-95 0.0.0.101 17-Mar-95 - заработали нормально GNU rmdir & rm. Hачал делать ls 0.0.0.100 15-Mar-95 - продолжаю отлаживать GNU rmdir & rm 0.0.0.100 13-Mar-95 0.0.0.99 8-Mar-95 - собрались две первые GNU-утилиты - rm и rmdir. Обе не работают пока. Это вам не безотказный unarj ! 0.0.0.98 5-Mar-95 - Работа с подкаталогами вчерне уже сделана. fixed bug in open2() (case of open(".")). Сделан системный вызов rmdir(). Реализован поиск выполняемой программы по пути PATH 0.0.0.97 4-Mar-95 - испр. баг в open2(), сделанный вчера (the case of open("/dir/file")). Сделана функция openwdir 0.0.0.97 3-Mar-95 - исправлен баг. в close(), связанный с закрытием каталогов, fixed bug in mkdir() 0.0.0.96 27-Feb-95 - функция getcwd() и команда pwd работают правильно с подкаталогами, сд. функция и сис.вызов getenv, mkdir, команда md 0.0.0.96 26-Feb-95 - испр. баг в open2() при создании файла с неMSDOS именем, испр. баг в lseek(,0,SEEK_SET) 0.0.0.96 25-Feb-95 - исправлен баг в boot-секторе из-за которого любой файл с именем kernel и любым расширением считался ядром (и происходили конфликты между kernel и kernel.ovl). Hовый boots.asm имеет версию 0.0.2.1 25-Feb-95. Испр. баг в open2() (при создании файла) и в lseek() 0.0.0.95 23-Feb-95 - Внутренняя команда l и внешняя команда ls системные вызовы telldir и seekdir Переделана работа с корневым каталогом, открываемым как файл. MS DOS горбуха! В UNIX/POSIX ВСЕ каталоги аналогичны обычным файлам (в том числе и корневой), что обеспечивает стройность, ортогональность и легкость программирования. А в MSDOS корневой каталог уникален - это единственный каталог, который не является файлом (он имеет фиксированную длину, а не представлен цепочкой кластеров, как обычные файлы и обычные некорневые каталоги). Кроме того, в корневом каталоге MSDOS нет ссылок "." и "..", как в обычных каталогах. (Это вызывает еще одну проверку при попытке открыть файлы "." или ".." в случае, когда текущим является root ("/")). (Такая горбатость MSDOS является рудиментом MSDOS 1.0 aka CP/M-86). Сделал баг в open2() и тут же его исправил. 0.0.0.94 21-Feb-95 - пытался собрать zoo под Пруликс. Для zoo обьема 64К com-файла мало. Hадо делать в Пруликсе exe-модули. Пытался собрать GNU file utilities под Пруликс. Разобрался с их локальной библиотекой и с использованием header-files from BSDI UNIX и с параметрами POSIX_SOURCE etc. Для GNU-утилит в Пруликсе еще не все системные вызовы. Сделал external variable environ. 0.0.0.94 15-Feb-95 - внешняя команда `key` 0.0.0.94 13-Feb-95 - внешняя команда `s` (`string`), клманда управления трассировкой trace, внеш. команды page и videomod 0.0.0.94 12-Feb-95 - sys_errlist, modified perror(), удалено несколько багов в io.c stdio.c dir.c 0.0.0.94 11-Feb-95 - испр. баг в lseek(), в opendir() 0.0.0.94 9-Feb-95 - разработан метод выдачи трассировочной информации при отладочных прогонах программ Пруликса (с использованием стандартных средств Turbo C и препроцессора APP) 0.0.0.94 30-Jan-95 0.0.0.94 29-Jan-95 - сис вызов chdir макросы S_ISDIR, S_ISREG, S_ISLABEL 0.0.0.94 28-Jan-95 - сис вызов getcwd() 0.0.0.93 23-Jan-95 - переделал системное прерывание с 60h на 83h и сделал его определяемым в файле conf.c Удалены за ненадобностью системные вызовы и функции offset(), seg(), farptr() 0.0.0.92 22-Jan-95 - Поддержка графики Геркулеса я ядре (msherc.asm, msherc1.asm). Сис. вызов int86 0.0.0.92 21-Jan-95 - boot record и связанные с этим файлы выделены в отдельный каталог BOOT и в отдельный архив pix_boot.arj. Дизассемблировал msherc.com. Сисопка у Горляка в 16:00 0.0.0.92 19-Jan-95 - эксперименты со сборкой GNU утилит под Proolix. Еще рано, еще многое не реализовано (до полного POSIXа еще далеко, как минимум, еще надо дерево подкаталогов, драйверы, монтирование файловых систем, многопользовательскость (permissions) (пока можно и без многозадачности)) 0.0.0.91 16-Jan-95 - испр. баг в close(), в getftime и setftime, сд. команду touch 0.0.0.91 15-Jan-95 - в absread добавлен детальный вывод сообщения об ошибке. Испр. баг в printf("%s",NULL). Испр. ошибка с макрофайлами, отсуствующими в поставке ядра (теперь они присуствуют) {=Б} (так будут обозначаться ошибки, обнаруженные Белотицким) 0.0.0.91 14-Jan-95 - испр. баг в printf("%2X") и баг в de.c (diskeditor), и баг в read(), испр. БАГ В absread.c (NearBuffer сделан static и сразу пропала DMA error, происходящая при пересечении 64К границы), возможно, это именно тот баг, что упоминался в {0.0.0.86 16-Dec-94} (необьяснимый баг был во внутр. cp, а после превращения cp во внешнюю команду баг пропал) 0.0.0.91 13-Jan-95 0.0.0.91 12-Jan-95 - по совету Белотицкого сделан оверлей в ядре (для экономии места в резид. части ядра - выигран тем самым 1К) и добавлено определение типа проца 0.0.0.90 11-Jan-95 - исправлен баг в printf("%s"). Испр. еще баги в printf. Сд. формат %u, модификатор "-" ("%-10s") 0.0.0.89 10-Jan-95 - функции и сис. вызовы fgets, fputc, fputs, fread, fwrite, fprintf, vfprintf, ftell, fseek, fgetpos, fsetpos, rewind. Введены файлы с хандлерами 0, 1, 2 и потоки stdin, stdout, stderr. Hаконец-то под этой версией собрался unarj! И выдал заставку! 0.0.0.89 9-Jan-95 - функции и сис. вызовы _chmod, access Сделан по совету Белотицкого антивирусный контроль в boot-секторе (ver. 0.0.2.0 9-Jan-95, длина бута 493 bytes) и в начале ядра. Аналогичный контроль имеет ОС PTS DOS (см. [Hикитенко]) Hачал делать потоковый I/O (файл stream.c): функции и сис.вызовы fopen, freopen, fdopen, fileno, fgetc, fclose 0.0.0.89 8-Jan-95 - функции и сис. вызовы getftime, setftime, chmod 0.0.0.89 7-Jan-95 - испр. мааленький баг в ядре. Удалены за ненадобностью подпрограммы (и сис.вызовы) ohb/ohw/ohd, puti/putl. Все это может теперь printf 0.0.0.89 6-Jan-95 - испр. ош. в gets. Разработан механизм передачи глобальных переменных из ядра в юзерский процесс и обратно. См. errno в command\c1.asm, include\errno.h, kernel\klib.asm и хотя бы в open() (файл io.c). Функции (и системные вызовы) putch/putchar и getch/getchar сделаны идентичными Сделана глоб. переменная More, доступная из юзерских процессов, управляющая паузой при выводе на экран. Сд. внешняя команда setmore. Реализован параметр 'width' в функциях семейства printf 0.0.0.88 29-Dec-94 - исправлен "мигающий" баг в gets. (Т.е., такой баг, который уже появлялся, был исправлен, а потом опять возник из-за некоторых глобальных изменений (в данном случае, из-за переноса header-файлов в каталог, include, ОБЩИЙ для ядра и для утилит). Для различения компиляции ядра и компиляции утилит введена препроцессорная переменная KERNEL, определенная только во время компиляции ядра (см. ее в ядерном makefile и см. ее в stdio.h). Исправлен баг в atoi() Исправлено 2 бага в vsprintf(), которые влияли и на sprintf, vprintf, printf Исправлен баг в itoa()/ltoa() Испр. баг в printf Все вызовы функций puts0 и последующие ohw/puti etc регулярно заменены на аналогичные вызовы printf во всем ядре и утилитах Устранены за ненадобностью системные вызовы (и функции) puts0(см. макрос в stdio.h) и puti() Обнаружена возможность глюков из-за вывода слишком длинных строк в printf() и чрезмерно большого значения MAX_LEN_STR в limits.h 0.0.0.87 25-Dec-94 - системные вызовы printf, sprintf, vsprintf, vprintf, itoa, ltoa, ultoa. 0.0.0.87 24-Dec-94 - начал пакет printf: функция printf 0.0.0.87 23-Dec-94 - испр. баг в write (переход через сектор), и баг в absread/abswrite. Сделана внешняя команда cp, чем заклюгована ошибка во внутренней Cp. 0.0.0.86 18-Dec-94 - испр баг в AppendClu 0.0.0.86 17-Dec-94 - вся работа целого дня потеряна из-за того, что дочка (4 года) нажала F8-Enter ;) 0.0.0.86 16-Dec-94 - заклюгован баг в cp и de (RTFM "Press ENTER█") 0.0.0.86 15-Dec-94 - испр баги в open(), close(). Обнаружен непонятный глюк в команде cp и в de 0.0.0.85 14-Dec-94 - макросы abs, labs, сис. вызовы div, ldiv. Добавлены недостающие сис вызовы групп str* и mem*, а в уже существующих исправлены обнаруженные баги (см. string.c и mem.c). Сделана заглушка для сис вызова system() 0.0.0.84 13-Dec-94 - исправлен баг с копированием во вторую копию FAT, испр. баг в unlink(), испр. баг в msdos() (восст. стар. векторы перед горяч. загр. MSDOS, теперь MSDOS загружается командой msdos и при включенном таймере (см.файл msdos.asm)). Hаписана команда cp 0.0.0.84 12-Dec-94 - исправлены баги во write, open, close. Hаписаны unlink(), rename() и соотв. сис. вызовы и команды rm и mv 0.0.0.83 11-Dec-94 - запись на диск: abswrite, secwrite, WritePhysSec, флаги O_CREAT, O_WRONLY, O_RDWR в функции open, испр. ошибка в puti, функция write !!!, функции NewCashe, AppendClu, LinkClu 0.0.0.83 10-Dec-94 - оптимизирован алгоритм чтения файла в функции read(). заработала команда msdos (загрузка msdos с винчестера из среды Пруликса без открывания дисковода A:), команды mount и umount 0.0.0.83 9-Dec-94 - оптимизирован алгоритм чтения выполняемого файла в функции execve() и алгоритм работы с буферами-кешами 0.0.0.82 7-Dec-94 - internal command `buf`, отловлены глюки в алгоритме кеширования и сброса на диск самых редко используемых блоков 0.0.0.81 5-Dec-94 - сделано почти как в MSDOS. Пул из BUFFERS буферов. (#define BUFFERS см. в файле limits.h, в каталоге include, в архиве pix_incl.arj) 0.0.0.81 4-Dec-94 0.0.0.81 1-Dec-94 - вся работа с диском буферизована через кеш Cashe 0.0.0.81 29-Nov-94 0.0.0.81 27-Nov-94 - int.command timer, целая куча системных вызовов типа str* (string.h/string.c), isalpha (ctype.h/ctype.c), malloc/free, tell/lseek 0.0.0.81 26-Nov-94 - syscall raise(int sig) 0.0.0.80 21-Nov-94 0.0.0.80 20-Nov-94 0.0.0.80 19-Nov-94 - boot 0.0.1.4 19-Nov-94, изменения несущественны 0.0.0.79 13-Nov-94 - новый boot (boot.asm 0.0.1.2 13-Nov-94) работает !!! 0.0.0.78 8-Nov-94 - boot-сектор грузится по адресу 0:7c00, а ядро - начиная с 60:0, поэтому, если длина ядра близится к 30К, во время загрузки будет затираться boot-сектор в ОЗУ и загрузка прекратится. Поэтому делаю новый boot-сектор (ver. 0.0.1.0), который будет перемещаться во 2-ю половину таблицу прерываний и загружать ядро оттуда. (Hе забыть diskette parameter table!!!) Что-то не получается со 2-й половиной таблицы прерываний. Hа int f0 какой-то адрес вида F000:XXXX - что-то от BIOS. А я его порчу. Лучше буду гнать boot- сектор (ver. 0.0.1.1) куда нибудь за пространство ядра - в 1000:0500. 0.0.0.78 7-Nov-94 - ассемблерную подпрограмму SysCall (klib.asm), реализующую механизм системных вызовов, переписываю на С, потому что так надо. 0.0.0.78 6-Nov-94 - начата функция fork() 0.0.0.78 5-Nov-94 - команда ps 0.0.0.77 3-Nov-94 - немного исправлен boot-сектор (0.0.0.7 3-Nov-94), он теперь читает секторы несколько раз при ошибках (retrying) 0.0.0.76 26-Oct-94 - izmenen adres zagruzki v boots.asm (boots.asm ver.0.0.0.6 26-Oct-94) na PSP=50h (bilo PSP=70h). Gruzitsya i s 360K i s 1.2M (???!!!) Gipoteza: kogda kernel udlinitsya na 200h bytes - opyat' nachnutsya glucki :( 0.0.0.75 24-Oct-94 - исправлены некоторые баги и добавлены новые... теперь эта версия не грузится с 360К, хотя раньше грузилась. Hо грузится с 1.2М, хотя раньше не все версии грузились... ГДЕ БАГ ??? (С 3" gruzitsya, no gluckaet, hotya ran'she sovsem ne gruzilas') 0.0.0.74 23-Oct-94 - сис вызовы strchr, strcmp, strcpy, strncpy, strlen внешний шелл sh.com, fixed bugs in argc, argv & env params 0.0.0.73 20-Oct-94 - работа с датой, вывод даты в верх-левом углу экрана, сис вызовы gettime и getdate, команда date 0.0.0.72 18-Oct-94 - system call htoi 0.0.0.71 16-Oct-94 - gentbl закончен (imho) 0.0.0.70 14-Oct-94 - сделаны limits.h и unistd.h, согласно POSIXу errno (начато), lib1.lib (начато). Hачат генератор описаний системных вызовов (на ассемблер) по исходной таблице описаний (для ядра и для утилит): gentbl.c/gentbl.com - генератор, syscall.tbl - таблица сис.вызовов 0.0.0.69 12-Oct-94 - функции wherex(), wherey(), мигающий символ в углу - средствами BIOS - это должно идти на всех видеоадаптерах. Затем вместо мигающего символа в углу сделано время (из CMOSа) 0.0.0.68 8-Oct-94 0.0.0.67 6-Oct-94 - русифицирована клавиатура (не экран!), сделана ку- ча заглушек/ловушек на все прерывания, на которые только можно и даже на те, на которые нельзя, сделана обработка прерывания 8 и мигающий символ в углу (скр) - только на Геркулесе 0.0.0.66 5-Oct-94 - internal command 'ls' - modify & add flags -L -F -T -M - более изящно сделана обработка клавиши BackSpace в gets() 0.0.0.65 3-Oct-94 - env передается в порожденный процесс. Сделана внутр. команда "set". 0.0.0.64 26-Sep-94 - начата переделка исходников ядра так, чтобы все ссылки (указатели '*') были far (для единообразия и для более простой реализации системных вызовов). Вначале переделаны функции open/read и функции работы со строками. read немного оптимизирована по скорости 0.0.0.63 25-Sep-94 - команда de 0.0.0.62 24-Sep-94 - cat.com: флаги -H -M -A, сис.вызов strlen, файлы-устройства /dev/* 0.0.0.57 15-Sep-94 - внешние утилиты cat.com и crc.com, сис.вызовы perror, exit, getche 0.0.0.56 15-Sep-94 - сделана передача argc, argv в пользовательские процессы, ядро после загрузки запускает rc.com (если находит, конечно ;), сделана команда echo 0.0.0.51 12-Sep-94 - начал делать передачу argc, argv в пользовательские процессы 0.0.0.50 4-Sep-94 - 0.0.0.47 2-Sep-94 - первый Пруликс дома на машине 286, system call shutdown, fixed error in asm proc getch(), еще куча багов исправлена, в частности, перелопачен бут-сектор, адресное пространство ядра и пула динамической памяти etc. Hо с 3-дюймового диска не грузится (раньше грузилось). IMHO что-то с анализом цепочек кластеров (и раньше 'cat - H' больших файлов слишком быстро пробегал) Введена CRC ядра - она постоянно меняется !!!??? :( 0.0.0.45 19-Jul-94 - ls будет выдавать обьем диска, обьем занятого и свободного. С понедельника (вчера) на неделю я остаюсь на работе один, нужно форсировать Пруликс. Hи дня без версии ! 0.0.0.44 18-Jul-94 - fixed error in absread.c (после смены дискеты появлялась read error) 0.0.0.43 13-Jul-94 - system calls ohw, ohb, puti, fixed error in sh.c (когда ком. строка нач. с пробела - вся команда игнорировалась) 0.0.0.42 12-Jul-94 - system calls open, read, close, filelength, puts0, minus, заглушки для write, lseek, creat, dup 0.0.0.41 7-Jul-94 - забрали инстpументальную машину. Hа ней теперь Li- nux и пока ни моего аккоунта, ни VPIX'а :( Компиляю под DV на 2:461/35@FidoNet и отлаживаю под DV на 2:461/36 :( 0.0.0.40 5-Jul-94 - fixed err in ls.c (60 sec & 62 sec), history.doc 0.0.0.39 4-Jul-94 - fixed error on puti() (stdio.h) - output ** вместо 00 {XT забрали :( } 0.0.0.38 20-Jun-94 - обьединение двух 38-х версий 0.0.0.38 18-Jun-94 - первый Пруликс, откомпилированный дома, на XT/VGA, в субботу - заметьте, из-за моего глюка номер версии не изменился по сравнению с предыдущей, только дата поменялась 0.0.0.38 14-Jun-94 - изменен вызов exec_ и формат выполняемого файла - добавлена сигнатура и ее проверка 0.0.0.37 9-Jun-94 - испр ошибка при сис вызове с 0 числом параметров, во все асм-модули вставлена строка с датой компиляции и идентефикацией, переходящая в obj и в bin модуль 0.0.0.36 8-Jun-94 - заработал первый системный вызов putch('Y') с передачей N параметров из стека пользователя в стек ядра. (Файл hello.c - hello.com) Создана таблица системных вызовов. Теперь системные вызовы из С-подпрограмм (функций) с N параметрами будет делать несложно 0.0.0.35 7-Jun-94 - redko poluchaetsya sest' za Proolix :( Если операционная система Пруликс мешает работе, ну ее нафиг... эту работу ;) 0.0.0.34 3-May-94 - doskey Ver 0.0.0.2 3-May-94 0.0.0.33 2-May-94 - doskey by Игорь Cазонов, 2:461/61.99@Fido 0.0.0.32 2-May-94 - первый Прулих в фирме Infocom. 0.0.0.31 4-Mar-94 - последний Прулих в фирме SIA 0.0.0.30 2-Mar-94 - Lost 150 000 ukr. coupon :( 0.0.0.29 1-Mar-94 - touch *.* ;) 0.0.0.28 28-Feb-94 0.0.0.27 27-Feb-94 - принес на работу БК-0010. Fixed error in setvect() 0.0.0.26 24-Feb-94 0.0.0.25 23-Feb-94 0.0.0.24 22-Feb-94 - Proolix for mouse (XProolix) 0.0.0.23 14-Feb-94 0.0.0.22 11-Feb-94 - редко получается сесть за Прулих... :( Начаты тесты Прулиха под ОС/2 в режиме ДОС-сессии - глючит... (по вине OS/2, ее DOS-сессия не является виртуальной XT в полном смысле этого слова) 0.0.0.21 5-Feb-94 - int0 глючит... 0.0.0.20 4-Feb-94 - работаю без стендовой машины. медленно... :( ре- шил делать микроядро, не зная, что это такое ;) 0.0.0.19 31-Jan-94 - забрали стендовую машину - работа замедлится :( 0.0.0.13 12-Jan-94 - break key ('\b') 0.0.0.12 11-Jan-94 - alloc.h 0.0.0.8 26-Dec-93 - fixed error in ls, in puti до этого история не велась, но начало Пруликса приходится где-то на сентябрь 1993 (или чуть позже)src/files.bbs0100664000076500007650000000046007725642462012706 0ustar prool2prool2BM Boot Manager BOOT Boot sector COMMAND Commands & utilities KERNEL Kernel INCLUDE Includes (*.h) ANNOUNCE.DOC Announce (uncomplete) GIST.DOC Gistogramm HISTORY.DOC Proolix history (in Russian) FILES.BBS files descriptions src/include/0040775000076500007650000000000007725644350012540 5ustar prool2prool2src/include/conio.h0100664000076500007650000000202407725644347014021 0ustar prool2prool2/* conio.h Direct MSDOS console input/output. Copyright (c) Serge Pustovoitoff 1993-1997 */ #if !defined(__VIDEO) #define __VIDEO #define setcolor(c) textattr ((c)) #ifndef __OLDCONIO__ #define BLINK 128 /* blink bit */ #define Norm 2 /* Prool */ #define Inverse 0x70 /* Prool */ int getcolor (void); void clrscr (void); void gotoxy (int x, int y); void textattr (int newattr); void textbackground (int newcolor); void textcolor (int newcolor); void textmode (int newmode); int wherex (void); int wherey (void); #endif int getch (void); int getch0 (void); int getche (void); char * getpass (const char *prompt); int kbhit (void); int kbhit0 (void); int putch (int c); int ungetch (int ch); #endif src/include/setjmp.h0100664000076500007650000000144407725644350014213 0ustar prool2prool2/* setjmp.h Defines typedef and functions for setjmp/longjmp. Copyright (c) Serge Pustovoitoff 1996-1997 */ #ifndef _SETJMP #define _SETJMP typedef struct { unsigned j_sp; unsigned j_ss; unsigned j_flag; unsigned j_cs; unsigned j_ip; unsigned j_bp; unsigned j_di; unsigned j_es; unsigned j_si; unsigned j_ds; unsigned j_ax; /* proolix */ unsigned j_bx; /* proolix */ unsigned j_cx; /* proolix */ unsigned j_dx; /* proolix */ } jmp_buf[1]; void far longjmp (jmp_buf jmpb, int retval); int far setjmp (jmp_buf jmpb); #endif src/include/mem.h0100664000076500007650000000220007725644350013456 0ustar prool2prool2/* mem.h Memory manipulation functions Copyright (c) Serge Pustovoitoff 1994-1997 */ #ifndef _STDDEF #define _STDDEF #ifndef _SIZE_T #define _SIZE_T typedef unsigned long size_t; #endif #endif #ifndef NULL #if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__) #define NULL 0 #else #define NULL 0L #endif #endif void far * memccpy (void far *dest, const void far *src, int c, size_t n); void far * memchr (const void far *s, int c, size_t n); int memcmp (const void far *s1, const void far *s2, size_t n); void far * memcpy (void far *dest, const void far *src, size_t n); int memicmp (const void far *s1, const void far *s2, size_t n); void far * memmove (void far *dest, const void far *src, size_t n); void far * memset (void far *s, int c, size_t n); void movedata(unsigned srcseg, unsigned srcoff, unsigned dstseg, unsigned dstoff, size_t n); void movmem (void far *src, void far *dest, unsigned length); void setmem (void far *dest, unsigned length, char value); src/include/bios.h0100664000076500007650000000442307725644347013653 0ustar prool2prool2/* bios.h Access to bios services. Copyright (c) Serge Pustovoitoff 1993-1997 */ /* For Proolix only */ /* Interface to int 14h - BIOS comport I/O control */ #ifndef EXE unsigned char inicom_(unsigned int portid, unsigned char Par); #endif unsigned int getcom_(unsigned int Com1); unsigned int getcomstat_(unsigned int Com1); unsigned int putcom_(unsigned int Com1, unsigned char Symbol); int inicom(unsigned int portid, unsigned char Par); int getcom(int portid); /* Defines for use int 14h - com-port I/O */ #define Baud110 0x00 #define Baud150 0x20 #define Baud300 0x40 #define Baud600 0x60 #define Baud1200 0x80 #define Baud2400 0xa0 #define Baud4800 0xc0 #define Baud9600 0xe0 #define Bit7 2 #define Bit8 3 #define StopBit1 0 #define StopBit2 4 #define None 0 #define Even 0x18 /* чет */ #define Odd 8 /* нечет */ /* Из книги Фролов А.В.,Фролов Г.В. Программирование модемов.-М.:"ДИАЛОГ-МИФИ", 1993.-240с.-(Библиотека системного программиста; Т.4) Portions Copyright by А.В.Фролов, Г.В.Фролов, 1993. COM1, COM3 - IRQ4 (INT 0CH) COM2, COM4 - IRQ3 (INT 0BH) ICR IIDR LCR MCR LSR MSR Offset 1 2 3 4 5 6 COM1 3F8 3F9 3FA 3FB 3FC 3FD 3FF COM2 2F8 2F9 2FA 2FB 2FC 2FD 2FF COM3 3E8 3E9 3EA 3EB 3EC 3ED 3EF COM4 2E8 2E9 2EA 2EB 2EC 2ED 2EF ICR - interrupt control reg IIDR - interrupt identification reg LCR - control reg MCR - modem control reg LSR - line status reg MSR - modem status reg */ #define ICR 1 #define IIDR 2 #define LCR 3 #define MCR 4 #define LSR 5 #define MSR 6 #define UART_8250 1 #define UART_16450 2 #define UART_16550 3 #define UART_16550A 4 /* Defines for use RS-232 adaptor via iAPX86's I/O ports (IN & OUT processor's commands */ #define B110 1040 #define B150 768 #define B300 384 #define B600 192 #define B1200 96 #define B2400 48 #define B4800 24 #define B9600 12 #define B19200 6 #define B38400 3 #define B57600 2 #define B115200 1 /* 14 Kbyte per second */ /* Из книги OFF */ void new_video_page (char page); src/include/conf.c0100664000076500007650000000543607725644347013644 0ustar prool2prool2/* conf.c Configuration file for Proolix Copyright (c) Serge Pustovoitoff 1994-1997 */ /* Определение имени DOSKEY подключает написанный на ассемблере shell Сазонова с редактированием командной строки, отсуствие онного - ортодоксальный шелл, написанный мной на С (без редактирования, только с клавишей Break */ /* #define DOSKEY */ /* Аппаратура */ /* Если определено CMOS - значит, в машине есть CMOS и RTC - Real Time Clock (AT и старше, хотя бывают и XT с CMOS RTC ) */ #define CMOS /* Если DEBUG определено, то будет выдаваться отладочная информация */ /* #define DEBUG */ /* Если _RC_ определено, то при загрузке Пруликса будет выполняться файл _RC_ */ #define _RC_ "rc.com" /* перехват кучи прерываний - глючит (иначе оставляем значение вектора от ROM BIOS */ /* #define CHANGE_INTS */ /* перехват int 5 - глючит (иначе оставляем значение вектора от ROM BIOS */ /* #define CHANGE_INT5 */ /* перехват int 1B (ctrl-break) */ #define CHANGE_INT_1B /* очистка экрана при загрузке Пруликса */ /* #define CLRSCR */ /* Видеокарта */ #define _VGA_ /*_DEFAULT_VIDEO_ _MDA_ _HERCULES_ _CGA_ _EGA_ _VGA_ */ #ifdef _HERCULES_ /* #define _MSHERC_ */ /* Это виснет */ #endif /* Видеорежим */ #define _VIDEO_ASCII_ /* _VIDEO_ASCII_ _VIDEO_GRAPH_ */ /* Монитор цветной/монохромный */ #define _MON_COL_ /* _MON_COL_ _MON_MONO_ */ /* Адрес видео сегмента*/ #define VIDEO_SEG 0xB800 /* 0xB000 0xB800 */ /* putch */ #define PutchBIOS putch0 /* putch0 putch1 putch2 putch3 */ /* putch0 - asm-program, use int 10h Fn=E (emulate tty) putch1 - asm-program, use int 10h Fn=9 (put sym & attr) putch2 - asm-program (direct write to video RAM). putch2 maked from putch3 (compiled from C to asm manually (like manual sunset ;)) Debugged under MSDOS (into HCAT2 program). Worked under MSDOS. Not worked under Proolix putch3 - C-program (direct write to video RAM). Debugged under MSDOS (into HCAT program). Worked under MSDOS. Not worked under Proolix :( */ #if defined(_HERCULES_) && defined(_VIDEO_GRAPH_) #ifdef PutchBIOS #undef PutchBIOS #endif #define PutchBIOS putch1 #endif /* Proolix System Call Interrupt Number */ /* MSDOS have number 21h ! See [Interrupt List] for search free & unusable interrupt no */ /* #define INT_NO 0x83 */ /* Old syscall */ #define INT_NO 0x84 /* New syscall */ /* Use processor definition library by B-coolWare. Владимир Захарычев 2:5028/52.6 bob@ymz.yaroslavl.su */ /* #define B_COOLWARE */ #define HDD_READ_ONLY 0 /* 0 - HDD mounted read/write, 1 - HDD mounted read only */ #define LASTDRIVE 16 /* max drives */ #define _STANDARD_ 0 #define _RUSSIAN_ 1 #define CODETABLE _RUSSIAN_ #define FONT_DIR "/bin" #define HOME_DIR "/" src/include/ctype.h0100664000076500007650000000110507725644350014027 0ustar prool2prool2/* ctype.h Defines the ctype macros. Copyright (c) Serge Pustovoitoff 1993-1997 */ #define isascii(c) ((unsigned)(c) < 128) #define _toupper(c) ((c) + 'A' - 'a') #define _tolower(c) ((c) + 'a' - 'A') #define toascii(c) ((c) & 0x7f) int tolower(int ch); int toupper(int ch); int isgraph(int ch); int isprint(int ch); int isalnum (int); int isalpha (int); int iscntrl (int); int isdigit (int); int islower (int); int ispunct (int); int isspace (int); int isupper (int); int isxdigit(int); src/include/dirent.h0100664000076500007650000000332207725644350014173 0ustar prool2prool2/* dirent.h Copyright (c) Serge Pustovoitoff 1995-1997 */ #include #ifndef _DIRENT_H_ #define _DIRENT_H_ #ifndef _ATTRFIELD_ #define _ATTRFIELD_ struct AttrField { unsigned int ReadOnly : 1; unsigned int Hidden : 1; unsigned int System : 1; unsigned int Label : 1; unsigned int Dir : 1; unsigned int Archive : 1; unsigned int Attr2 : 1; unsigned int Attr1 : 1; }; union FileAttr { struct AttrField B; unsigned char U; }; #endif #ifndef _FTIME_ #define _FTIME_ struct ftime { unsigned ft_tsec : 5; /* Two second interval */ unsigned ft_min : 6; /* Minutes */ unsigned ft_hour : 5; /* Hours */ unsigned ft_day : 5; /* Days */ unsigned ft_month : 4; /* Months */ unsigned ft_year : 7; /* Year */ }; #endif #define d_ino d_fileno /* backward compatibility */ #define DIR FILE struct dirent { char d_name [11]; union FileAttr Attr; char Reserv [10]; struct ftime FileDateTime; unsigned int d_fileno; /* initial cluster number in MSDOS/Proolix file systems */ unsigned long int Size; }; DIR far *opendir (const char far *dirname); #ifdef KERNEL DIR far *openwdir (const char far *dirname); #endif DIR far *openidir (int inode); struct dirent far *readdir (const DIR far *dirp); #ifdef KERNEL int writedir (const DIR far *dirp, struct dirent far *D); #endif void rewinddir (const DIR far *dirp); int closedir (const DIR far *dirp); long telldir (const DIR far *dirp); long seekdir (const DIR far *dirp, long offset, int where); int dircmp (struct dirent d1, struct dirent d2); #endif /* !_DIRENT_H_ */ src/include/dos.h0100664000076500007650000001123607725644350013476 0ustar prool2prool2/* dos.h Defines structs, unions, macros, and functions for dealing with MSDOS and the Intel iAPX86 microprocessor family. Copyright (c) Serge Pustovoitoff 1993-1997 */ #if !defined(__TIME_DATE_) #define __TIME_DATE_ struct time { unsigned char ti_min; /* Minutes */ unsigned char ti_hour; /* Hours */ unsigned char ti_hund; /* Hundredths of seconds */ unsigned char ti_sec; /* Seconds */ }; struct date { int da_year; /* Year - 1980 */ char da_day; /* Day of the month */ char da_mon; /* Month (1 = Jan) */ }; #endif #if !defined(__DOS_DEF_) #define __DOS_DEF_ /* Variables */ extern int errno; extern char ** environ; extern char * sys_errlist[]; /* prool */ #define FAT12 0 #define FAT16 1 #define NO_FAT 2 #define FA_RDONLY 0x01 /* Read only attribute */ #define FA_HIDDEN 0x02 /* Hidden file */ #define FA_SYSTEM 0x04 /* System file */ #define FA_LABEL 0x08 /* Volume label */ #define FA_DIREC 0x10 /* Directory */ #define FA_ARCH 0x20 /* Archive */ #define FA_ATTR2 0x40 /* Proolix Attr No.2 */ #define FA_ATTR1 0x80 /* Proolix Attr No.1 - Proolix file */ struct WORDREGS { unsigned int ax, bx, cx, dx, si, di, cflag, flags; }; struct BYTEREGS { unsigned char al, ah, bl, bh, cl, ch, dl, dh; }; union REGS { struct WORDREGS x; struct BYTEREGS h; }; struct SREGS { unsigned int es; unsigned int cs; unsigned int ss; unsigned int ds; }; struct REGPACK { unsigned r_ax, r_bx, r_cx, r_dx; unsigned r_bp, r_si, r_di, r_ds, r_es, r_flags; }; #define FP_OFF(fp) ((unsigned)(fp)) #define FP_SEG(fp) ((unsigned)((unsigned long)(fp) >> 16)) #define MK_FP(seg,ofs) ((void far *) \ (((unsigned long)(seg) << 16) | (unsigned)(ofs))) int absread (int drive, int nsects, unsigned long lsect, void far *buffer); /* prool */ int abswrite(int drive, int nsects, unsigned long lsect, void far *buffer); /* prool */ long dostounix (struct date *d, struct time *t); void getdate (struct date far *datep); /* prool */ void gettime (struct time far *timep); /* prool */ void interrupt (* getvect(int interruptno)) (); /* void far * getvect (int VecNo); */ int inport (int portid); unsigned char inportb(int portid); int int86 (int intno, union REGS far *inregs, union REGS far *outregs); /* prool */ int int86x (int intno, union REGS *inregs, union REGS *outregs, struct SREGS *segregs); void intr (int intno, struct REGPACK *preg); void outport (int portid, int value); void outportb(int portid, unsigned char value); int peek (unsigned segment, unsigned offset); char peekb (unsigned segment, unsigned offset); void poke (unsigned segment, unsigned offset, int value); void pokeb (unsigned segment, unsigned offset, char value); void setdate (struct date *datep); void settime (struct time *timep); void setvect (int interruptno, void interrupt (*isr) ()); /* These are in-line functions. These prototypes just clean up some syntax checks and code generation. */ void __cli__ (void); void __sti__ (void); unsigned char __inportb__(int portid); void __outportb__ (int portid, unsigned char value); void __int__ (int interruptnum); #define disable() __cli__() /* Clear interrupt flag */ #define enable() __sti__() /* Set interrupt flag */ #define inportb(portid) __inportb__(portid) /* Byte IN instruction */ #define outportb(portid, v) __outportb__(portid,v)/* Byte OUT instruction */ #define geninterrupt(i) __int__(i) /* Interrupt instruction */ /* some other compilers use inp, outp for inportb, outportb */ #define inp(portid) inportb(portid) #define outp(portid,v) outportb(portid,v) #if !__STDC__ #define poke(a,b,c) (*((int far*)MK_FP((a),(b))) = (int)(c)) #define pokeb(a,b,c) (*((char far*)MK_FP((a),(b))) = (char)(c)) #define peek(a,b) (*((int far*)MK_FP((a),(b)))) #define peekb(a,b) (*((char far*)MK_FP((a),(b)))) #endif #endif src/include/dir.h0100664000076500007650000000166507725644350013474 0ustar prool2prool2/* dir.h Defines structures, macros, and functions for dealing with directories and pathnames. Copyright (c) Serge Pustovoitoff 1995-1997 */ #include #if !defined(__DIR_DEF_) #define __DIR_DEF_ struct ffblk { char ff_reserved[21]; char ff_attrib; unsigned ff_ftime; unsigned ff_fdate; long ff_fsize; char ff_name[13]; }; #define WILDCARDS 0x01 #define EXTENSION 0x02 #define FILENAME 0x04 #define DIRECTORY 0x08 #define DRIVE 0x10 int chdir (const char far *path); /* prool */ int getcurdir (int drive, char *directory); char far* getcwd (char far *buf, int buflen); int mkdir (const char far *path, mode_t mode);/*prool*/ int rmdir (const char far *path); /* prool */ #endif src/include/errno.h0100664000076500007650000000711507725644350014037 0ustar prool2prool2/* errno.h Defines the system error variable errno and the error numbers set by system calls. Copyright (c) Serge Pustovoitoff 1993-1997 */ /* Dos Error Codes */ #define EZERO 0 /* Error 0 - no error */ #define EINVFNC 1 /* Invalid function number */ #define ENOFILE 2 /* File not found */ #define ENOPATH 3 /* Path not found */ #define ECONTR 7 /* Memory blocks destroyed */ #define EINVMEM 9 /* Invalid memory block address */ #define EINVENV 10 /* Invalid environment */ #define EINVFMT 11 /* Invalid format */ #define EINVACC 12 /* Invalid access code */ #define EINVDAT 13 /* Invalid data */ #define EINVDRV 15 /* Invalid drive specified */ #define ECURDIR 16 /* Attempt to remove CurDir */ #define ENOTSAM 17 /* Not same device */ #define ENMFILE 18 /* No more files */ #define ENOENT 2 /* No such file or directory */ #define EMFILE 4 /* Too many open files */ #define EACCES 5 /* Permission denied */ #define EBADF 6 /* Bad file number */ #define ENOMEM 8 /* Not enough core */ #define ENODEV 15 /* No such device */ #define EINVAL 19 /* Invalid argument */ #define E2BIG 20 /* Arg list too long */ #define ENOEXEC 21 /* Exec format error */ #define EXDEV 22 /* Cross-device link */ #define EDOM 33 /* Math argument */ #define ERANGE 34 /* Result too large */ #define EEXIST 35 /* File already exists */ #define EFAULT 36 /* Unknown error, I/O error, Proolix error */ #define EPERM 37 /* UNIX and Proolix error */ #define ESRCH 38 /* UNIX and Proolix error */ #define EINTR 39 /* UNIX and Proolix error */ #define EIO 40 /* UNIX and Proolix error */ #define ENXIO 41 /* UNIX and Proolix error */ #define ECHILD 42 /* UNIX and Proolix error */ #define EAGAIN 43 /* UNIX and Proolix error */ #define ENOTBLK 44 /* UNIX and Proolix error */ #define EBUSY 45 /* UNIX and Proolix error */ #define ENOTDIR 46 /* UNIX and Proolix error */ #define EISDIR 47 /* UNIX and Proolix error */ #define ENFILE 48 /* UNIX and Proolix error */ #define ENOTTY 49 /* UNIX and Proolix error */ #define ETXTBSY 50 /* UNIX and Proolix error */ #define EFBIG 51 /* UNIX and Proolix error */ #define ENOSPC 52 /* UNIX and Proolix error */ #define ESPIPE 53 /* UNIX and Proolix error */ #define EROFS 54 /* UNIX and Proolix error */ #define EMLINK 55 /* UNIX and Proolix error */ #define EPIPE 56 /* UNIX and Proolix error */ #define EUCLEAN 57 /* UNIX and Proolix error */ #define _sys_nerr 57 /* highest defined system error number */ extern int errno; src/include/fcntl.h0100664000076500007650000000232607725644350014017 0ustar prool2prool2/* fcntl.h Define flag values accessible to open. Copyright (c) Serge Pustovoitoff 1993-1997 Portions Copyright (c) 1983, 1990 The Regents of the University of California. All rights reserved. */ #ifndef _FCNTL_H_ #define _FCNTL_H_ /* DOS Fn=3C Directory Attribute Flags │7│6│5│4│3│2│1│0│ Directory Attribute Flags │ │ │ │ │ │ │ └─── 1 = read only │ │ │ │ │ │ └──── 1 = hidden │ │ │ │ │ └───── 1 = system │ │ │ │ └────── 1 = volume label (exclusive) │ │ │ └─────── 1 = subdirectory │ │ └──────── 1 = archive └─┴───────── unused */ #define O_RDONLY 1 #define O_WRONLY 2 #define O_RDWR 4 #define O_CREAT 0x0100 /* create and open file */ #define O_TRUNC 0x0200 /* open with truncation */ #define O_EXCL 0x0400 /* exclusive open */ #define O_APPEND 0x0800 /* to end of file */ /* MSDOS special bits */ #define O_TEXT 0x4000 /* CR-LF translation */ #define O_BINARY 0x8000 /* no translation */ /* Proolix special flag */ #define O_FREOPEN 8 #endif /* !_FCNTL_H_ */ src/include/io.h0100664000076500007650000000472407725644350013324 0ustar prool2prool2/* io.h Definitions for low level I/O functions. Copyright (c) Serge Pustovoitoff 1994-1997 */ #ifndef _IO_H #define _IO_H 1 #ifndef _MODE_T /* prool */ #define _MODE_T typedef unsigned int mode_t; #endif #ifndef _FTIME_ #define _FTIME_ struct ftime { unsigned ft_tsec : 5; /* Two second interval */ unsigned ft_min : 6; /* Minutes */ unsigned ft_hour : 5; /* Hours */ unsigned ft_day : 5; /* Days */ unsigned ft_month : 4; /* Months */ unsigned ft_year : 7; /* Year */ }; #endif #define SEEK_CUR 1 #define SEEK_END 2 #define SEEK_SET 0 int access (const char far *path, int amode); /* prool */ int _chmod (const char far *path, int func, ... /* int attr */); /* prool */ int chmod (const char far *path, int amode); /* prool */ int chsize (int handle, long size); int _close (int handle); int close (int handle); int _creat (const char far *path, mode_t attribute); /* prool */ int creat (const char far *path, mode_t amode); /* prool */ int dup (int handle); int dup2 (int oldhandle, int newhandle); int eof (int handle); long filelength(int handle); int getftime (int handle, struct ftime far *ftimep); /* prool */ int ioctl (int handle, unsigned long func, ...); /* prool */ /* optional 3rd and 4th args are: void FAR * argdx, int argcx */ /* prool */ int isatty (int handle); long lseek (int handle, long offset, int fromwhere); int _open (const char far *path, int oflags); /* prool */ int open (const char far *path, int access,...); /* prool */ long int _read (int handle, void far *buf, unsigned long len);/*prool*/ long int read (int handle, void far *buf, unsigned long len);/*prool*/ int setftime (int handle, struct ftime far *ftimep); /* prool */ int setmode (int handle, int amode); long tell (int handle); unsigned umask (unsigned cmask); int unlink (const char far *path); int unlock (int handle, long offset, long length); long int _write(int handle, void far *buf, unsigned long len);/*prool*/ long int write(int handle, void far *buf, unsigned long len);/*prool*/ /* macros for compatibility with earlier versions & other compilers. */ #define sopen(path,access,shflag,mode) open (path, (access)|(shflag), mode) #endif /* _IO_H */ src/include/kbd.h0100664000076500007650000000167607725644350013460 0ustar prool2prool2/* kbd.h BIOS keyboard status Copyright (c) Serge Pustovoitoff 1999 */ #ifndef KBD_H #define KBD_H /* From [PC Help] BIOS keyboard flags (located in BIOSDataArea 40:17) │7│6│5│4│3│2│1│0│ │ │ │ │ │ │ │ └──── right shift key depressed │ │ │ │ │ │ └───── left shift key depressed │ │ │ │ │ └────── CTRL key depressed │ │ │ │ └─────── ALT key depressed │ │ │ └──────── scroll-lock is active │ │ └───────── num-lock is active │ └────────── caps-lock is active └─────────── insert is active */ #define R_SHIFT 1 #define RIGHT_SHIFT 1 #define L_SHIFT 2 #define LEFT_SHIFT 2 #define CTRL 4 #define CONTROL 4 #define ALT 8 #define SCROLL_LOCK 0x10 #define NUM_LOCK 0x20 #define CAPS_LOCK 0x40 #define INS 0x80 #define INSERT 0x80 #endif src/include/limits.h0100664000076500007650000000541707725644350014216 0ustar prool2prool2/* limits.h Defines implementation specific limits on type values. Copyright (c) Serge Pustovoitoff 1993-1998 */ #ifndef LIMITS_H #define LIMITS_H here /* Количественные ограничения в Пруликсе. В скобках - минимальное значение согласно стандарту POSIX */ #define ARG_MAX 4096 /* (4096) макс. длина списка аргументов и среды */ #define MAX_ENV 20 /* максимальное число переменных в среде */ #define CHAR_BIT 8 /* (8) макс число бит в данных типа char */ /* максимальное и минимальное знач данных типа char */ #if (((int)((char)0x80)) < 0) #define CHAR_MAX 0x7F #define CHAR_MIN 0x80 #else #define CHAR_MAX 0xFFU #define CHAR_MIN 0x00 #endif #define CHILD_MAX 6 /* (6) макс число одновр сущ процессов с одинак euid */ #define CLK_TCK 18 /* (10) число тиков в секунде */ /* On TurboC 2.0 #define CLK_TCK 18.2 */ #define INT_MAX 0x7FFF /* ( 32767) */ #define INT_MIN ((int)0x8000) /* (-32767) */ #define LINK_MAX 8 /* (8) макс число связей файла */ #define LONG_MAX 0x7FFFFFFFL /* ( 2147483647) */ #define LONG_MIN ((long)0x80000000L) /* (-2147483647) */ #define MAX_CANON 255 /* (255) макс число байт в канонич очереди терминала */ #define MAX_INPUT 255 /* (255) */ #define MB_CUR_MAX 2 /* (MB_LEN_MAX) */ #define MB_LEN_MAX 2 /* (1) */ #define NAME_MAX 14 /* (14) макс число байт в имени файла, не считая завершающего NUL */ #define NGROUPS_MAX 1 /* (0) */ #ifndef OPEN_MAX #define OPEN_MAX 16 /* (16) макс число одновр открытых файлов */ #endif #ifndef TMP_MAX #define TMP_MAX 25 /* (25) */ #endif #define PATH_MAX 255 /* (255) макс длина пути */ #define PIPE_BUF 512 /* (512) */ #define SCHAR_MAX 0x7F /* макс знач данных типа signed char */ #define SCHAR_MIN -128 /* мин. знач данных типа signed char */ #define SHRT_MAX 0x7FFF /* макс знач данных типа short */ #define SHRT_MIN ((int)0x8000) /* мин. знач данных типа short */ #define UCHAR_MAX 0xFFU /* макс знач данных типа unsigned char */ #define UINT_MAX 0xFFFFU /* ( 65535) */ #define ULONG_MAX 0xFFFFFFFFUL /* (4294967295) */ #define USHRT_MAX 0xFFFFU /* (65535) */ #define PROC_MAX 10 /* максимальное число процессов */ /* Мои собственные ограничения: */ /* Пруль - ограниченный человек ;) */ /* максимальная длина строки */ #define MAX_LEN_STR 256 #define PassLen 80 #define MAX_ARG 40 #define SECTOR_SIZE 512 #define FAT_SECS 7 #define MAX_LINE 24 #define RETRYES 15 #define BUFFERS 10 /* max 127. Макс. размер буферного пула - 64К, длина буфера 512+6=518 б, 64К % 518 = 127. */ /* Память, выделяемая каждому COM-файлу (параграфов) */ #define ComMemory 0x1000UL #endifsrc/include/prool.h0100664000076500007650000000215407725644350014043 0ustar prool2prool2/* prool.h Prool's Global Header Version 1.0.12 1-Nov-98 Copyright (c) Serge Pustovoitoff, 1993-1998 */ #define EMAIL "E-mail prool@itl.net.ua" /* #define IP */ #define FIDO "FidoNet 2:461/35" #define BBS "none" #define VOICE "Voice (work) +380(572)123445, 235102" #define WWW "http://www.infocom.kharkov.ua/~prool/proolix.html" #define ESC 27 #define CR '\r' #define LF '\n' #define ENTER 13 #ifndef NULL #define NULL 0l #endif /* #define TAB '\t' #define HT '\t' #define SP ' ' #define SPACE ' ' #define BEL '\7' #define BEEP '\7' #define VT 11 #define FF 12 #define SO 14 #define SI 15 #define DC2 18 #define DC4 20 #define CAN 24 #define DEL 127 #define BS 8 */ src/include/proto.h0100664000076500007650000000731407725644350014056 0ustar prool2prool2/* proto.h Proolix Kernel Internal Fuctions Prototypes Copyright (c) Serge Pustovoitoff 1996 */ void loop(void); int mshercinit(void); void saycsip (void); void reboot (void); int bootread0 (int Dev, void far * Buf); int bootread (int Dev, void far *Buf); int secread (int dev, unsigned long lsect /* 0 - first for C convention */, char *buf); int secwrite (int dev, unsigned long lsect, char *buf); int ReadPhysSec (unsigned char drive, unsigned char sec, unsigned char head, unsigned char trk, void *Buffer); int ReadPhysSec2 (unsigned char drive, unsigned char sec, unsigned char head, unsigned char trk /* or cyl */, void far *Buf); int WritePhysSec (unsigned char drive, unsigned char sec, unsigned char head, unsigned char trk, char *Buffer); void far *end (void); void msdos(void); void initv(void); unsigned char unpack(unsigned char c); int PathToDir(const char far *path, struct dirent far *Dir); char *DirToPath(struct dirent far *Dir, char *path); void interrupt far sh (void); void interrupt far msh (void); int FlushAll(void); int LoadCache (unsigned long sec); int NewCache (unsigned long sec); int garbage (void); int shutdown(void); void reboot (void); void msdos(void); void ident(void); int l (int argc, char far *argv[]); void rm(int argc, char far *argv[] ); void mv(int argc, char far *argv[] ); void cp(int argc, char far *argv[] ); void e(int argc, char far*argv[]); void mem(void); void memd(void); void cat (int argc, char far *argv[] ); void vec(int argc,char far *argv[]); void de (void); void mount(int NewDevice); void umount(void); unsigned com_address ( int portid ) ; int readRTC (char *Hour, char *Min, char *Sec, char *Flag); int readRTCdate (char *Century, char *Year, char *Month, char *Day); int ReadTick (unsigned long *Tick, char *Flag); void On (char *str); void Off (char *str); unsigned long SecForClu (unsigned int CluNo); unsigned int NextClu (unsigned int CluNo); unsigned int NextClu2 (unsigned int CluNo); int LinkClu (unsigned int CluNo, unsigned int NeXT); unsigned int GetFreeClu(void); unsigned int AppendClu(unsigned int CluNo); int CluRead (int drive, unsigned int CluNo, void far * buffer); int putch0 (int); int putch1 (int); int putch2 (int); int putch3 (int); int open2 (int h, const char far *path, int flag); void sched (void); int OutIntVector(int i); #ifndef exe_header #include #endif int ViewEXE (struct exe_header far *Buf); void outMBR(char far *buf); void interrupt done(void); void interrupt CtrlAltDel(void); void interrupt Int0(void); void interrupt Int1(void); void interrupt Int2(void); void interrupt Int3(void); void interrupt Int4(void); void interrupt Int6(void); void interrupt Int7(void); void interrupt Int8(void); void interrupt Int20(void); void interrupt Int21(void); void interrupt Int75(void); void init (void); void nulldev (void); void FDDstrategy (void); void HDDstrategy (void); int execpix(void far *mem0,int len); int execdos(void far *mem0,int len); void SysCall1(void); void Int5dump(void); /* Hа самом деле это - interrupt far функции. Hо для успешной сборки ядра в виде com-файла пришлось слукавить и вручную указать ядерный сегмент при назначении адреса программы перехвата. (См. ниже в соотв. вызовах setvect(INT_NO, ... ) */ void ps (void); unsigned int stackend (void); unsigned int kernel_begin (void); unsigned int mem_top(void); void interrupt SysCall2(); int TR (int curdev); void print_mount (void); void out_devices (void); char dos_letter(int); unsigned int par_size_of_block ( void far *); void exitw (void);src/include/psp.h0100664000076500007650000000462007725644350013512 0ustar prool2prool2/* psp.h Program Segment Prefix (PSP) structure Copyright (c) Serge Pustovoitoff 1997 */ struct sPSP { /* by Prool */ /* comments from [Help PC] */ int CD20; /* machine code INT 20 instruction (CDh 20h) */ unsigned int TopMemPar; /* top of memory in segment (paragraph) form */ char Reserved; /* reserved for DOS, usually 0 */ /* 5 bytes - machine code instruction long call to the DOS */ /* function dispatcher (obsolete CP/M) */ char op; /* cpm_offset or .COM programs bytes available in segment */ unsigned int Avail; unsigned int cpm_segment; unsigned long Int22; /* INT 22 terminate address; used by Proolix and MSDOS */ unsigned long Int23; /* INT 23 Ctrl-Break exit address; the original INT 23 */ /* vector is NOT restored from this pointer (IP,CS) */ unsigned long Int24; /* INT 24 critical error exit address; the original */ /* INT 24 vector is NOT restored from this field (IP,CS) */ unsigned int ParentSeg; /* parent process segment addr (Undoc. DOS 2.x+) */ /* COMMAND.COM has a parent id of zero, or its own PSP */ char aHandle [20]; /* file handle array (Undocumented DOS 2.x+); if handle */ /* array element is FF then handle is available. Network */ /* redirectors often indicate remotes files by setting */ /* these to values between 80-FE. */ unsigned int aEnv; /* segment address of the environment, or zero (DOS 2.x+) */ unsigned long SS_SP; /* SS:SP on entry to last INT 21 function (Undoc. 2.x+) */ unsigned int sHandle; /* handle array size (Undocumented DOS 3.x+) */ unsigned long pHandle; /* handle array pointer (Undocumented DOS 3.x+) */ unsigned long prevPSP; /* pointer to previous PSP (deflt FFFF:FFFF, Undoc 3.x+) */ char DOS401 [20]; /* unused in DOS before 4.01 */ char FnCB [3]; /* DOS function dispatcher CDh 21h CBh (Undoc. 3.x+) */ char Unused [9]; char FCB1 [16]; /* default unopened FCB #1 (parts overlayed by FCB #2) */ char FCB2 [20]; /* default unopened FCB #2 (overlays part of FCB #1) */ unsigned char cLine_ctr; /* count of characters in command tail; all bytes */ /* following command name; also default DTA (128 bytes) */ char cLine [127]; /* all characters entered after the program name followed */ /* by a CR byte */ }; src/include/psp.inc0100664000076500007650000000476307725644350014044 0ustar prool2prool2 ; struct sPSP { by Prool comments from [Help PC] ; original from dos.h CD20 dw ? ; machine code INT 20 instruction (CDh 20h) TopMemPar dw ? ; top of memory in segment (paragraph) form Reserved db ? ; reserved for DOS, usually 0 LongCall db 5 dup (?) ; machine code instruction long call to the DOS ; function dispatcher (obsolete CP/M) Avail dw ? ; .COM programs bytes available in segment (CP/M) Int22 dd ? ; INT 22 terminate address; used by Proolix and MSDOS Int23 dd ? ; INT 23 Ctrl-Break exit address; the original INT 23 ; vector is NOT restored from this pointer (IP,CS) Int24 dd ? ; INT 24 critical error exit address; the original ; INT 24 vector is NOT restored from this field (IP,CS) ParentSeg dw ? ; parent process segment addr (Undoc. DOS 2.x+) ; COMMAND.COM has a parent id of zero, or its own PSP aHandle db 20 dup (?) ; file handle array (Undocumented DOS 2.x+); if handle ; array element is FF then handle is available. Network ; redirectors often indicate remotes files by setting ; these to values between 80-FE. aEnv dw ? ; segment address of the environment, or zero (DOS 2.x+) SS_SP dd ? ; SS:SP on entry to last INT 21 function (Undoc. 2.x+) sHandle dw ? ; handle array size (Undocumented DOS 3.x+) pHandle dd ? ; handle array pointer (Undocumented DOS 3.x+) prevPSP dd ? ; pointer to previous PSP (deflt FFFF:FFFF, Undoc 3.x+) DOS401 db 20 dup (?) ; unused in DOS before 4.01 FnCB db 3 dup (?) ; DOS function dispatcher CDh 21h CBh (Undoc. 3.x+) LList dd ? ; Proolix: far address of LList structure ; DOS: unused Unused db 4 dup (?) ; DOS: unused FCB1 db 16 dup (?) ; default unopened FCB #1 (parts overlayed by FCB #2) FCB2 db 19 dup (?) ; default unopened FCB #2 (overlays part of FCB #1) cLine_ctr db ? ; count of characters in command tail; all bytes ; following command name; also default DTA (128 bytes) cLine db 127 dup (?) ; all characters entered after the program name followed ; by a CR byte src/include/stdlib.h0100664000076500007650000000641107725644350014171 0ustar prool2prool2/* stdlib.h Definitions for common types, variables, and functions. Copyright (c) Serge Pustovoitoff 1994-1997 */ #if !defined(__STDLIB) #define __STDLIB #ifndef _SIZE_T #define _SIZE_T typedef unsigned long size_t; #endif #ifndef _DIV_T #define _DIV_T typedef struct { int quot; int rem; } div_t; #endif #ifndef _LDIV_T #define _LDIV_T typedef struct { long quot; long rem; } ldiv_t; #endif /* Maximum value returned by "rand" function */ #define RAND_MAX 0x7FFF typedef void (* atexit_t)(void); int abs (int x); double atof (const char *s); int htoi (const char far *s); /* prool */ long int htol (const char far *s); /* prool */ int atoi (const char far *s); /* prool */ long atol (const char far *s); /* prool */ void far * calloc (size_t nitems, size_t size); /* prool */ div_t div (int numer, int denom); void exit (int status); void free (void far *block); /* prool */ char far * getenv (const char far *name); /* prool */ long labs (long x); ldiv_t ldiv (long numer, long denom); void far * malloc (size_t size); /* prool */ void qsort (void far *base, size_t nelem, size_t width,/*prool*/ int /**/ (far *fcmp) (/* const void far *, const void far * */)); int rand (void); void far * realloc(void far *block, size_t size); /* prool */ void srand (unsigned seed); double strtod (const char *s, char **endptr); long strtol (const char *s, char **endptr, int radix); int system (const char far *command); unsigned long strtoul (const char *s, char **endptr, int radix); #if !__STDC__ #ifndef NULL #if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__) #define NULL 0 #else #define NULL 0L #endif #endif /* Variables */ extern int errno; extern char ** environ; extern char * sys_errlist[]; /* prool */ #define abs(x) (((x) < (0)) ? (-(x)) : (x)) /* prool */ #define labs(x) (((x) < (0)) ? (-(x)) : (x)) /* prool */ #define max(a,b) (((a) > (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) #define random(num) (rand() % (num)) #define randomize() srand((unsigned)time(NULL)) char * ecvt (double value, int ndig, int *dec, int *sign); void _exit (int status); char * fcvt (double value, int ndig, int *dec, int *sign); char * gcvt (double value, int ndec, char *buf); char far * itoa (int value, char far *string, int radix); /* prool */ void * lfind (const void *key, const void *base, size_t *num, size_t width, int (*fcmp)(/* const void *, const void * */)); unsigned long _lrotl(unsigned long val, int count); unsigned long _lrotr(unsigned long val, int count); char far * ltoa (long value, char far *string, int radix); /* prool */ int putenv (const char *name); unsigned _rotl (unsigned value, int count); unsigned _rotr (unsigned value, int count); char far * ultoa (unsigned long value, char far *string, int radix); /* prool */ #endif #endif src/include/string.h0100664000076500007650000000447507725644350014226 0ustar prool2prool2/* string.h Definitions for memory and string functions. Copyright (c) Serge Pustovoitoff 1994-1997 */ #ifndef _SIZE_T #define _SIZE_T typedef unsigned long size_t; #endif void far * memccpy (void far *dest,const void far *src,int c, size_t n); void far * memchr (const void far *s, int c, size_t n); int memcmp (const void far *s1, const void far *s2, size_t n); void far * memcpy (void far *dest, const void far *src, size_t n); int memicmp (const void far *s1, const void far *s2, size_t n); void far * memmove (void far *dest, const void far *src, size_t n); void far * memset (void far *s, int c, size_t n); void movedata(unsigned srcseg, unsigned srcoff, unsigned dstseg, unsigned dstoff, size_t n); char far * stpcpy (char far *dest, const char far *src); char far * strcat (char far *dest, const char far *src); char far * strchr (const char far *s, int c); int strcmp (const char far*s1, const char far*s2); char far * strcpy (char far*dest, const char far*src); size_t strcspn (const char far *s1, const char far *s2); char far * strdup (const char far *s); char far * strerror(int errnum); int stricmp (const char far *s1, const char far *s2); size_t strlen (const char far *s); char far * strlwr (char far *s); char far * strncat (char far *dest, const char far *src, size_t maxlen); int strncmp (const char far *s1, const char far *s2, size_t maxlen); char far * strncpy (char far*dest, const char far*src, size_t maxlen); int strnicmp(const char far *s1, const char far *s2, size_t maxlen); char far * strnset (char far *s, int ch, size_t n); char far * strpbrk (const char far *s1, const char far *s2); char far * strrchr (const char far *s, int c); char far * strrev (char far *s); char far * strset (char far *s, int ch); size_t strspn (const char far *s1, const char far *s2); char far * strstr (const char far *s1, const char far *s2); char far * strtok (char far *s1, const char far *s2); char far * strupr (char far *s); char far * _strerror (const char far *s); /* compatibility with other compilers */ #define strcmpi(s1,s2) stricmp(s1,s2) #define strncmpi(s1,s2,n) strnicmp(s1,s2,n) src/include/struct.h0100664000076500007650000001214507725644350014235 0ustar prool2prool2/* struct.h Proolix Kernel structures (struct) Copyright (c) Serge Pustovoitoff 1994, 1995 */ #ifndef LIMITS_H #include "limits.h" #endif #ifndef _IO_H #include #endif #if !defined(__TIME_DATE_) #define __TIME_DATE_ struct time { unsigned char ti_min; /* Minutes */ unsigned char ti_hour; /* Hours */ unsigned char ti_hund; /* Hundredths of seconds */ unsigned char ti_sec; /* Seconds */ }; struct date { int da_year; /* Year - 1980 */ char da_day; /* Day of the month */ char da_mon; /* Month (1 = Jan) */ }; #endif #ifndef STRUCT_H #define STRUCT_H struct MemBlk { char Type; unsigned int OwnerPar; unsigned int SizePar; }; /* struct TimeField { unsigned int Sec2 : 5; unsigned int Min : 6; unsigned int Hour : 5; }; struct DateField { unsigned int Day : 5; unsigned int Month : 4; unsigned int Year : 7; }; */ struct BootStru { char Jmp [3]; char OEM [8]; int SectSiz; char ClustSiz; int ResSecs; char FatCnt; int RootSiz; unsigned int TotSecs; char Media; int FatSize; int TrkSecs; int HeadCnt; unsigned long HidnSec; unsigned long BigSect; char DriveNo; char Thing; char BootSign; int SerialNo [2]; char VolLbl [11]; char FileSysId [8]; /* int FATaddr; int StartClu; int RootSize; */ }; struct Partition_stru { unsigned char indicator; /* 00 - non-bootable partition 80 - bootable partition (one partition only) */ unsigned char begin_head; unsigned char begin_sec; /* and 2 high bits of cylinder # */ unsigned char begin_cyl; /* low order bits of cylinder # */ /* 2 bytes are combined to a word similar to INT 13: │7│6│5│4│3│2│1│0│ 1st byte (sector) │ │ └─┴─┴─┴─┴─┴── Sector offset within cylinder └─┴───────────── High order bits of cylinder # │7│6│5│4│3│2│1│0│ 2nd byte (cylinder) └─┴─┴─┴─┴─┴─┴───── Low order bits of cylinder # */ unsigned char system_indicator; unsigned char end_head; unsigned char end_sec; /* and 2 high bits of cylinder # */ unsigned char end_cyl; /* low order bits of cylinder # */ unsigned long preceding_sec; unsigned long total_sec; }; struct MBRstru { char master_boot_loader [0x1BE]; struct Partition_stru Partition [4]; unsigned int Signature; /* 55AA */ }; struct DevRecord { char *Name; int Major; int Minor; char Byte; /* 1 - byte-oriented device, 0 - block-oriented */ }; struct DevByte { void (*dev_open) (); void (*dev_close) (); void (*dev_read) (); void (*dev_write) (); void (*dev_ioctl) (); }; struct DevBlock { void (*dev_open) (); void (*dev_close) (); void (*dev_strategy) (); }; /* Структура таблицы процессов */ #include struct processes { int pid; int status; /* 1 - активен, 0 - неактивен (или ждет) */ int wait; /* pid процесса (отца), который ждет окончания этого процесса или 0, если никто не ждет */ jmp_buf control_point; char huge *mem0; }; /* элемент буферного пула */ struct BufPool { unsigned long Sec; unsigned int Status; /* Статус буфера: 0 - свободный, 1 - заполненный, 2 - измененный */ unsigned int Counter; unsigned char M [SECTOR_SIZE]; }; struct reloc { unsigned int offset; unsigned int segment; }; /* заголовок исполняемого EXE файла (как в MSDOS) */ struct exe_header { /* комментарии из [TECH Help!] */ char MZ[2]; /* "подпись" файла .EXE ('MZ') */ unsigned int PartPag; /* длина неполной последней страницы (обычно игнорируется) */ unsigned int PageCnt; /* длина образа в 512-байтовых страницах, включая заголовок */ unsigned int ReloCnt; /* число элементов в таблице перемещения */ unsigned int HdrSize; /* длина заголовка в 16-байтовых параграфах */ unsigned int MinMem; /* минимум требуемой памяти за концом программы (параграфы) */ unsigned int MaxMem; /* максимум требуемой памяти за концом программы (параграфы) */ unsigned int ReloSS; /* сегментное смещение сегмента стека (для установки SS) */ unsigned int ExeSP; /* значение регистра SP (указателя стека) при запуске */ unsigned int ChkSum; /* контрольная сумма (отрицательная сумма всех слов в файле) */ unsigned int ExeIP; /* значение регистра IP (указателя команд) при запуске */ unsigned int ReloCS; /* сегментное смещение кодового сегмента (для установки CS) */ unsigned int TablOff; /* смещение в файле 1-го элемента перемещения (часто 001cH) */ unsigned int Overlay; /* номер оверлея (0 для главного модуля) */ struct reloc RelTbl []; }; struct DeviceStruct { char FileSystem; int head; int sec; int trk; unsigned long ResSecs; unsigned long MaxSectors; char dos_disk; /* 'A' 'B' 'C' 'D' ... */ char system_indicator; }; #endif src/include/sys/0040775000076500007650000000000007725644350013356 5ustar prool2prool2src/include/sys/types.h0100664000076500007650000000202606312070064014652 0ustar prool2prool2/* types.h Types. Copyright (c) Serge Pustovoitoff 1994-1997 */ #ifndef __TIME_T #define __TIME_T typedef long time_t; #endif #ifndef _SIZE_T #define _SIZE_T typedef unsigned long size_t; #endif #ifndef _MODE_T /* prool */ #define _MODE_T typedef unsigned int mode_t; #endif #ifndef __CLOCK_T #define __CLOCK_T typedef long clock_t; #endif #ifndef _DIV_T #define _DIV_T typedef struct { int quot; int rem; } div_t; #endif #ifndef _LDIV_T #define _LDIV_T typedef struct { long quot; long rem; } ldiv_t; #endif #ifndef _TYPES_H /* prool */ #define _TYPES_H #ifndef _CC_T /* prool */ #define _CC_T typedef unsigned char cc_t; #endif typedef int dev_t; typedef int gid_t; typedef int ino_t; typedef unsigned nlink_t; typedef unsigned long off_t; typedef int pid_t; typedef void far *sigjmp_buf; typedef unsigned speed_t; typedef unsigned tcflag_t; typedef int uid_t; typedef unsigned wchar_t; #endif src/include/sys/tmp0100664000076500007650000000000007725644350014064 0ustar prool2prool2src/include/sys/stat.h0100664000076500007650000000651306312072130014462 0ustar prool2prool2/* stat.h Definitions used for file status functions Copyright (c) Serge Pustovoitoff 1995-1997 */ #include #ifndef _STAT_H #define _STAT_H 1 #define S_IFMT 0xF000 /* file type mask */ #define S_IFDIR 0x4000 /* directory */ #define S_IFIFO 0x1000 /* FIFO special */ #define S_IFCHR 0x2000 /* character special */ #define S_IFBLK 0x3000 /* block special */ #define S_IFREG 0x8000 /* or just 0x0000, regular */ #define S_IREAD 0x0100 /* owner may read */ #define S_IWRITE 0x0080 /* owner may write */ #define S_IEXEC 0x0040 /* owner may execute */ int fstat (int handle, struct stat far *statbuf); /* prool */ int stat (char far *path, struct stat far *statbuf); /* prool */ #define lstat stat #if 1 /* Modified by Prool */ #define S_ISDIR(m) (m & FA_DIREC) /* directory */ /* regular file */ #define S_ISREG(m) (!((m & FA_DIREC)||(m & FA_LABEL))) /* fifo: include both fifo and socket (pipe) */ #if 1 #define S_ISFIFO(m) (0) #define S_ISLNK(m) (0) /* symbolic link */ #define S_ISCHR(m) (0) /* char special */ #define S_ISBLK(m) (0) /* block special */ #define S_ISSOCK(m) (0) /* socket */ #endif #define S_ISLABEL(m) (m & FA_LABEL) /* device label */ /* * Current stat structure with larger uid/gid/dev fields; * still 32-bit offsets and sizes, so we reserve space to increase later. */ struct stat { dev_t st_dev; /* inode's device */ ino_t st_ino; /* inode's number */ mode_t st_mode; /* inode protection mode */ nlink_t st_nlink; /* number of hard links */ uid_t st_uid; /* user ID of the file's owner */ gid_t st_gid; /* group ID of the file's group */ dev_t st_rdev; /* device type */ #ifdef notyet struct timespec st_atimespec; /* time of last access */ struct timespec st_mtimespec; /* time of last data modification */ struct timespec st_ctimespec; /* time of last file status change */ #else time_t st_atime; /* time of last access */ long st_spare1; time_t st_mtime; /* time of last data modification */ long st_spare2; time_t st_ctime; /* time of last file status change */ long st_spare3; #endif off_t st_size; /* file size, in bytes */ long st_size1; /* reserved for st_size expansion */ long st_blocks; /* blocks allocated for file */ long st_blocks1; /* reserved for st_blocks expansion */ unsigned long st_blksize; /* optimal blocksize for I/O */ unsigned long st_flags; /* user defined flags for file */ unsigned long st_gen; /* file generation number */ long st_lspare; long st_qspare[2*2]; }; #endif int mkdir (const char far *path, mode_t mode); /* prool */ #endif /* _STAT_H */ src/include/unistd.h0100664000076500007650000000105507725644350014215 0ustar prool2prool2/* unistd.h Copyright (c) Serge Pustovoitoff 1994, 1995 */ #ifndef _UNISTD_H_ #define _UNISTD_H_ #include /* #define POSIX_JOB_CONTROL */ /* #define POSIX_SAVED_IDS */ /* #define POSIX_VERSION 199401L */ /* номер версии действ стандарта POSIX */ /* #define POSIX_CHOWN_RESTRICTED */ /* #define POSIX_NO_TRUNC */ /* Если это определено, то имена, содерж. более NAME_MAX символов означ. ошибку, ИHАЧЕ исп. только первые NAME_MAX символов имени */ /* #define POSIX_VDISABLE 0 */ #endif /* !_UNISTD_H_ */ src/include/stdio.h0100664000076500007650000001522007725644350014030 0ustar prool2prool2/* stdio.h Definitions for stream input/output. Copyright (c) Serge Pustovoitoff 1994-1997 */ #if !defined(__STDIO_DEF_) #define __STDIO_DEF_ #include #ifndef _FTIME_ #define _FTIME_ struct ftime { unsigned ft_tsec : 5; /* Two second interval */ unsigned ft_min : 6; /* Minutes */ unsigned ft_hour : 5; /* Hours */ unsigned ft_day : 5; /* Days */ unsigned ft_month : 4; /* Months */ unsigned ft_year : 7; /* Year */ }; #endif #ifndef _ATTRFIELD_ #define _ATTRFIELD_ struct AttrField { unsigned int ReadOnly : 1; unsigned int Hidden : 1; unsigned int System : 1; unsigned int Label : 1; unsigned int Dir : 1; unsigned int Archive : 1; unsigned int Attr2 : 1; unsigned int Attr1 : 1; }; union FileAttr { struct AttrField B; unsigned char U; }; #endif #ifndef _SIZE_T #define _SIZE_T typedef unsigned long size_t; #endif #ifndef NULL # if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__) # define NULL 0 # else # define NULL 0L # endif #endif #if !defined(__STDARG) #include #endif /* prool */ /* Definition of the control structure for streams */ typedef struct {char Name [NAME_MAX+1]; char File; /* file type: 0 - device driver, 1 - ordinary file, 2 - directory, 3 - MS DOS root directory */ /* int Major; int Minor; */ union FileAttr Attr; int flag; struct ftime FileDateTime; unsigned int BegClu; /* для обычных файлов и каталогов - начальный кластер, для специальных файлов - это номер спец. файла в таблице */ unsigned long int Size; unsigned int Drive; /* or filesystem */ /* номер inode (нач.кластера) каталога с записью об этом файле */ unsigned int DirInode; /* номер позиции записи об этом файле в каталоге (см. opendir() и seekdir() */ long DirSeekPos; unsigned int AbsClu; unsigned long AbsSec; unsigned long AbsOffset; char Buf [32]; } FILE; /* End-of-file constant definition */ #define EOF (-1) /* End of file indicator */ /* Constants to be used as 3rd argument for "fseek" function */ #define SEEK_CUR 1 #define SEEK_END 2 #define SEEK_SET 0 #if 1 /* prool */ extern FILE far *stdin ; extern FILE far *stdout; extern FILE far *stderr; #else /* Standard I/O predefined streams for MSDOS TurboC 2.0 */ extern FILE _streams[]; #define stdin (&_streams[0]) #define stdout (&_streams[1]) #define stderr (&_streams[2]) #define stdaux (&_streams[3]) #define stdprn (&_streams[4]) #endif void ohd (unsigned long int ll); /* prool */ void ohs (const char far *s); /* prool */ typedef long fpos_t; int fgetpos (FILE far *stream, fpos_t far *pos); /* prool */ int fsetpos (FILE far *stream, const fpos_t far *pos); /* prool */ int fclose (FILE far *stream); /* prool */ int fflush (FILE far *stream); /* prool */ int fgetc (FILE far *stream); /* prool */ FILE far* fopen (const char far *path, const char far *mode); /* prool */ int fprintf (FILE far *stream, const char far *format, ...); /* prool */ int fputc (int c, FILE far *stream); /* prool */ int fputs (const char far *s, FILE far *stream); /* prool */ size_t fread (void far *ptr, size_t size, size_t n, FILE far *stream); /* prool */ FILE far* freopen (const char far *path, const char far *mode, FILE far *stream); /* prool */ int fscanf (FILE *stream, const char *format, ...); int fseek (FILE far *stream, long offset, int wh); /* prool */ long ftell (FILE far *stream); /* prool */ size_t fwrite (const void far *ptr, size_t size, size_t n, FILE far *stream); /* prool */ #ifdef KERNEL /* proolix */ char * gets (char *s); char * fgets (char *s, int n, FILE far *stream); #else char far * gets (char far *s); char far * fgets (char far *s, int n, FILE far *stream); #endif char far* _gets (char far *s); /* prool */ void perror (const char far *s); /* prool */ int printf (const char far *format, ...); /* prool */ int puts (const char far *s); /* prool */ #define puts0(s) printf(s) /* Это для совместимости сПрулем (спрулем - это наречие) */ int Puts0 (const char far *str); /* Prool */ int puti (int w, int Prec, int Zeroes); /* prool */ int putl (long int w, int Prec, int Zeroes); /* prool */ int rename (const char far *oldname, const char far *newname); /* prool */ void rewind (FILE far *stream); /* prool */ int scanf (const char *format, ...); int sprintf (char far *buffer, const char far *format, ...); /* prool */ int sscanf (const char *buffer, const char *format, ...); char far* strerror (int errnum); int ungetc (int c, FILE *stream); int vfprintf (FILE *stream, const char *format, va_list arglist); /* prool */ int vfscanf (FILE *stream, const char *format, va_list arglist); int vprintf (const char far *format, va_list arglist); /* prool */ int vscanf (const char *format, va_list arglist); int vsprintf (char far *buffer, const char far *format, va_list arglist); /* prool */ int vsscanf (const char *buffer, const char *format, va_list arglist); #if !__STDC__ int fcloseall(void); FILE far* fdopen (int handle, char far *type); /* prool */ int fgetchar (void); int flushall (void); int fputchar (int c); int getw (FILE *stream); int putw (int w, FILE *stream); char far* _strerror(const char far *s); int unlink (const char far *path); /* prool */ #ifdef KERNEL int delete (const char far *path); /* prool */ #endif #endif int _fgetc (FILE *stream); /* used by getc() macro */ int _fputc (char c, FILE *stream); /* used by putc() macro */ int fileno (const FILE far *stream); /* prool */ /* The following macros provide for common functions */ #ifdef Proolix int feof (FILE far *stream); int ferror (FILE far *stream); #else #define ferror(f) ((f)->flags & _F_ERR) #define feof(f) ((f)->flags & _F_EOF) #endif #define remove(path) unlink(path) #define getc(f) fgetc(f) #define putc(c,f) fputc(c,f) int putchar (int); int getchar (void); #define ungetc(c,f) ungetc((c),f) /* traditionally a macro */ extern int More; /* prool */ extern int NLine; /* prool */ #endif src/include/stdarg.h0100664000076500007650000000101507725644350014167 0ustar prool2prool2/* stdarg.h Definitions for accessing parameters in functions that accept a variable number of arguments. Copyright (c) Serge Pustovoitoff 1993-1997 */ #if !defined(__STDARG) #define __STDARG typedef void far *va_list; /* prool */ #define va_start(ap, parmN) (ap = ...) #if 0 #define va_arg(ap, type) (*((type *)(ap))++) #else #define va_arg(ap, type) (*((type far *)(ap))++) #endif #define va_end(ap) #define _va_ptr (...) #endif src/include/time.h0100664000076500007650000000202207725644350013640 0ustar prool2prool2/* time.h Struct and function declarations for dealing with time. Copyright (c) Serge Pustovoitoff 1994-1997 */ #ifndef _TM_DEFINED #define _TM_DEFINED #ifndef __TIME_T #define __TIME_T typedef long time_t; #endif #ifndef __CLOCK_T #define __CLOCK_T typedef long clock_t; #endif struct tm { int tm_sec; int tm_min; int tm_hour; int tm_mday; int tm_mon; int tm_year; int tm_wday; int tm_yday; int tm_isdst; }; char * asctime (const struct tm *tblock); char far* ctime (time_t time); /* prool */ double difftime(time_t time2, time_t time1); struct tm * gmtime(const time_t *timer); struct tm * localtime(const time_t *timer); time_t time (time_t far *timer); /* proolix */ clock_t clock(void); #if !__STDC__ extern int daylight; extern long timezone; int stime(time_t *tp); void tzset(void); #endif #endif src/include/alloc.h0100664000076500007650000000121707725644347014007 0ustar prool2prool2/* alloc.h memory management functions and variables. Copyright (c) Serge Pustovoitoff 1993-1997 */ #ifndef _STDDEF #define _STDDEF #ifndef _SIZE_T #define _SIZE_T typedef unsigned long size_t; #endif #endif #ifndef NULL #if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__) #define NULL 0 #else #define NULL 0L #endif #endif void far* calloc (size_t nitems, size_t size); /* prool */ unsigned long coreleft (void); /* prool */ void free (void far *block); /* prool */ void far* malloc (size_t size); void far* realloc (void far *block, size_t size); /* prool */ src/include/process.h0100664000076500007650000000202507725644350014363 0ustar prool2prool2/* process.h Symbols and structures for process management. Copyright (c) Serge Pustovoitoff 1994-1999 */ #include int exec(char far *path); int execl(char far *path, char far *arg0, ...); int execle(char far *path, char far *arg0, ...); int execlp(char far *path, char far *arg0, ...); int execlpe(char far *path, char far *arg0, ...); int execv(char far *path, char far *argv[]); int execve(char far*name, char far*_argv[], char far*far*env); int execvp(char far *path, char far *argv[]); int execvpe(char far *path, char far *argv[], char far *far *env); void exit(int status); void _exit(int status); int system(const char far *command); /* Proolix */ int fork (void); /* Proolix */ int service(int fn); /* Proolix: kernel service: fn=0 - ps */ void ps_(void); /* Proolix */ int wait (pid_t pid); /* Proolix */ int sema_lock (int far *sema); /* Proolix */ void sema_unlock (int far *sema); /* Proolix */ src/include/readme.1st0100664000076500007650000000220307725644350014420 0ustar prool2prool2 Proolix Include Files (Headers, *.h for C-compiler) (C) Serge Pustovoitoff, 1995-1999 Если Proolix определена (ifdef Proolix), значит идет сборка ОС Пруликс или Пруликc-утилит. Переменная KERNEL используется оригинальными header'ами by BSD и частично мной. Если KERNEL определена, значит происходит компиляция ядра BSD или Proolix. Если же KERNEL неопределена, значит, идет компиляция утилит или программ пользователя. Это необходимо из-за того, что некоторые системные вызовы и функции имеют некоторые различия при их вызове в ядре или во внешней утилите. Так, в утилитах Пруликса все передаваемые системным вызовам параметры типа char * имеют модификатор char far * (это несмотря на то, что утилиты компилируются компилятором Turbo C 2.0 в модели памяти tiny, где все ссылки типа char * являются по умолчанию near). Это связано с тем, что утилиты откомпилированы в модели tiny и поэтому ссылки из утилит в ядро и обратно могут быть произведены только far-указателями, причем слово far надо указывать явно. Сергей Пустовойтов, 13-03-97г. 21:25:46 prool@infocom.kharkov.ua Fido 2:461/35 src/kernel/0040775000076500007650000000000007725645020012370 5ustar prool2prool2src/kernel/fprintf.c0100664000076500007650000000137107725645015014207 0ustar prool2prool2#include #include #include #include "kernel.h" /****************************************************************************/ int fprintf(FILE far *stream, const char far *format, ...) { va_list v; int counter; char buf [MAX_LEN_STR]; va_start(v,0); counter=vsprintf(buf,format,v); if(fputs(buf, stream)==EOF) return EOF; return counter; } /****************************************************************************/ int vfprintf(FILE *stream, const char *format, va_list v) { int counter; char buf [MAX_LEN_STR]; va_start(v,0); counter=vsprintf(buf,format,v); if(fputs(buf,stream)==EOF)return EOF; return counter; } /****************************************************************************/ src/kernel/kernel.h0100664000076500007650000000403607725645016014026 0ustar prool2prool2/* Include file for external c-functions for kernel (as memd.c) */ #include /* structures */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /******************************** External variables ************************/ #ifdef MOUSE extern unsigned int PORT; #endif /* См. описание этих переменных в файле kernel.c */ extern int Mode, User; extern int HeadCnt, TrkSecs; extern unsigned long MaxSectors; extern unsigned int ProcessPar; extern struct {unsigned int ParNo; void (*Entry)(void);} SysTable []; extern unsigned long RootBeg, RootEnd, ResSecs; extern unsigned int CluSize; extern unsigned long DataStart; extern unsigned int MaxClusters; extern char Russian []; extern struct BufPool far *Cache; extern struct DevRecord Dev []; extern FILE FCBS [OPEN_MAX]; extern unsigned int CurDirClu; extern int Trace; extern int _argc; extern char far *_argv []; extern char far * far *pEnv; extern char far *hEnv; extern int curX, curY, maxX, maxY; extern char far *curAddr; extern char VideoAttrib; extern int CurrentDevice; extern int ReadOnly; extern int FATMode; extern int msdos_verbose; extern int SectorsOnCyl, FatSize, FatCnt; extern char MasterBootRecord [SECTOR_SIZE]; extern unsigned int CluSizeBytes; extern char far *OldInt; extern char far *KbdStatus; extern unsigned int MemTop; extern char Russian [256]; extern void interrupt (*OldTimerVec) (void); extern void far * Fin; extern struct DeviceStruct Devices []; extern int NextDOSDrive; extern struct processes process_table [PROC_MAX]; extern user_ss; extern user_sp; extern int emulation_mode; /* Глобальные переменные, доступные из юзерских процессов */ extern int errno; extern int More; extern int NLine; #define _HDD_ 0x80 #define EXTEND 5src/kernel/syscall.tbl0100664000076500007650000000605007725645020014543 0ustar prool2prool2; OS Proolix. System Calls Table ; ИмяВызова ЧислоПараметров [ТочкаВходаВЯдре [ Комментарий]] _getch 0 _getchar 0 _getche 0 _kbhit 0 _kbhit0 _gets 2 __gets _putch 1 _putchar 1 _puts 2 _htoi 2 _htol 2 _atoi 2 _atol 2 _itoa 4 _ltoa 5 _ultoa 5 _ohs 2 _printf 50 _sprintf 50 _fprintf 50 _vsprintf 6 _vprintf 4 _clrscr 0 _inport 1 _inportb 1 _outport 2 _outportb 2 _textattr 1 _gotoxy 2 _inicom_ 0 _getcom_ 1 _putcom_ 2 _getcomstat_ 1 _getvect 1 _setvect 3 _geninterrupt 1 _end 0 _open 5 _creat 3 _read 5 _write 5 _close 1 _lseek 4 _filelength 1 _tell 1 _unlink 2 _rename 4 _dup 1 _minus dup _shutdown 0 _perror 2 _memccpy 7 _memchr 5 _memcmp 6 _memcpy 6 _memicmp 6 _memmove 6 _memset 5 _stpcpy 5 _strcat 5 _strchr 4 _strcmp 5 _strcpy 5 _strcspn 5 _strdup 3 ;_strerror 1 _stricmp 5 _strlen 2 _strlwr 2 _strncat 6 _strncmp 6 _strncpy 6 _strnicmp 6 _strnset 5 _strpbrk 5 _strrchr 4 _strrev 2 _strset 3 _strspn 5 _strstr 5 _strtok 5 _strupr 2 _tolower 1 _toupper 1 _isgraph 1 _isprint 1 _isalnum 1 _isalpha 1 _iscntrl 1 _isdigit 1 _islower 1 _ispunct 1 _isspace 1 _isupper 1 _isxdigit 1 _malloc 2 _calloc 4 _realloc 4 _free 2 _div 2 _ldiv 4 _chmod 4 __chmod 4 _access 3 _fopen 4 _freopen 6 _fdopen 3 _fileno 2 _fgetc 2 _fgets 6 __fgets _fputc 3 _fputs 4 _fread 8 _fwrite 8 _vfprintf 50 _fclose 2 _fflush 2 _ftell 2 _fseek 5 _fgetpos 4 _fsetpos 4 _rewind 2 _int86 5 _getcwd 3 _chdir 2 _opendir 2 _readdir 2 _telldir 2 _seekdir 5 _rewinddir 2 _closedir 2 _mkdir 4 _rmdir 2 _getenv 2 _stat 4 _fstat 3 _isatty 1 _qsort 8 _getftime 3 _setftime 3 _gettime 2 _getdate 2 _time 2 _ctime 2 _rand 0 _srand 1 _getcolor 0 _wherex 0 _wherey 0 _absread 7 _abswrite 7 _exit 1 _strtoul 6 _fork 0 _service 1 _exec 2 _wait 1 src/kernel/time.c0100664000076500007650000000423707725645020013475 0ustar prool2prool2#include #include #include "kernel.h" #include /*==========================================================================*/ #ifdef CMOS extern unsigned char hour, min, secund; #else extern unsigned long Tick; unsigned long trash; #endif extern unsigned char century, year, month, day, flag; /*==========================================================================*/ unsigned char unpack(unsigned char c) { return (c>>4)*10 + (c & 0xf); } /*==========================================================================*/ #ifdef CMOS void gettime (struct time far * timep) { readRTC (&hour, &min, &secund, &flag); (*timep).ti_min=unpack(min); (*timep).ti_hour=unpack(hour); (*timep).ti_sec=unpack(secund); (*timep).ti_hund=0; } /*==========================================================================*/ void getdate (struct date far * datep) { readRTCdate (¢ury, &year, &month, &day); (*datep).da_year=unpack(century)*100+unpack(year)-1980; (*datep).da_day=unpack(day); (*datep).da_mon=unpack(month); } /*==========================================================================*/ #else /*==========================================================================*/ void gettime (struct time far * timep) { ReadTick(&Tick,&flag); trash=(Tick*1000)/182; (*timep).ti_hund=trash%100; trash/=100; (*timep).ti_sec=trash%60; trash/=60; (*timep).ti_min=trash%60; (*timep).ti_hour=trash/60; } /*==========================================================================*/ void getdate (struct date far * datep) { ReadTick(&Tick,&flag); (*datep).da_year=century*100+year-1980; (*datep).da_day=day+flag; (*datep).da_mon=month; } #endif /*==========================================================================*/ time_t time (time_t far *tloc) {struct time timep; struct date datep; time_t l; gettime (&timep); getdate (&datep); l=dostounix(&datep, &timep); if (tloc!=NULL) *tloc=l; return l; } /*==========================================================================*/ #pragma warn -par char far *ctime (time_t timer) { return"Day Jan 00 99:99:99 1900\n"; } #pragma warn +par src/kernel/gets.c0100664000076500007650000000044607725645015013503 0ustar prool2prool2#include #include #include "kernel.h" /* #define DEBUG */ /****************************************************************************/ char *gets (char *s) { #include "gets.inc" } /****************************************************************************/ src/kernel/mem.c0100664000076500007650000000421007725645016013311 0ustar prool2prool2#include #include #include "kernel.h" /****************************************************************************/ void far *memcpy(void far *dest, const void far *src, size_t n) {size_t i; void far *ret; /* if (dest==NULL) return NULL; */ /* if (src==NULL) return NULL; */ ret=dest; for (i=0;ic2) return 1; else if (c1c2) return 1; else if (c12) if (path[1]==':') path+=2; #endif if (path[0]==SLASH) path++; cc=path; while(*path++); while(--path>cc) if (*path==SLASH) break; if(path==cc) c1=cc; else c1=path+1; #ifdef MSDOS if ((cc=strchr(c1,'.'))!=NULL)*cc=0; #endif return c1; } src/kernel/strlen.c0100664000076500007650000000053207725645020014040 0ustar prool2prool2#include #include #include "kernel.h" /****************************************************************************/ size_t strlen (const char far *s) { size_t i; /* if (s==NULL) return NULL; */ i=0; while (*s++)i++; return i; } /****************************************************************************/ src/kernel/memd.c0100664000076500007650000000340107725645016013456 0ustar prool2prool2#include #include #include "kernel.h" char cmd [MAX_LEN_STR]; void memd(void) { char far * Adr0; char far * Adr; char c; int i; char Option = 'H'; int segm, off; /* Adr0 = (char far *) 0; */ segm = 0; off = 0; Adr0 = MK_FP (segm, off); printf("End=%x:%x\nUse /? command for help\n",FP_SEG(end()),FP_OFF(end())); while (1) { printf("%4x:%4x ",FP_SEG(Adr0),FP_OFF(Adr0)); switch (Option) { case 'A': case 'M': for(i=0,Adr=Adr0;i<16;i++,Adr++) { if (*Adr>=' ') putch(*Adr); else putch('.'); printf(" "); } if (Option=='A')break; else puts(""); printf(" "); case 'H': for(i=0,Adr=Adr0;i<16;i++,Adr++){printf("%2X ",*Adr);} break; } puts(""); putch(':'); gets(cmd); i=0; while (cmd[i]) if (cmd[i]=='\r') {cmd[i]=0; break;} else i++; if (cmd[0]=='/') { switch (c=toupper(cmd[1])) { case 'R': saycsip(); break; case 'Q': puts(""); return; case 'A': case 'H': case 'M': Option=c; break; case 'S': segm=htoi(cmd+2); Adr0=MK_FP(segm, off); break; case 'O': off=htoi(cmd+2); Adr0=MK_FP(segm, off); break; case '?':puts( "Commands:\n\ /Q - Quit\n\ /A - Ascii mode\n\ /H - Hex mode\n\ /M - Mix (hex & ascii) mode\n\ /S - set Segment\n\ /O - set Offset\n\ /R - registers dump\n\ Enter - next string"); break; default: puts("Invalid command"); } printf("\n "); } else if (!cmd[0]) {off+=16; Adr0 = MK_FP(segm, off);} else ; } } src/kernel/tr.c0100664000076500007650000000017007725645020013154 0ustar prool2prool2#include "kernel.h" int TR (int curdev) { if (curdev>1) return _HDD_; /* HDD */ else return curdev; /* FDD */ } src/kernel/mv.c0100664000076500007650000000200107725645016013151 0ustar prool2prool2/*-------------------------------------------------------------------------*/ /* internal mv */ /*-------------------------------------------------------------------------*/ #include #include #include "kernel.h" void mv_help(void) { puts("Uses: mv [file1] [file2]"); } void mv(int argc, char far *argv[] ) { int ii, j, n, Files=0; char path[2][PATH_MAX]; argc--; ii=1; do { if (argc) { if (argv[ii][0]=='-') { n=(int)strlen(argv[ii]); for (j=1;j2) {mv_help(); return;} } } } while (ii++ #include #include "kernel.h" /****************************************************************************/ /* Целочисленная арифметика */ /****************************************************************************/ div_t div(int number, int denom) {div_t R; R.quot=number / denom; R.rem=number % denom; return R; } /****************************************************************************/ ldiv_t ldiv(long number, long denom) {ldiv_t R; R.quot=number / denom; R.rem=number % denom; return R; } /****************************************************************************/ int system (const char far *command) { if (command==NULL) return 0; else return 1; } /****************************************************************************/ char far *getenv (const char far *name) {int i, lname; lname=(int)strlen(name); for (i=0;i #include #include "kernel.h" int CatLine; void cat (int argc, char far *argv[] ) { int h; unsigned char c, far *cc; int i, Files=0; #ifdef DEBUG printf("Cat: %s\n",argv[1]); #endif CatLine=0; cc=&c; argc--; More=1; NLine=1; i=1; do { if (argc) { Files++; if ((h=open(argv[i],O_RDONLY))==-1) { printf("Can't open %s\n",argv[i]); } while (1) { if(read(h,cc,1)<=0) break; putch(c); } close(h); } } while (i++ #include #include "kernel.h" int putch3 (int ch) { int LastRowOffset, i; switch(ch) { case 0: break; case '\n': curX=1; curY++; curAddr=MK_FP(VIDEO_SEG,maxX*(curY-1)*2); if (curY>maxY) goto scroll; break; default: *curAddr++=ch; *curAddr++=VideoAttrib; if (++curX>maxX) { curX=1; if (++curY>maxY) {scroll: curY=maxY; curAddr-=maxX*2; LastRowOffset=(maxY-1)*maxX*2; memcpy(MK_FP(VIDEO_SEG,0),MK_FP(VIDEO_SEG,maxX*2),LastRowOffset); for (i=0;i #include #include "kernel.h" void qsort (void far *base, size_t nmemb, size_t size, int (far *compar)(void far *, void far *)) {int i, Permute; void far *b1, far *b2; char far *Bolvan; if (base==NULL) return; if ((Bolvan=malloc(size))==NULL) return; do { Permute=0; for (i=0; i<(nmemb-1); i++) { if (compar(b1=(char far *)base+(int)( i *size), b2=(char far *)base+(int)((i+1)*size) )>0) { /* swap */ Permute=1; memcmp(Bolvan,b1,size); memcmp(b1,b2,size); memcmp(b2,Bolvan,size); } } } while (Permute); free(Bolvan); } src/kernel/rand.c0100664000076500007650000000400507725645017013462 0ustar prool2prool2/* rand.c - pseudorandom numbers generation */ /* rand() srand() */ /* ─ NICE.SOURCES (2:461/35.301) Msg : 34 of 167 From : Al xCruel 2:4653/1.8 Fri 07 Apr 95 12:00 To : Jura Lobunets Subj : Hадо! Генератор случайных чисел! ──────────────────────────────────────────────────────────────────────────────── .MSGID: 2:4653/1.8 f85748e0 .REPLY: 2:463/212.5 2f71f91a .PID: timEd-g2+ .TID: FastEcho 1.41/g 1995 Jura Lobunets wrote in a message to All: JL> Очень надо subj! В кратце, алгоритм генерации псевдослучайных чисел в интервале кратном 2 такой: - берем сдвиговый регистр, - записываем в него стартовое значение, | (дальше циклично) | | - получаем псевдослучайное число из регистра (!), | - берем бит 2 регистра и инвертируем его, | - берем бит 1 регистра и XOR'им его с инвертнутым 2 битом, | - берем бит 0 регистра и XOR'им его с предыдущим результатом, | - получившийся в итоге бит запихиваем в старший разрад регистра, | - сдвигаем регистр, | | (цикл на количество иттераций) Единственный недостаток - пропускаются комбинации типа 1010 и 0101 и т.д. в соответствии с разрядностью. Да! Вычитал все это в одной умной буке, там еще картинка была: ----- - - - - - - - - - ------------- | N | | 2 | 1 | 0 | Shift register ----- - - - - - - - - - ------------- ^ | | | | | | | | ------- | | | ---| XOR O<-------------- | | | |<------------------ | | |<---------------------- ------- bk00l! Al XCRUEl. --- * Origin: la sagrada familia (2:4653/1.8) .PATH: 4653/1 51/2 5100/8 5020/251 144 400 461/21 35 */ static unsigned int RandomSave; int rand (void) {unsigned int reg, bit; reg=RandomSave; bit=((!(reg&4))^(reg&2))^(reg&1); reg>>=1; reg|=(bit<<15); RandomSave=reg; if (reg<0) reg=-reg; return reg; } void srand (unsigned seed) { RandomSave=seed; } src/kernel/gets.inc0100664000076500007650000000246607725645015014036 0ustar prool2prool2int i; char buf[MAX_LEN_STR]; int c; if (s==NULL) {errno=EINVAL; return NULL;} for(i=0;i'); #endif switch (c) { case '\b' : /* ERASE=8 */ if (i) { if (wherex()==0) {int y; y=wherey(); if (y!=0) y--; buf[--i]=0; gotoxy(79,y); putch(' '); gotoxy(79,y); } else { buf[--i]=0; putch('\b'); putch(' '); putch('\b'); } } else buf[i]=0; break; case EOF : case 4 : /* CTRL D */ case '\r' : /* CR */ case '\n' : /* LF */ buf[i]=0; i=MAX_LEN_STR; break; default: buf[i++]=c; } } buf[MAX_LEN_STR-1]=0; #ifdef DEBUG printf(" gets:buf=",buf); puts(buf); #endif #if 1 for (i=0;i #include #include "kernel.h" #include "signal.h" /****************************************************************************/ void null_command(void); void run_boot(int dev,int head,int sec,int trk); void start(char *cmd); /****************************************************************************/ struct internal_commands { char far *command_name; void (*command_entry) (void); } InternalCommand [] = { {"cls", clrscr}, {"clear", clrscr}, {"dev", out_devices}, {"exitw", exitw}, {"", null_command} }; /****************************************************************************/ void null_command (void) { /* null action */ return; } /****************************************************************************/ int print_exec_message(int e) { switch(e) { case 1 : printf("%Fs: not found\n",_argv[0]); break; case 2 : printf("%Fs: not executable\n",_argv[0]); break; case 3 : printf("%Fs: read error\n",_argv[0]); break; case 4 : printf("%Fs: memory fault\n",_argv[0]); break; case 5 : printf("%Fs: no mem\n",_argv[0]); default: ; case 0 : ; } return e; } /****************************************************************************/ void garbage_collection(void) { if (!garbage()) puts("\nGarbage collected"); else puts("\nNo fragmentation"); } /****************************************************************************/ static void fcbs(void) {int i, j; char c; printf( "No ---name---- flag T Beg Size D ino Seek ACl RCl ASc RSc ofset\n"); for (i=0;i1) print_exec_message(i); else printf("%s: not found or not executable\n",_argv[0]); return ; } void boot(char far *argv[]) {int d; if (shutdown()) { printf("Shutdown error!\n"); return; } d=toupper(argv[1][0])-'A'; printf("boot from %c:\n",dos_letter(d)); switch(d) { case 0: case 1: run_boot(d,0,1,0); default: if (Devices[d].sec==0) {printf("Device %c: not present\n",dos_letter(d));return;} run_boot(0x80,Devices[d].head,Devices[d].sec,Devices[d].trk); } } /***************************************************************************** sh() *****************************************************************************/ char sh_str_orig [MAX_LEN_STR]; char sh_str [MAX_LEN_STR]; void interrupt far sh (void) { int i; puts(IDENT); while(1) { /* Вывод символа-приглашения shell'а и ввод командной строки */ #ifndef DOSKEY for (i=0;i "); gets(sh_str_orig); #ifdef DEBUG printf("sh:"); printf(sh_str_orig); #endif #else printf("% "); doskey(sh_str_orig); #endif #if 0 if (!str[0]) goto shut; #endif strncpy(sh_str,sh_str_orig,MAX_LEN_STR); /* Разбор командной строки */ i=0; while (sh_str[i]) if (sh_str[i]=='\r') {sh_str[i]=0; break;} else i++; _argc=0; i=0; /* Пропуск пробелов в начале командной строки */ for(;(iMAX_ARG) {printf("Too many arguments"); goto l2;} for(;(i #include #include #include "kernel.h" /****************************************************************************/ /* #define DEBUG */ /****************************************************************************/ unsigned long SecForClu (unsigned int CluNo) {unsigned long l; /* Sector=ResSecs + FatCnt*FatSize + (RootSiz*32)/SectSiz + ((CluNo-2)*ClustSiz) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ DataStart */ if ((CluNo>MaxClusters)||(CluNo<2)) { printf("SecForClu: Invalid cluster number. CluNo=%u, MaxClusters=%u", CluNo,MaxClusters); return -1; } l=DataStart + ( ((unsigned long)CluNo-2) * CluSize ); #ifdef DEBUG printf("sec4clu: return %li ",l); #endif return l; } src/kernel/string.c0100664000076500007650000001525007725645020014042 0ustar prool2prool2#include #include #include "kernel.h" /****************************************************************************/ char far *strcpy (char far *dest, const char far *src) {char far *cc; /* if (dest==NULL) return NULL; */ /* if (src==NULL) return NULL; */ cc=dest; do *dest++ = *src; while (*src++); return cc; } /****************************************************************************/ char far *stpcpy (char far *dest, const char far *src) { /* if (dest==NULL) return NULL; */ /* if (src==NULL) return NULL; */ do *dest++ = *src; while (*src++); return dest-1; } /****************************************************************************/ size_t strcspn(const char far *s1, const char far *s2) { size_t i; /* if (s1==NULL) return NULL; */ /* if (s2==NULL) return NULL; */ i=0; while(*s1) { if (strchr(s2,*s1)!=NULL)break; i++; s1++; } return i; } /****************************************************************************/ char far *strcat (char far *dest, const char far *src) { char far *cc; /* if (dest==NULL) return NULL; */ /* if (src==NULL) return NULL; */ cc=dest; while(*dest++); strcpy(--dest,src); return cc; } /****************************************************************************/ int strcmp (const char far *s1, const char far *s2) {char c1,c2; /* if (s1==NULL) return 0; */ /* if (s2==NULL) return 0; */ do {c1=*s1++; c2=*s2++; if (c1>c2) return 1; else if (c1c2) return 1; else if (c1c2) return 1; else if (c1c2) return 1; else if (c1 #include #include #define MAX_STR_LEN 256 int main(int argc, char *argv[]) {FILE *fi, *fo; char s [MAX_STR_LEN]; int Status; char *cc; printf("APP - Assembler PreProcessor Version 0.0.0.0 9-Feb-95\n\ Copyright (C) by Serge Pustovoitoff, 1995. prool@infocom.kharkov.ua, 2:461/35\n\ \n"); if (argc!=3) {printf("Syntax: app input_file output_file\n"); exit(0);} fi=fopen(argv[1],"r"); if (fi==NULL) {printf("Can't open input file %s\n",argv[1]); exit(1);} fo=fopen(argv[2],"w"); if (fo==NULL) {printf("Can't open output file %s\n",argv[2]); exit(1);} Status=0; if (fputs("\tinclude\tdebug.mac\n", fo)==EOF) {printf("Can't write output file %s\n",argv[1]); goto Ex; } while(1) { s[0]=0; if (fgets(s, MAX_STR_LEN, fi)==NULL) break; switch (Status) { case 0: /* начальное состояние автомата */ if (!strcmp(s,"\tifndef\t??version\n")) {Status=1; continue; } break; case 1: /* нашли ifndef ?? version */ if (!strcmp(s,"\tendif\n")) Status=0; continue; default: ; } /* filtr */ cc=s; if (memcmp(s,"\t?debug\t",7)==0) { switch (s[8]) { case 'S': case 'C': case 'E': case 'B': continue; case 'L': default : s[1]='\t'; cc=s+1; } } else if (memcmp(s+5,"short",5)==0) { strcpy(s+5,s+11); } if (fputs(cc, fo)==EOF) {printf("Can't write output file %s\n",argv[1]); break; } } Ex: fclose(fi); if (fclose(fo)==EOF) {printf("Can't close output file %s\n",argv[1]); exit(1);} exit(0); } src/kernel/k2.c0100664000076500007650000004364407725645015013064 0ustar prool2prool2#include #include #include "kernel.h" /* #define DEBUG */ /* #define PRINTF_DEBUG */ int NextDrive=2; /* disk C: */ void out_boot(void far *buf); /****************************************************************************/ #ifdef PRINTF_DEBUG char far *far_global_init = "far_global_init"; char far *far_global_uninit; char *near_global_init = "near_global_init"; char *near_global_uninit; char global_array_init [] = "global_array_init"; char global_array_uninit [100]; #endif #define EXTEND 5 #define EXTEND2 0xF #include "ppt.c" /****************************************************************************/ int shutdown(void) {int i; if ((i=FlushAll())!=0) puts("flush error"); return i; } /****************************************************************************/ int LinkClu (unsigned int CluNo, unsigned int NeXT) { int nsect, offset; long fat_byte_no; int b1, b2, b_next; unsigned char far *cc; unsigned int far *ii; if (CluNo>MaxClusters) {puts("LinkClu: Invalid cluster number"); return -1;} if (FATMode==FAT12) { /* FAT 12 */ /* определяем номер байта в FAT */ fat_byte_no=(CluNo*3)/2; /* определяем номер сектора FAT */ nsect=(int)(fat_byte_no/SECTOR_SIZE); /* nsect-относительный номер сектора FAT. 0 - первый сектор FAT */ if (nsect>=FatSize) {puts("LinkClu: Invalid FAT's computing"); return -1;} if ( (b1=LoadCache(ResSecs+nsect)) == - 1 ) {puts("\nLinkClu: FAT read error"); return -1;} if (FatCnt==2) if ( (b2=LoadCache(ResSecs+nsect+FatSize)) == - 1 ) {puts("\nLinkClu: FAT read error"); return -1;} offset=(int)(fat_byte_no%SECTOR_SIZE); if (offset==(SECTOR_SIZE-1)) { (*(Cache+b1)).Status=2; cc=(unsigned char far *)((*(Cache+b1)).M+(SECTOR_SIZE-1)); if (CluNo&1) *cc=(unsigned char)(NeXT>>4); else {*cc&=0xf0; *cc|=(unsigned char)(NeXT>>8);} if ( (b_next=LoadCache(ResSecs+nsect+1)) == - 1 ) {puts("\nLinkClu: FAT read error"); return -1;} (*(Cache+b_next)).Status=2; cc=(unsigned char far *)((*(Cache+b_next)).M); if (CluNo&1) {*cc&=0x0f; *cc|=((unsigned char)(NeXT>>8))<<4;} else *cc=(unsigned char)(NeXT&0xff); if (FatCnt==2) { (*(Cache+b2)).Status=2; cc=(unsigned char far *)((*(Cache+b2)).M+(SECTOR_SIZE-1)); if (CluNo&1) *cc=(unsigned char)(NeXT>>4); else {*cc&=0xf0; *cc|=(unsigned char)(NeXT>>8);} if ( (b_next=LoadCache(ResSecs+nsect+1+FatSize)) == - 1 ) {puts("\nLinkClu: FAT read error"); return -1;} (*(Cache+b_next)).Status=2; cc=(unsigned char far *)((*(Cache+b_next)).M); if (CluNo&1) {*cc&=0x0f; *cc|=((unsigned char)(NeXT>>8))<<4;} else *cc=(unsigned char)(NeXT&0xff); } } else { (*(Cache+b1)).Status=2; ii=(unsigned int far *)((*(Cache+b1)).M+offset); if (CluNo&1) {*ii&=0xf; *ii|=NeXT<<4;} else {*ii&=0xf000; *ii|=NeXT&0xfff;} if (FatCnt==2) { (*(Cache+b2)).Status=2; ii=(unsigned int far *)((*(Cache+b2)).M+offset); if (CluNo&1) {*ii&=0xf; *ii|=NeXT<<4;} else {*ii&=0xf000; *ii|=NeXT&0xfff;} } } } else { /* FAT 16 */ /* определяем номер байта в таблице FAT-16 */ fat_byte_no=((long)CluNo)*2; /* определяем номер сектора FAT */ nsect=(int)(fat_byte_no/SECTOR_SIZE); /* nsect-относительный номер сектора FAT. 0 - первый сектор FAT */ if (nsect>=FatSize) {puts("LinkClu: Invalid FAT's computing"); return -1;} if ( (b1=LoadCache(ResSecs+nsect)) == - 1 ) {puts("\nLinkClu: FAT read error"); return -1;} if (FatCnt==2) if ( (b2=LoadCache(ResSecs+nsect+FatSize)) == - 1 ) {puts("\nLinkClu: FAT read error"); return -1;} offset=(int)(fat_byte_no%SECTOR_SIZE); (*(Cache+b1)).Status=2; *(int far *)((*(Cache+b1)).M+offset)=NeXT; if (FatCnt==2) { (*(Cache+b2)).Status=2; *(int far *)((*(Cache+b2)).M+offset)=NeXT; } } return 0; } /****************************************************************************/ unsigned int GetFreeClu(void) {int i; /* поиск по FAT */ for(i=2;i<=MaxClusters;i++) { if (NextClu(i)==0) {/* нашли пустой кластер */ /* занимаем его и возвращаем его номер */ if (LinkClu(i,0xffff)!=-1) return i; else return -1; } } /* нет пустых кластеров */ return -1; } /****************************************************************************/ unsigned int AppendClu(unsigned int CluNo) {unsigned int i; if (CluNo>MaxClusters) {puts("AppendClu: Invalid cluster number"); return -1;} if ((i=GetFreeClu())==0xFFFF) return 0xFFFF; /* нашли пустой кластер */ /* формируем последнее звено цепочки кластеров */ if (LinkClu(CluNo,i)==-1) return 0xFFFF; else return i; } /*--------------------------------------------------------------------------*/ char dos_letter(int dev) { if (dev<2) { return dev+'A'; } else { return (dev-2)/2+'C'; } } /*--------------------------------------------------------------------------*/ void print_mount(void) { if (CurrentDevice==-1) puts("No device mount"); else { printf("Mount at %i (DOS %c:)",CurrentDevice,dos_letter(CurrentDevice)); printf(" mode read"); if (ReadOnly) printf(" only"); else printf("/write"); if (emulation_mode==1) printf("\n(running under MSDOS or MSDOS-emulator (f.e. Windows 95))"); printf("\n"); } return; } /*--------------------------------------------------------------------------*/ void mount(int NewDevice) { int i; unsigned char sec, head, trk; struct MBRstru *MBR; struct BootStru far *B; char Buf [SECTOR_SIZE]; if (NewDevice==-1) { print_mount(); return; } if (CurrentDevice!=-1) #if 0 { printf("Already "); print_mount(); return; } #else { umount(); } #endif if(Cache==NULL) {puts("mount: No memory for disk cache"); return;} for(i=0;i1) { /* HDD */ if ((Devices[NewDevice].sec==0)||((FATMode=Devices[NewDevice].FileSystem)==NO_FAT)) { printf("mount: invalid device\n"); CurrentDevice=-1; return; } head=Devices[NewDevice].head; sec=Devices[NewDevice].sec; trk=Devices[NewDevice].trk; if (ReadPhysSec2 (_HDD_, sec, head, trk, Buf)) printf ("boot: partition boot sector read error\n"); #ifdef DEBUG printf("partition boot sector loaded OK\n"); #endif B = (void far *) Buf; HeadCnt=B->HeadCnt; TrkSecs=B->TrkSecs; SectorsOnCyl=HeadCnt*TrkSecs; #if 0 ResSecs=(unsigned long)Devices[NewDevice].sec+ (unsigned long)Devices[NewDevice].head*(unsigned long)TrkSecs+ (unsigned long)Devices[NewDevice].trk*SectorsOnCyl; #else ResSecs=(unsigned long)(Devices[NewDevice].sec & 0x3F)+ (unsigned long)Devices[NewDevice].head*(unsigned long)TrkSecs+ (unsigned long)(Devices[NewDevice].trk|((int)(Devices[NewDevice].sec & 0xC0)<<2))* SectorsOnCyl; #endif #ifdef DEBUG printf("ResSecs=%lu\n",ResSecs); #endif MaxSectors=Devices[NewDevice].MaxSectors+ResSecs; } else { /* FDD */ FATMode=FAT12; if (NewDevice==1) if (Devices[NewDevice].sec==0) { printf("mount: invalid device b:\n"); CurrentDevice=-1; return; } if (bootread(CurrentDevice,Buf)) { puts("mount: Boot read error"); CurrentDevice=-1; } B = (void *) Buf; if ((i=B->ResSecs)!=0) ResSecs=i; ResSecs=B->HidnSec+1; if ((i=B->TotSecs)!=0) MaxSectors=i; else MaxSectors=B->BigSect+B->HidnSec; #if 0 out_boot((void far *) Buf); #endif HeadCnt=B->HeadCnt; TrkSecs=B->TrkSecs; SectorsOnCyl=HeadCnt*TrkSecs; } if (CurrentDevice!=-1) { CluSize=B->ClustSiz; CluSizeBytes=CluSize * SECTOR_SIZE; FatSize=B->FatSize; FatCnt=B->FatCnt; #ifdef DEBUG printf("\nQ4 "); #endif RootBeg = ResSecs + B->FatCnt * B->FatSize; #ifdef DEBUG printf("\nB->SectSiz=%i ",B->SectSiz); #endif RootEnd = RootBeg + ( ( B->RootSiz * 32 ) / B->SectSiz ) - 1; #ifdef DEBUG printf(" Q4.2 "); #endif DataStart = RootEnd+1; #ifdef DEBUG printf(" Q4.3 "); #endif MaxClusters=(unsigned int)((MaxSectors-DataStart)/CluSize+1); #ifdef DEBUG printf(" Q5 "); #endif #if defined (DEBUG) /***/ printf("\nHeadCnt =%2i TrkSecs =%2i CluSize =%2i FatSize =%2i FatCnt =%1i\ RootBeg =%lu\nRootEnd =%lu ResSecs =%lu MaxSectors =%lu MaxClusters =%u", HeadCnt,TrkSecs,CluSize,FatSize,FatCnt,RootBeg,RootEnd,ResSecs, MaxSectors,MaxClusters); printf("\nboot: Cluster size = %u\n",CluSizeBytes); #endif /***/ CurDirClu=0; puts(""); } #endif /* NODISK */ #ifdef DEBUG printf(" Q6 "); #endif } /*--------------------------------------------------------------------------*/ void umount (void) {int i; shutdown(); CurrentDevice=-1; if(Cache==NULL) {puts("umount: No memory for disk cache"); return;} for(i=0;i>4); (*MB).SizePar=MemTop-CurPar; /* запоминание всех векторов прерываний */ if ((OldInt=malloc(256*4))==NULL) puts("No mem for old interrupt table"); if (OldInt!=NULL) { __cli__(); memcpy(OldInt,MK_FP(0,0),256*4); __sti__(); #ifdef DEBUG puts("\nInterrupt vectors saved"); #endif /* printf("Orig Int5=%04X:%04X\n", *(int far *)5*4,*(int far *)(5*4+2)); */ } else puts("init(): No mem"); setvect(0x0,Int0); setvect(0x3,Int3); #ifdef CHANGE_INTS initv(); setvect(0x18,done); setvect(0x19,CtrlAltDel); setvect(0x1,Int1); setvect(0x2,Int2); setvect(0x4,Int4); setvect(0x6,Int6); setvect(0x7,Int7); setvect(0x75,Int75); #endif /* #ifdef CHANGE_INT5 */ /* setvect(0x5,Int5); */ /* setvect(5, (void interrupt(*)(void))MK_FP(_Begin,FP_OFF(Int5dump))); */ /* puts("Int 5 hooked"); */ /* #endif */ curAddr=MK_FP(VIDEO_SEG,0); /* Смотри комментарий у описания прототипа функции SysCall1 (это выше) */ /* setvect(INT_NO, (void interrupt(*)(void))MK_FP(_Begin,FP_OFF(SysCall1))); */ setvect(INT_NO, SysCall2); #ifdef DEBUG printf("before MSHerc\n"); #endif #if defined(_HERCULES_) && defined(_MSHERC_) if(!mshercinit()) printf("\nHercules Resident Video Support Routines. Version 1.10+Proolix"); else printf("\nHercules Video Card not present."); #endif OldTimerVec=getvect(0x8); /* setvect(0x8,Int8); */ /* setvect(0x85,Int8); */ #if CODETABLE==_RUSSIAN_ /* russification module initialization */ for (i=0;i<256;i++) Russian[i]=i; for (i='A';i<='Z';i++) Russian[i]=RussianUpper[i-'A']; for (i='a';i<='z';i++) Russian[i]=RussianLower[i-'a']; Russian['[']='х'; Russian['{']='Х'; Russian[']']='ъ'; Russian['}']='Ъ'; Russian[';']='ж'; Russian[':']='Ж'; Russian['\'']='э'; Russian['"']='Э'; Russian[',']='б'; Russian['<']='Б'; Russian['.']='ю'; Russian['>']='Ю'; #endif if ((hEnv=malloc(ARG_MAX))==NULL) puts("init: No mem for argv"); if ((pEnv=malloc(MAX_ENV*4))==NULL) puts("init: No mem for main env."); for (i=0; i1) ReadOnly = HDD_READ_ONLY; else ReadOnly = 0; {unsigned int seg; seg=FP_SEG((unsigned long)getvect(0x21)); printf("int 21h seg=%04X\n",seg); if (seg!=0xF000) {emulation_mode=1; i=2; /* ReadOnly=1; */ } else {emulation_mode=0;} } CurrentDevice=-1; mount(i); } /****************************************************************************/ void test_devices(void) {unsigned int i; struct MBRstru *MBR; char MBRBuf [SECTOR_SIZE]; for (i=0;i>6)+1; #ifdef DEBUG printf("disk drives number = %i\n\n",i); #endif if (i) Devices[0].sec=-1; if (i>1) Devices[1].sec=-1; if (bootread0 (_HDD_, MBRBuf)) printf ("test_devices: MBR read error\n"); #ifdef DEBUG outMBR(MBRBuf); #endif #ifdef DEBUG printf("# head sec trk ResSecs MaxSectors\n"); #endif process_partition_table (MBRBuf); }src/kernel/sayr.asm0100664000076500007650000000136207725645017014055 0ustar prool2prool2; say string locals _TEXT segment byte public 'CODE' assume cs:_TEXT sayr_proc proc ; Процедура вывода строки при помощи функций BIOS ; Вход: DS:SI - ASCIIZ строка. ; All registers saved ; В графических режимах не работает ; ALL REGS SAVED! push ax push si PUSHF cld sayr_l1: lodsb or al,al jz sayr_ret mov ah,0eh int 10h jmp short sayr_l1 sayr_ret: POPF pop si pop ax ret sayr_proc endp public sayr_proc _TEXT ends end src/kernel/vec.c0100664000076500007650000000050107725645020013302 0ustar prool2prool2#include #include #include "kernel.h" void vec (int argc,char far *argv[]) {int i; if (argc==2) { i=htoi(argv[1]); OutIntVector(i); return; } else { More=2; NLine=1; for (i=0;i<256;i++) if (OutIntVector(i)==EOF) break; puts(""); More=0; NLine=1; } } src/kernel/syserr.c0100664000076500007650000000422607725645020014064 0ustar prool2prool2char *sys_errlist[] = { /* EZERO 0 */ "Error 0 - no error", /* EINVFNC 1 */ "Invalid function number", /* ENOENT 2 */ "No such file or directory", /* ENOPATH 3 */ "Path not found", /* EMFILE 4 */ "Too many open files", /* EACCES 5 */ "Permission denied", /* EBADF 6 */ "Bad file number", /* ECONTR 7 */ "Memory blocks destroyed", /* ENOMEM 8 */ "Not enough core", /* EINVMEM 9 */ "Invalid memory block address", /* EINVENV 10 */ "Invalid environment", /* EINVFMT 11 */ "Invalid format", /* EINVACC 12 */ "Invalid access code", /* EINVDAT 13 */ "Invalid data", /* 14 */ "Unknown error", /* ENODEV 15 */ "No such device", /* ECURDIR 16 */ "Attempt to remove CurDir", /* ENOTSAM 17 */ "Not same device", /* ENMFILE 18 */ "No more files", /* EINVAL 19 */ "Invalid argument", /* E2BIG 20 */ "Arg list too long", /* ENOEXEC 21 */ "Exec format error", /* EXDEV 22 */ "Cross-device link", /* 23 */ "Unknown error", /* 24 */ "Unknown error", /* 25 */ "Unknown error", /* 26 */ "Unknown error", /* 27 */ "Unknown error", /* 28 */ "Unknown error", /* 29 */ "Unknown error", /* 30 */ "Unknown error", /* 31 */ "Unknown error", /* 32 */ "Unknown error", /* EDOM 33 */ "Math argument", /* ERANGE 34 */ "Result too large", /* EEXIST 35 */ "File already exists", /* EFAULT 36 */ "Unknown error", /* EPERM 37 */ "Unknown error", /* ESRCH 38 */ "Unknown error", /* EINTR 39 */ "Unknown error", /* EIO 40 */ "Unknown error", /* ENXIO 41 */ "Unknown error", /* ECHILD 42 */ "Unknown error", /* EAGAIN 43 */ "Unknown error", /* ENOTBLK 44 */ "Unknown error", /* EBUSY 45 */ "Unknown error", /* ENOTDIR 46 */ "Unknown error", /* EISDIR 47 */ "Unknown error", /* ENFILE 48 */ "Unknown error", /* ENOTTY 49 */ "Unknown error", /* ETXTBSY 50 */ "Unknown error", /* EFBIG 51 */ "Unknown error", /* ENOSPC 52 */ "Unknown error", /* ESPIPE 53 */ "Unknown error", /* EROFS 54 */ "Unknown error", /* EMLINK 55 */ "Unknown error", /* EPIPE 56 */ "Unknown error", /* EUCLEAN 57 */ "Unknown error" }; int sys_nerr = 57; src/kernel/putch2.asm0100664000076500007650000000665207725645017014313 0ustar prool2prool2; int putch3 (int ch) .8086 jumps _TEXT segment byte public 'CODE' assume cs:_TEXT VIDEO_SEG equ 0B800H _curX dw 1 _curY dw 1 _maxX dw 80 _maxY dw 25 _curAddr dd 0 _VideoAttrib db 7 _LastRowOffset dw 0 _putch2 proc near push bp mov bp,sp ; SAVE ALL REGS push ax push bx push cx push dx push si push di PUSHF ; byte ptr [bp+4] - argument # 1 ;int LastRowOffset, i; cld ;switch(ch) ; { ; case 0 : break; mov ax,word ptr [bp+4] or ax,ax jz l_break ; case '\r': break; cmp ax,13 je l_break ; case '\n': curX=1; cmp ax,10 ; '\n' jne l_default mov _curX,1 ; curY++; inc _curY ; curAddr=MK_FP(VIDEO_SEG,maxX*(curY-1)*2); mov word ptr _curAddr+2,VIDEO_SEG mov ax,_curY dec ax shl ax,1 mul _maxX mov word ptr _curAddr,ax ; if (curY>maxY) goto scroll; mov ax,_curY cmp ax,_maxY ; jg l_scroll ; break; jmp l_break ; default : *curAddr++=ch; l_default: les di,_curAddr stosb ; *curAddr++=VideoAttrib; mov al,_VideoAttrib stosb add word ptr _curAddr,2 ; if (++curX>maxX) mov ax,_curX inc ax mov _curX,ax cmp ax,_maxX jle l_1 ; { ; curX=1; mov _curX,1 ; if (++curY>maxY) mov ax,_curY inc ax mov _curY,ax cmp ax,_maxY JMP l_2 ;;;;;;;;;;;;;;;;;;;; jle l_2 ; {scroll: l_scroll: ; curY=maxY; mov ax,_maxY mov _curY,ax ; curAddr-=maxX*2; mov ax,word ptr _curAddr mov bx,_maxX shl bx,1 sub ax,bx mov word ptr _curAddr,ax ; LastRowOffset=(maxY-1)*maxX*2; mov ax,_maxY dec ax mul _maxX shl ax,1 mov cx,ax mov _LastRowOffset,ax ; memcpy(MK_FP(VIDEO_SEG,0),MK_FP(VIDEO_SEG,maxX*2),LastRowOffset); push DS mov ax,VIDEO_SEG mov DS,ax mov ES,ax mov si,_maxX shl si,1 xor di,di rep movsb ; DS:SI -> ES:DI pop DS ; for (i=0;i #include #include "kernel.h" /****************************************************************************/ char far *strchr (const char far *str, int c) { /* if (str==NULL) return NULL; */ while (*str) if (*str==c) return (char far *) str; else str++; return NULL; } /****************************************************************************/ src/kernel/dos.c0100664000076500007650000000161107725645015013321 0ustar prool2prool2#include #include #include #include "kernel.h" /****************************************************************************/ int int86 (int intno, union REGS far *inregs, union REGS far *outregs) {int i; i=(*inregs).x.ax; /* mov bx,word ptr [bp+6] mov ax,word ptr [bx] mov word ptr [bp-2],ax */ i=(*inregs).x.bx; /* mov bx,word ptr [bp+6] mov ax,word ptr [bx+2] mov word ptr [bp-2],ax */ i=(*inregs).h.al; /* mov bx,word ptr [bp+6] mov al,byte ptr [bx] mov ah,0 mov word ptr [bp-2],ax */ } /****************************************************************************/ /* int int86x (int intno, union REGS *inregs, union REGS *outregs, struct SREGS *segregs) { } */ src/kernel/de.c0100664000076500007650000000264107725645015013130 0ustar prool2prool2/*-------------------------------------------------------------------------*/ /* internal disk edit */ /*-------------------------------------------------------------------------*/ #include #include #include "kernel.h" void de (void) { unsigned int n; char str[MAX_LEN_STR]; puts("Proolix Disk Editor by Serge Pustovoitoff\n\n\ The Disk Editor is currently in Read-Only mode"); printf("0 - boot sector\n1 -%i - FAT\n%i-%i - root dir\n%i-%i - data area\n", RootBeg-1,RootBeg,DataStart-1,DataStart,MaxSectors-1); while(1) {int line, adr, b; More=1; NLine=1; printf("Sector no > "); gets(str); *strchr(str,'\r')=0; if (!str[0]) break; n=atoi(str); printf("Sector no %i",n); if (n==0) puts(", boot sector"); else if (n=' ') putch(c); else putch (' '); } puts(""); adr+=16; } More=0; NLine=1; } /* */ } puts(""); ret:return; } src/kernel/absread.c0100664000076500007650000000602407725645014014137 0ustar prool2prool2#include #include #include "kernel.h" int Int13perror(unsigned err); /****************************************************************************/ /* #define DEBUG */ /* Необходимо подумать о том, что считывать с дисков можно не посекторно, */ /* а целыми дорожками. Это будет быстрее. */ /****************************************************************************/ extern unsigned char NearBuffer [SECTOR_SIZE]; /* defined in c0.asm */ /****************************************************************************/ int secread (int drive, unsigned long AbsSec, char *Buffer) {/* Read absolute sectors Input: drive (for int 13h Fn=2) abs sec number buffer Output: return!=0 if error */ int Track, SecNoOnCyl, i; char Head, SecOnTrk; Track=(int)(AbsSec/SectorsOnCyl); /*SectorsOnCyl=HeadCnt*TrkSecs,Track==Cyl */ SecNoOnCyl=(int)(AbsSec%SectorsOnCyl); Head=SecNoOnCyl/TrkSecs; SecOnTrk=SecNoOnCyl%TrkSecs+1; /* 2 bytes are combined to a word similar to INT 13: │7│6│5│4│3│2│1│0│ 1st byte (sector) │ │ └─┴─┴─┴─┴─┴── Sector offset within cylinder └─┴───────────── High order bits of cylinder # │7│6│5│4│3│2│1│0│ 2nd byte (cylinder) └─┴─┴─┴─┴─┴─┴───── Low order bits of cylinder # */ if ((i=Track &0x0300)!=0) { SecOnTrk = (SecOnTrk & 0x3F) | (int)(i>>2); } return ReadPhysSec(drive, SecOnTrk, Head, Track, Buffer); } /****************************************************************************/ int absread (int drive, int nsects, unsigned long lsect, void far *FarBuffer) { int i, j, k; unsigned err; #ifdef DEBUG printf("absread: lsect=%lu ",lsect); #endif for (i=0;i=MaxSectors) { printf("absread: lsect >=MaxSectors. lsect=%lu ",lsect); printf("MaxSectors=%lu\n",MaxSectors); return -1; } while(1) { #ifdef DEBUG /* Это проверка на непересечение адресом границы 64к. Иначе чтение/ запись флопов глючит (DMA overload) */ /* ЭТОТ ОПЕРАТОР HЕ УБИРАТЬ !!! При удлинении кода ядра опять наступит пересечение границы и опять надо будет NearBuffer куда-то перемещать */ /* printf("absread: NearBuffer = %lX ",(long)NearBuffer); */ #endif err=1; for (j=0;j>=8; printf("absread: error %2X in sec %li: ",err,lsect); Int13perror(err); printf(" Ignore (i), retry (r) or abort (a) ? "); j=getchar(); puts(""); if (j=='r') continue; else if (j=='a') return -1; else /* ignore */ break; } else break; } #if 1 for (k=0;k #include #include "kernel.h" #define Prec 2 #define Zero 0 /*----------------------------------------------------------------------------*/ /* E M A I N */ /*----------------------------------------------------------------------------*/ void e(int argc, char far*argv[]) { int i; printf("argc = %i\nProg name = %s\n",argc,argv[0]); argc += 1; for (i=0; i #include #include "kernel.h" #include #include /****************************************************************************/ #define CheckUserWriteDir /* #define DEBUG */ /****************************************************************************/ int FlushBuf(unsigned int i) { if ((*(Cache+i)).Status==2) { #if 0 printf(" w"); #endif if (abswrite(TR(CurrentDevice),1,(*(Cache+i)).Sec,(*(Cache+i)).M)) { printf("\nFlushBuf: abswrite error on sector %i\n",(*(Cache+i)).Sec); return -1; } else { (*(Cache+i)).Status=1; } } return 0; } /****************************************************************************/ int FlushAll(void) {int i, err; err=0; for (i=0;imax) { max=(*(Cache+i)).Counter; maxbuf=i; } /* нашли кандидата */ i=maxbuf; if (FlushBuf(i)) return -1; Fill: /* исписываем сектор нулями */ (*(Cache+i)).Status=2; for (j=0;jmax) { max=(*(Cache+i)).Counter; maxbuf=i; } /* нашли кандидата */ i=maxbuf; if (FlushBuf(i)) return -1; Load: if (absread(TR(CurrentDevice), 1, sec, (*(Cache+i)).M )) { printf("\nLoadCache: absread error on sector %i\n",sec); (*(Cache+i)).Status=0; return -1; } (*(Cache+i)).Status=1; (*(Cache+i)).Sec=sec; TouchCache(i); return i; } struct dirent Bolvan; /****************************************************************************/ int open2 (int h, const char far *path, int flag) {int i, j, Search, File, DevNo, SaveCur; struct dirent far *D; struct time timep; struct date datep; DIR far *dir; char far *cc; char far *cc0; const char far *name; char path0 [PATH_MAX+1]; struct dirent *pBolvan; pBolvan=&Bolvan; /* специальный файл ? */ i=0; File=1; if (!memcmp(path,"/dev/",5)) { do { if (!strcmp(path+5,Dev[i++].Name)) {File=0; DevNo=i; break;} } while (Dev[i].Name[0]); } if (!File) FCBS[h].File=0; else FCBS[h].File=1; /* Разбор имени path на собственно-path (path0) и name */ strncpy(path0,path,PATH_MAX); path0[PATH_MAX]=0; #if 0 /* Если в path0 последний символ '/', и он не один, то загасим его */ i=strlen(path0); if (i-->1) if (path0[i]=='/') path0[i]=0; #endif cc=path0; cc0=NULL; while ((cc=strchr(cc,'/'))!=NULL) cc0=cc++; if (cc0==NULL) { /* В пути path нет ни одного символа '/', что означает, что это локальное имя (без пути) */ path0[0]=0; name=path; } else { /* Имя path содержит по крайней мере один символ '/', значит это имя с путем. ("Все путем" ;) */ /* Запоминаем текущий каталог */ SaveCur=CurDirClu; if (cc0==path0) {/* символ '/' первый и единственный (имя вида "/file") */ name=path0+1; /* Делаем текущим каталог "/" */ if (chdir("/")==-1) { #ifdef DEBUG printf("L1"); #endif errno=ENOENT; goto ret_err; } } else { *cc0++=0; name=cc0; /* Делаем текущим каталог path0 */ if (chdir(path0)==-1) { #ifdef DEBUG printf("L2"); #endif errno=ENOENT; goto ret_err; } } } /* Если открываем файл "/" или при текущем корневом каталоге открываем "." или "..", то значит, открываем root dir */ if ( ( strcmp(path,"/")==0 ) || ( (CurDirClu==0) && ( (!strcmp(name,"."))||(!strcmp(name,"..")) ) ) ) {/* open (rootdir) */ FCBS[h].File=3; #ifdef CheckUserWriteDir if (((flag&O_WRONLY)||(flag&O_RDWR)) && Mode) {errno=EACCES; goto ret_err;} #endif strcpy(FCBS[h].Name,"/"); FCBS[h].BegClu=0; FCBS[h].Attr.B.Dir=1; FCBS[h].flag=flag; FCBS[h].Size=-1; FCBS[h].AbsOffset=0l; FCBS[h].AbsSec=RootBeg; goto ret_norm; } if (!strcmp(name,".")) /* файл "." (текущий каталог) должен открываться специальным способом, с использованием хранящейся в системе информации о текущем каталоге (переменная CurDirClu) */ {/* open (curdir) */ FCBS[h].File=2; #ifdef CheckUserWriteDir if (((flag&O_WRONLY)||(flag&O_RDWR)) && Mode) { errno=EACCES; return -1; } #endif strcpy(FCBS[h].Name,name); FCBS[h].BegClu=CurDirClu; FCBS[h].Attr.B.Dir=1; FCBS[h].DirInode=-1; FCBS[h].flag=flag; FCBS[h].Size=-1; FCBS[h].AbsOffset=0l; FCBS[h].AbsSec=SecForClu(CurDirClu); FCBS[h].AbsClu=CurDirClu; goto ret_norm; } if (File!=0) {/* file or dir */ /* Ищем файл (or dir) в каталоге */ PathToDir(name, pBolvan); #ifdef DEBUG printf("open2: `%Fs'->",name); printf("`%s' ",Bolvan.d_name); #endif if ((dir=opendir("."))==NULL) {puts("open: can't search in current dir"); errno=EFAULT; goto ret_err;} while(1) { if ((D=readdir(dir))==NULL) break; if ( (*D).d_name[0]==0 ) continue; if ( (*D).d_name[0]==0xe5 ) continue; if ( (*D).Attr.B.Label ) continue; #ifdef DEBUG /* printf("open2: d1=`%s' d2=`%s' ",(*D).d_name,Bolvan.d_name); */ #endif if (dircmp((*D),Bolvan)==0) {Search=1; FCBS[h].DirInode=CurDirClu; FCBS[h].DirSeekPos=telldir(dir)-32; goto l_cont; } } Search=0; l_cont: if (closedir(dir)==-1) goto ret_err; if (Search) { if ((flag&O_EXCL)&&(flag&O_CREAT)) {errno=EEXIST; goto ret_err;} FCBS[h].Attr.U=(*D).Attr.U; if ((*D).Attr.B.Dir) {/* found dir */ #ifdef CheckUserWriteDir if (((flag&O_WRONLY)||(flag&O_RDWR)) && User) {errno=EACCES; goto ret_err;} #endif FCBS[h].File=2; FCBS[h].Size=-1; } else {/* found ordinary (regular) file (not directory) */ if (flag&O_TRUNC) { /* truncate */ if ((i=(*D).d_fileno)!=0) while(1) { j=NextClu(i); if(LinkClu(i,0)==-1) {errno=EFAULT; goto ret_err;}; if (j==-1) break; else i=j; } (*D).Size=0; (*D).d_fileno=0; #if 0 if ((dir=openwdir("."))==NULL) {puts("open: can't search in current dir"); errno=EFAULT; goto ret_err;} if (seekdir(dir,FCBS[h].DirSeekPos,SEEK_SET)==-1) goto ret_err; if (writedir(dir,D)==-1) goto ret_err; if (closedir(dir)==-1) goto ret_err; #endif } FCBS[h].Size=(*D).Size; } FCBS[h].flag=flag; FCBS[h].FileDateTime.ft_hour =(*D).FileDateTime.ft_hour; FCBS[h].FileDateTime.ft_min =(*D).FileDateTime.ft_min ; FCBS[h].FileDateTime.ft_tsec =(*D).FileDateTime.ft_tsec ; FCBS[h].FileDateTime.ft_day =(*D).FileDateTime.ft_day ; FCBS[h].FileDateTime.ft_month=(*D).FileDateTime.ft_month; FCBS[h].FileDateTime.ft_year =(*D).FileDateTime.ft_year ; if ((FCBS[h].BegClu=(*D).d_fileno)==0) { FCBS[h].AbsSec=RootBeg; FCBS[h].File=3; } else { FCBS[h].AbsClu=FCBS[h].BegClu; FCBS[h].AbsSec=SecForClu(FCBS[h].AbsClu); } FCBS[h].AbsOffset=0l; } else { /* File not exist*/ if (flag&O_RDONLY) { #ifdef DEBUG printf("L3"); #endif errno=ENOENT; goto ret_err; } /* Creating */ /* Ищем свободный вход в каталоге */ if ((dir=openwdir("."))==NULL) {puts("open: can't search in current dir"); errno=EFAULT; goto ret_err;} while(1) { if ((D=(void far *)readdir(dir))==NULL) break; if (!(*D).d_name[0] || ((*D).d_name[0]==0xe5)) {/* нашли св. вход в каталог */ /* создаем запись о файле */ /* заполняем поля FCB */ FCBS[h].DirInode=CurDirClu; if ((FCBS[h].DirSeekPos=seekdir(dir,-32l,SEEK_CUR))==-1) printf("open: can't seek cur dir"); (*D).Attr.U=FA_ARCH; PathToDir(name,D); gettime (&timep); (*D).FileDateTime.ft_tsec=timep.ti_sec*2; (*D).FileDateTime.ft_min =timep.ti_min; (*D).FileDateTime.ft_hour=timep.ti_hour; getdate(&datep); (*D).FileDateTime.ft_day =datep.da_day; (*D).FileDateTime.ft_month=datep.da_mon; (*D).FileDateTime.ft_year =datep.da_year; (*D).d_fileno=0; (*D).Size=0; /* заполняем поля FCB */ FCBS[h].Attr.U =(*D).Attr.U; FCBS[h].flag=flag; FCBS[h].FileDateTime.ft_hour =(*D).FileDateTime.ft_hour; FCBS[h].FileDateTime.ft_min =(*D).FileDateTime.ft_min ; FCBS[h].FileDateTime.ft_tsec =(*D).FileDateTime.ft_tsec ; FCBS[h].FileDateTime.ft_day =(*D).FileDateTime.ft_day ; FCBS[h].FileDateTime.ft_month=(*D).FileDateTime.ft_month; FCBS[h].FileDateTime.ft_year =(*D).FileDateTime.ft_year ; FCBS[h].BegClu=(*D).d_fileno; FCBS[h].Size=(*D).Size; FCBS[h].AbsOffset=0l; FCBS[h].AbsClu=FCBS[h].BegClu; FCBS[h].AbsSec=0; if (writedir(dir, D)==0) { closedir(dir); goto ret_norm; } else goto L1; } } L1: /* св. входа нет :( */ closedir(dir); errno=ENOSPC; goto ret_err; } /* file not exist. creating */ } /* file */ else { /* dev */ /* DRIVER /dev/?????????? */ /* FCBS[h].Major=Dev[DevNo].Major; FCBS[h].Minor=Dev[DevNo].Minor; */ FCBS[h].Size=-1; if (!Dev[DevNo].Byte) { FCBS[h].AbsOffset=0l; FCBS[h].AbsSec=0; } } /* dev */ ret_norm: errno=0; /* Если это необходимо, восстанавливаем прежний текущий каталог */ if (path0[0]) CurDirClu=SaveCur; return h; ret_err: FCBS[h].Name[0]=0; /* Если это необходимо, восстанавливаем прежний текущий каталог */ if (path0[0]) CurDirClu=SaveCur; return -1; } /****************************************************************************/ int open (const char far *path, int flag,...) {int h, k; /* Эти флаги реализованы O_RDONLY O_WRONLY O_RDWR O_CREAT /* create and open file */ O_TRUNC /* open with truncation */ O_EXCL /* exclusive open */ O_APPEND /* to end of file */ Эти флаги будут реализованы? O_NOINHERIT O_DENYALL O_DENYWRITE O_DENYREAD O_DENYNONE */ /* Проверяем флаги на корректность */ /* Проверяем обязательные флаги на присуствие */ if (!((O_RDONLY|O_WRONLY|O_RDWR) & flag)) goto L_INVAL; /* Проверяем флаги на несовместимые сочетания */ if ((flag&O_RDONLY)&&((flag&O_WRONLY)||(flag&O_RDWR))) goto L_INVAL; if ((flag&O_RDWR)&&((flag&O_WRONLY))) goto L_INVAL; if ((flag&O_TRUNC)&&((flag&O_RDONLY))) goto L_INVAL; h=-1; if (path==NULL) { goto L_INVAL; } if (*path==0) { L_INVAL: #ifdef DEBUG printf("L4"); #endif errno=ENOENT; return -1; } /* Здесь (или далее) сделать сравнение открываемого файла с уже открытыми по номеру нач. кластера и номеру файловой системы */ /* for(k=0;kOPEN_MAX)) {errno=EBADF; return -1;} if (ftimep==NULL) {errno=EINVAL; return -1;} if (!FCBS[h].Name[0]) {errno=EBADF; return -1;} (*ftimep).ft_hour = FCBS[h].FileDateTime.ft_hour ; (*ftimep).ft_min = FCBS[h].FileDateTime.ft_min ; (*ftimep).ft_tsec = FCBS[h].FileDateTime.ft_tsec ; (*ftimep).ft_day = FCBS[h].FileDateTime.ft_day ; (*ftimep).ft_month= FCBS[h].FileDateTime.ft_month ; (*ftimep).ft_year = FCBS[h].FileDateTime.ft_year ; return 0; } /****************************************************************************/ int setftime (int h, struct ftime far *ftimep) {DIR far *fp; struct dirent far *D; if ((h<0)||(h>OPEN_MAX)) {errno=EBADF; return -1;} if (ftimep==NULL) {errno=EINVAL; return -1;} if (!FCBS[h].Name[0]) {errno=EBADF; return -1;} if ( (FCBS[h].flag & O_WRONLY) || (FCBS[h].flag & O_RDWR) ) { if ((fp=openidir(FCBS[h].DirInode))==NULL) return -1; if (seekdir(fp,FCBS[h].DirSeekPos,SEEK_SET)==-1) return -1; if ((D=readdir(fp))==NULL) return -1; if (seekdir(fp,FCBS[h].DirSeekPos,SEEK_SET)==-1) return -1; (*D).FileDateTime.ft_hour = (*ftimep).ft_hour ; (*D).FileDateTime.ft_min = (*ftimep).ft_min ; (*D).FileDateTime.ft_tsec = (*ftimep).ft_tsec ; (*D).FileDateTime.ft_day = (*ftimep).ft_day ; (*D).FileDateTime.ft_month = (*ftimep).ft_month ; (*D).FileDateTime.ft_year = (*ftimep).ft_year ; FCBS[h].FileDateTime.ft_hour = (*ftimep).ft_hour ; FCBS[h].FileDateTime.ft_min = (*ftimep).ft_min ; FCBS[h].FileDateTime.ft_tsec = (*ftimep).ft_tsec ; FCBS[h].FileDateTime.ft_day = (*ftimep).ft_day ; FCBS[h].FileDateTime.ft_month = (*ftimep).ft_month; FCBS[h].FileDateTime.ft_year = (*ftimep).ft_year ; if (writedir(fp,D)==-1) return -1; return closedir(fp); } else { errno=EPERM; } return -1; } /****************************************************************************/ int chmod(const char far *filename, int amode) {int h; h=amode; if ((h=open(filename,O_RDONLY))==-1) return -1; else close(h); return 0; } /****************************************************************************/ int _chmod(const char far *filename, int func, ...) {int h; int attribute; va_list v; /* func: 0 - read attr, 1 - set attr. attr see in */ if ((h=open(filename,func?O_WRONLY:O_RDONLY))==-1) return -1; if (func==1) { /* Функция 1 - установить атрибуты файла */ int Label; int Dir; int Attr1; va_start(v,0); attribute = va_arg(v,int); /* Сохраняем неизменяемые атрибуты */ Label=FCBS[h].Attr.B.Label; Dir =FCBS[h].Attr.B.Dir ; Attr1=FCBS[h].Attr.B.Attr1; /* Устанавливаем атрибуты */ FCBS[h].Attr.U = attribute; /* Восстанавливаем неизменяемые атрибуты */ FCBS[h].Attr.B.Label=Label; FCBS[h].Attr.B.Dir =Dir ; FCBS[h].Attr.B.Attr1=Attr1; } else {/* Функция 0 - взять атрибуты файла */ attribute=FCBS[h].Attr.U; } if (close(h)==-1) return -1; return attribute; } /****************************************************************************/ int access(const char far *filename, int amode) {int flag, h; if (amode==2) flag=O_WRONLY; else flag=O_RDONLY; if((h=open(filename,flag))==-1) return -1; else if(close(h)==-1) return -1; return 0; } /****************************************************************************/ long int read(int h, void far *buf, unsigned long len) { int i, b; long l; char c; if ((h<0)||(h>OPEN_MAX)) {errno=EBADF; return -1;} if (buf==NULL) {errno=EINVAL; return -1;} if (len==0) {errno=0; return 0;} if (!FCBS[h].Name[0]) {errno=EBADF; return -1;} if (FCBS[h].flag & O_WRONLY) {errno=EACCES; return -1;} if (h==0) if (FCBS[h].File==0) { for(i=0;i FCBS[h].Size) if ((len=FCBS[h].Size-FCBS[h].AbsOffset)==0) {errno=0; return 0; } if ((b=LoadCache(FCBS[h].AbsSec))==-1) {errno=EFAULT; return -1; } SecOffset=(int)(FCBS[h].AbsOffset % SECTOR_SIZE); for (i=0;iOPEN_MAX)) {errno=EBADF; return -1;} if (buf==NULL) {errno=EINVAL; return -1;} if (!FCBS[h].Name[0]) {errno=EBADF; return -1;} if (FCBS[h].flag & O_RDONLY) {errno=EACCES; return -1;} if (len==0) {errno=0; return 0;} if((h>=0)&&(h<=2)) if (FCBS[h].File==0) { for(l=0;lOPEN_MAX)) {errno=EBADF; return -1;} else { if (FCBS[h].Name[0]) { if ( (FCBS[h].File==1) || (FCBS[h].File==2) ) { if ((FCBS[h].flag&O_WRONLY)||(FCBS[h].flag&O_RDWR)) { if ((i=FCBS[h].DirInode)!=-1) { if ((fp=openidir(i))==NULL) return -1; if (seekdir(fp,FCBS[h].DirSeekPos,SEEK_SET)==-1) return -1; if ((D=readdir(fp))==NULL) return -1; if ((*D).d_fileno!=FCBS[h].BegClu) {Update=1; (*D).d_fileno=FCBS[h].BegClu;} if (FCBS[h].File==1) if ((*D).SizeOPEN_MAX)) {errno=EBADF; return -1;} if(FCBS[h].Name[0]) return FCBS[h].Size; else return -1; } /****************************************************************************/ long tell(int h) { if ((h<0)||(h>OPEN_MAX)) {errno=EBADF; return -1L;} if (!FCBS[h].Name[0]) {errno=EBADF; return -1L;} return FCBS[h].AbsOffset; } /****************************************************************************/ long lseek(int h, long offset, int fromwhere) {int i; long j, n; if ((h<0)||(h>OPEN_MAX)) {errno=EBADF; return -1L;} if (!FCBS[h].Name[0]) {errno=EBADF; return -1L;} switch (fromwhere) { case SEEK_SET: if (offset<0) {errno=EINVAL; return -1L;} /* offset>=0 */ /* установка файла в начало (rewind) */ FCBS[h].AbsOffset=0l; if ((FCBS[h].File==1)||(FCBS[h].File==2)) /* file or directory */ { FCBS[h].AbsClu=FCBS[h].BegClu; FCBS[h].AbsSec=SecForClu(FCBS[h].AbsClu); } else if (FCBS[h].File==3) /* root dir */ FCBS[h].AbsSec=RootBeg; /* после этого мы перескакиваем на следующий пункт case и его выполнение делает именно то, что надо */ case SEEK_CUR: if (offset==0) return FCBS[h].AbsOffset; if (offset>0) {char buf[SECTOR_SIZE]; for (i=0; i int service(int fn) { switch (fn) { case 1: ps_(); } return 0; } src/kernel/msh.h0100664000076500007650000000120307725645016013326 0ustar prool2prool2#define MenuColumn 68 struct DeskTop { int x; int y; char Name [13]; }; struct DeskTop Folder [MAX_LINE]; struct DeskTop Desk [ ] = { {MenuColumn, 4," [Click] "}, {MenuColumn, 5," [Exec] "}, {MenuColumn, 6," [Attr] "}, {MenuColumn, 7," [Cls] "}, {MenuColumn, 8," [Mem] "}, {MenuColumn, 9," [Ls -l] "}, {MenuColumn,10," [Help] "}, {MenuColumn,11," [Echo] "}, {MenuColumn,12," [Vectors] "}, {MenuColumn,13," [Ladder] "}, {MenuColumn,14," [Reboot] "}, {MenuColumn,15," [Int 0] "}, {MenuColumn,16," [Int 18h] "}, {MenuColumn,17," [Int 19h] "}, {MenuColumn,18," [Com Addr] "}, {-1,-1,""} }; int DeskNo; src/kernel/vexe.c0100664000076500007650000000117707725645020013506 0ustar prool2prool2#include #include #include #include "viewexe.c" #define BUFLEN 512 void ident (void) { printf("View EXE ver. 0.0.0.1 9-Mar-96 (c) by Prool\n\n"); } void main (int argc, char *argv[]) {char buf [BUFLEN]; int h, i; if (argc!=2) { ident(); printf("usage: vexe filename"); } else { if ((h=open(argv[1],O_RDONLY | O_BINARY))==-1) printf("Can't open %s\n",argv[1]); if ((i=read(h,buf,BUFLEN))!=BUFLEN) printf("Can't read %s. read()=%i\n",argv[1],i); close(h); printf("File %s\n\n",argv[1]); ViewEXE((void *)buf); printf("\n\n"); ident(); } } src/kernel/ls.c0100664000076500007650000000750407725645016013162 0ustar prool2prool2#include #include #include "kernel.h" /****************************************************************************/ /* #define DEBUG */ /****************************************************************************/ void l_help(void) { puts("Uses: l [-l] [-L] [-U] [-H] [-F] [-T] [-M]\n\n\ Switches:\n\n\ -l - long info\n\ -L - very long info\n\ -U - list unused dir records\n\ -H - hex output (default - dec output)\n\ -F - free space\n\ -T - title\n\ -M - more"); } /****************************************************************************/ void OutAttr(struct AttrField far *Attr) { if ((*Attr).Attr1) putch('*'); else putch('.'); if ((*Attr).Attr2) putch('*'); else putch('.'); if ((*Attr).Archive) putch('A'); else putch('.'); if ((*Attr).Dir) putch('D'); else putch('.'); if ((*Attr).Label) putch('L'); else putch('.'); if ((*Attr).System) putch('S'); else putch('.'); if ((*Attr).Hidden) putch('H'); else putch('.'); if ((*Attr).ReadOnly) putch('R'); else putch('.'); } /****************************************************************************/ void OutTimeDate(struct ftime far *t) { printf("%2i:%02i:%02i %2i-%02i-%02i", (*t).ft_hour, (*t).ft_min, (*t).ft_tsec*2, (*t).ft_day, (*t).ft_month,1980+(*t).ft_year); } /****************************************************************************/ int l (int argc, char far *argv[]) {int i, j, k, n; struct dirent far *D; char Path [NAME_MAX+1]; int FlagL=0; int FlagU=0; int FlagLL=0; int FlagH=0; int FlagF=0; int FlagT=0; unsigned long size; unsigned long SumSize=0; unsigned long Total; DIR far *dir; argc--; i=1; do { if (argc) { if (argv[i][0]=='-') { n=(int)strlen(argv[i]); for (j=1;j\n")==EOF) goto l_ret; continue; } printf("%-13s",DirToPath(D,Path)); SumSize+=(size=(*D).Size); if (!FlagL) {if (puts("")==EOF) goto l_ret; continue; } else { OutAttr(&((*D).Attr.B)); if (FlagLL) {putch(' '); for (k=0;k<10;k++)printf("%2X",(*D).Reserv[k]); } putch(' '); OutTimeDate(&((*D).FileDateTime)); printf(FlagH?" %4X":" %5u",(*D).d_fileno); if (printf(FlagH?" %8lX\n":" %8lu\n",size)==EOF) goto l_ret; } } l_ret: if (closedir(dir)==EOF) perror("l: closedir"); if (FlagF) { Total=(MaxSectors - (unsigned long)DataStart) * (unsigned long)SECTOR_SIZE; printf("Total drive size %li\n",Total); printf("Total allocated %li\n",SumSize); printf("Free %li\n",Total-SumSize); } More=0; NLine=1; return 0; } src/kernel/minus.c0100664000076500007650000000014507725645016013671 0ustar prool2prool2#include #include #include "kernel.h" int minus(void) { return -1; } src/kernel/ctype.c0100664000076500007650000000274307725645015013667 0ustar prool2prool2#include #include #include "kernel.h" /****************************************************************************/ int isgraph(int c) { return ((c) >= 0x21 && (c) <= 0x7e); } /****************************************************************************/ int isprint(int c) { return ((c) >= 0x20 && (c) <= 0x7e); } /****************************************************************************/ int isalnum (int c) {return isdigit(c)||isalpha(c);} int isalpha (int c) {return islower(c)||isupper(c);} int iscntrl (int c) {return c<' ';} int isdigit (int c) {return (c>='0')&&(c<='9');} int islower (int c) {return (c>='a')&&(c<='z');} int ispunct (int c) { switch(c) { /* (C) Список символов пунктуации взят из программы Connect Д.Орлова и др. Copyright by KHEMZ, Inc. 1991, 1994 */ case '.': case ',': case '!': case '"': case '\'': case '(': case ')': case '*': case '+': case '-': case '/': case ':': case ';': case '<': case '=': case '>': case '?': case '[': case '\\': case ']': case '^': case '{': case '|': case '}': case '~': return 1; default: return 0; } } /****************************************************************************/ int isspace (int c) {if ((c==' ')||(c=='\t')) return 1; else return 0;} int isupper (int c) {return (c>='A')&&(c<='Z');} int isxdigit(int c) {return ((c>='0')&&(c<='9'))||((c>='a')&&(c<='f'))||((c>='A')&&(c<='F'));} src/kernel/tlib.cmd0100664000076500007650000000140007725645020013777 0ustar prool2prool2kernel/C/E-+stdlib-+ctype-+strchr-+strdup-+string-+strlen-+tolower-+cluread-+nextclu-+sec4clu-+readsec2-+out_mbr-+out_dev-+k2-+int8-+ints-+int0-+ints5-+minus-+nulldev-+setjmp-+out_os-+tr-+videopag-+strtoul-+service-+int1b-+exitw & -+memd-+absread-+abswrite-+cmos-+nocmos-+time-+regdump -+sayr-+port-+ohb-+vector-+clrscr-+cursor-+reboot-+cold-+hdd2-+genint-+msdos-+loop-+comport -+stdio-+initv-+kbhit-+end-+getch0-+putch0-+putch1-+putch2-+putch3-+int13err-+bootread-+bootred0-+readsec & -+txtattr-+intercept-+vec-+out_iv-+out_boot-+mem-+memmove-+ls-+rm-+mv-+cp-+cat-+de-+e-+int86-+stream-+gets-+mouse-+printf-+fprintf-+run_boot & -+char_in-+char_out-+ohw-+msherc-+msherc1-+io-+dir-+debug-+p2d-+d2p-+sh-+stat-+syserr-+viewexe-+rand-+int5dump-+qsort-+conv,kernel.dic src/kernel/stdio.c0100664000076500007650000000454607725645017013672 0ustar prool2prool2#include #include #include #include "kernel.h" /****************************************************************************/ #if 0 /* Это сохранено для истории */ char Hex [] = "0123456789ABCDEF"; void ohb (char c) { putch(Hex[c>>4]); putch(Hex[c&0xf]); } void ohw (int w) { ohb(w>>8); ohb(w&0xff); } void ohd (unsigned long int ll) { ohw(ll>>16); ohw(ll&0xffff); } #endif /****************************************************************************/ void perror(const char far *str) { printf("%s: ",str); puts(sys_errlist[errno]); return; /* потом нужно будет заменить printf на fprintf(stderr, ... */ } /****************************************************************************/ void ohs(const char far *s) { do printf("%2X ",*s); while (*s++); } /****************************************************************************/ int unlink(const char far *path) {int h; /* Проверка существования файла и проверка, что это не каталог */ if ((h=open(path,O_RDONLY))==-1) {errno=ENOENT; return -1;} else { if (FCBS[h].Attr.B.Dir) {close(h); errno=EPERM; return -1;} if (close(h)==-1) return -1; } /* Собственно удаление */ return delete(path); } /****************************************************************************/ int delete (const char far *path) {int h, Inode; DIR far *fp; struct dirent far *D; long Pos; if ((h=open(path,O_WRONLY|O_TRUNC))==-1) return -1; Inode=FCBS[h].DirInode; Pos=FCBS[h].DirSeekPos; if (close(h)==-1) return -1; if ((fp=openidir(Inode))==NULL) return -1; if (seekdir(fp,Pos,SEEK_SET)==-1) return -1; if ((D=readdir(fp))==NULL) return -1; (*D).d_name[0]=0xE5; if (seekdir(fp,Pos,SEEK_SET)==-1) return -1; if (writedir(fp,D)==-1) return -1; if (closedir(fp)==-1) return -1; return 0; } /****************************************************************************/ int rename(const char far *old, const char far *new) {int h; struct dirent far *D; DIR far *fp; if((h=open(old,O_WRONLY))==-1) return -1; if ((fp=openidir(FCBS[h].DirInode))==NULL) return -1; if (seekdir(fp,FCBS[h].DirSeekPos,SEEK_SET)==-1) return -1; if ((D=readdir(fp))==NULL) return -1; PathToDir(new,D); if (seekdir(fp,FCBS[h].DirSeekPos,SEEK_SET)==-1) return -1; if (writedir(fp,D)==-1) return -1; FCBS[h].Name[0]=0; if (closedir(fp)==-1) return -1; return 0; } src/kernel/abswrite.c0100664000076500007650000000510207725645014014352 0ustar prool2prool2#include #include #include "kernel.h" extern unsigned char NearBuffer []; int Int13perror(unsigned err); /****************************************************************************/ /* #define DEBUG */ /****************************************************************************/ extern unsigned char NearBuffer [SECTOR_SIZE]; /* defined in kernel.c */ /****************************************************************************/ int secwrite (int drive, unsigned long AbsSec, char *Buffer) {/* Write absolute sectors Input: drive (for int 13h Fn=2) abs sec number buffer Output: return!=0 if error */ int Track, SecNoOnCyl, i; char Head, SecOnTrk; Track=(int)(AbsSec/SectorsOnCyl); /* SectorsOnCyl=HeadCnt*TrkSecs, Track == Cyl */ SecNoOnCyl=(int)(AbsSec%SectorsOnCyl); Head=SecNoOnCyl/TrkSecs; SecOnTrk=SecNoOnCyl%TrkSecs+1; /* 2 bytes are combined to a word similar to INT 13: │7│6│5│4│3│2│1│0│ 1st byte (sector) │ │ └─┴─┴─┴─┴─┴── Sector offset within cylinder └─┴───────────── High order bits of cylinder # │7│6│5│4│3│2│1│0│ 2nd byte (cylinder) └─┴─┴─┴─┴─┴─┴───── Low order bits of cylinder # */ if ((i=Track &0x0300)!=0) { SecOnTrk = (SecOnTrk & 0x3F) | (int)(i>>2); } return WritePhysSec(drive, SecOnTrk, Head, Track, Buffer); } /****************************************************************************/ int abswrite (int drive, int nsects, unsigned long lsect, void far *FarBuffer) { int i, j, k; unsigned err; if (ReadOnly) { puts("Drive has mounted read only. Write not allowed!"); return -1; } for (i=0;i=MaxSectors) { puts("absread: lsect >=MaxSectors"); return -1; } #if 1 for (k=0;k>=8; printf("absread: error %2X in sec %i: ",err,lsect); Int13perror(err); printf(" Ignore (i), retry (r) or abort (a) ? "); j=getchar(); puts(""); if (j=='r') continue; else if (j=='a') return -1; else /* ignore */ break; } else break; } /* FarBuffer = (char far *) FarBuffer + SECTOR_SIZE; */ } return 0; } /****************************************************************************/ src/kernel/bios.c0100664000076500007650000000704707725645014013500 0ustar prool2prool2#include #ifndef EXE #include "kernel.h" #include #else #include #endif #include /*---------------------------------------------------------------------------*/ /* Из книги Фролов А.В.,Фролов Г.В. Программирование модемов.-М.:"ДИАЛОГ-МИФИ", 1993.-240с.-(Библиотека системного программиста; Т.4) Portions Copyright by А.В.Фролов, Г.В.Фролов, 1993. */ unsigned com_address ( int portid ) { unsigned base_address; if(( portid > 4) || ( portid < 0 )) return( -1 ); base_address = *(( unsigned far * ) MK_FP( 0x40, portid * 2 )); return( base_address ); } /* Из книги OFF */ /*---------------------------------------------------------------------------*/ #ifndef EXE int inicom (unsigned int portid, unsigned char Par) {int i; int ComBase; i=inicom_(portid,Par); if((ComBase=com_address(portid))==0)return -1; outp (ComBase+LCR, inp((ComBase+LCR) | 0x80) ); outp (ComBase+ICR,0); return i; } #endif /*---------------------------------------------------------------------------*/ int getcom(int portid) {int ComBase; if((ComBase=com_address(portid))==0) return -1; if ( inp(ComBase+LSR) & 1 ) return inp(ComBase); else return -2; } /*---------------------------------------------------------------------------*/ int putcom(int portid, unsigned char byte) {int ComBase; if((ComBase=com_address(portid))==0) return -1; while (( inp(ComBase+LSR) & 0x20 )==0); outp(ComBase,byte); return 0; } /*---------------------------------------------------------------------------*/ int getcomstat(int portid) {int ComBase; if((ComBase=com_address(portid))==0) return -1; return inp(ComBase+LSR); } /*---------------------------------------------------------------------------*/ int is_UART_8250 (int port ) { int save_scr, in_scr; int addr; int ComBase; ComBase=com_address(port); #ifdef EXE if (ComBase) printf("%4X",ComBase); #endif if(ComBase==0)return -1; addr=ComBase+(0x3ff-0x3f8); save_scr=inp(addr); outp(addr,0x5a); in_scr=inp(addr); if(in_scr!=0x5a){ outp(addr,save_scr); return UART_8250; } outp(addr,0xa5); in_scr=inp(addr); outp(addr,save_scr); if(in_scr!=0xa5) return UART_8250; return 0; } /*---------------------------------------------------------------------------*/ int is_UART_FIFO(int port) { /*int save_iir;*/ int in_iir; int addr; int ComBase; if((ComBase=com_address(port))==0) return -1; addr=ComBase+(0x3fa-0x3f8); /*save_iir=inp(addr);*/ outp(addr,1); in_iir=inp(addr); outp(addr,0); if((in_iir & 0x40) == 1) return UART_16550A; if((in_iir&0x80)==1) return UART_16550; return UART_16450; } /*---------------------------------------------------------------------------*/ int uart_type (int port) {int test; if( (test=is_UART_8250(port)) == UART_8250 ) return UART_8250; else if (test==-1) return -1; if(( test = is_UART_FIFO(port) ) == UART_16550A ) return UART_16550A; if(test == UART_16550) return UART_16550; return UART_16450; } #ifdef EXE main() {int i; char * UARTname [] = { "8250 without FIFO", "16450 without FIFO", "16550 with FIFO", "16550A with FIFO"}; clrscr(); puts("Port Base addr UART type"); printf( "COM1 ");if((i=uart_type(0))!=-1)printf(UARTname[i-1]);else printf("Not found"); printf("\nCOM2 ");if((i=uart_type(1))!=-1)printf(UARTname[i-1]);else printf("Not found"); printf("\nCOM3 ");if((i=uart_type(2))!=-1)printf(UARTname[i-1]);else printf("Not found"); printf("\nCOM4 ");if((i=uart_type(3))!=-1)printf(UARTname[i-1]);else printf("Not found"); puts(""); } #endif src/kernel/msherc.asm0100664000076500007650000025265307725645016014372 0ustar prool2prool2; MSHerc.com ; Disassembled by Sourcer V 5.04 (C) V COMMUNICATIONS, INC. 1988-1993 ; Copyright (C) Comments for Serge Pustovoitoff, 1995 ;PAGE ,78 ;██████████████████████████████████████████████████████████████████████████ ;██ ██ ;██ MSHERC ██ ;██ ██ ;██ Created: 7-Mar-88 ██ ;██ Passes: 9 Analysis Options on: none ██ ;██ ██ ;██████████████████████████████████████████████████████████████████████████ ; The following equates show data references outside the range of the program. Vec10h equ 10h*4 equip_bits_ equ 410h video_mode_ equ 449h video_columns_ equ 44Ah video_buf_siz_ equ 44Ch video_segment_ equ 44Eh vid_curs_pos0_ equ 450h vid_curs_pos1_ equ 452h vid_curs_mode_ equ 460h video_page_ equ 462h data_3e equ 81h data_143e equ 9C38h ;* data_144e equ 0AA39h ;* data_145e equ 0B053h ;* data_146e equ 0B83Ah ;* data_147e equ 2000h data_148e equ 7FA6h data_149e equ 2000h seg_a segment byte public assume cs:seg_a org 100h msherc proc far start: jmp StayResident Trap10h: push bp push es push ds push di push si push dx push cx push bx push ax mov bp,sp push cs pop ds mov es,data_25 cld cmp ah,0EFh je l_Fn_EF ; Fn = EF ; From [Interrupt List]: ;INT 10 - VIDEO - MSHERC.COM - GET VIDEO ADAPTER TYPE AND MODE ; AH = EFh ;Return: DL = video adapter type ; 00h original Hercules ; 01h Hercules Plus ; 02h Hercules InColor??? ; DH = memory mode byte ; 01h "half" mode ; 03h "full" mode or ah,ah jz l_Fn_0 ; Fn = 00 set video mode cmp byte ptr Flag,0 jnz ToOld cmp ah,0Fh ja l_Fn_GT_0F ; Fn > 0F l_Fn: ; Fn <= 0F mov di,[bp+1] and di,0FFh ; di = ah (from stack) shl di,1 ; di *= 2 call word ptr FunTab[di] l_iret: ; выход из прерывания pop ax pop bx pop cx pop dx pop si pop di pop ds pop es pop bp iret l_Fn_GT_0F: cmp ah,0F0h jb l_iret ; Fn > F0 - exit jmp short ToOld l_Fn_EF: call sub_4 jmp short l_iret l_Fn_0: cmp al,8 je l_Fn cmp al,88h je l_Fn mov byte ptr Flag,1 ToOld: ; Передаем упр. старому вектору pop ax pop bx pop cx pop dx pop si pop di pop ds pop es pop bp jmp dword ptr cs:OldVec10h msherc endp public msherc ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ; SUBROUTINE ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ Null proc near retn Null endp ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ db 7 dup (0) ; Data table (indexed access) FunTab dw offset SetVideoMode ; 0 set video mode data_6 dw offset SetCur ; 1 set cursor data_7 dw offset SetCurPos ; 2 set cur pos data_8 dw offset GetCurPos ; 3 get cur pos data_9 dw offset Null ; 4 get pen data_10 dw offset SetPage ; 5 set page data_11 dw offset ScrollUp ; 6 scroll up data_12 dw offset ScrollDn ; 7 scroll down data_13 dw offset GetSymAttr ; 8 get sym/attr data_14 dw offset WriteSymAttr ; 9 write sym/attr data_15 dw offset WriteSym ; A write sym data_16 dw offset Null ; B set palette/border data_17 dw offset Dot ; C dot data_18 dw offset GetPoint ; D get point data_19 dw offset tty ; E tty data_20 dw offset GetVideoMode ; F get video mode OldVec10h dd 0 public OldVec10h Flag db 1 FlagH db 3 ; or 1 if Flag data_25 dw 0 data_26 db 0 data_27 db 35h db 2Dh, 2Eh, 07h, 5Bh, 02h, 57h db 57h, 02h, 03h db 0, 0, 0, 0 data_29 dw 0 data_30 dw 0 data_32 dw 0 data_33 db 1 ; Data table (indexed access) db 02h, 04h, 08h, 10h, 20h, 40h db 80h data_34 db 0FEh ; Data table (indexed access) db 0FCh,0F8h,0F0h,0E0h,0C0h, 80h db 00h data_35 db 0 ; Data table (indexed access) db 01h, 03h, 07h, 0Fh, 1Fh, 3Fh db 7Fh data_36 dw 0 ; Data table (indexed access) db 00h, 20h, 00h, 40h, 00h, 60h db 5Ah, 00h, 5Ah, 20h, 5Ah, 40h db 5Ah, 60h,0B4h, 00h,0B4h, 20h db 0B4h, 40h,0B4h, 60h, 0Eh, 01h db 0Eh, 21h, 0Eh, 41h, 0Eh, 61h db 68h, 01h, 68h, 21h, 68h, 41h db 68h, 61h,0C2h, 01h,0C2h, 21h db 0C2h, 41h,0C2h, 61h, 1Ch, 02h db 1Ch, 22h, 1Ch, 42h, 1Ch, 62h db 76h, 02h, 76h, 22h, 76h, 42h db 76h, 62h,0D0h, 02h,0D0h, 22h db 0D0h, 42h,0D0h, 62h, 2Ah, 03h db 2Ah, 23h, 2Ah, 43h, 2Ah, 63h db 84h, 03h, 84h, 23h, 84h, 43h db 84h, 63h,0DEh, 03h,0DEh, 23h db 0DEh, 43h,0DEh, 63h, 38h, 04h db 38h, 24h, 38h, 44h, 38h, 64h db 92h, 04h, 92h, 24h, 92h, 44h db 92h, 64h,0ECh, 04h,0ECh, 24h db 0ECh, 44h,0ECh, 64h, 46h, 05h db 46h, 25h, 46h, 45h, 46h, 65h db 0A0h, 05h,0A0h, 25h,0A0h, 45h db 0A0h, 65h,0FAh, 05h,0FAh, 25h db 0FAh, 45h,0FAh, 65h, 54h, 06h db 54h, 26h, 54h, 46h, 54h, 66h db 0AEh, 06h,0AEh, 26h,0AEh, 46h db 0AEh, 66h, 08h, 07h, 08h, 27h db 08h, 47h, 08h, 67h, 62h, 07h db 62h, 27h, 62h, 47h, 62h, 67h db 0BCh, 07h,0BCh, 27h,0BCh, 47h db 0BCh, 67h, 16h, 08h, 16h, 28h db 16h, 48h, 16h db 'hp', 8, 'p(pHph' db 0CAh, 08h,0CAh, 28h,0CAh, 48h db 0CAh db 'h$' db 9, '$' db ')$' db 'I$' db 'i~', 9, '~)~I~i' db 0D8h, 09h,0D8h, 29h,0D8h, 49h db 0D8h db 'i2', 0Ah, '2*2J2j' db 8Ch, 0Ah, 8Ch, 2Ah, 8Ch, 4Ah db 8Ch, 6Ah,0E6h, 0Ah,0E6h, 2Ah db 0E6h, 4Ah,0E6h, 6Ah, 40h, 0Bh db 40h, 2Bh, 40h, 4Bh, 40h, 6Bh db 9Ah, 0Bh, 9Ah, 2Bh, 9Ah, 4Bh db 9Ah, 6Bh,0F4h, 0Bh,0F4h, 2Bh db 0F4h, 4Bh,0F4h db 'kN', 0Ch, 'N,NLNl' db 0A8h, 0Ch,0A8h, 2Ch,0A8h, 4Ch db 0A8h, 6Ch, 02h, 0Dh, 02h, 2Dh db 02h, 4Dh, 02h db 'm\', 0Dh, '\-\M\m' db 0B6h, 0Dh,0B6h, 2Dh,0B6h, 4Dh db 0B6h, 6Dh, 10h, 0Eh, 10h, 2Eh db 10h, 4Eh, 10h, 6Eh, 6Ah, 0Eh db 6Ah, 2Eh, 6Ah, 4Eh, 6Ah, 6Eh db 0C4h, 0Eh,0C4h, 2Eh,0C4h, 4Eh db 0C4h, 6Eh, 1Eh, 0Fh, 1Eh, 2Fh db 1Eh, 4Fh, 1Eh, 6Fh, 78h, 0Fh db 78h, 2Fh, 78h, 4Fh, 78h, 6Fh db 0D2h, 0Fh,0D2h, 2Fh,0D2h, 4Fh db 0D2h, 6Fh, 2Ch, 10h, 2Ch, 30h db 2Ch, 50h, 2Ch, 70h, 86h, 10h db 86h, 30h, 86h, 50h, 86h, 70h db 0E0h, 10h,0E0h, 30h,0E0h, 50h db 0E0h, 70h, 3Ah, 11h, 3Ah, 31h db 3Ah, 51h, 3Ah, 71h, 94h, 11h db 94h, 31h, 94h, 51h, 94h, 71h db 0EEh, 11h,0EEh, 31h,0EEh, 51h db 0EEh, 71h, 48h, 12h, 48h, 32h db 48h, 52h, 48h, 72h,0A2h, 12h db 0A2h, 32h,0A2h, 52h,0A2h, 72h db 0FCh, 12h,0FCh, 32h,0FCh, 52h db 0FCh, 72h, 56h, 13h, 56h, 33h db 56h, 53h, 56h, 73h,0B0h, 13h db 0B0h loc_7: xor si,ds:data_145e[bx+si] jnc $+0Ch ; Jump if carry=0 adc al,0Ah xor al,0Ah loc_8: push sp or dh,[si+64h] adc al,64h ; 'd' xor al,64h ; 'd' push sp db 64h, 74h,0BEh, 14h,0BEh, 34h db 0BEh, 54h,0BEh, 74h, 18h, 15h db 18h, 35h, 18h, 55h, 18h db 75h, 72h loc_9: adc ax,3572h ;* jc loc_16 ;*Jump if carry Set db 72h, 55h ; Fixup - byte match jc $+77h ; Jump if carry Set int 3 ; Debug breakpoint adc ax,35CCh int 3 ; Debug breakpoint push bp int 3 ; Debug breakpoint jnz loc_14 ; Jump if not zero push ss db 26h, 36h, 26h, 56h, 26h, 76h db 80h, 16h, 80h, 36h, 80h, 56h db 80h, 76h,0DAh loc_12: push ss db 0DAh, 36h,0DAh, 56h,0DAh, 76h db 34h, 17h, 34h, 37h, 34h, 57h db 34h, 77h, 8Eh loc_13: pop ss db 8Eh, 37h, 8Eh, 57h, 8Eh loc_14: ja loc_12 ; Jump if above pop ss call $-17C6h push di call $+427Ah sbb [bp+si+38h],al inc dx pop ax inc dx loc_15: js loc_8 ; Jump if sign=1 sbb ds:data_143e[si],bl pop ax pushf ; Push flags js loc_15 ; Jump if sign=1 ;* sbb dh,dh db 18h,0F6h ; Fixup - byte match ;* cmp dh,dh db 38h,0F6h ; Fixup - byte match pop ax idiv byte ptr [bx+si+50h] ; al,ah rem = ax/data sbb [bx+si+39h],dx push ax pop cx push ax ;* jns loc_10 ;*Jump if not sign db 79h,0AAh ; Fixup - byte match sbb ss:data_144e[bp+si],bp pop cx stosb ; Store al to es:[di] jns loc_17 ; Jump if not sign sbb al,[si] cmp al,[si] loc_17: pop dx add al,7Ah ; 'z' pop si sbb bl,[bp+3Ah] pop si pop dx pop si jp loc_13 ; Jump if parity=1 sbb bh,ds:data_146e[bx+si] pop dx mov ax,127Ah sbb dx,[bp+si] cmp dx,[bp+si] pop bx adc bh,[bp+di+6Ch] sbb bp,[si+3Bh] db 6Ch, 5Bh, 6Ch, 7Bh,0C6h, 1Bh db 0C6h, 3Bh,0C6h, 5Bh,0C6h, 7Bh db 20h, 1Ch db 20h, 3Ch, 20h data_37 dw 205Ch db 7Ch, 7Ah data_38 dw 7A1Ch data_39 dw 7A3Ch ; Data table (indexed access) db 5Ch, 7Ah, 7Ch,0D4h, 1Ch,0D4h db 3Ch,0D4h, 5Ch,0D4h, 7Ch, 2Eh db 1Dh db 2Eh, 3Dh, 2Eh data_40 db 5Dh db 2Eh, 7Dh, 88h, 1Dh, 88h, 3Dh db 88h, 5Dh, 88h, 7Dh,0E2h, 1Dh db 0E2h, 3Dh,0E2h, 5Dh,0E2h, 7Dh db 3Ch, 1Eh, 3Ch, 3Eh, 3Ch, 5Eh db 3Ch, 7Eh, 96h, 1Eh, 96h db 3Eh data_41 dw 0 data_43 db 0 data_44 db 0Eh data_45 db 0 db 0 db 25 dup (0) data_47 db 0 db 15 dup (0) db 7Eh, 81h,0A5h, 81h, 81h,0BDh db 99h, 81h, 7Eh, 00h, 00h, 00h db 00h, 00h, 7Eh,0FFh,0DBh,0FFh db 0FFh,0C3h,0E7h,0FFh, 7Eh, 00h db 00h, 00h, 00h, 00h, 00h, 36h db 7Fh, 7Fh, 7Fh, 7Fh, 3Eh, 1Ch db 08h, 00h, 00h, 00h, 00h, 00h db 00h, 08h, 1Ch, 3Eh, 7Fh, 3Eh db 1Ch, 08h, 00h, 00h, 00h, 00h db 00h, 18h, 3Ch, 3Ch,0E7h,0E7h db 0E7h, 3Ch, 18h, 18h, 3Ch, 00h db 00h, 00h, 00h, 00h, 18h, 3Ch db 7Eh,0FFh,0FFh, 7Eh, 18h, 18h db 3Ch db 8 dup (0) db 18h, 3Ch, 3Ch, 18h, 00h, 00h db 00h, 00h, 00h,0FFh,0FFh,0FFh db 0FFh,0FFh,0E7h,0C3h, 81h,0E7h db 0FFh,0FFh,0FFh,0FFh,0FFh, 00h db 00h, 00h, 00h, 3Ch, 66h, 42h db 42h, 66h, 3Ch, 00h, 00h, 00h db 00h,0FFh,0FFh,0FFh,0FFh,0C3h db 99h,0BDh,0BDh, 99h,0C3h,0FFh db 0FFh,0FFh,0FFh, 00h, 00h, 0Fh db 07h, 0Dh, 19h, 3Ch, 66h, 66h db 66h, 3Ch, 00h, 00h, 00h, 00h db 00h, 3Ch, 66h, 66h, 66h, 3Ch db 18h, 7Eh, 18h, 18h, 00h, 00h db 00h, 00h, 00h, 3Fh, 33h, 3Fh db 30h, 30h, 30h, 70h,0F0h,0E0h db 00h, 00h, 00h, 00h, 00h, 7Fh db 63h, 7Fh, 63h, 63h, 63h, 67h db 0E7h,0E6h, 60h, 00h, 00h, 00h db 00h, 18h, 18h,0DBh, 3Ch,0E7h db 3Ch,0DBh, 18h, 18h, 00h, 00h db 00h, 00h, 00h, 40h, 60h, 70h db 7Ch, 7Fh, 7Ch, 70h, 60h, 40h db 00h, 00h, 00h, 00h, 00h, 01h db 03h, 07h, 1Fh, 7Fh, 1Fh, 07h db 03h, 01h, 00h, 00h, 00h, 00h db 00h, 18h, 3Ch, 7Eh, 18h, 18h db 18h, 7Eh, 3Ch, 18h, 00h, 00h db 00h, 00h, 00h, 33h, 33h, 33h db 33h, 33h, 33h, 00h, 33h, 33h db 00h, 00h, 00h, 00h, 00h, 7Fh db 0DBh,0DBh,0DBh, 7Bh, 1Bh, 1Bh db 1Bh, 1Bh, 00h, 00h, 00h, 00h db 3Eh, 63h, 30h, 1Ch, 36h, 63h db 63h, 36h, 1Ch, 06h db 63h, 3Eh db 9 dup (0) db 7Fh, 7Fh, 7Fh, 00h, 00h, 00h db 00h, 00h, 18h, 3Ch, 7Eh, 18h db 18h, 18h, 7Eh, 3Ch, 18h, 00h db 00h, 00h, 00h, 18h, 3Ch, 7Eh db 18h, 18h, 18h, 18h, 18h, 18h db 00h, 00h, 00h, 00h, 00h, 00h db 18h, 18h, 18h, 18h, 18h, 18h db 7Eh, 3Ch, 18h, 00h, 00h, 00h db 00h, 00h, 00h, 00h, 0Ch, 06h db 0FFh, 06h, 0Ch, 00h db 8 dup (0) db 18h, 30h, 7Fh, 30h, 18h, 00h db 9 dup (0) db 60h, 60h, 60h, 7Fh, 00h db 8 dup (0) db 24h, 66h,0FFh, 66h, 24h db 8 dup (0) db 08h, 1Ch, 1Ch, 3Eh, 3Eh, 7Fh db 7Fh db 7 dup (0) db 7Fh, 7Fh, 3Eh, 3Eh, 1Ch, 1Ch db 08h, 00h db 19 dup (0) db 18h, 3Ch, 3Ch, 3Ch, 18h, 18h db 00h, 18h, 18h, 00h, 00h, 00h db 00h, 63h, 63h, 63h, 22h, 00h db 10 dup (0) db 36h, 36h, 7Fh, 36h, 36h, 36h db 7Fh, 36h, 36h, 00h, 00h, 00h db 0Ch, 0Ch, 3Eh, 63h, 61h, 60h db 3Eh, 03h, 43h, 63h, 3Eh, 0Ch db 0Ch, 00h, 00h, 00h, 00h, 00h db 61h, 63h, 06h, 0Ch, 18h, 33h db 63h, 00h, 00h, 00h, 00h, 00h db 1Ch, 36h, 36h, 1Ch, 3Bh, 6Eh db 66h, 66h, 3Bh, 00h, 00h, 00h db 00h db 30h, 30h, 30h, 60h db 11 dup (0) db 0Ch, 18h, 30h, 30h, 30h, 30h db 30h, 18h, 0Ch, 00h, 00h, 00h db 00h, 00h, 18h, 0Ch, 06h, 06h db 06h, 06h, 06h, 0Ch, 18h db 7 dup (0) db 66h, 3Ch,0FFh, 3Ch, 66h db 8 dup (0) db 18h, 18h, 18h,0FFh, 18h, 18h db 18h, 00h db 11 dup (0) db 18h, 18h, 18h, 30h db 9 dup (0) db 0FFh, 00h db 14 dup (0) db 18h, 18h, 00h, 00h, 00h, 00h db 00h, 01h, 03h, 06h, 0Ch, 18h db 30h, 60h,0C0h, 80h, 00h, 00h db 00h, 00h, 00h db '>cgo{scc>' db 00h, 00h, 00h, 00h, 00h, 0Ch db 1Ch, 3Ch, 0Ch, 0Ch, 0Ch, 0Ch db 0Ch, 3Fh, 00h, 00h, 00h, 00h db 00h, 3Eh, 63h, 03h, 06h, 0Ch db 18h, 30h, 63h, 7Fh, 00h, 00h db 00h, 00h, 00h, 3Eh, 63h, 03h db 03h, 1Eh, 03h, 03h, 63h, 3Eh db 00h, 00h, 00h, 00h, 00h, 06h db 0Eh, 1Eh, 36h, 66h, 7Fh, 06h db 06h, 0Fh, 00h, 00h, 00h, 00h db 00h, 7Fh, 60h, 60h, 60h, 7Eh db 03h, 03h, 63h, 3Eh, 00h, 00h db 00h, 00h, 00h, 1Ch db '0``~ccc>' db 00h, 00h, 00h, 00h, 00h, 7Fh db 63h, 03h, 06h, 0Ch, 18h, 18h db 18h, 18h, 00h, 00h, 00h, 00h db 00h db '>ccc>ccc>' db 00h, 00h, 00h, 00h, 00h, 3Eh db 63h, 63h, 63h, 3Fh, 03h, 03h db 06h, 3Ch, 00h, 00h, 00h, 00h db 00h, 00h, 18h, 18h, 00h, 00h db 18h, 18h, 00h db 7 dup (0) db 18h, 18h, 00h, 00h, 00h, 18h db 18h, 30h, 00h, 00h, 00h, 00h db 00h, 06h, 0Ch, 18h, 30h, 60h db 30h, 18h, 0Ch, 06h db 8 dup (0) db 7Eh, 00h, 00h, 7Eh, 00h, 00h db 00h, 00h, 00h, 00h, 00h, 60h db 30h, 18h, 0Ch, 06h, 0Ch, 18h db 30h, 60h, 00h, 00h, 00h, 00h db 00h, 3Eh, 63h, 63h, 06h, 0Ch db 0Ch, 00h, 0Ch, 0Ch, 00h, 00h db 00h, 00h, 00h db '>ccooon`>' db 00h, 00h, 00h, 00h, 00h, 08h db 1Ch, 36h, 63h, 63h, 7Fh, 63h db 63h, 63h, 00h, 00h, 00h, 00h db 00h db '~333>333~' db 00h, 00h, 00h, 00h, 00h, 1Eh db 33h, 61h, 60h, 60h, 60h, 61h db 33h, 1Eh, 00h, 00h, 00h, 00h db 00h db '|6333336|' db 00h, 00h, 00h, 00h, 00h, 7Fh db 33h, 31h, 34h, 3Ch, 34h, 31h db 33h, 7Fh, 00h, 00h, 00h, 00h db 00h, 7Fh db '314<400x' db 00h, 00h, 00h, 00h, 00h, 1Eh db 33h, 61h, 60h, 60h, 6Fh, 63h db 33h, 1Dh, 00h, 00h, 00h, 00h db 00h, 63h, 63h, 63h, 63h, 7Fh db 63h, 63h, 63h, 63h, 00h, 00h db 00h, 00h, 00h db 3Ch db 7 dup (18h) db 3Ch, 00h, 00h, 00h, 00h, 00h db 0Fh, 06h, 06h, 06h, 06h, 06h db 66h, 66h, 3Ch, 00h, 00h, 00h db 00h, 00h db 's366<663s' db 0, 0, 0, 0, 0 db 'x0000013' db 7Fh, 00h, 00h, 00h, 00h, 00h db 0C3h,0E7h,0FFh,0DBh,0C3h,0C3h db 0C3h,0C3h,0C3h, 00h, 00h, 00h db 00h, 00h, 63h, 73h, 7Bh, 7Fh db 6Fh, 67h, 63h, 63h, 63h, 00h db 00h, 00h, 00h, 00h, 1Ch, 36h db 63h, 63h, 63h, 63h, 63h, 36h db 1Ch, 00h, 00h, 00h, 00h, 00h db '~333>000x' db 0, 0, 0, 0, 0 db '>ccccko>' db 6, 7, 0, 0, 0, 0 db '~333>633{' db 00h, 00h, 00h, 00h, 00h, 3Eh db 63h, 63h, 30h, 1Ch, 06h, 63h db 63h, 3Eh, 00h, 00h, 00h, 00h db 00h,0FFh,0DBh, 99h, 18h, 18h db 18h, 18h, 18h, 3Ch, 00h, 00h db 00h, 00h, 00h db 'cccccccc>' db 00h, 00h, 00h, 00h, 00h,0C3h db 0C3h,0C3h,0C3h,0C3h,0C3h, 66h db 3Ch, 18h, 00h, 00h, 00h, 00h db 00h,0C3h,0C3h,0C3h,0C3h,0C3h db 0DBh,0FFh, 66h, 66h, 00h, 00h db 00h, 00h, 00h,0C3h,0C3h, 66h db 3Ch, 18h, 3Ch, 66h,0C3h,0C3h db 00h, 00h, 00h, 00h, 00h,0C3h db 0C3h,0C3h, 66h, 3Ch, 18h, 18h db 18h, 3Ch, 00h, 00h, 00h, 00h db 00h,0FFh,0C3h, 86h, 0Ch, 18h db 30h, 61h,0C3h,0FFh, 00h, 00h db 00h, 00h, 00h db 3Ch db 7 dup (30h) db 3Ch, 00h, 00h, 00h, 00h, 00h db 40h, 60h, 70h, 38h, 1Ch, 0Eh db 07h, 03h, 01h, 00h, 00h, 00h db 00h, 00h db 3Ch db 7 dup (0Ch) db 3Ch, 00h, 00h, 00h, 08h, 1Ch db 36h, 63h db 21 dup (0) db 0FFh, 00h, 00h, 18h, 18h, 0Ch db 16 dup (0) db 3Ch, 06h, 3Eh, 66h, 66h, 3Bh db 00h, 00h, 00h, 00h, 00h db 'p00<6333n' db 0 db 7 dup (0) db 3Eh, 63h, 60h, 60h, 63h, 3Eh db 00h, 00h, 00h, 00h, 00h, 0Eh db 06h, 06h, 1Eh, 36h, 66h, 66h db 66h, 3Bh, 00h db 7 dup (0) db 3Eh, 63h, 7Fh, 60h, 63h, 3Eh db 00h, 00h, 00h, 00h, 00h, 1Ch db '620|000x' db 0 db 7 dup (0) db 3Bh, 66h, 66h, 66h, 3Eh, 06h db 66h, 3Ch, 00h, 00h, 00h db 'p006;333s' db 00h, 00h, 00h, 00h, 00h, 0Ch db 0Ch, 00h, 1Ch, 0Ch, 0Ch, 0Ch db 0Ch, 1Eh, 00h, 00h, 00h, 00h db 00h, 06h, 06h, 00h, 0Eh, 06h db 06h, 06h, 66h, 66h, 3Ch, 00h db 00h, 00h, 00h db 'p0036<63s' db 00h, 00h, 00h, 00h, 00h, 1Ch db 7 dup (0Ch) db 1Eh db 8 dup (0) db 0E6h,0DBh,0DBh,0DBh,0DBh,0DBh db 8 dup (0) db 6Eh, 33h, 33h, 33h, 33h, 33h db 00h db 7 dup (0) db 3Eh, 63h, 63h, 63h, 63h, 3Eh db 8 dup (0) db 'n333>00x' db 00h, 00h, 00h, 00h, 00h, 00h db 3Bh, 66h, 66h, 66h, 3Eh, 06h db 06h, 0Fh, 00h, 00h, 00h, 00h db 00h, 00h, 6Eh, 33h, 33h, 30h db 30h, 78h, 00h db 7 dup (0) db 3Eh, 63h, 38h, 0Eh, 63h, 3Eh db 00h, 00h, 00h, 00h, 00h, 08h db 18h, 18h, 7Eh, 18h, 18h, 18h db 1Bh, 0Eh, 00h, 00h, 00h, 00h db 00h, 00h, 00h, 00h, 66h, 66h db 66h, 66h, 66h, 3Bh, 00h db 7 dup (0) db 0C3h,0C3h,0C3h, 66h, 3Ch, 18h db 8 dup (0) db 0C3h,0C3h,0DBh,0DBh, 7Eh, 66h db 8 dup (0) db 63h, 36h, 1Ch, 1Ch, 36h, 63h db 8 dup (0) db 63h, 63h, 63h, 63h, 3Fh, 03h db 06h, 3Ch, 00h, 00h, 00h, 00h db 00h, 00h, 7Fh, 66h, 0Ch, 18h db 33h, 7Fh, 00h, 00h, 00h, 00h db 00h, 0Eh, 18h, 18h, 18h, 70h db 18h, 18h, 18h, 0Eh, 00h, 00h db 00h, 00h, 00h, 18h, 18h, 18h db 18h, 00h, 18h, 18h, 18h, 18h db 00h, 00h, 00h, 00h, 00h, 70h db 18h, 18h, 18h, 1Ch, 18h, 18h db 18h, 70h, 00h, 00h, 00h, 00h db 00h db 3Bh, 6Eh db 15 dup (0) db 08h, 1Ch, 36h, 63h, 63h, 63h db 7Fh, 00h, 00h, 00h, 00h, 1Eh db 33h, 61h, 60h, 60h, 61h, 63h db 3Eh, 06h, 03h, 3Eh, 00h, 00h db 00h, 66h, 66h, 00h, 66h, 66h db 66h, 66h, 66h, 3Bh, 00h, 00h db 00h, 00h, 06h, 0Ch, 18h, 00h db 3Eh, 63h, 7Fh, 60h, 63h, 3Eh db 00h, 00h, 00h, 00h, 08h, 1Ch db 36h, 00h, 3Ch, 06h, 3Eh, 66h db 66h, 3Bh, 00h, 00h, 00h, 00h db 00h, 66h, 66h, 00h, 3Ch, 06h db 3Eh, 66h, 66h, 3Bh, 00h, 00h db 00h, 00h, 30h, 18h, 0Ch, 00h db 3Ch, 06h, 3Eh, 66h, 66h, 3Bh db 00h, 00h, 00h, 00h, 1Ch, 36h db 1Ch, 00h, 3Ch, 06h, 3Eh, 66h db 66h, 3Bh, 00h db 7 dup (0) db 3Ch, 66h, 60h, 66h, 3Ch, 06h db 3Ch, 00h, 00h, 00h, 08h, 1Ch db 36h, 00h, 3Eh, 63h, 7Fh, 60h db 63h, 3Eh, 00h, 00h, 00h, 00h db 00h, 66h, 66h, 00h, 3Eh, 63h db 7Fh, 60h, 63h, 3Eh, 00h, 00h db 00h, 00h, 30h, 18h, 0Ch, 00h db 3Eh, 63h, 7Fh, 60h, 63h, 3Eh db 00h, 00h, 00h, 00h, 00h, 36h db 36h, 00h, 1Ch, 0Ch, 0Ch, 0Ch db 0Ch, 1Eh, 00h, 00h, 00h, 00h db 18h, 3Ch, 66h, 00h, 38h, 18h db 18h, 18h, 18h, 3Ch, 00h, 00h db 00h, 00h, 60h, 30h, 18h, 00h db 38h, 18h, 18h, 18h, 18h, 3Ch db 00h, 00h, 00h, 00h, 63h, 63h db 08h, 1Ch, 36h, 63h, 63h, 7Fh db 63h, 63h, 00h, 00h, 00h, 1Ch db 36h, 1Ch, 00h, 1Ch, 36h, 63h db 63h, 7Fh, 63h, 63h, 00h, 00h db 00h, 0Ch, 18h, 30h, 00h, 7Fh db 33h, 30h, 3Eh, 30h, 33h, 7Fh db 00h db 7 dup (0) db 6Eh, 3Bh, 1Bh, 7Eh,0D8h,0DCh db 77h, 00h, 00h, 00h, 00h, 1Fh db 36h, 66h, 66h, 7Fh, 66h, 66h db 66h, 67h, 00h, 00h, 00h, 00h db 08h, 1Ch, 36h, 00h, 3Eh, 63h db 63h, 63h, 63h, 3Eh, 00h, 00h db 00h, 00h, 00h, 63h, 63h, 00h db 3Eh, 63h, 63h, 63h, 63h, 3Eh db 00h, 00h, 00h, 00h, 30h, 18h db 0Ch, 00h, 3Eh, 63h, 63h, 63h db 63h, 3Eh, 00h, 00h, 00h, 00h db 18h, 3Ch, 66h, 00h, 66h, 66h db 66h, 66h, 66h, 3Bh, 00h, 00h db 00h, 00h, 30h, 18h, 0Ch, 00h db 66h, 66h, 66h, 66h, 66h, 3Bh db 00h, 00h, 00h, 00h, 00h, 63h db 63h, 00h, 63h, 63h, 63h, 63h db 3Fh, 03h, 06h, 3Ch, 00h, 00h db 63h, 63h, 1Ch, 36h, 63h, 63h db 63h, 63h, 36h, 1Ch, 00h, 00h db 00h, 00h, 63h, 63h, 00h, 63h db 63h, 63h, 63h, 63h, 63h, 3Eh db 00h, 00h, 00h, 00h, 18h, 18h db 7Eh,0C3h,0C0h,0C0h,0C3h, 7Eh db 18h, 18h, 00h, 00h, 00h, 00h db 1Ch db '600x000s~' db 00h, 00h, 00h, 00h, 00h,0C3h db 66h, 3Ch, 18h,0FFh, 18h,0FFh db 18h, 18h, 00h, 00h, 00h, 00h db 0FCh db 'ff|bfoff' db 0F3h, 00h, 00h, 00h, 00h, 0Eh db 1Bh, 18h, 18h, 18h, 7Eh, 18h db 18h, 18h, 18h,0D8h, 70h, 00h db 00h, 0Ch, 18h, 30h, 00h, 3Ch db 06h, 3Eh, 66h, 66h, 3Bh, 00h db 00h, 00h, 00h, 0Ch, 18h, 30h db 00h, 38h, 18h, 18h, 18h, 18h db 3Ch, 00h, 00h, 00h, 00h, 0Ch db 18h, 30h, 00h, 3Eh, 63h, 63h db 63h, 63h, 3Eh, 00h, 00h, 00h db 00h, 0Ch, 18h, 30h, 00h, 66h db 66h, 66h, 66h, 66h, 3Bh, 00h db 00h, 00h, 00h, 00h, 3Bh, 6Eh db 00h, 6Eh, 33h, 33h, 3Bh, 33h db 33h, 33h, 00h, 00h, 3Bh, 6Eh db 00h, 63h, 73h, 7Bh, 7Fh, 6Fh db 67h, 63h, 63h, 00h, 00h, 00h db 00h, 3Ch, 6Ch, 6Ch, 3Eh, 00h db 7Eh, 00h db 7 dup (0) db 38h, 6Ch, 6Ch, 38h, 00h, 7Ch db 00h db 8 dup (0) db 18h, 18h, 00h, 18h, 18h, 33h db 33h, 1Eh, 00h, 00h db 8 dup (0) db 7Fh, 60h, 60h db 11 dup (0) db 7Fh, 03h, 03h, 00h, 00h, 00h db 00h, 00h, 00h, 60h,0E0h, 63h db 66h, 6Ch, 18h, 30h, 6Eh,0C3h db 06h, 0Ch, 1Fh, 00h, 00h, 60h db 0E0h, 63h, 66h, 6Ch, 18h, 30h db 67h,0CFh, 1Fh, 03h, 03h, 00h db 00h, 00h, 18h, 18h, 00h, 18h db 18h, 3Ch, 3Ch, 3Ch, 18h, 00h db 00h, 00h, 00h, 00h, 00h, 00h db 1Bh, 36h, 6Ch, 36h, 1Bh, 00h db 8 dup (0) db 6Ch, 36h, 1Bh, 36h, 6Ch, 00h db 00h, 00h, 00h, 00h, 11h, 44h db 11h, 44h, 11h, 44h, 11h, 44h db 11h, 44h, 11h, 44h, 11h, 44h db 55h,0AAh, 55h,0AAh, 55h,0AAh db 55h,0AAh, 55h,0AAh, 55h,0AAh db 55h,0AAh,0DDh, 77h,0DDh, 77h db 0DDh, 77h,0DDh, 77h,0DDh, 77h db 0DDh, 77h,0DDh, 77h, 18h db 20 dup (18h) db 0F8h db 11 dup (18h) db 0F8h, 18h,0F8h, 18h, 18h, 18h db 18h, 18h, 18h db 7 dup (36h) db 0F6h, 36h, 36h, 36h, 36h, 36h db 36h, 00h, 00h, 00h, 00h, 00h db 00h,0FEh db 7 dup (36h) db 00h, 00h, 00h, 00h, 00h,0F8h db 18h,0F8h, 18h, 18h, 18h, 18h db 18h, 18h, 36h, 36h, 36h, 36h db 36h,0F6h, 06h,0F6h db 36h, 36h db 18 dup (36h) db 00h, 00h, 00h, 00h, 00h,0FEh db 06h,0F6h db 36h, 36h, 36h db 8 dup (36h) db 0F6h, 06h,0FEh, 00h, 00h, 00h db 00h, 00h, 00h, 36h, 36h, 36h db 36h, 36h, 36h, 36h,0FEh, 00h db 00h, 00h, 00h, 00h, 00h, 18h db 18h, 18h, 18h, 18h,0F8h, 18h db 0F8h db 13 dup (0) db 0F8h db 13 dup (18h) db 1Fh, 00h, 00h, 00h, 00h, 00h db 00h, 18h, 18h, 18h, 18h, 18h db 18h, 18h,0FFh, 00h db 12 dup (0) db 0FFh, 18h db 12 dup (18h) db 1Fh, 18h, 18h, 18h, 18h, 18h db 18h db 7 dup (0) db 0FFh, 00h, 00h, 00h, 00h, 00h db 00h, 18h, 18h, 18h, 18h, 18h db 18h, 18h,0FFh, 18h db 10 dup (18h) db 1Fh, 18h, 1Fh, 18h, 18h, 18h db 18h, 18h, 18h db 7 dup (36h) db 37h db 11 dup (36h) db 37h, 30h, 3Fh db 11 dup (0) db 3Fh, 30h, 37h db 11 dup (36h) db 0F7h, 00h,0FFh, 00h db 10 dup (0) db 0FFh, 00h,0F7h, 36h, 36h, 36h db 8 dup (36h) db '707666666' db 00h, 00h, 00h, 00h, 00h,0FFh db 00h,0FFh, 00h, 00h, 00h, 00h db 00h, 00h, 36h, 36h, 36h, 36h db 36h,0F7h, 00h,0F7h, 36h, 36h db 36h, 36h, 36h, 36h, 18h, 18h db 18h, 18h, 18h,0FFh, 00h,0FFh db 00h, 00h, 00h, 00h, 00h, 00h db 36h, 36h, 36h, 36h, 36h, 36h db 36h,0FFh, 00h db 10 dup (0) db 0FFh, 00h,0FFh, 18h, 18h, 18h db 18h, 18h, 18h, 00h, 00h, 00h db 00h, 00h, 00h, 00h,0FFh db 13 dup (36h) db 3Fh, 00h, 00h, 00h, 00h, 00h db 00h, 18h, 18h, 18h, 18h, 18h db 1Fh, 18h, 1Fh db 11 dup (0) db 1Fh, 18h, 1Fh, 18h, 18h, 18h db 18h, 18h, 18h db 7 dup (0) db 3Fh db 13 dup (36h) db 0FFh, 36h, 36h, 36h, 36h, 36h db 36h, 18h, 18h, 18h, 18h, 18h db 0FFh, 18h,0FFh db 13 dup (18h) db 0F8h db 13 dup (0) db 1Fh, 18h, 18h, 18h, 18h, 18h db 18h db 14 dup (0FFh) db 7 dup (0) db 7 dup (0FFh) db 14 dup (0F0h) db 14 dup (0Fh) db 7 dup (0FFh) db 12 dup (0) db 3Bh, 6Eh, 6Ch, 6Ch, 6Eh, 3Bh db 00h, 00h, 00h, 00h, 00h, 00h db 00h db '>c~cc~`` ' db 00h, 00h, 00h, 7Fh db 'cc``````' db 7 dup (0) db 7Fh, 36h, 36h, 36h, 36h, 36h db 36h, 00h, 00h, 00h, 00h, 00h db 7Fh, 63h, 30h, 18h, 0Ch, 18h db 30h, 63h, 7Fh db 8 dup (0) db 3Eh, 6Ch, 6Ch, 6Ch, 6Ch, 38h db 00h, 00h, 00h, 00h, 00h, 00h db 00h db '3333>00`' db 00h, 00h, 00h, 00h, 00h, 00h db 3Bh, 6Eh, 0Ch, 0Ch, 0Ch, 0Ch db 0Ch, 00h, 00h, 00h, 00h, 00h db 7Eh, 18h, 3Ch, 66h, 66h, 66h db 3Ch, 18h, 7Eh, 00h, 00h, 00h db 00h, 00h, 1Ch, 36h, 63h, 63h db 7Fh, 63h, 63h, 36h, 1Ch, 00h db 00h, 00h, 00h, 00h, 1Ch, 36h db 63h, 63h, 63h, 36h, 1Ch, 36h db 36h, 77h, 00h, 00h, 00h, 00h db 1Eh, 30h, 18h, 0Ch, 3Eh, 66h db 66h, 66h, 3Ch, 00h db 7 dup (0) db 7Eh,0DBh,0DBh, 7Eh, 00h, 00h db 00h, 00h, 00h, 00h, 00h, 03h db 06h, 7Eh,0DBh,0DBh,0F3h, 7Eh db 60h,0C0h, 00h, 00h, 00h, 00h db 00h, 1Ch, 30h, 60h, 60h, 7Ch db 60h, 60h, 30h, 1Ch db 7 dup (0) db 3Eh db 7 dup (63h) db 00h, 00h, 00h, 00h, 00h, 00h db 7Fh, 00h, 7Fh, 7Fh, 00h, 7Fh db 00h, 00h, 00h, 00h, 00h, 00h db 18h, 18h, 18h,0FFh, 18h, 18h db 18h, 00h,0FFh, 00h, 00h, 00h db 00h, 00h, 30h, 18h, 0Ch, 06h db 0Ch, 18h, 30h, 00h,0FFh, 00h db 00h, 00h, 00h, 00h, 0Ch, 18h db 30h, 60h, 30h, 18h, 0Ch, 00h db 0FFh, 00h, 00h, 00h, 00h, 00h db 0Eh db 1Bh, 1Bh db 17 dup (18h) db 0D8h,0D8h, 70h, 00h, 00h, 00h db 00h, 00h, 18h, 18h, 00h, 00h db 0FFh, 00h, 00h, 18h, 18h db 7 dup (0) db 3Bh, 6Eh, 00h, 3Bh, 6Eh, 00h db 00h, 00h, 00h, 00h, 00h, 38h db 6Ch, 6Ch, 38h, 00h db 14 dup (0) db 18h, 18h db 13 dup (0) db 30h, 00h, 00h, 00h, 00h, 00h db 00h, 00h, 0Fh, 0Ch, 0Ch, 0Ch db 0Ch, 0Ch,0ECh, 6Ch, 3Ch, 1Ch db 00h, 00h, 00h, 00h,0D8h db 6Ch, 6Ch, 6Ch, 6Ch, 6Ch db 8 dup (0) db 70h,0D8h, 30h, 60h,0C8h,0F8h db 11 dup (0) db 3Ch, 3Ch, 3Ch, 3Ch, 3Ch, 3Ch db 18 dup (0) ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ; SUBROUTINE ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ GetVideoMode proc near mov ah,es:video_columns_ mov al,8 mov [bp],ax mov al,es:video_page_ mov [bp+3],al retn GetVideoMode endp ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ; SUBROUTINE ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ SetVideoMode proc near mov ah,es:equip_bits_ and ah,30h cmp ah,30h je loc_20 retn loc_20: mov data_26,2 push ax xor ax,ax mov byte ptr es:video_mode_,8 mov word ptr es:video_columns_,50h mov es:video_page_,al mov es:vid_curs_pos0_,ax cmp FlagH,3 jne loc_21 ; Jump if not equal mov es:vid_curs_pos1_,ax loc_21: mov es:video_segment_,ax mov word ptr es:video_buf_siz_,8000h mov Flag,al mov si,offset data_27 mov cx,0Eh mov ah,0 cli ; Disable interrupts mov dx,3B8h mov al,data_26 out dx,al ; port 3B8h, MDA video control call sub_6 mov dx,3BFh mov al,FlagH out dx,al ; port 3BFh, Hercules config mov cx,14h call sub_19 pop ax test al,80h jnz loc_23 ; Jump if not zero mov ax,0B000h push es mov es,ax xor di,di ; Zero register xor ax,ax ; Zero register mov cx,8000h cmp FlagH,3 je loc_22 ; Jump if equal shr cx,1 ; Shift w/zeros fill loc_22: rep stosw ; Rep when cx >0 Store ax to es:[di] pop es loc_23: mov dx,3B8h mov al,data_26 or al,8 mov data_26,al out dx,al ; port 3B8h, MDA video control retn SetVideoMode endp ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ; SUBROUTINE ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ sub_4 proc near call TestHerc mov [bp+6],dx retn sub_4 endp ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ; SUBROUTINE ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ TestHerc proc near ; проверка на наличие Геркулеса ; Выход: dl = ff - не Геркулес ; dl = 02 - Hercules in Color ; dl = 01 - Hercules+ ; dl = 00 - Hercules mov dx,3BAh in al,dx ; port 3BAh, MDA/EGA vid status, 6845 chip and al,70h ; 0111 0000 выделение битов типа Геркулеса ; (see [Interrupt List]) ; 000 = adapter is Hercules or compatible ; 001 = adapter is Hercules+ ; 101 = adapter is Hercules InColor ; else: adapter is unknown cmp al,50h ; 0101 0000 (Hercules InColor) jne @@24 mov dl,2 jmp short @@ret db 90h @@24: cmp al,10h jne @@25 mov dl,1 jmp short @@ret db 90h @@25: ; Проверка на мигание старшего бита порта 3BA mov dx,3BAh mov cx,0FFFFh in al,dx ; port 3BAh, MDA/EGA vid status mov bl,al @@loop: in al,dx ; port 3BAh, MDA/EGA vid status xor al,bl test al,80h jnz @@27 ; бит мигает loop @@loop ; да вроде не мигает ; ergo - это не Геркулес mov dl,0FFh jmp short @@ret @@27: ; Значит, просто Гекулес или что-то совместимое xor dl,dl @@ret: mov dh,FlagH shr dh,1 retn TestHerc endp public TestHerc ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ; SUBROUTINE ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ sub_6 proc near cli ; Disable interrupts locloop_29: mov dx,3B4h mov al,ah out dx,al ; port 3B4h, MDA/EGA reg index ; al = 0, horiz char total inc dx lodsb ; String [si] to al out dx,al ; port 3B5h, MDA/EGA indxd data inc ah loop locloop_29 ; Loop if cx > 0 sti ; Enable interrupts retn sub_6 endp db 0 ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ; SUBROUTINE ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ SetPage proc near mov ah,data_26 and ah,7Fh xor cx,cx ; Zero register and al,1 jz loc_30 ; Jump if zero dec al cmp FlagH,3 jne loc_30 ; Jump if not equal inc al mov cx,8000h or ah,80h loc_30: mov data_26,ah mov es:video_page_,al mov es:video_segment_,cx push ax mov dx,3B8h mov al,ah out dx,al ; port 3B8h, MDA video control pop ax xor ah,ah ; Zero register shl ax,1 ; Shift w/zeros fill mov di,ax mov bx,es:vid_curs_pos0_[di] retn SetPage endp ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ; SUBROUTINE ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ SetCurPos proc near xor ax,ax ; Zero register mov al,bh and ax,1 shl ax,1 ; Shift w/zeros fill mov di,ax mov es:vid_curs_pos0_[di],dx retn SetCurPos endp ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ; SUBROUTINE ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ GetCurPos proc near xor ax,ax ; Zero register mov al,bh shl ax,1 ; Shift w/zeros fill mov di,ax mov dx,es:vid_curs_pos0_[di] mov [bp+6],dx mov cx,es:vid_curs_mode_ mov [bp+4],cx retn GetCurPos endp ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ; SUBROUTINE ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ SetCur proc near mov es:vid_curs_mode_,cx retn SetCur endp db 0 ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ; SUBROUTINE ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ WriteSym proc near mov bh,1 jmp loc_44 ;▀▀▀▀ External Entry into Subroutine ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ GetSymAttr: mov bl,bh xor bh,bh ; Zero register mov cx,0B800h or bl,bl ; Zero ? jnz loc_31 ; Jump if not zero mov cx,0B000h push cx loc_31: shl bx,1 ; Shift w/zeros fill mov bx,es:vid_curs_pos0_[bx] mov al,bh xor ah,ah ; Zero register mul data_44 ; ax = data * al push ax xor bh,bh ; Zero register mov cx,bx shl bx,1 ; Shift w/zeros fill shl bx,1 ; Shift w/zeros fill shl bx,1 ; Shift w/zeros fill add cx,bx pop dx call sub_20 mov di,cx mov bl,dl neg bl add bl,7 pop es xor cx,cx ; Zero register mov cl,0Eh mov si,offset data_45 mov dx,1 locloop_32: mov ah,es:[di] mov al,es:[di+1] xchg cx,bx shl ax,cl ; Shift w/zeros fill xchg cx,bx mov [si],ah inc si rol al,1 ; Rotate or dh,al xor al,ah not al and dl,al add di,2000h jns loc_33 ; Jump if not sign sub di,7FA6h loc_33: loop locloop_32 ; Loop if cx > 0 push dx xor cx,cx ; Zero register mov cl,0Eh mov dx,cx push ds pop es mov di,offset data_47 add di,cx mov ax,1 loc_34: push di mov si,offset data_45 repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] pop di jz loc_35 ; Jump if zero inc ax mov cx,dx add di,cx cmp ax,0FFh jbe loc_34 ; Jump if below or = xor ax,ax ; Zero register loc_35: pop dx cmp al,0B3h jbe loc_37 ; Jump if below or = cmp al,0DFh ja loc_37 ; Jump if above or dl,dl ; Zero ? jnz loc_38 ; Jump if not zero loc_36: xor ax,ax ; Zero register jmp short loc_38 loc_37: and dh,1 jnz loc_36 ; Jump if not zero loc_38: mov [bp],ax mov es,data_25 retn db 14 dup (0) ;▀▀▀▀ External Entry into Subroutine ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ Dot: mov di,0B000h test bh,1 jz loc_39 ; Jump if zero mov di,0B800h loc_39: mov es,di call sub_20 mov di,cx mov bx,dx mov bl,data_33[bx] or al,al ; Zero ? jnz loc_40 ; Jump if not zero not bl and es:[di],bl jmp short loc_ret_42 db 90h loc_40: test al,80h jz loc_41 ; Jump if zero xor es:[di],bl jmp short loc_ret_42 db 90h loc_41: or es:[di],bl loc_ret_42: retn ;▀▀▀▀ External Entry into Subroutine ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ GetPoint: mov di,0B000h test bh,1 jz loc_43 ; Jump if zero mov di,0B800h loc_43: mov es,di call sub_20 mov di,cx mov bx,dx mov bl,data_33[bx] mov al,es:[di] and al,bl neg al sbb al,al neg al mov [bp],al retn db 7 dup (0) WriteSym endp ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ; SUBROUTINE ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ WriteSymAttr proc near loc_44: or cx,cx ; Zero ? jnz loc_45 ; Jump if not zero jmp loc_ret_61 loc_45: mov ah,bl push ax mov dx,0B000h test bh,1 jz loc_46 ; Jump if zero mov dx,0B800h loc_46: mov bl,bh xor bh,bh ; Zero register shl bx,1 ; Shift w/zeros fill mov bx,es:vid_curs_pos0_[bx] mov al,bh xor ah,ah ; Zero register mul data_44 ; ax = data * al push ax mov es,dx xor bh,bh ; Zero register mov ax,bx shl bx,1 ; Shift w/zeros fill shl bx,1 ; Shift w/zeros fill shl bx,1 ; Shift w/zeros fill add bx,ax mov dx,cx shl cx,1 ; Shift w/zeros fill shl cx,1 ; Shift w/zeros fill shl cx,1 ; Shift w/zeros fill add dx,cx mov cx,dx add cx,bx dec cx mov ax,bx shr ax,1 ; Shift w/zeros fill shr ax,1 ; Shift w/zeros fill shr ax,1 ; Shift w/zeros fill mov dx,cx shr dx,1 ; Shift w/zeros fill shr dx,1 ; Shift w/zeros fill shr dx,1 ; Shift w/zeros fill sub dx,ax inc dx mov data_29,dx xchg bx,cx ;* and bx,7 db 83h,0E3h, 07h ; Fixup - byte match neg bx ;* add bx,7 db 83h,0C3h, 07h ; Fixup - byte match mov al,data_35[bx] mov byte ptr data_41+1,al pop dx call sub_20 mov di,cx mov bx,dx mov data_43,bl mov al,data_34[bx] mov byte ptr data_41,al mov bx,data_41 or bl,bl ; Zero ? jz loc_47 ; Jump if zero dec data_29 loc_47: or bh,bh ; Zero ? jz loc_48 ; Jump if zero dec data_29 loc_48: pop ax push ax xor ch,ch ; Zero register mov cl,0Eh push cx push di test ah,80h jnz loc_53 ; Jump if not zero xor al,al ; Zero register locloop_49: push cx mov cx,data_29 mov dx,di or bl,bl ; Zero ? jz loc_50 ; Jump if zero and es:[di],bl inc di loc_50: rep stosb ; Rep when cx >0 Store al to es:[di] or bh,bh ; Zero ? jz loc_51 ; Jump if zero and es:[di],bh loc_51: mov di,dx add di,data_149e jns loc_52 ; Jump if not sign sub di,7FA6h loc_52: pop cx loop locloop_49 ; Loop if cx > 0 loc_53: mov dx,data_41 or dl,dl ; Zero ? jz loc_54 ; Jump if zero inc data_29 loc_54: or dh,dh ; Zero ? jz loc_55 ; Jump if zero not dh loc_55: pop di pop cx mov bl,data_43 inc bl pop ax xor dl,dl ; Zero register cmp al,0B3h jbe loc_56 ; Jump if below or = cmp al,0DFh ja loc_56 ; Jump if above inc dl loc_56: mul cl ; ax = reg * al mov si,offset data_47 add si,ax locloop_57: push cx lodsb ; String [si] to al or al,al ; Zero ? jz loc_59 ; Jump if zero mov ah,dl and ah,al ror ah,1 ; Rotate mov cl,bl rol ax,cl ; Rotate push di mov cx,data_29 locloop_58: xor es:[di],ah mov bh,al shr ax,1 ; Shift w/zeros fill or ah,bh inc di loop locloop_58 ; Loop if cx > 0 and ah,dh xor es:[di],ah pop di loc_59: add di,2000h jns loc_60 ; Jump if not sign sub di,7FA6h loc_60: pop cx loop locloop_57 ; Loop if cx > 0 push cs pop ds mov es,data_25 loc_ret_61: retn WriteSymAttr endp db 12 dup (0) ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ; SUBROUTINE ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ScrollUp proc near mov bl,bh push bx sub dh,ch inc dh sub dh,al mov byte ptr data_30,dh xor ah,ah ; Zero register mul data_44 ; ax = data * al mov data_32,ax sub dl,cl inc dl xor dh,dh ; Zero register mov byte ptr data_30+1,dh mov ax,0Eh mov bx,ax mul byte ptr data_30 ; ax = data * al mov data_30,ax mov ax,bx mul ch ; ax = reg * al push ax mov ax,dx shl dx,1 ; Shift w/zeros fill shl dx,1 ; Shift w/zeros fill shl dx,1 ; Shift w/zeros fill add dx,ax mov data_29,dx xor ch,ch ; Zero register mov ax,cx shl cx,1 ; Shift w/zeros fill shl cx,1 ; Shift w/zeros fill shl cx,1 ; Shift w/zeros fill add cx,ax mov ax,cx pop dx mov bx,dx call sub_20 mov di,cx mov dx,bx add dx,data_32 mov cx,ax call sub_20 mov si,cx push ax xor bh,bh ; Zero register mov bl,dl mov cl,data_34[bx] add ax,data_29 dec ax mov dx,ax and ax,7 neg ax add ax,7 mov bx,ax mov ch,data_35[bx] mov data_41,cx shr dx,1 ; Shift w/zeros fill shr dx,1 ; Shift w/zeros fill shr dx,1 ; Shift w/zeros fill pop ax shr ax,1 ; Shift w/zeros fill shr ax,1 ; Shift w/zeros fill shr ax,1 ; Shift w/zeros fill sub dx,ax inc dx or cl,cl ; Zero ? jz loc_62 ; Jump if zero dec dx loc_62: or ch,ch ; Zero ? jz loc_63 ; Jump if zero dec dx loc_63: mov data_29,dx mov bx,data_41 mov cx,0B800h test byte ptr es:video_page_,1 jnz loc_64 ; Jump if not zero mov cx,0B000h loc_64: mov es,cx mov ds,cx xor cx,cx ; Zero register add cx,cs:data_32 jnz loc_65 ; Jump if not zero mov cx,cs:data_30 jmp short loc_71 db 90h loc_65: mov cx,cs:data_30 locloop_66: push cx push si push di or bl,bl ; Zero ? jz loc_67 ; Jump if zero mov ah,es:[di] and ah,bl lodsb ; String [si] to al not bl and al,bl not bl or al,ah stosb ; Store al to es:[di] loc_67: mov cx,cs:data_29 rep movsb ; Rep when cx >0 Mov [si] to es:[di] or bh,bh ; Zero ? jz loc_68 ; Jump if zero mov ah,es:[di] and ah,bh lodsb ; String [si] to al not bh and al,bh not bh or al,ah stosb ; Store al to es:[di] loc_68: pop di pop si add si,2000h jns loc_69 ; Jump if not sign sub si,7FA6h loc_69: add di,data_147e jns loc_70 ; Jump if not sign sub di,7FA6h loc_70: pop cx loop locloop_66 ; Loop if cx > 0 mov cx,cs:data_32 loc_71: pop si locloop_72: push cx push di or bl,bl ; Zero ? jz loc_73 ; Jump if zero mov ah,es:[di] and ah,bl mov dx,si not bl and dl,bl not bl or ah,dl xchg ah,al stosb ; Store al to es:[di] loc_73: mov cx,cs:data_29 mov ax,si rep stosb ; Rep when cx >0 Store al to es:[di] or bh,bh ; Zero ? jz loc_74 ; Jump if zero mov ah,es:[di] and ah,bh mov dx,si not bh and dl,bh not bh or ah,dl xchg ah,al stosb ; Store al to es:[di] loc_74: pop di add di,2000h jns loc_75 ; Jump if not sign sub di,7FA6h loc_75: pop cx loop locloop_72 ; Loop if cx > 0 push cs pop ds mov es,data_25 retn ScrollUp endp ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ; SUBROUTINE ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ScrollDn proc near mov bl,bh push bx sub dh,ch inc dh add ch,dh dec ch sub dh,al mov byte ptr data_30,dh xor ah,ah ; Zero register mul data_44 ; ax = data * al mov data_32,ax sub dl,cl inc dl xor dh,dh ; Zero register mov byte ptr data_30+1,dh mov ax,0Eh mov bx,ax mul byte ptr data_30 ; ax = data * al mov data_30,ax mov ax,bx mul ch ; ax = reg * al add ax,0Dh push ax mov ax,dx shl dx,1 ; Shift w/zeros fill shl dx,1 ; Shift w/zeros fill shl dx,1 ; Shift w/zeros fill add dx,ax mov data_29,dx xor ch,ch ; Zero register mov ax,cx shl cx,1 ; Shift w/zeros fill shl cx,1 ; Shift w/zeros fill shl cx,1 ; Shift w/zeros fill add cx,ax mov ax,cx pop dx mov bx,dx call sub_20 mov di,cx mov dx,bx sub dx,data_32 mov cx,ax call sub_20 mov si,cx push ax xor bh,bh ; Zero register mov bl,dl mov cl,data_34[bx] add ax,data_29 dec ax mov dx,ax and ax,7 neg ax add ax,7 mov bx,ax mov ch,data_35[bx] mov data_41,cx shr dx,1 ; Shift w/zeros fill shr dx,1 ; Shift w/zeros fill shr dx,1 ; Shift w/zeros fill pop ax shr ax,1 ; Shift w/zeros fill shr ax,1 ; Shift w/zeros fill shr ax,1 ; Shift w/zeros fill sub dx,ax inc dx or cl,cl ; Zero ? jz loc_76 ; Jump if zero dec dx loc_76: or ch,ch ; Zero ? jz loc_77 ; Jump if zero dec dx loc_77: mov data_29,dx mov bx,data_41 mov cx,0B800h test byte ptr es:video_page_,1 jnz loc_78 ; Jump if not zero mov cx,0B000h loc_78: mov es,cx mov ds,cx xor cx,cx ; Zero register add cx,cs:data_32 jnz loc_79 ; Jump if not zero mov cx,cs:data_30 jmp short loc_85 db 90h loc_79: mov cx,cs:data_30 locloop_80: push cx push si push di or bl,bl ; Zero ? jz loc_81 ; Jump if zero mov ah,es:[di] and ah,bl lodsb ; String [si] to al not bl and al,bl not bl or al,ah stosb ; Store al to es:[di] loc_81: mov cx,cs:data_29 rep movsb ; Rep when cx >0 Mov [si] to es:[di] or bh,bh ; Zero ? jz loc_82 ; Jump if zero mov ah,es:[di] and ah,bh lodsb ; String [si] to al not bh and al,bh not bh or al,ah stosb ; Store al to es:[di] loc_82: pop di sub di,2000h jns loc_83 ; Jump if not sign add di,data_148e loc_83: pop si sub si,2000h jns loc_84 ; Jump if not sign add si,7FA6h loc_84: pop cx loop locloop_80 ; Loop if cx > 0 mov cx,cs:data_32 loc_85: pop si locloop_86: push cx push di or bl,bl ; Zero ? jz loc_87 ; Jump if zero mov ah,es:[di] and ah,bl mov dx,si not bl and dl,bl not bl or ah,dl xchg ah,al stosb ; Store al to es:[di] loc_87: mov cx,cs:data_29 mov ax,si rep stosb ; Rep when cx >0 Store al to es:[di] or bh,bh ; Zero ? jz loc_88 ; Jump if zero mov ah,es:[di] and ah,bh mov dx,si not bh and dl,bh not bh or ah,dl xchg ah,al stosb ; Store al to es:[di] loc_88: pop di sub di,2000h jns loc_89 ; Jump if not sign add di,7FA6h loc_89: pop cx loop locloop_86 ; Loop if cx > 0 push cs pop ds mov es,data_25 retn ScrollDn endp db 7 dup (0) ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ; SUBROUTINE ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ tty proc near mov cl,bl xor bx,bx ; Zero register mov bl,es:video_page_ shl bx,1 ; Shift w/zeros fill mov dx,es:vid_curs_pos0_[bx] cmp al,7 je loc_91 ; Jump if equal cmp al,8 je loc_92 ; Jump if equal cmp al,0Ah je loc_94 ; Jump if equal cmp al,0Dh je loc_93 ; Jump if equal mov bl,cl mov cx,1 mov bh,es:video_page_ call WriteSymAttr xor bx,bx ; Zero register mov bl,es:video_page_ shl bx,1 ; Shift w/zeros fill mov dx,es:vid_curs_pos0_[bx] inc dl cmp dl,50h ; 'P' jge loc_95 ; Jump if > or = loc_90: mov bh,es:data_40 call SetCurPos jmp short loc_ret_97 db 90h loc_91: mov ah,0Eh pushf ; Push flags call OldVec10h jmp short loc_ret_97 db 90h loc_92: cmp dl,0 je loc_ret_97 ; Jump if equal dec dl jmp short loc_90 loc_93: xor dl,dl ; Zero register jmp short loc_90 loc_94: mov cx,19h dec cl cmp dh,cl je loc_96 ; Jump if equal inc dh jmp short loc_90 loc_95: xor dl,dl ; Zero register mov cx,19h dec cl cmp dh,cl jge loc_96 ; Jump if > or = inc dh jmp short loc_90 loc_96: mov bh,es:data_40 call SetCurPos mov ax,1 xor cx,cx ; Zero register xor bh,bh ; Zero register mov dx,184Fh call ScrollUp loc_ret_97: retn tty endp db 10 dup (0) ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ; SUBROUTINE ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ sub_19 proc near mov dx,3BAh locloop_98: in al,dx ; port 3BAh, MDA/EGA vid status or al,al ; Zero ? js loc_99 ; Jump if sign=1 jmp short locloop_98 loc_99: in al,dx ; port 3BAh, MDA/EGA vid status or al,al ; Zero ? jns loc_100 ; Jump if not sign jmp short loc_99 loc_100: loop locloop_98 ; Loop if cx > 0 retn sub_19 endp ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ; SUBROUTINE ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ sub_20 proc near push si mov si,dx shl si,1 ; Shift w/zeros fill mov dx,data_36[si] push cx shr cx,1 ; Shift w/zeros fill shr cx,1 ; Shift w/zeros fill shr cx,1 ; Shift w/zeros fill add cx,dx pop dx ;* and dx,7 db 83h,0E2h, 07h ; Fixup - byte match neg dx ;* add dx,7 db 83h,0C2h, 07h ; Fixup - byte match pop si retn sub_20 endp db 15 dup (0) ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ; MAIN ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ StayResident: ; Проверка, может мы уже резидентны? mov dl,0FFh mov ah,0EFh int 10h cmp dl,0FFh mov dx,offset s_already jne AlreadyStayResident call TestHerc ; проверка на наличие Геркулеса cmp dl,0FFh jne HercPresent mov dx,offset s_not_herc AlreadyStayResident: mov ah,9 int 21h ; DOS Services display char string at ds:dx xor ax,ax int 20h ; DOS program terminate HercPresent: ; Сканируем командную строку на флаги cld xor cx,cx mov cl,80h jcxz loc_105 mov di,data_3e ; = 81H - адрес ком строки в PSP loc_104: mov al,2Fh ; '/' repne scasb ; Rep zf=0+cx >0 Scan es:[di] for al jcxz loc_105 mov al,[di] ; флаг and al,0DFh ; uppercase cmp al,48h ; 'H' jne loc_104 mov FlagH,1 ; Hайден флаг /H loc_105: ; save old vector of int 10h push es xor ax,ax mov es,ax ; ES:=0 mov bx,es:Vec10h ; bx := 0:40 mov word ptr OldVec10h,bx mov bx,es:Vec10h+2 mov word ptr OldVec10h+2,bx ; set new vector of unt 10h cli mov word ptr es:Vec10h,offset Trap10h mov es:Vec10h+2,cs sti pop es mov ah,9 mov dx,offset s_OK int 21h ; ; calculate resident memory mov dx,offset StayResident ; 1A20h mov cl,4 shr dx,cl ; Shift w/zeros fill inc dx mov ax,3100h int 21h ; TSR al=return code,dx=paragraphs s_OK db 'Hercules Resident Video Support Routines. Version 1.10',0Dh,0Ah db '$' s_already db 'Hercules Video Support Routines are already installed.',0Dh,0Ah db '$' s_not_herc db 'Hercules Video Card not present.',0Dh,0Ah db 'Hercules Video Support Routines not installed.', 0Dh, 0Ah, '$' seg_a ends end start src/kernel/debug.mac0100664000076500007650000000062407725645015014143 0ustar prool2prool2 extrn debugl:near extrn debuge:near debug macro P1,P2 ifidn , push ax mov ax,P2 call debugl pop ax else ifidn , mov al,'E' else mov al,'B' endif call debuge endif endm src/kernel/alloc.c0100664000076500007650000001762207725645014013636 0ustar prool2prool2/* #define DEBUG_ALLOC */ /*****************************************************************************/ static unsigned int parleft(void) {int CurPar, ret; struct MemBlk far * MB; ret=0; CurPar = FP_SEG(Fin) + (FP_OFF(Fin) >> 4); MB = MK_FP(CurPar,0); while (1) { if (!((*MB).OwnerPar)) if ((*MB).SizePar>ret)ret+=(*MB).SizePar-1; if ((*MB).Type != 'M') break; CurPar+=(*MB).SizePar; MB = MK_FP (CurPar,0); } return ret; } /*****************************************************************************/ static unsigned int parxtent(void) {int CurPar, ret; struct MemBlk far * MB; ret=0; CurPar = FP_SEG(Fin) + (FP_OFF(Fin) >> 4); MB = MK_FP(CurPar,0); while (1) { if (!((*MB).OwnerPar)) if ((*MB).SizePar>ret)ret=(*MB).SizePar-1; if ((*MB).Type != 'M') break; CurPar+=(*MB).SizePar; MB = MK_FP (CurPar,0); } return ret; } /*****************************************************************************/ static unsigned long coreleft(void) {unsigned long l; l=parleft(); return l<<4; } /*****************************************************************************/ static unsigned long int corextent(void) {unsigned long l; l=parxtent(); return l<<4; } /*****************************************************************************/ void mem(void) {int CurPar; char c; struct MemBlk far * MB; CurPar = FP_SEG(Fin) + (FP_OFF(Fin) >> 4); MB = MK_FP(CurPar,0); puts("\nRAM OwnPar Size"); while (1) { printf("%4X:0000 %c %4X %4X",CurPar,(c=(*MB).Type)<' '?' ':c, (*MB).OwnerPar,(*MB).SizePar); if ((*MB).Type != 'M') {puts(""); break;} CurPar+=(*MB).SizePar; MB = MK_FP (CurPar,0); puts(""); } printf("Free memory %li\nMaximum free block %li\n",coreleft(), corextent()); } /****************************************************************************/ void far *malloc (size_t size) { unsigned int CurPar, NeedPar, RestosPar; struct MemBlk far * MB; struct MemBlk far * Rest; struct MemBlk MB2; if (size==0) return NULL; if (size==-1L) { size=corextent(); } NeedPar=(int)(size>>4)+1; if (size & 0xF) NeedPar++; #ifdef DEBUG_ALLOC printf("A1\n"); #endif CurPar = FP_SEG(Fin) + (FP_OFF(Fin) >> 4); MB = MK_FP(CurPar,0); #ifdef DEBUG_ALLOC printf("A2\n"); #endif while (1) { #ifdef DEBUG_ALLOC printf("A3\n"); #endif if(!(*MB).OwnerPar) /* block is free */ if ((*MB).SizePar>=NeedPar) { /* memory yes */ #ifdef DEBUG_ALLOC printf("A11\n"); #endif MB2.Type=(*MB).Type; MB2.SizePar=(*MB).SizePar; (*MB).SizePar=NeedPar; (*MB).OwnerPar=ProcessPar; #ifdef DEBUG_ALLOC printf("malloc: ProcessPar=%04X\n",ProcessPar); #endif if (MB2.SizePar>NeedPar) {/* restos of blk */ #ifdef DEBUG_ALLOC printf("A10\n"); #endif (*MB).Type='M'; RestosPar=CurPar+NeedPar; Rest=MK_FP(RestosPar,0); (*Rest).OwnerPar=0; (*Rest).SizePar=MB2.SizePar-NeedPar; (*Rest).Type=MB2.Type; } #ifdef DEBUG_ALLOC printf("A13\n"); #endif return MK_FP(CurPar+1,0); } else ; /* no memory in this blk */ else ; /* blk is busy */ if ((*MB).Type != 'M') break; CurPar+=(*MB).SizePar; MB = MK_FP (CurPar,0); } #ifdef DEBUG_ALLOC printf("alloc\n"); #endif return NULL; } /*****************************************************************************/ void free ( void far * block) { size_t CurPar; struct MemBlk far * MB; if (block==0) return; block=MK_FP(FP_SEG(block) + (FP_OFF(block)>>4) -1,0); /* normalization */ CurPar = FP_SEG(Fin) + (FP_OFF(Fin) >> 4); MB = MK_FP(CurPar,0); while (1) { if (MB==block) {(*MB).OwnerPar=0;return;} if ((*MB).Type != 'M') break; CurPar+=(*MB).SizePar; MB = MK_FP (CurPar,0); } } /*****************************************************************************/ unsigned int par_size_of_block ( void far * block) { size_t CurPar; struct MemBlk far * MB; if (block==0) return 0; block=MK_FP(FP_SEG(block) + (FP_OFF(block)>>4) -1,0); /* normalization */ CurPar = FP_SEG(Fin) + (FP_OFF(Fin) >> 4); MB = MK_FP(CurPar,0); while (1) { if (MB==block) {return (*MB).SizePar;} if ((*MB).Type != 'M') break; CurPar+=(*MB).SizePar; MB = MK_FP (CurPar,0); } return 0xFFFF; } /*****************************************************************************/ int garbage (void) {int ret=1; size_t CurPar; int opt=1; struct MemBlk far * MB; struct MemBlk far * MB0; while(opt) { opt=0; CurPar = FP_SEG(Fin) + (FP_OFF(Fin) >> 4); MB = MK_FP(CurPar,0); if (((*MB).Type) != 'M') return 1; MB0=MB; while (1) { CurPar+=(*MB).SizePar; MB = MK_FP (CurPar,0); if ( (((*MB0).OwnerPar)==0) && (((*MB).OwnerPar)==0) ) { (*MB0).Type=(*MB).Type; (*MB0).SizePar+=(*MB).SizePar; ret=0; opt=1; } else MB0=MB; if ((*MB).Type != 'M') break; } } return ret; } /*****************************************************************************/ void far *calloc (size_t nitems, size_t size) {size_t m, i; void far *Pointer; char huge *Setter; /* тут глюки. везде надо huge ? */ if ((Pointer=malloc(m=nitems*size))!=NULL) { Setter=Pointer; for(i=0;i>4) -1,0); /* normalization */ CurPar = FP_SEG(Fin) + (FP_OFF(Fin) >> 4); MB = MK_FP(CurPar,0); while (1) { if (MB==block) {/* нашли блок памяти */ goto l_found; } if ((*MB).Type != 'M') break; CurPar+=(*MB).SizePar; MB = MK_FP (CurPar,0); } /* такого блока памяти нет */ return NULL; } l_found: /* если попытка изменить размер свободного блока памяти - то ну его нафиг */ if (!MB->OwnerPar) return NULL; /* ищем следующий блок */ if ((*MB).Type != 'M') MB_next=NULL; CurPar+=(*MB).SizePar; MB_next = MK_FP (CurPar,0); /* определяем новый размер в параграфах */ NeedPar=(int)(size>>4)+1; if (size & 0xF) NeedPar++; if (MB->SizePar==NeedPar) return block; /* никакого изменения не надо */ if (MB->SizePar>NeedPar) {/* уменьшаем размер блока */ Delta=MB->SizePar-NeedPar; MB->SizePar=NeedPar; /* создаем блок-кусочек */ CurPar = FP_SEG(MB) + (FP_OFF(MB) >> 4); CurPar+=MB->SizePar; MB_kusochek= MK_FP(CurPar,0); MB_kusochek->Type='M'; MB_kusochek->OwnerPar=0; MB_kusochek->SizePar=MB->SizePar-NeedPar-1; /* если следующий блок тоже пустой, то блок-кусочек поглощает его */ if (!MB_next->OwnerPar) { MB_kusochek->SizePar+=(MB_next->SizePar+1); } } else {/* увеличиваем размер блока */ /* если следующий блок несвободен - выход */ if (MB_next->OwnerPar) return NULL; /* если наш блок последний - выход */ if (MB->Type=='Z') return NULL; /* вычисляем приращение размера нашего блока */ Delta=NeedPar-MB->SizePar; /* если следующий блок меньше необходимого приращения - выход */ if (MB_next->SizeParSizePar==Delta) { MB->SizePar=NeedPar; return block; } /* наш блок отьест кусочек от следующего блока */ MB->SizePar=NeedPar; /* */ CurPar = FP_SEG(MB) + (FP_OFF(MB) >> 4); CurPar+=MB->SizePar; MB_kusochek= MK_FP(CurPar,0); MB_kusochek->Type=MB_next->Type; MB_kusochek->OwnerPar=0; MB_kusochek->SizePar=MB_next->SizePar-Delta; } return NULL; }src/kernel/dev_con.c0100664000076500007650000000027607725645015014157 0ustar prool2prool2#include #include #include "kernel.h" int console_read (int minor) { return getch(); } int console_write (int minor, int byte) { return putch (byte); } src/kernel/int0.c0100664000076500007650000000027707725645015013415 0ustar prool2prool2#include #include #include "kernel.h" void interrupt Int0(void) { puts("\nInterrupt 0 - IMHO, divide by zero\n"); #if 0 loop(); #else getch(); #endif } src/kernel/d2p.c0100664000076500007650000000176507725645015013233 0ustar prool2prool2#include #include #include "kernel.h" /****************************************************************************/ /* #define DEBUG */ /****************************************************************************/ char *DirToPath(struct dirent far *Dir, char *path) {char c, far *cc, *ret; int i; unsigned len; #ifdef DEBUG printf("D2P: dir=%s ",(*Dir).d_name); #endif if (Dir==NULL) return NULL; if (path==NULL) return NULL; ret=path; if ((*Dir).Attr.B.Attr1) { cc=memchr((*Dir).d_name,' ',11); if (cc==NULL) len=11; else len=(int)(cc-(*Dir).d_name); memcpy(path,(*Dir).d_name,(len>11)?11:len); path[len]=0; } else { for(i=0;i<8;i++) if ((c=(*Dir).d_name[i])!=' ') *path++=c; else break; if ((*Dir).d_name[8]!=' ') { *path++='.'; for (i=8;i<11;i++) if ((c=(*Dir).d_name[i])!=' ') *path++=c; else break; } *path=0; strlwr(ret); } #ifdef DEBUG printf(" path=%s ",ret); #endif return ret; } src/kernel/int8.c0100664000076500007650000004473007725645015013427 0ustar prool2prool2/*************************BEGIN**********************************************/ /* #define DEBUG */ #include #include #include "kernel.h" void start(char *cmd); unsigned char c=0; unsigned int unique_pid=1; jmp_buf int8_point; int current_pid=0; int sema_ps=0; /****************************************************************************/ int sema_lock (int far *sema) { __cli__(); if (*sema==0) { *sema=1; __sti__(); return 0; /* locked OK */ } __sti__(); return 1; /* no locked */ } /****************************************************************************/ void sema_unlock (int far *sema) { __cli__(); if (*sema==1) *sema=0; __sti__(); } /****************************************************************************/ int generate_pid (void) { return unique_pid++; } /****************************************************************************/ int load_file(char far *name, char huge *adr) {int h, i; #ifdef DEBUG printf("load_file: `%Fs'\n",name); #endif if ((h=open(name,O_RDONLY))==-1) { printf("load_file: Can't open `%Fs'\n",name); return 1; } while (1) { i=(int)read(h, (void far *)adr, SECTOR_SIZE); if (i!=SECTOR_SIZE) break; adr+=SECTOR_SIZE; } close(h); return 0; } /****************************************************************************/ void ps_ (void) {int i; printf("current_pid=%i\n",current_pid); printf( "# PID status mem0 cs ip ds es ax ss sp flag cmd stacktop\n" ); for (i=0;i or s \n"); return; } chdir("/bin"); printf("command=%s\n",cmd); create_process(cmd); /* create_process("sh"); */ /* create_process("p1"); */ /* create_process("p2"); */ /* create_process("p3"); */ for (i=0;i #include #include #include #include /* #define DEBUG */ extern int CluSize; int CluRead (int drive, unsigned int CluNo, void far * buffer) {int i; #ifdef DEBUG printf("\nCluRead=%u ",CluNo); #endif i=absread (TR(drive), CluSize,SecForClu(CluNo), buffer); return i; }src/kernel/ohw.asm0100664000076500007650000000074207725645016013674 0ustar prool2prool2; ohw locals _TEXT segment byte public 'CODE' assume cs:_TEXT extrn ohb:near ohw proc ; Вывод слова в HEX-виде. Вход: слово в ax. ; Все регистры сохраняются. ; Вызывает подпрограмму ohb push ax ; Сохр. ради al. mov al,ah call ohb pop ax ; Восст. al. call ohb ret ohw endp public ohw _TEXT ends end src/kernel/out_iv.c0100664000076500007650000000025307725645016014043 0ustar prool2prool2#include #include #include "kernel.h" int OutIntVector (int i) { return printf("%2x %4x:%4x\n",i,FP_SEG(getvect(i)),FP_OFF(getvect(i))); } src/kernel/c0.asm0100664000076500007650000001363707725645014013406 0ustar prool2prool2; Startup module for Proolix kernel (similar to Turbo C 2.0's c0t.obj and ; similar to UNIX's crt.o) ; History ; 0.0.2.15 2-Nov-99 add BeforeSS, BeforeSP ; 0.0.2.14 17-May-97 ; 0.0.2.13 28-Apr-97 отловлен большой глюк в связи с тем, что ядро ; откомпилировано Turbo C 2.0 в модели памяти small, ; где должно быть DS=SS, а у меня было DS!=SS ; 0.0.2.12 28-Apr-97 ; 0.0.2.11 21-Apr-97 ; 0.0.2.10 20-Apr-97 отловлен большой глюк с mov SP, ... ; 0.0.2.9 22-Mar-97 ; 0.0.2.8 8-Mar-97 ; 0.0.2.7 3-Mar-97 ; 0.0.2.6 2-Mar-96 ; 0.0.2.5 2-Feb-96 ; 0.0.2.4 14-Oct-96 ; 0.0.2.3 29-Sep-96 ; 0.0.2.2 16-May-96 ; 0.0.2.1 11-May-96 начал делать control-break ; 0.0.2.0 21-Apr-96 _execexe ; 0.0.1.5 3-Apr-96 ; 0.0.1.4 31-Mar-96 ; 0.0.1.3 24-Mar-96 ; 0.0.1.2 18-Mar-96 ; 0.0.1.1 17-Mar-96 ; 0.0.1.0 14-Mar-96 for EXE kernel ; 0.0.0.15 5-Nov-95 for com kernel ; 0.0.0.15 4-Nov-95 ; 0.0.0.14 15-Jan-95 ; Макрос. Вывод одного символа через ROM BIOS. chr1 macro sym ; Not worked in graph mode (registr bl - background color!) ; NO SAVE REGS !!! mov ax,0e00h+sym int 10h endm chr1 sayr macro str ; NO SAVE REGS !!! ; Макрокоманда, аналогичная макрокоманде say. Только say использует функцию 9h ; ДОС, а sayr - функцию ROM BIOS (функция 0eh прерывания 10h) ; В графических режимах не работает mov si,offset str call sayr_proc endm sayr extrn _errno:word extrn _More:word extrn _NLine:word extrn _HeadCnt:word extrn _TrkSecs:word extrn _CurrentDevice:word StackTopPar equ 0fffh _TEXT segment byte public 'CODE' DGROUP group _DATA,_BSS assume cs:_TEXT,ds:DGROUP ; ,ss:DGROUP .8086 _Begin: ; mov DX,DGROUP mov dx,_DATA mov DGROUP@,dx mov DS,dx cli mov SS,dx mov SP,StackTopPar shl 4 sti mov ax,ES:[4] mov _CurrentDevice,ax extrn _saycsip:near call _saycsip extrn _main:near jmp _main DGROUP@ dw 0 public DGROUP@ KernelSS dw 0 KernelSP dw 0 _UserSS dw 0 _UserDS dw 0 UserSP dw 0 SaveAX dw 0 _Trace dw 0 _Succ dw 0 public _UserSS public _UserDS public _Trace public _Succ _stackend proc near mov ax,DGROUP@ add ax,StackTopPar ret _stackend endp public _stackend _kernel_begin proc near mov ax,seg _Begin ret _kernel_begin endp public _kernel_begin extrn _Mode:word extrn _User:word _execpix proc near push bp mov bp,sp push ax push bx push cx push dx push si push di push DS push ES mov ax,word ptr [bp+6] ; segm ; exec(), выданный из режима ядра (_Mode=0, SS=70h) производит переход в ; режим пользователя (_Mode=1, SS=User's SS) ; exec(), выданный из режима пользователя, не производит изменения режима ; (это еще нужно продумать хорошо, а пока exec у меня происходит только из ; режима ядра с безусловным переходом в режим пользователя) ; SAVE SS SP CLI mov CS:KernelSS,SS mov CS:KernelSP,SP mov CS:_Mode,1 STI mov DS,ax mov ES,ax mov word ptr CS:@@seg,ax mov bx,0fffeh sub bx,word ptr [bp+8] ; 0fffeh - len ; save Return address in PSP mov cx,offset Return mov ES:[12],cx mov cx,CS mov ES:[14],cx CLI mov SS,ax mov SP,bx STI ; EXEC! JMP dword ptr StartAddr ; было CALL Return: public Return ; RESTORE SS SP CLI mov SS,CS:KernelSS mov SP,CS:KernelSP mov CS:_Mode,0 STI pop ES pop DS pop di pop si pop dx pop cx pop bx pop ax pop bp ret StartAddr dw 102h @@seg dw 0 ; seg _execpix endp public _execpix _WritePhysSec proc ; int WritePhysSec (unsigned char drive, unsigned char sec, unsigned char head, ; unsigned char trk, char *Buffer); ; ALL REGS SAVED push bp mov bp,sp push bx push cx push dx push ES push DS pop ES mov dl,byte ptr [bp+ 4] ; drive mov cl,byte ptr [bp+ 6] ; sec mov dh,byte ptr [bp+ 8] ; head mov ch,byte ptr [bp+10] ; trk mov bx,word ptr [bp+12] ; Buffer mov ax,0301h; Fn=03, Write 1 sector int 13h jc @@err xor ax,ax jmp @@ret @@err: ; mov ax,-1 @@ret: pop ES pop dx pop cx pop bx ; mov sp,bp pop bp ret _WritePhysSec endp public _WritePhysSec _TEXT ends _DATA segment word public 'DATA' ; System call table _SysTable label word public _SysTable include syskern.asm _DATA ends _BSS segment word public 'BSS' _NearBuffer db 512 dup ('.') ; for absread.c. public _NearBuffer ; нужно не пересекать границу 64k _BSS ends public _Begin end _Beginsrc/kernel/msdos.asm0100664000076500007650000000143607725645016014225 0ustar prool2prool2_TEXT segment byte public 'CODE' assume cs:_TEXT _msdos proc extrn _RestoreVec:near ; вернуть старые прерывания cli call _RestoreVec sti xor ax,ax mov ES,ax ; Read MBR mov dl,80h ; drive mov dh,0 ; head mov cl,1 ; sec mov ch,0 ; trk mov al,1 ; sec count mov ah,2 ; Fn read mov bx,7c00h int 13h nop jc @@reboot ;jmp 0:7c00 db 0eah dw 7c00h dw 0 @@reboot:; jmp ffff:0 db 0eah dw 0 dw 0ffffh _msdos endp public _msdos _TEXT ends end src/kernel/msh.c0100664000076500007650000001232607725645016013331 0ustar prool2prool2/* Mouse shell for Proolix (aka Desktop for Proolix) */ #include #include "kernel.h" #include #include #include "msh.h" void help(void); void ladder(void); /*---------------------------------------------------------------------------*/ void msh_pause(long int L) {long int k; for ( k=0 ; k < L ; k++); } /*---------------------------------------------------------------------------*/ void drebezg(void) { /* while (kbhit())getch();*/ } /*---------------------------------------------------------------------------*/ void msh_ident(void) { gotoxy(20,0); printf("\007XProolix for BK-0010 ;) Ver. 0.0.0.6 4-Mar-94"); /* History 0.0.0.6 4-Mar-94 - сделал правильную работу с com-портами 0.0.0.5 2-Mar-94 - делаю правильную работу с com-портами по книге Фроловых (см. коммент в bios.c) 0.0.0.4 1-Mar-94 0.0.0.3 27-Feb-94 - см. комментарий в kernel.c на данную дату 0.0.0.2 25-Feb-94 0.0.0.1 25-Feb-94 - эта версия не имела в себе номера версии, но была уже анонсирована в kharkov.friends */ } /*---------------------------------------------------------------------------*/ void atsay(int x, int y, char * str) { gotoxy(x,y); printf(str); } /*---------------------------------------------------------------------------*/ void attr(void) {unsigned int i,j; for (i=0;i<16;i++) for (j=0;j<16;j++) { gotoxy(i,j); textattr(j+(i<<4)); putch('*'); } } /*---------------------------------------------------------------------------*/ void icon(struct DeskTop Desk [], int i) { gotoxy(Desk[i].x,Desk[i].y); printf(Desk[i].Name); } /*---------------------------------------------------------------------------*/ int execm(void) { int i; int k, b, MaxFolder; long ii; unsigned int j; char far *rec; int Chars; int Files; struct dirent far *D; if (CurrentDevice==-1) {puts("No mount"); return -1;} for(i=0;i"); } else goto br; */ } else if (Files #include #include "kernel.h" void nulldev (void) { } /****************************************************************************/ void FDDstrategy (void) { } /****************************************************************************/ void HDDstrategy (void) { } src/kernel/cold.asm0100664000076500007650000000050707725645014014015 0ustar prool2prool2_TEXT segment byte public 'CODE' assume cs:_TEXT _cold proc near mov ax,40h mov ds,ax mov bx,72h mov [bx],4321h db 0eah ; JMP F000:FFF0 dw 0fff0h,0f000h _cold endp public _cold _TEXT ends end src/kernel/conv.c0100664000076500007650000001406007725645015013503 0ustar prool2prool2#include #include #include "kernel.h" /****************************************************************************/ /* #define DEBUG */ /****************************************************************************/ char HexDigit [] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; int Divisor8 [] = {0100000, 010000, 01000, 0100, 010, 1}; int Divisor10 [] = {10000, 1000, 100, 10, 1}; long Divisor10L [] = {1000000000L, 100000000L, 10000000L, 1000000L, 100000L, 10000L, 1000L, 100L, 10L, 1L}; long Divisor8L [] = {010000000000L, 01000000000L, 0100000000L, 010000000L, 01000000L, 0100000L, 010000L, 01000L, 0100L, 010L, 01L}; int htoi(const char far *s) { int i; char c; i=0; while (*s) { i<<=4; c=toupper(*s++); if ((c>='0')&&(c<='9')) i+=c-'0'; else if ((c>='A')&&(c<='F')) i+=c+10-'A'; else return 0; } return i; } /****************************************************************************/ long htol(const char far *s) { long i; char c; i=0; while (*s) { i<<=4; c=toupper(*s++); if ((c>='0')&&(c<='9')) i+=c-'0'; else if ((c>='A')&&(c<='F')) i+=c+10-'A'; else return 0; } return i; } /****************************************************************************/ int atoi(const char far *s) { int i; char c; i=0; if (*s=='+') s++; else if(*s=='-')return-atoi(++s); while (*s) { c=*s++; if (isdigit(c)) {i=i*10; i+=c-'0';} else break; } return i; } /****************************************************************************/ long atol(const char far *s) { long i; char c; i=0; if (*s=='+') s++; else if(*s=='-')return-atol(++s); while (*s) { c=*s++; if (isdigit(c)) {i=i*10; i+=c-'0';} else break; } return i; } /****************************************************************************/ #if 0 void fuck1(void) { int Divisor [] = {10000, 1000, 100, 10, 1}; printf("fuck1 = %04X\n",Divisor[0]); } #endif /****************************************************************************/ char far *itoa (int w, char far *str, int radix) { char far *ret; int i, r, pow, n; /* printf("itoa = %04X\n",Divisor10[0]); */ if (radix>34) radix=34; ret=str; if (w<0) if (radix==10) {*str++='-'; itoa(-w,str,-10); return ret;} switch(radix) { case 2: for (i=0;i<16;i++) {*str++='0'+ w & 0x8000; w<<=1;} break; case 8: for (i=0;i<6;i++) {r=w/Divisor8[i]; w%=Divisor8[i]; *str++='0'+r;} break; case 16: for (i=0;i<4;i++) {*str++=HexDigit[(w&0xF000)>>12];w<<=4;} break; case 10: *str++='0'; for (i=0;i<5;i++) {r=w/Divisor10[i]; w%=Divisor10[i]; *str++='0'+r; #ifdef DEBUG printf("itoa: Divisor10[i]=%04X r=%04X w=%04X\n", Divisor10[i],r,w); #endif } break; case -10: for (i=0;i<5;i++) {r=w/Divisor10[i]; w%=Divisor10[i]; *str++='0'+r; } break; default: pow=UINT_MAX; for (i=1;i<16;i++) {pow/=radix; if (pow>0) break;} n=i; pow=1; for (i=1;i34) radix=34; ret=str; if (w<0) if (radix==10) {*str++='-'; ltoa(-w,str,-10); return ret;} switch(radix) { case 2: for (i=0;i<32;i++) {*str++='0'+ w & 0x8000; w<<=1;} break; case 8: for (i=0;i<11;i++) {r=w/Divisor8L[i]; w%=Divisor8L[i]; *str++='0'+r;} break; case 16: for (i=0;i<8;i++) {*str++=HexDigit[(int)((w&0xF0000000L)>>28)];w<<=4;} break; case 10: *str++='0'; for (i=0;i<10;i++) {r=w/Divisor10L[i]; w%=Divisor10L[i]; *str++='0'+r; } break; case -10: for (i=0;i<10;i++) {r=w/Divisor10L[i]; w%=Divisor10L[i]; *str++='0'+r; } break; default: pow=ULONG_MAX; for (i=1;i<32;i++) {pow/=radix; if (pow>0) break;} n=i; pow=1; for (i=1;i34) radix=34; ret=str; switch(radix) { case 2: for (i=0;i<32;i++) {*str++='0'+ w & 0x8000; w<<=1;} break; case 8: for (i=0;i<11;i++) {r=w/Divisor8L[i]; w%=Divisor8L[i]; *str++='0'+r;} break; case 16: for (i=0;i<8;i++) {*str++=HexDigit[(int)((w&0xF0000000L)>>28)];w<<=4;} break; case 10: *str++='0'; for (i=0;i<10;i++) {r=w/Divisor10L[i]; w%=Divisor10L[i]; *str++='0'+r; } break; case -10: for (i=0;i<10;i++) {r=w/Divisor10L[i]; w%=Divisor10L[i]; *str++='0'+r; } break; default: pow=ULONG_MAX; for (i=1;i<32;i++) {pow/=radix; if (pow>0) break;} n=i; pow=1; for (i=1;i #include #include "../include/conf.c" #define BUFSIZE 160 int main(int argc, char *argv[]) { int i, j ,k, FlagN; FILE *table, *kernel, *util, *make; char Table [] = "syscall.tbl"; char KLib [] = "syskern.asm"; char buf [BUFSIZE]; char s1 [BUFSIZE]; char s2 [BUFSIZE]; char s3 [BUFSIZE]; char Module [BUFSIZE]; char Proc [] = "\ ; Do not edit this file.\n\ ; This file is automatically generated\n\n\ \tmodel tiny\n\ \t.code\n\ %s:\tmov\tax,%i\n\ \tint\t0%02Xh\n\ \tret\n\ \tpublic\t%s\n\ \tend\n"; char do_not_edit [] = "\ %s Do not edit this file.\n\ %s This file is automatically generated\n\n"; if (argc<2) { puts("usage: gentbl CommandSourcePath [-n]\n\ -n - no overwrite existing modules *.asm"); return 1; } if (argc==3) if (!strcmp(argv[2],"-n")) FlagN=1; else FlagN=0; puts("\n\tGenTbl v. 0.0.0.3 24-Mar-96 Generate System Calls\n"); /* History 0.0.0.3 24-Mar-96 0.0.0.2 13-Dec-95 */ buf[0]=0; if((table=fopen(Table,"rt"))==NULL) {printf("Can't open %s\n",Table);return 2;} if((kernel=fopen(KLib,"wt"))==NULL) {printf("Can't open %s\n",KLib);return 2;} sprintf(Module,"%s\\syscall.h",argv[1]); if((make=fopen(Module,"wt"))==NULL) {printf("Can't open %s\n",Module);return 2;} if(fprintf(make,do_not_edit,";",";")==EOF) {printf("Can't write %s\n",Module);return 2;} if(fprintf(make,"INT_NO\tequ\t0%02Xh\n",INT_NO)==EOF) {printf("Can't write %s\n",Module);return 2;} if(fprintf(kernel,do_not_edit,";",";")==EOF) {printf("Can't write %s\n",KLib);return 2;} for(i=0;;) { if(fgets(buf,BUFSIZE,table)==NULL) break; switch (buf[0]) { case '\n': case ' ' : case ';' : case 0 : continue; } s3[0]=0; sscanf(buf,"%s %s %s",s1,s2,s3); if (!s3[0]) strcpy(s3,s1); if(fprintf(kernel,"extrn\t%s:near\ndw\t%s,_TEXT:%s\n",s3,s2,s3)==EOF) {printf("Can't write %s\n",KLib);return 2;} if(fprintf(make,"%s\tequ\t%03i\n",s1+1,i)==EOF) {printf("Can't write %s\n",Module);return 2;} sprintf(Module,"%s\\%03i.ASM",argv[1],i); if (FlagN) if((util=fopen(Module,"rt"))!=NULL) { fclose(util); printf("System Call %03i %013s existing. Not rewrited.\n",i,s1); goto LL; } if((util=fopen(Module,"wt"))==NULL) {printf("Can't open %s\n",Module);return 2;} if(fprintf(util,Proc,s1,i,INT_NO,s1)==EOF) {printf("Can't write %s\n",Module);return 2;} if(fclose(util)) {printf("Can't close %s\n",Module);} if (strcmp(s1,s3)) printf("System Call %03i %s %s\n",i,s1,s3); else printf("System Call %03i %s\n",i,s1); LL: i++; } if(fclose(table)) {printf("Can't close %s\n",Table); } if(fclose(kernel)) {printf("Can't close %s\n",KLib); } if(fclose(make)) {printf("Can't close %s\n",Module); } puts(""); sprintf(Module,"%s\\tlib.cmd",argv[1]); printf("Generate %s\n",Module); if((make=fopen(Module,"wt"))==NULL) {printf("Can't open %s\n",Module);return 2;} for (j=0;j #include #include "kernel.h" void interrupt Int5(void) { /* puts("\nInterrupt 5 - U pressed PrintScreen key\n"); */ } src/kernel/ppt.c0100664000076500007650000000311507725645016013341 0ustar prool2prool2void process_partition_table (char far *MBRBuf) { struct MBRstru far *MBR; char ExtBuf [SECTOR_SIZE]; int i; MBR=(void far *)MBRBuf; for (i=0; i<4; i++) { if (MBR->Partition[i].system_indicator) { if (NextDrivePartition[i].begin_head; Devices[NextDrive].sec=MBR->Partition[i].begin_sec; Devices[NextDrive].trk=MBR->Partition[i].begin_cyl; Devices[NextDrive].system_indicator=MBR->Partition[i].system_indicator; switch(MBR->Partition[i].system_indicator) { case 1 : Devices[NextDrive].FileSystem=FAT12; break; case 4 : case 6 : Devices[NextDrive].FileSystem=FAT16; break; default: Devices[NextDrive].FileSystem=NO_FAT; } switch(MBR->Partition[i].system_indicator) { case EXTEND: case EXTEND2: Devices[NextDrive].dos_disk=' '; break; default: Devices[NextDrive].dos_disk=NextDOSDrive++; } Devices[NextDrive].ResSecs=MBR->Partition[i].preceding_sec + 1; Devices[NextDrive].MaxSectors=MBR->Partition[i].total_sec +Devices[NextDrive].ResSecs; NextDrive++; if((MBR->Partition[i].system_indicator==EXTEND)||(MBR->Partition[i].system_indicator==EXTEND2)) { /* extended partition */ if (ReadPhysSec2 (_HDD_,MBR->Partition[i].begin_sec, MBR->Partition[i].begin_head,MBR->Partition[i].begin_cyl,ExtBuf)) printf ("boot: extend boot sector read error\n"); process_partition_table(ExtBuf); } } } } } src/kernel/regdump.asm0100664000076500007650000000430007725645017014535 0ustar prool2prool2; Register dump _TEXT segment byte public 'CODE' assume cs:_TEXT sayr macro str ; В графических режимах не работает push si lea si,str ; Было mov si,offset str call sayr_proc pop si endm sayr chr1 macro sym ; via BIOS ; Not worked in graph mode (bl - bg color!) ; NO SAVE REG mov al,sym mov ah,0eh int 10h endm chr1 extrn sayr_proc:near extrn ohw:near _saycsip proc near ; REG SAVED push ax push DS chr1 'i' chr1 'p' chr1 '=' push CS pop ax call ohw chr1 ':' call ll ll: pop ax call ohw chr1 ' ' chr1 'd' chr1 's' chr1 '=' push DS pop ax call ohw push CS pop DS sayr s_ax pop ax push ax call ohw sayr s_bx mov ax,bx call ohw sayr s_cx mov ax,cx call ohw sayr s_dx mov ax,dx call ohw sayr s_si mov ax,si call ohw sayr s_di mov ax,di call ohw sayr s_ss mov ax,SS call ohw sayr s_sp mov ax,SP add ax,6 ; исправление SP (с учетом call saycsip и двух push) call ohw sayr s_es mov ax,ES call ohw sayr s_bp mov ax,BP call ohw pop DS pop ax ret ;s0 db 13,10,"CS:IP=",0 s_ax db ' ax=',0 s_bx db ' bx=',0 s_cx db ' cx=',0 s_dx db ' dx=',0 s_si db ' si=',0 s_di db ' di=',0 s_ss db ' SS=',0 s_sp db ' SP=',0 s_ds db ' DS=',0 s_es db ' ES=',0 s_bp db ' BP=',0 _saycsip endp public _saycsip _TEXT ends end src/kernel/videopag.c0100664000076500007650000000031507725645020014326 0ustar prool2prool2#include #include #include "kernel.h" void new_video_page (char page) { union REGS regs; regs.h.ah=5; regs.h.al=page; regs.x.flags=0; int86(0x10,®s,®s); } src/kernel/cp.c0100664000076500007650000000315507725645015013143 0ustar prool2prool2/*-------------------------------------------------------------------------*/ /* internal cp */ /*-------------------------------------------------------------------------*/ #include #include #include "kernel.h" void cp_help(void) { puts("usage: cp [file1] [file2]"); } int copy(char *path1, char *path2) {int h1, h2, i1, i2; long n, m; char buf [SECTOR_SIZE]; if((h1=open(path1,O_RDONLY))==-1) return -1; if (access(path2,2)==0) if (unlink(path2)) {printf("Cp: can't unlink target\n"); return -1; } if((h2=open(path2,O_WRONLY|O_CREAT|O_EXCL))==-1) {close(h1); return -1;} while(1) { if((n=read(h1,buf,SECTOR_SIZE))==-1) break; if(n==0) {m=0; break;} if((m=write(h2,buf,n))==-1) break; if (m!=n) break; } i1=close(h1); i2=close(h2); if (n==-1) return -1; if (m==-1) return -1; if (m!=n) return -1; if (i1==-1) return -1; return (i2); } void cp(int argc, char far *argv[] ) { int ii, j, n, Files=0; char path[2][PATH_MAX]; argc--; ii=1; do { if (argc) { if (argv[ii][0]=='-') { n=(int)strlen(argv[ii]); for (j=1;j2) {cp_help(); return; } } } } while (ii++ #include #include #include "kernel.h" #define NormalColor 14 #define Inverse 0x70 /*==========================================================================*/ /* #define DEBUG */ /*==========================================================================*/ int sema_putch=0; /*==========================================================================*/ #if 1 int mputch(int c) { while (sema_lock(&sema_putch)==1); PutchBIOS(c); sema_unlock(&sema_putch); return c; } #endif /****************************************************************************/ int Puts1 (const char far *str) {int i; char c; while((c=*str++)!=0) if ((i=mputch(c))==EOF) return EOF; return i; } /****************************************************************************/ int putch(int c) { switch (c) { case '\n': mputch('\r'); mputch('\n'); #if 1 if (More) if (++NLine>MAX_LINE) { NLine=1; Puts1("more"); if (More==2) Puts1(". Press ESC for quit, or anykey for continue"); if ((c=getch())==ESC) {errno=EFAULT; return EOF; } else { errno=0; mputch('\r'); mputch('\n'); return '\n'; } } else ; else ; #endif break; case 9: /* TAB */ mputch(' '); break; default: return mputch(c); } return c; } /****************************************************************************/ int putchar (int c) { return putch(c); } /****************************************************************************/ int Puts0 (const char far *str) {int i; char c; while((c=*str++)!=0) if ((i=putch(c))==EOF) return EOF; return i; } /****************************************************************************/ int puts (const char far *str) { if (str==NULL) return puts("(null)"); if(Puts0(str)==EOF)return EOF; return Puts0("\n"); } src/kernel/clrscr.asm0100664000076500007650000000143207725645014014362 0ustar prool2prool2 include macros.asm _TEXT segment byte public 'CODE' assume cs:_TEXT _clrscr proc near push ax push bx push cx push dx push BP ; Сохранение BP, который меняется одним из ; вызовом int 10h sub bh,bh mov ah,08h int 10h mov bl,bh mov bh,ah sub cx,cx mov dx,184Fh mov ax,0600h int 10h mov bh,bl sub dx,dx mov ah,02h int 10h pop BP pop dx pop cx pop bx pop ax ret _clrscr endp public _clrscr _TEXT ends end src/kernel/stream.c0100664000076500007650000001107307725645020014026 0ustar prool2prool2#include #include #include "kernel.h" /****************************************************************************/ /* #define DEBUG */ /****************************************************************************/ int mflag(const char far *mode) {int flag; if (mode==NULL) return O_RDONLY; if (*(mode+1)!='+') { switch (*mode) { case 'w': flag=O_WRONLY|O_CREAT|O_TRUNC; break; case 'a': flag=O_WRONLY|O_CREAT|O_TRUNC|O_APPEND; break; case 'r': default : flag=O_RDONLY; } } else { switch (*mode) { case 'w': flag=O_RDWR|O_CREAT|O_TRUNC; break; case 'a': flag=O_RDWR|O_CREAT|O_TRUNC|O_APPEND; break; case 'r': flag=O_RDWR; break; default : flag=O_RDONLY; } } return flag; } /****************************************************************************/ FILE far *fopen (const char far *path, const char far *mode) {int h; FILE far *fp; if((h=open(path, mflag(mode)))==-1)return NULL; fp=FCBS; fp+=h; return fp; } /****************************************************************************/ FILE far *freopen (const char far *path, const char far *mode, FILE far *stream) { fclose(stream); if(open2 (fileno(stream), path, mflag(mode))==-1)return NULL; return stream; } /****************************************************************************/ FILE far* fdopen (int h, char far *type) {FILE far *fp; fp=FCBS; fp+=h; FCBS[h].flag=mflag(type); return fp; } /****************************************************************************/ int fileno (const FILE far *stream) {FILE far *fp; fp=FCBS; if (stream==NULL) return -1; return (int)(stream-fp); } /****************************************************************************/ int fgetc (FILE far *stream) {int h; char c; h=fileno(stream); if (h==-1) return EOF; if (read(h,&c,1)==1) return c; return EOF; } /****************************************************************************/ char far *_gets (char far *s) { #include "gets.inc" } /****************************************************************************/ char *fgets (char *s, int n, FILE far *stream) { #include "fgets.inc" } /****************************************************************************/ char far *_fgets (char far *s, int n, FILE far *stream) { #include "fgets.inc" } /****************************************************************************/ int fputc (int c, FILE far *stream) { switch((int)write(fileno(stream),&c,1)) { case 1: return c; case 0: /* eof */ case -1: default: return EOF; } } /****************************************************************************/ int fputs (const char far *s, FILE far *stream) { return (int)fwrite(s,1,strlen(s),stream); } /****************************************************************************/ size_t fread (void far *ptr, size_t size, size_t n, FILE far *stream) { long int i; if ((size==0)||(n==0))return 0; i=read(fileno(stream),ptr,size*n); if (i>=0) return i/size; return -1; } /****************************************************************************/ size_t fwrite (const void far *ptr, size_t size, size_t n, FILE far *stream) { long int i; if ((size==0)||(n==0))return 0; i=write(fileno(stream),ptr,size*n); if (i>=0) return i/size; return -1; } /****************************************************************************/ long ftell (FILE far *stream) { return tell(fileno(stream)); } /****************************************************************************/ int fseek (FILE far *stream, long offset, int wh) { if (lseek(fileno(stream),offset,wh)==-1) return -1; return 0; } /****************************************************************************/ int fsetpos (FILE far *stream, const fpos_t far *pos) { return fseek(stream, *pos, SEEK_SET); } /****************************************************************************/ int fgetpos (FILE far *stream, fpos_t far *pos) { if((*pos=ftell(stream))==-1)return -1; return 0; } /****************************************************************************/ void rewind (FILE far *stream) { (void)fseek(stream,0L,SEEK_SET); } /****************************************************************************/ int fclose (FILE far *stream) { if (close(fileno(stream))==-1) return EOF; else return 0; } /****************************************************************************/ #pragma warn -par int fflush (FILE far *stream) { return FlushAll(); } #pragma warn +par /****************************************************************************/ src/kernel/strdup.c0100664000076500007650000000060007725645020014046 0ustar prool2prool2#include #include #include "kernel.h" /****************************************************************************/ char far *strdup(const char far *s) {char far *new; /* if (s==NULL) return NULL; */ if ( (new=malloc(strlen(s))) != NULL ) strcpy(new,s); return new; } /****************************************************************************/ src/kernel/dir.c0100664000076500007650000002111107725645015013307 0ustar prool2prool2#include #include #include "kernel.h" /****************************************************************************/ /* #define DEBUG */ /****************************************************************************/ char far *GetUpDir(unsigned int dir_inode, char far *tail) { char b1 [PATH_MAX+1]; char b2 [NAME_MAX+1]; if (dir_inode==0) { strcpy(b1,"/"); strcat(b1,tail); return b1; } else {struct dirent far *D; DIR far *dir; if (chdir("..")==-1) return NULL; if ((dir=opendir("."))==NULL) return NULL; for(;;) { if ((D=readdir(dir))==NULL) break; if ((*D).d_fileno==dir_inode) { strcpy(b1,DirToPath(D,b2)); if (strlen(tail)!=0) { strcat(b1,"/"); strcat(b1,tail); } return (closedir(dir)==EOF)?NULL:GetUpDir(CurDirClu,b1); } } closedir(dir); return NULL; } } /****************************************************************************/ char Buf2 [PATH_MAX+1]; /****************************************************************************/ char far *getcwd (char far *buf, int buflen) { char far *cc; int SaveDir; if (buf==NULL) goto L_INVAL; else if (buflen<=0) {L_INVAL: printf("getcwd:EINVAL\n"); errno=EINVAL; return NULL;} else if (buflen<(PATH_MAX+1)) {printf("getcwd:ERANGE\n"); errno=ERANGE; return NULL;} #ifdef DEBUG printf("getcwd: CurDirClu=%i\n", CurDirClu); #endif if (CurDirClu!=0) { SaveDir=CurDirClu; if ((cc=GetUpDir(CurDirClu,""))==NULL) return NULL; strcpy(Buf2,cc); #ifdef DEBUG printf("getcwd: Buf2=%s\n",Buf2); printf("getcwd: cc=%Fs\n",cc); #endif CurDirClu=SaveDir; } else { strcpy(Buf2,"/"); } #ifdef DEBUG printf("pwd=%s\n",Buf2); #endif strncpy(buf,Buf2,buflen); #ifdef DEBUG printf("pwd=%Fs\n",buf); #endif return buf; } /****************************************************************************/ int chdir (const char far *path) {int i, h, SaveDir; char far *cc; char LocalDir0 [PATH_MAX+1]; char LocalDir [PATH_MAX+1]; #ifdef DEBUG printf("chdir to `%Fs'\n",path); #endif if (path==NULL) {errno=ENOENT; return -1;} if (*path==0) return 0; strncpy(LocalDir0, path, PATH_MAX+1); #ifdef DEBUG printf("LocalDir0="); printf(LocalDir0); printf("\n"); #endif /* Transform: "/usr/bin/" -> "/usr/bin" "/" -> "/" "/usr/bin" -> "/usr/bin" */ i=(int)strlen(LocalDir0)-1; if (i!=0) if (LocalDir0[i]=='/') LocalDir0[i]=0; #ifdef DEBUG printf("LocalDir0=`%s'\n",LocalDir0); #endif SaveDir=CurDirClu; if ((cc=strchr(LocalDir0,'/'))!=NULL) { /* full pathname (with '/' separator[s] ) */ if (cc==LocalDir0) { CurDirClu=0; /* cd 1 */ } else { for (i=0; i<=PATH_MAX; i++) LocalDir[i]=0; memcpy(LocalDir,LocalDir0, ((i=(int)(cc-(char far *)LocalDir0))>PATH_MAX)?PATH_MAX:i); if (chdir(LocalDir)==-1) {CurDirClu=SaveDir; return -1; } } return chdir(cc+1); } else { /* short pathname (dirname only, without '/' separators) */ h=open(LocalDir0,O_RDONLY); if (h==-1) return -1; if (!FCBS[h].Attr.B.Dir) {close(h); errno=ENOTDIR; return -1;} CurDirClu=FCBS[h].BegClu; } close(h); return 0; } /****************************************************************************/ DIR far *opendir (const char far *dirname) {int h; DIR far *fp; if ((h=open(dirname,O_RDONLY))==-1) return NULL; if (!FCBS[h].Attr.B.Dir) {close(h); errno=ENOTDIR; return NULL;} fp=FCBS; fp+=h; return fp; } /****************************************************************************/ DIR far *openwdir (const char far *dirname) {int h; DIR far *fp; if ((h=open(dirname,O_RDWR))==-1) return NULL; if (!FCBS[h].Attr.B.Dir) {close(h); errno=ENOTDIR; return NULL;} fp=FCBS; fp+=h; return fp; } /****************************************************************************/ DIR far *openidir (int inode) {int OldCurDir; DIR far *fp; OldCurDir=CurDirClu; CurDirClu=inode; fp=openwdir("."); CurDirClu=OldCurDir; return fp; } /****************************************************************************/ struct dirent far *readdir (const DIR far *dirp) { long int i; int h; if (dirp==NULL) {errno=EBADF; return NULL;} if((h=fileno(dirp))==-1) return NULL; i=read(h,FCBS[h].Buf,32); if (i!=32) return NULL; return (struct dirent far *)(FCBS[h].Buf); } /****************************************************************************/ int writedir (const DIR far *dirp, struct dirent far *D) { long int i; int h; if (dirp==NULL) {errno=EBADF; return -1;} if((h=fileno(dirp))==-1) return -1; i=write(h,D,32); if (i!=32) return -1; return 0; } /****************************************************************************/ void rewinddir (const DIR far *dirp) { lseek(fileno(dirp),0,SEEK_SET); } /****************************************************************************/ int closedir (const DIR far *dirp) { if (close(fileno(dirp))==-1) return EOF; else return 0; } /****************************************************************************/ long telldir (const DIR far *dirp) { return tell(fileno(dirp)); } /****************************************************************************/ long seekdir (const DIR far *dirp, long offset, int wh) { return lseek(fileno(dirp),offset,wh); } /****************************************************************************/ int dircmp (struct dirent d1, struct dirent d2) { #ifdef DEBUG {int i; printf("dircmp: d1=<"); for (i=0;i<11;i++) printf("%c",d1.d_name[i]); printf(">_d2=<"); for (i=0;i<11;i++) printf("%c",d2.d_name[i]); printf("> "); } #endif if (d1.Attr.B.Attr1) { if (d2.Attr.B.Attr1) { return memcmp(d1.d_name,d2.d_name,11); } else { return -1; } } else { if (d2.Attr.B.Attr1) { return -1; } else { return memcmp(d1.d_name,d2.d_name,11); } } } /****************************************************************************/ #pragma warn -par int mkdir (const char far *path, mode_t mode) {int i, j, h, err; struct dirent Pattern [2]; if ((h=open(path,O_CREAT|O_EXCL|O_WRONLY))==-1) return -1 ; FCBS[h].Attr.U=FA_DIREC; FCBS[h].File=2; for (i=0; i<11; i++) {Pattern[0].d_name[i]=' '; Pattern[1].d_name[i]=' '; } Pattern[0].d_name[0]='.'; Pattern[1].d_name[0]='.'; Pattern[1].d_name[1]='.'; Pattern[0].Attr.U=FA_DIREC; Pattern[1].Attr.U=FA_DIREC; Pattern[0].Size=0L; Pattern[1].Size=0L; Pattern[1].d_fileno=CurDirClu; Pattern[0].FileDateTime.ft_hour = FCBS[h].FileDateTime.ft_hour ; Pattern[0].FileDateTime.ft_min = FCBS[h].FileDateTime.ft_min ; Pattern[0].FileDateTime.ft_tsec = FCBS[h].FileDateTime.ft_tsec ; Pattern[0].FileDateTime.ft_day = FCBS[h].FileDateTime.ft_day ; Pattern[0].FileDateTime.ft_month = FCBS[h].FileDateTime.ft_month ; Pattern[0].FileDateTime.ft_year = FCBS[h].FileDateTime.ft_year ; Pattern[1].FileDateTime.ft_hour = FCBS[h].FileDateTime.ft_hour ; Pattern[1].FileDateTime.ft_min = FCBS[h].FileDateTime.ft_min ; Pattern[1].FileDateTime.ft_tsec = FCBS[h].FileDateTime.ft_tsec ; Pattern[1].FileDateTime.ft_day = FCBS[h].FileDateTime.ft_day ; Pattern[1].FileDateTime.ft_month = FCBS[h].FileDateTime.ft_month ; Pattern[1].FileDateTime.ft_year = FCBS[h].FileDateTime.ft_year ; for (j=0; j<2; j++) for (i=0;i<10;i++) Pattern[j].Reserv[i]=0; if (write(h, Pattern, 2*32)==2*32) err=0; else {err=1; goto l_cl; } Pattern[0].d_fileno=FCBS[h].BegClu; if (lseek(h,0,SEEK_SET)==-1L) return -1; if (write(h, Pattern, 2*32)==2*32) err=0; else {err=1; goto l_cl; } /* Pattern[0].d_name[0]=0xE5; for(i=2;i<(CluSize*SECTOR_SIZE/32);i++) { if (write(h, Pattern, 32)==32) err=0; else {err=1; goto l_cl; } } */ l_cl: if (close(h)==-1) err++; return err?-1:0; } #pragma warn +par /****************************************************************************/ int rmdir (const char far *path) {int i; DIR far *dir; struct dirent far *D; /* Проверка, непустой ли каталог */ if ((dir=opendir(path))==NULL) {errno=ENOENT; return -1;} else { for(i=0;i<2;i++) { if ((D=readdir(dir))==NULL) {i=errno; closedir(dir); errno=i; return -1; } } for(;;) { if ((D=readdir(dir))==NULL) break; if ((*D).d_name[0]== 0) continue; if ((*D).d_name[0]==0xE5) continue; /* Hайден ненулевой вход - следовательно, каталог не пуст, следовательно его нельзя удалять */ closedir(dir); errno=EEXIST; return -1; } if (closedir(dir)==-1) return -1; } /* Удаление каталога */ return delete(path); } src/kernel/strtoul.c0100664000076500007650000001061607725645020014251 0ustar prool2prool2#include #include #include "kernel.h" /* strtol,strtoul,strtoll,strtoull convert string to long, unsigned long, long long or unsigned long long. strtoxx(char *src,char **ptr,int base) converts the string pointed to by src to an long of appropriate long and returnes it. It skips leading spaces and tabs (but not newlines, formfeeds, backspaces), then it accepts an optional sign and a sequence of digits in the specified radix. If the value of ptr is not (char **)NULL, a pointer to the character terminating the scan is returned in the location pointed to by ptr. Trailing spaces will NOT be skipped. If an error is detected, the result will be LONG_MIN, 0 or LONG_MAX, (or LONGLONG..) and errno will be set to EDOM if there are no digits ERANGE if the result would overflow. the ptr will be set to src. This file is based on the strtol from the the GNU C Library. it can be compiled with the UNSIGNED and/or LONGLONG flag set */ #include #define UNSIGNED #ifdef LONGLONG #define UTYPE_MAX (~(ulonglong) 0) #define TYPE_MIN LONGLONG_MIN #define TYPE_MAX LONGLONG_MAX #define longtype long #define ulongtype unsigned long #ifdef UNSIGNED #define function ulongtype strtoull #else #define function longtype strtoll #endif #else #define UTYPE_MAX (unsigned long) ~0L #define TYPE_MIN LONG_MIN #define TYPE_MAX LONG_MAX #define longtype long int #define ulongtype unsigned long int #ifdef UNSIGNED #define function ulongtype strtoul #else #define function longtype strtol #endif #endif #include int my_errno; /* Convert NPTR to an `unsigned long int' or `long int' in base BASE. If BASE is 0 the base is determined by the presence of a leading zero, indicating octal or a leading "0x" or "0X", indicating hexadecimal. If BASE is < 2 or > 36, it is reset to 10. If ENDPTR is not NULL, a pointer to the character after the last one converted is stored in *ENDPTR. */ function (const char *nptr,char **endptr,int base) { int negative; register ulongtype cutoff; register unsigned int cutlim; register ulongtype i; register const char *s; register unsigned char c; const char *save; int overflow; if (base < 0 || base == 1 || base > 36) base = 10; s = nptr; /* Skip white space. */ while (isspace (*s)) ++s; if (*s == '\0') { goto noconv; } /* Check for a sign. */ if (*s == '-') { negative = 1; ++s; } else if (*s == '+') { negative = 0; ++s; } else negative = 0; if (base == 16 && s[0] == '0' && toupper (s[1]) == 'X') s += 2; /* If BASE is zero, figure it out ourselves. */ if (base == 0) if (*s == '0') { if (toupper (s[1]) == 'X') { s += 2; base = 16; } else base = 8; } else base = 10; /* Save the pointer so we can check later if anything happened. */ save = s; cutoff = UTYPE_MAX / (unsigned long int) base; cutlim = (unsigned int) (UTYPE_MAX % (unsigned long int) base); overflow = 0; i = 0; for (c = *s; c != '\0'; c = *++s) { if (isdigit (c)) c -= '0'; else if (isalpha (c)) c = toupper (c) - 'A' + 10; else break; if (c >= base) break; /* Check for overflow. */ if (i > cutoff || (i == cutoff && c > cutlim)) overflow = 1; else { i *= (ulongtype) base; i += c; } } /* Check if anything actually happened. */ if (s == save) goto noconv; /* Store in ENDPTR the address of one character past the last character we converted. */ if (endptr != NULL) *endptr = (char *) s; #ifndef UNSIGNED /* Check for a value that is within the range of `unsigned long int', but outside the range of `long int'. */ if (negative) { if (i > (ulongtype) TYPE_MIN) overflow = 1; } else if (i > (ulongtype) TYPE_MAX) overflow = 1; #endif if (overflow) { my_errno=ERANGE; #ifdef UNSIGNED return UTYPE_MAX; #else return negative ? TYPE_MIN : TYPE_MAX; #endif } /* Return the result of the appropriate sign. */ return (negative ? -((longtype) i) : i); noconv: /* There was no number to convert. */ my_errno=EDOM; if (endptr != NULL) *endptr = (char *) nptr; return 0L; } src/kernel/txtattr.asm0100664000076500007650000000116107725645020014600 0ustar prool2prool2_TEXT segment byte public 'CODE' assume cs:_TEXT extrn _TextAttr:byte _textattr proc near push bp mov bp,sp ; word ptr [bp+4] - argument 1 mov al,byte ptr [bp+4] mov _TextAttr,al ; mov sp,bp pop bp ret _textattr endp public _textattr _getcolor proc near push bp mov bp,sp mov al,_TextAttr xor ah,ah ; mov sp,bp pop bp ret _getcolor endp public _getcolor _TEXT ends end src/kernel/genint.asm0100664000076500007650000000070007725645015014354 0ustar prool2prool2_TEXT segment byte public 'CODE' assume cs:_TEXT _geninterrupt proc near push bp mov bp,sp push bx mov bl,byte ptr [bp+4] ; interrupt no mov byte ptr CS:@@cmd+1,bl jmp @@cmd @@cmd: int 0 pop bx ; mov sp,bp pop bp ret _geninterrupt endp public _geninterrupt _TEXT ends end src/kernel/mouse.asm0100664000076500007650000000034707725645016014230 0ustar prool2prool2Titlo equ ' Mouse Package for XProolix' ; _TEXT segment byte public 'CODE' assume cs:_TEXT db ' Mouse port=' _PORT dw 1 ; 1 == COM2 public _PORT _TEXT ends end src/kernel/int1b.c0100664000076500007650000000265407725645015013561 0ustar prool2prool2#include #include #include "kernel.h" void interrupt int1b (void) /* Interrupt 1B - ctrl-break pressed */ {int i; /* pushf */ /* old fl = [BP+22] */ /* push cs */ /* old cs = [BP+20] */ /* push ip */ /* old ip = [BP+18] */ /* push ax */ /* old ax = [BP+16] */ /* push bx */ /* old bx = [BP+14] */ /* push cx */ /* old cx = [BP+12] */ /* push dx */ /* old dx = [BP+10] */ /* push es */ /* old es = [BP+ 8] */ /* push ds */ /* old ds = [BP+ 6] */ /* push si */ /* old si = [BP+ 4] */ /* push di */ /* old di = [BP+ 2] */ /* push bp */ /* old BP = [BP] */ /* mov bp,DGROUP */ /* mov ds,bp */ /* mov bp,sp */ /* sub sp,2 */ asm mov ax,[BP+20]; asm mov i,ax; printf("CS:IP = %04X",i); asm mov ax,[BP+18]; asm mov i,ax; printf(":%04X",i); asm mov ax,[BP+22]; asm mov i,ax; printf(" FL=%04X",i); asm mov ax,[BP+6]; asm mov i,ax; printf(" DS=%04X",i); asm mov ax,SS; asm mov i,ax; printf(" SS:SP=%04X:",i); asm mov ax,SP; asm mov i,ax; printf("%04X",i); } src/kernel/bootred0.asm0100664000076500007650000000162307725645014014612 0ustar prool2prool2; read boot sector _TEXT segment byte public 'CODE' assume cs:_TEXT ; bootread0 (int dev, void far * buf) return 0 or ErrorCode _bootread0 proc near push bp mov bp,sp ; word ptr [bp+4] - argument 1 ; word ptr [bp+6] - argument 2 ... push bx push cx push dx push ES mov dx,word ptr [bp+4] mov bx,word ptr [bp+6] mov ES,word ptr [bp+8] mov cx,1 mov dh,0 mov ax,0201h ; Fn=02, Read 1 sector int 13h jc @@err xor ax,ax jmp @@ret @@err: @@ret: pop ES pop dx pop cx pop bx ; mov sp,bp pop bp ret _bootread0 endp public _bootread0 _TEXT ends end src/kernel/ints.c0100664000076500007650000000145707725645015013521 0ustar prool2prool2#include #include #include "kernel.h" void interrupt done(void) { puts("\n INTERRUPT "); } void interrupt CtrlAltDel(void) { puts("\nU pressed Control Alt Del\n"); } void interrupt Int1(void) { puts("\nInterrupt 1 - Trace\n"); } void interrupt Int2(void) { puts("\nInterrupt 2 - Non-maskable (NMI)\n"); } void interrupt Int3(void) { /* puts("\nInterrupt 3 - Breakpoint\n"); */ } void interrupt Int4(void) { puts("\nInterrupt 4 - Overflow trap\n"); } void interrupt Int6(void) { puts("\nInterrupt 6 - Invalid opcode (186,286,386)\n"); } void interrupt Int7(void) { puts("\nInterrupt 7 - Coprocessor not available (286,386)\n"); } void interrupt Int75(void) { puts("\nInterrupt 75 - numeric coprocessor NMI error (AT,XT286,PS50+)\n"); } src/kernel/reboot.asm0100664000076500007650000000051507725645017014370 0ustar prool2prool2_TEXT segment byte public 'CODE' assume cs:_TEXT _reboot proc near mov ax,40h mov ds,ax mov bx,72h mov [bx],1234h db 0eah ; JMP F000:FFF0 dw 0fff0h,0f000h _reboot endp public _reboot _TEXT ends end src/kernel/char_in.c0100664000076500007650000000475507725645014014152 0ustar prool2prool2#include #include #include #include #include #include "kernel.h" #define Norm 2 #define Inverse 0x70 /*==========================================================================*/ /* #define DEBUG */ /*==========================================================================*/ #ifdef MOUSE /*--------------------------------------------------------------------------*/ int getch(void) {int j; while ((j=getcom(PORT))==-2); /* Wait a click or move mouse (wait a byte from com port */ while (getcom(PORT)!=2); /* Это против дребезга мыши */ return j; } /*--------------------------------------------------------------------------*/ int kbhit(void) {int j; j=getcomstat(PORT); if (j==-1) return 0; else return (j & 1); } /*--------------------------------------------------------------------------*/ #else /* no MOUSE */ /*--------------------------------------------------------------------------*/ char extended_kbd_code=0; /*--------------------------------------------------------------------------*/ int getch(void) {int c; if (extended_kbd_code) {c=extended_kbd_code; extended_kbd_code=0; } else { c=getch0(); if ((char)c==0) { extended_kbd_code=c>>8; c=0; if ((extended_kbd_code>='h')&&(extended_kbd_code<='o')) {/* Alt-F1 .. Alt-F8 */ new_video_page(extended_kbd_code-'h'); extended_kbd_code=0; return getch(); } } else c=(char)c; } #if CODETABLE==_RUSSIAN_ if (*KbdStatus & SCROLL_LOCK) c=Russian[c]; #endif return c; } /*--------------------------------------------------------------------------*/ int kbhit(void) { if (extended_kbd_code) return 1; else return kbhit0(); } #endif /*--------------------------------------------------------------------------*/ /****************************************************************************/ int getchar(void) {int c; /* Судя по исходниками GNU file утилит (функция yesno()) при нажатии клавиши Enter должен возвращаться код '\n', а не '\r' как в MSDOS. А также getchar должна быть с эхом. */ c=getch(); #ifdef DEBUG putch('['); putch(c); putch(']'); #endif if (c!='\b') c=putchar (c=='\r'?'\n':c); /* '\b' - BREAK */ return c; } /****************************************************************************/ int getche (void) {int c; c=getch(); if (c<' ') if (c=='\b') return putch(c); else return c; else return putch(c); } src/kernel/kernel.c0100664000076500007650000001452407725645015014023 0ustar prool2prool2/* OS Proolix Kernel Copyright (C) 1993-1999 Serge Pustovoitoff, prool@itl.net.ua http://prool.kharkov.org/proolix/ ftp://ftp.itl.net.ua/pub/proolix/ Fidonet 2:461/35 Free with sources ****************************************************************************/ #define VER "Ver. 0.1.1.19 4-Nov-99" /****************************************************************************/ /* #define KERNEL_DEBUG */ /* #define NODISK */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /******************************** External variables ***********************/ #ifdef MOUSE extern unsigned int PORT; #endif /* Mode: 0 - если работает код ядра, или системный вызов из юзерского процесса, 1 - если работает код юзерского процесса. User: 0 - если работает код ядра, 1 - если работает юзерский процесс или системный вызов из юзерского процесса */ int Mode, User; int HeadCnt, TrkSecs; int SectorsOnCyl, FatSize, FatCnt; unsigned int MaxClusters; unsigned long MaxSectors; /* extern unsigned int _Begin; */ extern struct {unsigned int ParNo; void (*Entry)(void);} SysTable []; extern int Trace; unsigned int MemTop; void far * Fin; int emulation_mode; /* 0 - boot from disk/diskette; */ /* 1 - boot from file under MSDOS-session Windows 95 */ /******************************** Public variables *************************/ /* char NearBuffer [512]; */ #if defined (_HERCULES_) && defined (_MON_MONO_) int TextAttr=7; #else int TextAttr=0x70; #endif int _argc; char far *_argv [MAX_ARG]; char far * far *pEnv; char far *hEnv; unsigned int Global; unsigned int Counter; char far *KbdStatus; int curX=1, curY=1, maxX=80, maxY=25; char far *curAddr; char VideoAttrib=7; /* long int Secund=0; */ #ifdef CMOS unsigned char hour, min, secund; #else unsigned long Tick; #endif unsigned char century, year, month, day, flag; #if CODETABLE==_RUSSIAN_ char Russian [256]; #endif void interrupt (*OldTimerVec) (void); unsigned long RootBeg, RootEnd, ResSecs; unsigned int CluSizeBytes; struct BufPool far *Cache; int CurrentDevice=-1; int ReadOnly; int NextDOSDrive='C'; /* Глобальные переменные, доступные из юзерских процессов */ int errno=0; int More=0; int NLine=1; /* */ unsigned int ProcessPar; unsigned int CluSize; unsigned long DataStart; int x, y; struct MemBlk *MB; int FATMode; FILE FCBS [OPEN_MAX]; char MasterBootRecord [SECTOR_SIZE]; char far *OldInt; FILE far *stdin ; FILE far *stdout; FILE far *stderr; /* таблица специальных файлов (файлов типа Device) */ struct DevRecord Dev [] = { /* name, major, minor, byte (1 - byte-oriented device, 0 - block-oriented) */ /* Один и тот же major номер устройства для байториентированных и для блокориентированных обозначает РАЗHЫЕ устройства. Это сделано для экономии места в таблицах */ {"null", 0,0,1}, {"console", 1,0,1}, {"fd0", 0,0,0}, {"fd1", 0,1,0}, {"hd0", 1,0,0}, {"hd1", 1,1,0}, {"ttyS00", 2,0,1}, /* COM */ {"ttyS01", 2,1,1}, {"lp00", 3,0,1}, /* LPT */ {"lp01", 3,1,1}, {"mem", 4,0,1}, {"kmem", 5,0,1}, {"",-1,-1,-1} }; /* таблица специальных файлов байториентированных */ struct DevByte TableByte [5] = { {nulldev,nulldev,nulldev,nulldev,nulldev}, {nulldev,nulldev,nulldev,nulldev,nulldev}, {nulldev,nulldev,nulldev,nulldev,nulldev}, {nulldev,nulldev,nulldev,nulldev,nulldev}, {nulldev,nulldev,nulldev,nulldev,nulldev}, }; /* таблица специальных файлов блокориентированных */ struct DevBlock TableBlock [2] = { /* open, close, strategy */ {nulldev,nulldev,FDDstrategy}, /* FDD */ {nulldev,nulldev,HDDstrategy}, /* HDD */ }; unsigned int CurDirClu; struct DeviceStruct Devices [LASTDRIVE]; /* Devices [0] - disk A: sec=0 if not present Devices [1] - disk B: sec=0 if not present Devices [2] - disk C: sec=0 if not present Devices [3] - disk D: sec=0 if not present ... */ /* Таблица процессов */ struct processes process_table [PROC_MAX]; /************************** include functions ******************************/ #include "alloc.c" #include "process.c" #include "syscall.c" void test_devices(void); void interrupt int1b(void); /**************************** Functions ************************************/ #if 0 void fuck(void) { int Divisor [] = {10000, 1000, 100, 10, 1}; printf("fuck = %04X\n",Divisor[0]); } #endif void ident(void) { printf("Proolix "); printf("%s\nCompile by Turbo C 2.01 at %s %s\n",VER,__DATE__,__TIME__); } /*---------------------------------------------------------------------------- ╔══════════════════════════════════════════════════════════════════════════╗ ║ ╔══════════════════════════════════════════════════════════════════════╗ ║ ║ ║ ║ ║ ║ ║ Main function ║ ║ ║ ║ ║ ║ ║ ╚══════════════════════════════════════════════════════════════════════╝ ║ ╚══════════════════════════════════════════════════════════════════════════╝ ----------------------------------------------------------------------------*/ void main (void) {int i; /* int OldSegment, OldOffset; */ Mode=0; /* kernel mode */ User=0; ProcessPar=kernel_begin(); puts("\nKernel started"); test_devices(); init(); ident(); print_mount(); #ifndef NODISK #if 1 _argv[0]="kernel.ovl"; _argv[1]="\r"; _argv[2]=NULL; if ((i=execve(_argv[0],_argv,pEnv))!=0) printf("kernel: no overlay. rc=%i ",i); #endif #ifdef _RC_ _argv[0]=_RC_; _argv[1]=NULL; execve(_argv[0],_argv,pEnv); #endif /* _RC_ */ #endif /* NODISK */ #ifdef CHANGE_INT_1B #if 0 setvect(0x1B,(void interrupt(*)(void)) sh ); #else setvect(0x1B,(void interrupt(*)(void)) int1b ); #endif #endif sh(); }src/kernel/files.bbs0100664000076500007650000000334207725645015014165 0ustar prool2prool2ALLOC.C Allocate memory subprograms APP.C Assembler preprocessor APP.COM Assembler preprocessor BIOS.C bios programs C0.ASM Kernel startup code CAT.C cat - int. command CMOS.ASM CMOS timer support CONV.C see stdlib.h CS0.LIB obj modules from Turbo C 2.0 library cs.lib (long int support etc) CTYPE.C see stdlib.h DE.C Disk edit for Proolix E.C e - debug int command GENTBL.C Generate system call table - syskern.asm INT5DUMP.ASM Register dump IO.C I/O procedures KEY.ASM gets() by Igor Sazonov (for "%"-shell like c-shell ;) LS.C ls - internal command MAKEFILE Makefile ;) MEM.C See mem.h MEMD.C memd - memory dump, internal command MSH.C msh (mouse shell ;) - XProolix for mouse without keyboard NOCMOS.ASM Real clock timer without CMOS (on XT only) support OHB.ASM Output Hex Byte OHW.ASM Output Hex Word PROCESS.C Process' procedures REGDUMP.ASM Register dump SAYR.ASM Output ASCIIZ string via BIOS SH.C sh - shell (prompt "$") STDIO.C see stdio.h STDLIB.C see stdlib.h STRCHR.C string support procedures STRDUP.C string support procedures STRING.C string support procedures STRLEN.C string support procedures SYSCALL.C system call SYSCALL.TBL Source General Main Table of System Calls TIME.C Dostime package. For compatible with MSDOS VEC.C vec - int.command (show interrupt vectors) absread.c absread() abswrite.c abswrite() bootread.c bootread() bootred0.asm bootread0() char_in.c character input routines char_out.c character output routines clrscr.asm clrscr() - clear screen cluread.c CluRead() - cluster read cold.asm cold() - cold reboot reboot.asm reboot() - hot reboot comport.asm serial port routines exitw.asm Assembler utility for Proolix src/kernel/key.asm0100664000076500007650000002320607725645016013667 0ustar prool2prool2comment | Высылаю исходник редактора командной строки с историей для Пруликса. Поддерживаемые кнопки - влево,вправо,Home,End,Забой(Backspace),BK(Enter): как обычно; вверх,вниз : перемещение по истории; ESC : очистка строки и установка в начало буфера указателя истории; Ctrl-Left,Ctrl-Right,Ctrl-Backspace. Буфер истории кольцевой.Никаких АТ-шных приколов вроде нету,-должно работать на чем угодно, а кроме того буду проверять на наличие введенной строки в буфере истории и ставить ее первой,сдвигая, соответственно,весь буфер (редко встречал - толко в XTREE PRO). Проверить не удалось, не пишу я почти ничего на сях, а Borland C,вообще не люблю; стоит у меня Symantec C 6.0, написал маленький тестик - работает, а проблема может возникнуть в единственном месте - при копировании строки в выходную: ES должен быть выставлен правильно. Транслировал TASM 3.2 c ключами "-Z -q -t -m -ml". FidoNet 2:461/61.99 Игорь Cазонов | ; Version 0.0.0.2 3-May-94 .model tiny,pascal .8086 jumps locals @@ HISDEPTH equ 10 MaxLen equ 81 .code db 0 strbuf db MaxLen dup (?) hisbuf db MaxLen * HISDEPTH dup (0) curr dw ? cursor dw ? depth dw 0 ; текущая глубина буфера команд current dw offset hisbuf ; текущая команда в буфере HisHead dw offset hisbuf HisCur dw offset hisbuf global _doskey:proc _doskey PROC C USES di,si ARG string push ds es mov ax,40h mov es,ax mov bx,63h mov bx,es:[bx] cmp bx,03b4h jnz @@more mov vseg,0b000h @@more: mov ax,cs mov es,ax mov ds,ax mov ax,HisHead mov HisCur,ax mov curr,offset strbuf mov strbuf,0 xor bh,bh mov ah,3 int 10h mov cursor,dx ; newkey: xor ax,ax int 16h cmp ax,0e7fh ; Ctrl+BackSpace jz @@cbs cmp al,' ' jb @@ctrl ; символ push ax cmp curr,offset strbuf+80 ; на переполнение входной строки jae newkey push curr call StrLen inc cx mov si,curr add si,cx mov di,si inc di std inc cx rep movsb pop ax mov di,curr mov [di],al inc curr call FlushBuf jmp newkey @@ctrl: cmp al,8 ; backspace jz @@bs cmp al,01bh ; ESC jz @@esc cmp ah,04bh ; left jz @@left cmp ah,04dh ; right jz @@right cmp ah,053h ; Del jz @@del cmp ah,047h ; Home jz @@home cmp ah,04fh ; End jz @@end cmp al,0dh ; Enter jz @@enter cmp ah,048h ; Up jz @@up cmp ah,050h ; Down jz @@down cmp ah,073h ; Ctrl+left jz @@cleft cmp ah,074h ; Ctrl+right jz @@cright jmp newkey @@bs: cmp curr,offset strbuf jz newkey mov cx,curr push cx CALL StrLen inc cx mov si,curr mov di,si dec di cld rep movsb dec curr call FlushBuf jmp newkey @@del: mov ax,curr mov cx,offset strbuf sub ax,cx push cx CALL StrLen cmp ax,cx jae newkey mov cx,curr push cx CALL StrLen inc cx mov di,curr mov si,di inc si cld rep movsb call FlushBuf jmp newkey @@esc: mov strbuf,0 mov curr,offset strbuf mov ax,HisHead mov HisCur,ax CALL FlushBuf jmp newkey @@left: cmp curr,offset strbuf jz newkey dec curr CALL SetCur jmp newkey @@right:mov ax,curr mov cx,offset strbuf sub ax,cx push cx CALL StrLen cmp ax,cx jae newkey inc curr CALL SetCur jmp newkey @@home: mov curr,offset strbuf CALL SetCur jmp newkey @@end: mov bx,offset strbuf push bx CALL StrLen add bx,cx mov curr,bx CALL SetCur jmp newkey @@cleft: mov bx,1 std jmp @@word @@cright: xor bx,bx cld @@word: mov si,curr @@cl3: lodsb or al,bl jz newkey cmp byte ptr [si],0 jz @@cl1 cmp byte ptr [si],'1' jb @@cl3 @@cl2: lodsb cmp al,'1' jb @@cl4 cmp byte ptr [si],'1' jae @@cl2 @@cl1: add si,bx @@cl4: mov curr,si CALL SetCur jmp newkey @@up: CALL GetPrev jmp @@his @@down: CALL GetNext @@his: cmp byte ptr [bx],0 jz newkey mov HisCur,bx push bx push offset strbuf CALL StrCpy mov bx,offset strbuf push bx CALL StrLen add bx,cx mov curr,bx CALL SetCur CALL FlushBuf jmp newkey @@cbs: cmp curr,offset strbuf jz newkey std mov si,curr @@bs3: lodsb cmp byte ptr [si],0 jz @@bs1 cmp byte ptr [si],'1' jb @@bs3 @@bs2: lodsb cmp al,'1' jb @@bs4 cmp byte ptr [si],'1' jae @@bs2 @@bs1: inc si @@bs4: mov di,si mov si,curr mov curr,di mov cx,si sub cx,di inc cx cld rep movsb CALL SetCur CALL FlushBuf jmp newkey @@enter:CALL AddHistory mov ax,0e0dh xor bh,bh int 10h mov ax,0e0ah xor bh,bh int 10h mov ax,string push offset strbuf push ax CALL StrCpy ; !!! надо чтобы ES смотрел правильно ; У меня Borland C нет, тестировалось ; на Symantec C 6.0 - всё OK pop es ds ret _doskey ENDP FlushBuf PROC USES ax,si xor bh,bh mov dx,cursor mov ah,2 int 10h mov si,offset strbuf push si CALL StrLen push es db 0B8h ;mov ax,VideoSeg vseg dw 0b800h mov es,ax mov ax,cursor mov bx,ax mov al,ah mov ah,160 mul ah xor bh,bh shl bx,1 add bx,ax mov di,bx or cx,cx jz @@empty cld push cx @@out: lodsb stosb inc di loop @@out pop cx @@empty:neg cx add cx,79 cld @@blank:mov al,020h stosb inc di loop @@blank pop es CALL SetCur ret FlushBuf ENDP StrLen PROC USES ax,di ARG instring:word mov di,instring xor al,al cld mov cx,0ffffh repne scasb neg cx dec cx dec cx ret StrLen ENDP StrCpy PROC USES di,si,cx ARG str1,str2 mov si,str1 mov di,str2 push si CALL StrLen inc cx cld rep movsb ret StrCpy ENDP SetCur PROC USES ax,bx,dx mov ax,curr sub ax,offset strbuf mov dx,cursor add dl,al xor bh,bh mov ah,2 int 10h ret SetCur ENDP AddHistory PROC push offset strbuf push HisHead CALL StrCpy add HisHead,MaxLen cmp HisHead,offset curr jb @@ret mov HisHead,offset hisbuf @@ret: mov ax,HisHead mov HisCur,ax ret AddHistory ENDP GetPrev PROC ; bx - addr mov bx,HisCur cmp bx,offset hisbuf jnz @@nojmp mov bx, offset hisbuf + (HISDEPTH - 1) * MaxLen jmp @@ret @@nojmp:sub bx,MaxLen @@ret: ret GetPrev ENDP GetNext PROC ; bx - addr mov bx,HisCur cmp bx, offset hisbuf + (HISDEPTH - 1) * MaxLen jnz @@nojmp mov bx,offset hisbuf jmp @@ret @@nojmp:add bx,MaxLen @@ret: ret GetNext ENDP end src/kernel/ohb.asm0100664000076500007650000000165207725645016013650 0ustar prool2prool2; ohb locals _TEXT segment byte public 'CODE' assume cs:_TEXT ohb proc ; Procedure output hex byte Ver 0.1.1 6 Dec 93 via BIOS ; Input: AL - byte ; All regs. reserved ;) ; Not worked in graph mode. bl - bg color !!! push ax push cx push dx mov dl,al mov cl,4 shr al,cl call ohb1 mov al,dl and al,0fh call ohb1 pop dx pop cx pop ax ret ohb endp ohb1 proc ; Regs not saved !!! push ax cmp al,9 ja @@_1 ; al > 9 ; al <= 9 add al,'0' jmp @@_out @@_1: add al,'A'-10 @@_out: mov ah,0eh int 10h pop ax ret ohb1 endp public ohb _TEXT ends end src/kernel/comport.asm0100664000076500007650000000274107725645015014562 0ustar prool2prool2_TEXT segment byte public 'CODE' assume cs:_TEXT _inicom_ proc near push bp mov bp,sp PUSH dx mov dx,word ptr [bp+4] mov al,byte ptr [bp+6] mov ah,0 int 14h POP dx ; mov sp,bp pop bp ret _inicom_ endp public _inicom_ _getcom_ proc near push bp mov bp,sp ; word ptr [bp+4] - argument 1 PUSH dx mov dx,word ptr [bp+4] mov ah,2 int 14h POP dx ; mov sp,bp pop bp ret _getcom_ endp public _getcom_ _putcom_ proc near push bp mov bp,sp ; word ptr [bp+4] - argument 1 ; 6 2 PUSH dx mov dx,word ptr [bp+4] mov al,byte ptr [bp+6] mov ah,2 int 14h POP dx ; mov sp,bp pop bp ret _putcom_ endp public _putcom_ _getcomstat_ proc near push bp mov bp,sp ; word ptr [bp+4] - argument 1 PUSH dx mov dx,word ptr [bp+4] mov ah,3 int 14h POP dx ; mov sp,bp pop bp ret _getcomstat_ endp public _getcomstat_ _TEXT ends end src/kernel/nocmos.asm0100664000076500007650000000175307725645016014400 0ustar prool2prool2Titlo equ ' NoCMOS Kernel Package ' Ver equ ' V 0.0.0.2 2-Nov-1994 ' ; CMOS & Real Time Clock asm functions for Proolix's Kernel _TEXT segment byte public 'CODE' assume cs:_TEXT _ReadTick proc near push bp mov bp,sp push bx push cx push dx ; word ptr [bp+4] - argument 1 ; 6 2 ; ... ; int ReadTick (unsigned long *Tick, char *Flag) mov ah,0 int 1ah jc @@ret ; error mov bx,word ptr [bp+4] mov word ptr [bx],dx mov word ptr [bx+2],cx mov bx,word ptr [bp+6] mov byte ptr [bx],al xor ax,ax jmp @@ret @@err: mov ax,1 @@ret: pop dx pop cx pop bx ; mov sp,bp pop bp ret _ReadTick endp public _ReadTick _TEXT ends end src/kernel/setjmp.asm0100664000076500007650000000716707725645017014412 0ustar prool2prool2 .8086 _TEXT segment byte public 'CODE' assume cs:_TEXT ; include macros.asm ; int setjmp(jmp_buf jmpb) _setjmp proc far ; SP = old SP - 6 (2 bytes - jmpb addr, 4 bytes - ; retf addr) push bp ; SP = old SP - 8 mov bp,sp ; BP = old SP - 8 ; old BP = [BP] ; old IP = [BP+2] ; old CS = [BP+4] ; jmpb addr = [BP+6] pushf ; SP = old SP - 12 ; flag = [BP- 2] push ax ; SP = old SP - 14 ; ax = [BP- 4] push bx ; SP = old SP - 16 ; bx = [BP- 6] push cx ; SP = old SP - 18 ; cx = [BP- 8] push dx ; SP = old SP - 20 ; dx = [BP-10] push si ; SP = old SP - 22 ; si = [BP-12] push di ; SP = old SP - 24 ; di = [BP-14] push ds ; SP = old SP - 26 ; ds = [BP-16] push es ; SP = old SP - 28 ; es = [BP-18] ; mov ax,SETJMP_DATA ; mov ds,ax mov bx,word ptr [bp+6] ; bx - adress of jmpb mov ax,BP add ax,8 mov word ptr [bx+ 0],ax ;j_sp mov word ptr [bx+ 2],ss ;j_ss mov ax,[BP-2] mov word ptr [bx+ 4],ax ;j_flag mov ax,[BP+4] mov word ptr [bx+ 6],ax ;j_cs mov ax,[BP+2] mov word ptr [bx+ 8],ax ;j_ip mov ax,[BP] mov word ptr [bx+10],ax ;j_bp mov word ptr [bx+12],di ;j_di mov ax,[BP-18] mov word ptr [bx+14],ax ;j_es mov word ptr [bx+16],si ;j_si mov word ptr [bx+18],DS ;j_ds mov ax,[BP-4] mov word ptr [bx+20],ax ;j_ax mov ax,[BP-6] mov word ptr [bx+22],ax ;j_bx mov word ptr [bx+24],cx ;j_cx mov word ptr [bx+26],dx ;j_dx pop es pop ds pop di pop si pop dx pop cx pop bx pop ax popf xor ax,ax pop bp ret _setjmp endp ; void _Cdecl longjmp(jmp_buf jmpb, int retval); _longjmp proc far mov bp,sp ; chr1 'Q' mov bx,word ptr [bp+4] ; bx - adress of jmpb cli mov ax,[bx] ; j_sp mov SP,ax mov ax,[bx+2] ; j_ss mov SS,ax sti push word ptr [bx+ 4] ;j_flag push word ptr [bx+ 6] ;j_cs push word ptr [bx+ 8] ;j_ip push word ptr [bx+10] ;j_bp push word ptr [bx+12] ;j_di push word ptr [bx+14] ;j_es push word ptr [bx+16] ;j_si push word ptr [bx+18] ;j_ds push word ptr [bx+20] ;j_ax push word ptr [bx+22] ;j_bx push word ptr [bx+24] ;j_cx push word ptr [bx+26] ;j_dx ; chr1 'q' pop dx pop cx pop bx pop ax pop ds pop si pop es pop di pop bp IRET ; == {pop ip; pop cs; popf} _longjmp endp _TEXT ends public _longjmp public _setjmp end src/kernel/nextclu.c0100664000076500007650000000434607725645016014227 0ustar prool2prool2#include #include #include #include "kernel.h" /* NextClu(), NextClu2() - next cluster number compute and load to Cache) */ /* NextClu() - kernel's internal module */ /* NextClu2() - boot manager internal module */ /* Согласовывать NextClu() с NextClu2() ! */ unsigned int NextClu (unsigned int CluNo) /* -1 for eof or error */ { unsigned long j; unsigned int nsect, offset, b; unsigned int i; if ((CluNo>MaxClusters)||(CluNo==0)) { printf("NextClu: Invalid cluster number. CluNo=%u, MaxClusters=%u", CluNo, MaxClusters); return -1; } if (FATMode==FAT12) { /* FAT 12 */ /* определяем номер байта в таблице FAT-12 */ j=(CluNo*3)/2; /* определяем номер сектора FAT */ nsect=(unsigned int)(j/SECTOR_SIZE); printf("nsect=%i ",nsect); /* nsect-относительный номер сектора FAT. 0 - первый сектор FAT */ if (nsect>=FatSize) {puts("NextClu: Invalid FAT's computing"); return -1;} if ( (b=LoadCache(ResSecs+nsect)) == -1U ) {puts("\nNextClu: FAT read error"); return -1;} offset=(unsigned int)(j%SECTOR_SIZE); printf("offset=%i ",offset); if (offset==(SECTOR_SIZE-1)) {unsigned char c; c=*(unsigned char far *)((*(Cache+b)).M+(SECTOR_SIZE-1)); if ( (b=LoadCache(ResSecs+nsect+1)) == -1U ) {puts("\nNextClu: FAT read error"); return -1;} printf("c=%04X ",c); i=((unsigned int)c)| (((unsigned int)(*(unsigned char far *)((*(Cache+b)).M)))<<8); } else i=*(int far *)((*(Cache+b)).M+offset); printf("word=%04X ",i); if (CluNo & 1) {putch('n');i>>=4;} else {putch('c');i&=0xfff;} if (i>0xff0) return -1; } else { /* FAT 16 */ /* определяем номер байта в таблице FAT-16 */ j=((long)CluNo)*2; /* определяем номер сектора FAT */ nsect=(unsigned int)(j/SECTOR_SIZE); /* nsect-относительный номер сектора FAT. 0 - первый сектор FAT */ if (nsect>=FatSize) {puts("NextClu: Invalid FAT's computing"); return -1;} if ( (b=LoadCache(ResSecs+nsect)) == -1U ) {puts("\nNextClu: FAT read error"); return -1;} offset=(unsigned int)(j%SECTOR_SIZE); i=*(int far *)((*(Cache+b)).M+offset); if (i>0xfff0) return -1; } #if 1 printf("%i->%i ",CluNo,i); #endif return i; }src/kernel/viewexe.c0100664000076500007650000001061307725645020014206 0ustar prool2prool2#include #include "..\include\limits.h" #include "..\include\struct.h" void ViewEXE (struct exe_header far *Buf) {long i, j; printf("Bytes on last page %04X\n",Buf->PartPag ); printf("Pages in file %04X\n",Buf->PageCnt ); printf("Relocations %04X\n",Buf->ReloCnt ); printf("Paragraphe in header %04X\n",Buf->HdrSize ); printf("MinMem %04X par\n",Buf->MinMem ); printf("MaxMem %04X par\n",Buf->MaxMem ); printf("SS:SP %04X:%04X\n",Buf->ReloSS,Buf->ExeSP); printf("CheckSum %04X\n",Buf->ChkSum ); printf("CS:IP %04X:%04X\n",Buf->ReloCS,Buf->ExeIP); printf("Relocation table addr %04X\n",Buf->TablOff ); /* printf("Overlay No. %1X\n",Buf->Overlay); */ } /* Из [TECH Help!] ╔════════════════════════════════════════════════════════════════════════════╗ ║ Структура заголовка файла EXE ║ ╚════════════════════════════════════════════════════════════════════════════╝ Смещ. Длина Содержимое ▀▀▀▀▀▀ ▀▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ┌───────┐ +0 2 │4Dh 5aH│ "подпись" файла .EXE ('MZ') ├───┴───┤ +2 2 │PartPag│ длина неполной последней страницы (обычно игнорируется) ├───┴───┤ +4 2 │PageCnt│ длина образа в 512-байтовых страницах, включая заголовок ├───┴───┤ +6 2 │ReloCnt│ число элементов в таблице перемещения ├───┴───┤ +8 2 │HdrSize│ длина заголовка в 16-байтовых параграфах ├───┴───┤ +0aH 2 │MinMem │ минимум требуемой памяти за концом программы (параграфы) ├───┴───┤ +0cH 2 │MaxMem │ максимум требуемой памяти за концом программы (параграфы) ├───┴───┤ +0eH 2 │ReloSS │ сегментное смещение сегмента стека (для установки SS) ├───┴───┤ +10H 2 │ExeSP │ значение регистра SP (указателя стека) при запуске ├───┴───┤ +12H 2 │ChkSum │ контрольная сумма (отрицательная сумма всех слов в файле) ├───┴───┤ +14H 2 │ExeIP │ значение регистра IP (указателя команд) при запуске ├───┴───┤ +16H 2 │ReloCS │ сегментное смещение кодового сегмента (для установки CS) ├───┴───┤ +18H 2 │TablOff│ смещение в файле 1-го элемента перемещения (часто 001cH) ├───┴───┤ +1aH 2 │Overlay│ номер оверлея (0 для главного модуля) └───┴───┘ 1cH размер форматированной порции заголовка EXE ┌───────┬───────┬ ─ ─ ┬───────┬───────┐ Таблица перемещения. Начало + ? 4*? │ смещ. сегмент│  │ смещ. сегмент│ по смещению [EXE+18H]. Имеет └───┴───┴───┴───┴ ─ ─ ┴───┴───┴───┴───┘ [EXE+6] 4-байтовых элемента. + ? ? пропуск до границы параграфа + ? ? начало образа программы ──────────────────────────────────────────────────────────────────────────────── Поскольку EXE-файл может быть загружен в любой сегмент, все абсолютные сегмент- ные ссылки (FAR CALL, далекие указатели, ссылки типа MOV AX,data_seg) должны быть приведены к адресам памяти, соответствующим загрузке. Ниже приведены шаги, используемые программой загрузки DOS (функция 4bH ) при загрузке файла EXE: 1. создать PSP посредством функции DOS 26H 2. прочитать 1cH байт файла EXE (форматированную порцию заголовка EXE) в локальную область памяти 3. определить размер модуля = ( (PageCnt*512)-(HdrSize*16) ) - PartPag 4. определить файловое смещение загружаемого модуля = (HdrSize * 16) 5. выбрать сегментный адрес, START_SEG, для загрузки (обычно PSP + 10H) 6. считать модуль в область памяти, начинающуюся с адреса START_SEG:0000 7. LSEEK (уст. указатель файла) на начало таблицы перемещения (TablOff) 8. для каждого элемента перемещения (ReloCnt): a. считать элемент как два 16-битовых слова (I_OFF,I_SEG) b. вычислить RELO_SEG=(START_SEG+I_SEG) (адрес перемещаемой ссылки) c. извлечь слово по адресу RELO_SEG:I_OFF (прочитать текущее значение) d. прибавить START_SEG к этому слову (выполнить привязку сегмента) e. поместить результат обратно по его адресу (RELO_SEG:I_OFF) 9. Распределить память для программы согласно MaxMem и MinMem 10. Инициализировать регистры и запустить программу: a. ES = DS = PSP b. AX = отражает корректность идентификаторов дисков в командной строке c. SS = START_SEG+ReloSS, SP = ExeSP d. CS = START_SEG+ReloCS, IP = ExeIP (команды: PUSH seg; PUSH offset; RETF) */ src/kernel/port.asm0100664000076500007650000000233307725645016014061 0ustar prool2prool2_TEXT segment byte public 'CODE' assume cs:_TEXT _inport proc near push bp mov bp,sp push dx mov dx,word ptr [bp+4] in ax,dx pop dx ; mov sp,bp pop bp ret _inport endp public _inport _inportb proc near push bp mov bp,sp push dx mov dx,word ptr [bp+4] in al,dx pop dx ; mov sp,bp pop bp ret _inportb endp public _inportb _outport proc near push bp mov bp,sp push dx mov dx,word ptr [bp+4] mov ax,word ptr [bp+6] out dx,ax pop dx ; mov sp,bp pop bp ret _outport endp public _outport _outportb proc near push bp mov bp,sp push dx mov dx,word ptr [bp+4] mov al,byte ptr [bp+6] out dx,al pop dx ; mov sp,bp pop bp ret _outportb endp public _outportb _TEXT ends end src/kernel/out_boot.c0100664000076500007650000000450207725645016014371 0ustar prool2prool2#include #include #include "kernel.h" #define DEBUG putch__(char c) { switch (c) { case 0: c=' '; break; default: if (c<' ') c='.'; } return putch(c); } void out_boot(void far *buf) {int i; unsigned long DiskSize; unsigned long TrueSectors; struct BootStru far *b; b=buf; printf("\n\ ----------------------------------Disk parameters:------------------------------\n\ Jump command %02X %02X %02X \n\ OEM name %-8s\n\ OEM name ", (*b).Jmp[0],