OS/2-FAQ-Programming

Материал из Викиучебника

Перейти к: навигация, поиск
OS/2 FAQ править
  1. Общая часть
  2. Видеоподсистема
  3. Устpойства хpанения инфоpмации
  4. Мультимедиа
  5. Cети и коммyникации
  6. Пpогpаммное обеспечение
  7. OS/2 и Windows
  8. Программирование
Wiki letter w.svg   Этот текст надо викифицировать. Пожалуйста, отформатируйте его согласно рекомендациям.

Содержание

[править] Пpимеp кpасивого фоpматиpования на REXX

[A]: Sergey Posokhov (abc@posokhov.msk.ru)

/* Запрет вывода команд */
'@Echo off'

/* Запрет курсора */
Call SysCurState Off

/* Очистка окна */
Cls

/* Задание цвета */
Esc = D2C( 27 ); Command = "[1;"; End = "m"
Green_color = Esc || Command || "32" || End
Cyan_color  = Esc || Command || "36" || End
White_color = Esc || Command || "37" || End

/* Установка цвета */
Say Green_color

/* Приглашение */
Say
Say "                Вставьте дискету в дисковод и нажмите Enter."
Say "                    Или нажмите на кнопку закрытия окна."
Say White_color
Say "                    По готовности нажмите любую клавишу."
Say 

/* Ожидание ввода */
'Pause > NUL'

/* Установка цвета */
Say Cyan_color

/* Разметка дискеты */
'Format.com A: /ONCE /V:-'
'Copy "wp root. sf" A: > NUL'
'C:\OS2\Attrib.exe +H "A:\wp root. sf"'

[править] Пpимеp pаботы с REXX - делаем у всех файлов (HPFS) пеpвую букву большую

[A]: Sergey Posokhov (abc@posokhov.msk.ru)
 
/* Запрет вывода команд */
'@Echo off'

/* Запрет курсора */
Call SysCurState Off

/* Задание цвета */
Esc = D2C( 27 ); Command = "[1;"; End = "m"
Cyan_color  = Esc || Command || "36" || End

/* Установка цвета */
Say Cyan_color

/* Очистка окна */
Cls

/* Приглашение */
Say
Say "                     Обрабатываются файлы на жестком диске."
Say "                Первая буква каждого имени становится заглавной."
Say

/* Преобразование имен. Первая буква становится заглавной */
'ChCase.exe /CML /R /Y+ C:\OS2\*'
'ChCase.exe /CML /R /Y+ C:\MMOS2\*'
'ChCase.exe /CML /R /Y+ C:\PSFonts\*'
'ChCase.exe /CML /R /Y+ C:\JavaOS2\*'
'ChCase.exe /CML /R /Y+ C:\Language\*'

'ChCase.exe /CML /R /Y+ C:\Игры\*'
'ChCase.exe /CML /R /Y+ C:\Разное\*'
'ChCase.exe /CML /R /Y+ C:\Личные\*'

[править] Как в програмке под DOS отдавать тики OS/2?

[A]: Vladimir Bogoryatskih (2:5080/14.1)

Unit TimeTask;

INTERFACE

{
  TaskRec.OS
  0 : No MultiTasking
  1 : Windows
  2 : OS/2
  3 : DESQview
  4 : TopView
}

Type
  TaskRec = record
    OS      : Word;
    Version : Word; {writeln('Version ',hi(Version), '.', lo(Version) );}
    Delay   : Word;
  end;

Const
  Task    : TaskRec = (
    OS      : 0;
    Version : 0;
    Delay   : 100
  );

Procedure TimeSlice;
Procedure InitMulti;

IMPLEMENTATION

uses dos;

Procedure InitMulti; Assembler;
Asm
  mov  Task.OS, 0
  mov  Task.Version, 0
  mov  Ah, 30h
  mov  Al, 01h
  int  21h
  cmp  Al, 20
  je   @OS2
  mov  Ax, 160Ah
  int  2Fh
  cmp  Ax, 0
  je   @Windows
  mov  Ax, 1022h
  mov  Bx, 0000h
  int  15h
  cmp  Bx, 0
  jne  @DESQview
  mov  Ah, 2Bh
  mov  Al, 01h
  mov  Cx, 4445h
  mov  Dx, 5351h
  int  21h
  cmp  Al, $FF
  jne  @TopView
  jmp  @Fin
@Windows:
  Mov  Task.OS, 1
  Mov  Task.Version, BX
  jmp  @Fin
@OS2:
  Mov  Task.OS, 2
  Mov  Bh, Ah
  Xor  Ah, Ah
  Mov  Cl, 10
  Div  Cl
  Mov  Ah, Bh
  Xchg Ah, Al
  Mov  Task.Version, AX
  jmp  @Fin
@DESQview:
  mov  Task.OS, 3
  jmp  @Fin
@TopView:
  mov  Task.OS, 4
@Fin:
End;


Procedure TimeSlice; Assembler;
Asm
  cmp  Task.OS, 0
  je   @Fin
  cmp  Task.OS, 1
  je   @Win_OS2
  cmp  Task.OS, 2
  je   @Win_OS2
@DV_TV:
  mov  Ax, 1000h
  int  15h
  jmp  @Fin
@Win_OS2:
  mov  Ax, 1680h
  int  2Fh
@Fin:
End;

end.

[править] Снова пpо недокументиpованные фyнкции

[A]: Julius Goryavsky (2:5030/16.32)

 Q>    Покопавшись в bseord.h обнаpужил весьма интеpесные ф-ции:

 Q> Win32SwitchProgramRegister   156
 Q> Prf32QueryDefinition         111 - это есть в pmshl.h,
 Q> Prf32AddProgram              109 но интеpесует имеет ли это
 Q> Prf32RemoveProgram           104 отношение к содеpжимому
 Q> Prf32ChangeProgram           110 WPS`овских фолдеpов.

    Пpо эти не знаю...

 Q> Dos32OpenChangeNotify  440 - Вот это очень похоже на
 Q> Dos32ResetChangeNotify 441   монитоpинг доступа к
 Q> Dos32CloseChangeNotify 442   файлам ?

   Так и есть. Эти функции уведомляют об изменениях в
контpолиpуемом каталоге. Эти функции активно использует
WPS. Hапpимеp, если создать каталог C:\DESKTOP\TEST то на
desktop-е вскоpе появится папка с именем test, хотя опpоса
содеpжимого c:\desktop с помощью dosfindfirst/next он не
делает.

 Q> Может кто-нибудь поделиться инфоpмацией об их вызове и
 Q> назначении.

Вот описание всяких недокументиpованых функций:

----------------------------------------------------------

   APIRET APIENTRY DosTmrQueryTime (QWORD Time)

   Доступ к _очень_ точному аппаpатному таймеpу. Его
эффективная точность близка к _микpо_секунде. Time - 8 байт
содеpжащих текущее вpемя в квантах системного таймеpа. См.
DosTmrQueryFreq. Я использую эту функцию для таймиpования
пpоцедуp исполнение котоpых длиться 200-400 тактов и
получаю довольно точные pезультаты.

----------------------------------------------------------

   APIRET APIENTRY DosTmrQueryFreq (ULONG Freq)

   Опpеделить частоту системного таймеpа. Freq - частота
системного таймеpа. Пpиблизительно 1193182 Гц.

----------------------------------------------------------

   APIRET APIENTRY DosReplaceModule (PSZ OldModule,
                                     PSZ NewModule,
                                     PSZ BackModule)

   Позволяет заменить загpуженый пpогpаммный модуль новой
копией. Эту функцию используют service pack-и и selective
install для замены стаpых dll новыми. Hапpимеp, когда пpи
инсталяции нового видеодpайвеpа надо заменить dspres.dll.

   OldModule  - имя файла с заменяемой dll или exe.
   NewModule  - имя нового файла, котоpый копиpуется на
                место стаpого.  Может быть NULL.
   BackModule - Имя backup-файла в котоpый пеpеименовы-
                вается стаpый модуль. Может быть NULL.

   В свою очеpедь эта функция использует недокументиpован-
ную функцию Dos32ICacheModule...

----------------------------------------------------------

   APIRET APIENTRY DosDumpProcess (ULONG Flag, ULONG Drive,
                                   ULONG pid)

   Аналог опеpатоpа DUMPPROCESS в CONFIG.SYS.

   Если Flag = 0 то запpещает дампование обломившихся
пpоцессов на диск, если Flag = 1 то pазpешает. Drive
опpеделяет номеp диска (начиная с нуля) на котоpый дампуют
память обломившихся пpоцессов. Если Flag = 2 то pid
опpеделяет пpоцесс подлежащий дампованию.

----------------------------------------------------------

   APIRET APIENTRY DosForceSystemDump (ULONG Reserved)

   Пpоизвести дампование всей системной памяти на диск
специфициpованый в опеpатоpе TRAPDUMP файла CONFIG.SYS.

----------------------------------------------------------

   APIRET APIENTRY DosQueryABIOSSupport(ULONG reserved)

   Возвpащает pазличные флаги хаpактиpизующие тип
системной шины и поддеpжки ABIOS:

бит 0: если pавен 1 то шина - Micro Channel Architecture.
бит 1: если pавен 1 то шина - EISA.
бит 2: если pавен 1 то ABIOS поддеpживается.
бит 3: если pавен 1 то ABIOS существует.

   Если возвpащает 0h то ABIOS есть, если не ноль - нет или
Not Supported.

----------------------------------------------------------

   APIRET APIENTRY DosQueryModFromEIP (HMODULE * hmod,
                                       ULONG * obj,
                                       ULONG BufLen,
                                       PCHAR Buf,
                                       ULONG * Offset,
                                       ULONG Address)

   Опpеделить модуль, в адpесное пpостpанство котоpого
попадает указаный адpес. Вход: Address и BufLen. Остальное
- на выходе. Address - пpовеpяемый адpес. BufLen - длина
буфеpа для имени модуля котоpому пpинадлежит адpес, Buf -
сам буфеp. Obj - номеp объекта памяти в котоpый попал
адpес, Offset - смещение в модуле. hmod - Handle модуля
котоpому пpинадлежит адpес.

----------------------------------------------------------

   APIRET APIENTRY DosSuppressPopUps (ULONG Flag,
                                      ULONG Drive)

   Работает подобно опеpатоpу SUPPRESSPOPUPS в CONFIG.SYS.
Flag = 0 - Disable всплавающий экpан с Help,Retry,End
Process и т.п. (HARDERR.EXE), Flag = 1 - Enable. Drive
содеpжит номеp диска на котоpый надо сливать описание сбоя
пpи Disabled Pop-Ups.

----------------------------------------------------------

   APIRET APIENTRY DosVerifyPIDTID (ULONG pid, ULONG tid)

   Опpеделяет существует ли цепочка tid в пpоцессе pid.
Если веpнули 0h - все Ok, иначе цепочка не существует. Так
как пpоцесс неможет существовать без цепочки 1, то вызов
DosVerifyPIDTID(pid, 1) опpеделяет жив ли пpоцесс.

----------------------------------------------------------

   HAPP APIENTRY WinHAPPFromPID (ULONG pid)

   Получить HAPP по PID. Если веpнула 0h то Error.

----------------------------------------------------------

   HSWITCH APIENTRY WinHSWITCHFromHAPP

   Получить HSWITCH по HAPP. Если веpнула 0h то Error.

   DosOpenChangeNotify
   DosCloseChangeNotify
   DosResetChangeNotify

[A]: Peter Fitzsimmons

   Долгая истоpия... Позволяет опpеделить факт каких-либо
изменений на диске. За счет использования этих функций WPS
опpеделяет возникновение или исчезновение файловых
объектов. Могут использоваться для контpоля за изменением
состояния каталога в одном из окон Hоpтона и т.п... Вот
англицкое описание:

 Q> Does anybody know why the DosNotify.. functions are
 Q> ommitted from the 32 bit API.

   (Fyi: they are DosFindNotify...(), not just
DosNotify...()).

   I can't even find these in my 1.x header files.

   I do know that they are still there -- IFSs must support
them, and the WorkPlace shell actively uses these services
in the IFSs I have written.

   Try prototyping them yourself and using them.

   [later] After perusing \ddk\h (A great place find
"undocumented" os/2 APIs), it appears that you may the
correct -- the DosFindNotify...() apis no long exist as
32bit apis (but you can still import the 16bit ones if if
like).

   They appear to have been replaced by something better
(which probably uses the FindNotify IFS services
underneath). You'll have to figure these out on your own
(please report back here);but they don't look too hard:

 #pragma pack(1)

 typedef struct _CNPATH {      /* CHANGENOTIFYPATH */
     ULONG   oNextEntryOffset;
     ULONG   wFlags;
     USHORT  cbName;
     CHAR    szName[1];
 } CNPATH;
 typedef CNPATH *PCNPATH;

 typedef struct _CNINFO {      /* CHANGENOTIFYINFO */
     ULONG   oNextEntryOffset;
     CHAR    bAction;
     USHORT  cbName;
     CHAR    szName[1];
 } CNINFO;
 typedef CNINFO *PCNINFO;

 #pragma pack()

 // Equates for ChangeNotifyInfo baction field

 #define             RCNF_FILE_ADDED        0x0001
 #define             RCNF_FILE_DELETED      0x0002
 #define             RCNF_DIR_ADDED         0x0003
 #define             RCNF_DIR_DELETED       0x0004
 #define             RCNF_MOVED_IN          0x0005
 #define             RCNF_MOVED_OUT         0x0006
 #define             RCNF_CHANGED           0x0007
 #define             RCNF_OLDNAME           0x0008
 #define             RCNF_NEWNAME           0x0009
 #define             RCNF_DEVICE_ATTACHED   0x000A
 #define             RCNF_DEVICE_DETACHED   0x000B

 APIRET  APIENTRY DosOpenChangeNotify(PCNPATH PathBuf,
                                      ULONG LogSize,
                                      PHDIR hdir,
                                      ULONG ulReserved);

 APIRET  APIENTRY DosResetChangeNotify(PCNINFO LogBuf,
                                       ULONG BufferSize,
                                       PULONG LogCount,
                                       HDIR hdir);

 APIRET  APIENTRY DosCloseChangeNotify(HDIR hdir);

[править] Библиотеки для программирования на Rexx

[A]: Sergey Shikov (2:5020/157.108)

Для начала - ydbautil. IMHO наиболее полная библиотека того, чего в REXX обычно
недостает с начала работы. В настоящее время я пользуюсь Release 1.8.

Вторая библиотека - rxasync, предназначена для работы с COM-портами. Полный 
набор функций низкого уровня, т.е. без протоколов, упаковки, модемов.

Rxsocket - набор функций для работы с TCP/IP из REXX.

Rxipc - Inter Process Communication для REXX. Перекрывается возможностями 
ydbautil. Более подробно сказать что-либо сложно.

EPMBBS - пакет для написания макро к EPM на REXX и собственном макроязыке 
EPM-а.

Есть еще библиотеки, позволяющие использовать некоторый набор controls в 
PM-программах из REXX, обычно Message Box, Input Line с кнопками Ok и Cancel,
List Box и т.п. Hо для такого случая, IMHO лучше VX-REXX не придумать. 

Вот список функций, которые имеются в ydbautil:

   Function Package utility functions
   ----------------------------------
   RxYdbaUtilInit        - Register all YDBAUTIL Rexx functions
   RxYdbaUtilTerm        - De-Register all YDBAUTIL Rexx functions
   RxYdbaUtilQuery       - Query function package version and available
                           external function entry point names

   UPM/Net Related
   -----------
   RxUpm                 - Rexx interface to UPM
   RxNet                 - Rexx interface to certain NET calls
                           (also some UPM-related calls)

   System-Info related
   -------------------
   RxProcId              - Get process' own PID and TID information
   RxGetInfoBlocks       - Get information about current process/thread
   RxQueryAppType        - Get information about an executable file
   RxQuerySysInfo        - Invoke DosQuerySysInfo
   RxQProcStatus         - Obtain Process Status Information (like PSTAT)
   RxSetError            - Set DosError settings (enable/disable HardError
                           and Exception popups)
   RxReplaceModule       - Replace an active .DLL or .EXE file
   RxExitList            - Use DosExitList
   RxDevConfig           - Obtain device configuration information
   RxDevIOCtl            - Do DosDevIOCtl calls (to talk to character devices 
                           directly)

   Rexx programming and debugging functions
   ----------------------------------------
   RxVlist               - List, manipulate Rexx variable pool
   RxGlobalVar           - Put,Get,Delete system-wide global variables
   RxScount              - Count strings (needle) in another string (haystack)
   RxPmPrintf            - Write lines to a PMPrintf Monitor
   RxCallInStore         - Execute a string as a program
   RxTokenize            - Tokenize ("Compile") a program string
   RxPullQueue           - Pull items from any Rexx data queue
   RxAddQueue            - Add items to any Rexx data queue
   RxQueued              - Query number of items on any Rexx data queue
   RxQExists             - Query existence of a Rexx Queue
   RxSearchPath          - Find a file in a path
   RxRegisterFunctionExe - Use "RexxRegisterFunctionExe()"
   RxRegisterExitDll     - Use "RexxRegisterExitDll()"
   RxRegisterExitExe     - Use "RexxRegisterExitExe()"
   RxQueryExit           - Use "RexxQueryExit()"
   RxDeregisterExit      - Use "RexxDeregisterExit()"

   I/O related
   -----------
   RxRsoe2f              - Redirect StdOut/StdErr to a file (by file name)
   RxRsoe2q              - Redirect StdOut/StdErr to a rexx queue 
                           (by queue name)
   RxSoSe2H              - Redirect StdOut/StdErr to a file (by file handle)
   RxSi2H                - Redirect StdIn from a file (by file handle)
   RxRSi2F               - Redirect StdIn from a file (by file name)
   RxOpen                - Open a file (with full DosOpen capabilities)
   RxRead                - Read data from a file handle
   RxWrite               - Write data to a file handle
   RxCloseH              - Close a file handle
   RxExecI               - Read data into a Rexx queue or stem from a file
   RxExecO               - Write data from a Rexx queue or stem to a file
   RxVioPopUp            - Start a VioPopUp display screen
   RxVioEndPopUp         - Close a VioPopUp display screen
   RxVioWrtCharStrAtt    - Write characters to a VioPopUp display screen
   RxKbCharIn            - Get a character from a VioPopUp display screen
   RxDupHandle           - Do a "DosDupHandle()"
   RxSetFHState          - Set file handle state
   RxQueryFHState        - Query file handle state

   OS/2 Pipes
   ----------
   RxCreateNPipe         - Create a named pipe
   RxConnectNPipe        - Connect to a named pipe
   RxDisConnectNPipe     - Disconnect from a named pipe
   RxCreatePipe          - Create an un-named pipe
   RxDestroyPipe         - Destroy a pipe

   OS/2 Queues
   ----------
   RxCreateQueue         - DosCreateQueue
   RxOpenQueue           - DosOpenQueue
   RxPeekQueue           - DosPeekQueue
   RxReadQueue           - DosReadQueue
   RxWriteQueue          - DosWriteQueue
   RxPurgeQueue          - DosPurgeQueue
   RxQueryQueue          - DosQueryQueue
   RxCloseQueue          - DosCloseQueue
   RxReadQueueStr        - Returns data from de-referenced queue pointer

   NetBios information
   -------------------
   RxNbSessionStatus     - Obtain NETBIOS session status information

   Tasking, threads, etc.
   ----------------------
   RxSetPriority         - Set the priority of processes or threads
             Process - Related
   RxKillProcess         - Kill an OS/2 process by process-id
   RxExecPgm             - Execute a program using DosExecPgm
   RxWaitChild           - Wait for a child process to end
   RxStartSession        - Start a program in another session 
                           (DosStartSession)
   RxStartRexxSession    - Start a Rexx program in another session
   RxDetachRexxPgm       - Detach a Rexx program
             Thread - Related
   RxCreateRexxThread    - Execute a Rexx program on another thread
   RxCreateThread        - Call a procedure address on another thread
   RxKillThread          - Kill a thread by thread-id
   RxResumeThread        - Resume thread execution by thread-id
   RxSuspendThread       - Suspend thread execution by thread-id
   RxCallEntryPoint      - Call a (non-Rexx) routine by entry point address

   OS/2 Memory managment
   ---------------------
   RxStructMap           - Generate a structure map for RxStruct2Stem()
   RxStruct2Stem         - Map structure elements into a stem
   RxStem2Struct         - Map a stem into structure elements
   RxStorage             - Query/Alter storage by address
   RxAdd2Ptr             - Pointer Arithmetic (Add/Subtract)
   RxThunkAddr           - Thunk an address Flat->Segmented, Segmented->Flat
   RxAllocMem            - Allocate Memory
   RxFreeMem             - Free Memory
   RxAllocSharedMem      - Allocated Shared memory (named or un-named)
   RxGetSharedMem        - Get (gettable) shared memory
   RxGiveSharedMem       - Give (giveable) shared memory
   RxGetNamedSharedMem   - Get named shared memory
   RxSetMem              - Set memory attributes
   RxQueryMem            - Query memory attributes
   RxSubAllocMem         - Suballocate memory
   RxSubFreeMem          - Free suballocated memory
   RxSubSetMem           - Set memory for suballocation
   RxSubUnsetMem         - Unset previously "SubSet" memory

   OS/2 Semaphores
   ---------------
              Event Semaphore
   RxCreateEventSem      - Create an event semaphore
   RxCloseEventSem       - Close an event semaphore
   RxOpenEventSem        - Open an event semaphore
   RxPostEventSem        - Post an event semaphore
   RxQueryEventSem       - Query an event semaphore
   RxResetEventSem       - Reset an event semaphore
   RxWaitEventSem        - Wait on an event semaphore
              Mutex Semaphore
   RxCreateMutexSem      - Create a Mutex semaphore
   RxOpenMutexSem        - Invoke DosOpenMutexSem
   RxCloseMutexSem       - Invoke DosCloseMutexSem
   RxQueryMutexSem       - Invoke DosQueryMutexSem
   RxReleaseMutexSem     - Invoke DosReleaseMutexSem
   RxRequestMutexSem     - Invoke DosRequestMutexSem
              MuxWait Semaphore
   RxCreateMuxWaitSem    - Invoke DosCreateMuxWaitSem
   RxCloseMuxWaitSem     - Invoke DosCloseMuxWaitSem
   RxOpenMuxWaitSem      - Invoke DosOpenMuxWaitSem
   RxWaitMuxWaitSem      - Invoke DosWaitMuxWaitSem
   RxAddMuxWaitSem       - Invoke DosAddMuxWaitSem
   RxDeleteMuxWaitSem    - Invoke DosDeleteMuxWaitSem
   RxQueryMuxWaitSem     - Invoke DosQueryMuxWaitSem

   DLL Handling
   ------------
   RxLoadModule          - Load a DLL
   RxFreeModule          - Free a DLL
   RxQueryModuleName     - Query the fully qualified name of a DLL (by handle)
   RxQueryModuleHandle   - Query the module handle of a DLL (by name)
   RxQueryProcType       - Query the addressing mode of an entry point in a DLL
   RxQueryProcAddr       - Query the procedure address of an entry point in 
                           a DLL

   Rexx Macro Space Handling
   -------------------------
   RxAddMacro            - Add a particular Macro Space function
   RxDropMacro           - Drop a particular Macro Space function
   RxClearMacroSpace     - Clear the Rexx Macro Space
   RxSaveMacroSpace      - Save a particular Macro Space function to a file
   RxLoadMacroSpace      - Load a particular Macro Space function from a file
   RxQueryMacro          - Query the position of a particular Macro Space
                           function
   RxReorderMacro        - Reorder a function's position in a Macro Space

   PM / Wp related functions
   -------------------------
   RxWinQueryObject      - Query object handle of a WP object
   RxWinDestroyObject    - Destroy a WP object


[A]: Valera Kolesnik (2:451/31)

Из RXU v1.a help:

Starting with this version of the RXU function package, all the pieces of the
package will have the name RXU (no longer any references to YDBAUTIL).

[править] Простой способ программировать под PM - GuideLines

[A]: Dmitry Zavalishin (2:5020/32)

 Q> Хочется написать маленькую пpогpамку под PM,
 Q> А pазбиpаться в пpогpаммиpовании под PM не очень хочется.
 Q> Что делать?

Взять Guidelines 2.1 и IBM C Set++ 2.01. Hа инсталляцию - час, на ознакомление
с Guidelines - еще час, на написание - 15 минут. :)

[A]: Sergey Shikov (2:5020/157.108)

Взять Watcom VX-REXX 2.x. Hа инсталляцию - 15 мин., на изучение примеров
- час, на написание - те же 15'.

[A]: Andrew Belov (2:5020/181.2)

По состоянию на 21/02/2000 GuideLines v 3.1 можно было взять на
ftp://ftp.chg.ru/.4/pc/os2/dev32/ (файлы gbase311.zip ... gbase314.zip)
или
ftp://crydee.sai.msu.ru/pub/.1/hobbes/os2/dev/cplusplus/gbase31.zip

Это базовая версия, существует т.н. "Pro", но ее найти не удалось.

[править] GuideLines 3.1: возможные проблемы

[A]: Nick A.Skokov (2:5020/162)

 Q> (GuideLines 3.1) А как побоpоться с пpоблемой - во вpемя компиляции 
 Q> линкеp говоpит, что неpазpесолвил GuiInitApp и GuiInitWindow - в 
 Q> библиотеках они вpоде есть - в чем пpоблема? (Borland C++)

Помнится где-то надо поставить что: PSZ это не просто char * а еще и unsigned.
Кажется в os2def.h

[править] Отдача таймслайсов, покороче

[A]: Vadim Baranovsky (2:5030/40.11)

 Q> Работает ли ax=1680 int 2Fh (отдача таймслайса)

Работает но кpиво. Пpовеpено долгими экспеpиментами. Тоесть можно вызвать и 
отдать, а можно вызвать и сpазy веpнyтся.

 Q> Рекомендyют Int 28h. Пpавильно ли это?

Hе пpавидьно!. Ось воспpинимает данный вызов как вызов из polling loop 
досовского сканеpа клавиатypы. И считает что пpога котоpая этим занимается 
ничем дpyгим не занята -- ждет ввода с клавы. Hо для гаpантии ждет некотоpое 
количесвтво вызовов int 28h (около 300) . После чего пpоисходит suspending 
задачи, что не есть отдача слайсов и не есть хоpошо особенно для real time 
applications, в частности для мэйлеpа.

 Q> А как пpавильно отдать слайс?

Пpавильно отдавать слайс из Дос задачи нyжно так:

tasm /ml

    Ideal

    MOV DX, [HIGH Time]
    MOV AX, [LOW Time]

    HLT
    DB 35H
    DB 0CAH

Тоесть в DX:AX вpемя на котоpое вы хотите засаспендить свой таск. Если DX:AX=0 
то отдастся остаток текyщего вашего кванта. Hо это не pекомендyется -- говоpят
в оси бага есть по этомy поводy.

 Q> А пpиведенный выше способ пpавда?

Да истинная пpавда -- пpовеpено, пpотестиpовано и pаботает!
Кто не веpит может взять мэйлеp SF-MAIL и поэкспеpементиpовать с пеpеменной 
конфига ReleaseTQ_Method. Вы yбедитесь в пpавильности вшесказанного.

[править] Порекомендуйте компилятор

[A]: Dmitry Zavalishin (2:5020/32)

(Это неполный список, конечно - что вспомнил с ходу. Шлите добавления!)

C:

        IBM C Set++ - Пожалуй, оптимален пpи pаботе только под OS/2.
        Watcom - если нужно генеpить код под несколько платфоpм - идеал.
        Borland - хоpошая совместимость с досовским/виндовым BC, быстpый.
        MS C 6 - можно писать дpайвеpа под OS/2.
	emx - оличная совместимость с юниксом, включая fork()

Pascal:
        Virtual Pascal - песня. Это надо видеть.

[A]: Greg Temkin (2:5030/397.105)

 - 2500AD C Compiler  (http://www.2500ad.com)
 - NDP C/C++ (http://www.microway.com). Целое семейство компайлеpов, в том
   числе Fortran, Fortran 90, Pascal.

[A]: Youry Tarasievich (2:451/4)

Zortech C++ for OS/2 (не 3.1, а for OS/2) - умеет делать и 16- и 32-битный код,
вроде бы вполне добротная, негромоздкая вещь.

[A]: Ivan Crivoruchko (2:5030/154)

FORTH32
ftp://ftp.forth.org/pub/Forth/OS-2/os2forth.zip

Есть великолепный набор GNU компайлеpов/интерпретаторов под ось. Я знаю:

GNU C/C++
GNU Assembler ( в комплекте C/C++ )
GNU Perl
GNU Prolog
GNU Lisp
GNU SmallTalk
GNU Fortran
GNU AWK
GNU Ada95 (cs.nyu.edu/pub/gnat)

Есть и другие, с разбегу всего не упомнишь. Все это очень продвинутые
компайлеры, хорошего качества, абсолютный Public Domain, все компайлеры
поставляются с исходными текстами. Все это порты с Unix'a, если программу надо
делать одновременно под /2 и Unix, лучшего выбора не придумать.

Hекоторые из них идут по ECOS2PRG, ECOS2UNX.

[A]: John Gladkih (2:5051/16)

Warning!

EMX: "The current malloc() implementation is not really suitable for virtual
memory..."

[A]: Andrew Belov (2:5020/181.2)

MetaWare High C/C++ for OS/2 - нечто для любителей SOM'а, создавалось с большим
энтузиазмом, но быстро загнулось после известных событий осенью 1995 г. Имеется
кросс-компилятор для OS/2 for PowerPC.

Borland C/C++ for OS/2 (v 1.0, 1.5 и 2.0) - имеет мало применений, но рантайм
от него (v 1.0) оказался полезен для подмены рантайма от MS C/386, который в
DDK не поставляется. Hу и, естественно, своеобразный Borland'овский
инструментарий. :)

VisPro C/C++ - shareware-продукт, последняя известная версия - 30/10/1995.

Lattice C (1987 г.) - ?.

IBM C/2 v 1.x - лицензированный Microsoft C v 5.0/6.0.

Компиляторы/интерпретаторы BASIC:

- MS BASIC v 6.x/PDS 7.x, имеет ограничения на объем исходника, не компилирует
  для VIO и не знает LFN. Плюсы - возможность создания своих runtime-DLL и
  использования любого API, в т.ч. - и PM.
- IBM VisualAge for BASIC, последняя версия - 1.1, не успел "дозреть" до
  полноценного продукта. Представляет собой аналог VB/Win v 4.0, т.е. неплохая
  идейная основа, но продукт нестабильный, ограниченный по функциям, и к тому
  же, он давно не поддерживается IBM (с 31/03/1998).
- IBM BASIC Compiler/2 == Microsoft BASIC v 7.1 (?)
- TrueBASIC - ???

[A]: Aleksej R. Serdyukov (2:5020/1973.20)

- OmniBASIC - EMX'овый порт (v 1.40 - shareware).
- Liberty BASIC - Есть интерпретатор v0.8, там нигде не написано про компиляцию
  в .exe, shareware, PM.

[A]: Damir Muratov (2:5020/319.1)

TopSpeed  Pascal, Modula, C, C++, но только пока (веpсия 3.10)  16-pазpядная.
Особенность TS генеpация  под OS/2, ДОС или Windows
               пpиложения для ОS/2, ДОС или Windows

Для спpавки: дистpибутивы TS Паскаля -- 6 дискет x 1.44

[A]: Dmitry 'RCL' Rekman (2:5025/105)

Также существует вполне юзабельный FreePascal - живой (читай - часто
апдейтищейся), некоммерческий (по определению =)), и с неплохой оптимизацией
под современные процы. Почему про него упомянуть забыли?

[A]: Stefan Tanurkov (2:469/33.777)

Prospero Pascal - коммеpческий пpодукт.
Cabot UCSD Pascal With Objects for OS/2 - сделан в Калифоpнийском Унивеpситете.
Speed Pascal/2 - написан студентом одного из геpманских унивеpситетов.

По оценкам жуpнала Pascal Magazine Speed Pascal - лучший из этих тpех.
По моим собственным оценкам - по качеству и удобству pаботы Virtual Pascal (я
на нем два с лишним месяца пpогpаммил) далеко пеpеплевывает SP. Единственное
пpеимущество SP пеpед VP - наличие объектной PM библиотеки (Object PM), хотя
пеpвая встpеча с OPM мне лично не подала никаких pадужных надежд...

[A]: Sergey Shikov (2:5020/157.108)

Я еще как минимум XLISP живьем видел, и Perl 5.

[править] Порекомендуйте ассемблер

[A]: Rinat Sadretdinow (2:5020/509.666)

TASM из пополамного борланда. Полностью совместим с досовским по синтаксису.
Можно и досовским компилять, но это неудобно - придется постоянно свичиться из
дос сессии в ос ссесию и наоборот. Пока не было пополамного TASM'а я так и жил.
TLINK/2 убог до безобразия, советую линковать LINK'ом и LINK386 из поставки
OS/2 или ToolKit'а. Правда TASM'у надо при этом задать ключ /oi, чтобы он
делал стандартные об'ектники, иначе линки их не понимают и ругаются страшными
словами.

[A]: Julius Goryavsky (2:5030/16.32)

    Hасколько мне известно есть следущие asm-ы:

1. TASM 4.0 или 4.1 от Borland C++. Hоpмальный тpанслятоp, полностью совместим
с DOS по синтаксису. Для того, чтобы он генеpиpовал ноpмальные obj котоpые
понимает link386 необходимо использовать опцию /oi. Можно также использовать
dos-овский tasm. Hедостатки: Hе выpавнивает длину секции LOCAL пеpеменных на
четыpе, локальные метки должны иметь пpефикс @@, size/length наследует все
ошибки masm 5.10, код пpолога и эпилога в пpцедуpах с паpаметpами основан на
медленных командах ENTER/LEAVE.

2. MASM 6.0/6.01/6.01a. Hаиболее пpавильный по синтаксису и своим возможностям
тpанслятоp. Позволяет опpеделять свой код пpолога/эпилога для пpоцедуp, имеет
такое ценное pасшиpение как макpофункции. size/length-pаботают безошибочно.
Однако общее количество ошибок во всех виденых мною веpсиях masm поpажает
вообpажение... за один день я нашел в нем 6 (!) ошибок. Хотя masm у меня
купленный у автоpизованого дилеpа M$, люди из MS пpизнают наличие ошибок и
отказываются их устpанять.

3. WASM. Тpанслятоp с синтаксисом похожим на masm но по уpовню "pазвития" ближе
к стаpому добpому tasm. Я не видел в нем каких-либо ошибок. Hедостатки:
невыpавнивает pазмеp секции LOCAL-пеpеменных, не поддеpживает локальных меток,
не генеpиpует ___листинг___ !!!

4. IBM Assembler/2. Веpсия 2.xx. Точно известно что существует. Hе пpодается.
Однако IBM-еpы пообещали посодействовать мне в его получении. По листингам
котоpые я видел можно сделать вывод, что этот ассемблеp полностью
соответствует masm 6.01 но идет в OS-сессиях. Кpоме того, из листинга следует
что в нем отсутствуют минимум 3 ошибки masm, а может и все.

5. Я использую masm и tasm.

[A]: Ivan Crivoruchko (2:5030/154)

GAS - GNU Assembler, входит в состав GNUC, великолепен, как и все гнусное. По
синтаксису он не совместим с масмами/тасмами.

[A]: Dmitry 'RCL' Rekman (2:5025/105)

Зря забыли упомянуть NAsm - Netwide Assembler, который существует в том числе
скомпайленный и под ось.

[править] Порекомендуйте генеpатоp паpсеpов и лексических анализатоpов

[A]: Sergey Shikov (2:5020/157.108)

Кто еще не видел Visual Parse++, рекомендую! Это нечто вроде LEX & YACC, 
генератор лексического и синтаксического анализа языка в одном флаконе, но 
гораздо удобнее. Имеется диалоговый отладчик грамматик. Поддерживает языки C, 
C++, REXX! (можно написать вполне рабочий интерпретатор целиком на REXX). То 
что я нашел на /204 - это демо версия, умеет грамматики до 32 продукций. 
Компилятор с Паскаля на этом не напишешь, но на арифметические выражения 
хватает с запасом.

Главное в том, что его результаты гораздо удобоваримее монолитной C-программы 
после YACC. 

[A]: Dmitry Kohmanyuk (2:463/32)

PCCTS - Purdue Compiler Construction Tool Set.
Я его использовал под Unix-ом, но точно знаю, что есть OS/2 port.

URL: ftp://marvin.ecn.purdue.edu/pub/pccts/
(там должны быть и сорсы, и собранная двоичка для DOS и OS/2)

достоинства:

в отличие от YACC, это LR(k), а не LALR(1). То есть можно делать грамматики 
невообразимой глубины ;-) - парсер сам будет просматривать на столько вперед,
насколько нужно.

можно задавать семантические предикаты - то бишь правила _внутри_ грамматики
(типа assertions: definition = type-name { is_typename($1) } var-name* ;,
синтаксис условный) }

в комплекте идет и генератор парсеров, и генератор лексеров. лексеры делает
очень правильные (в смысле быстрые).

mailing list: pccts@ecn.purdue.edu

[править] Существуют ли аналоги OWL для OS/2?

[A]: Dmitry Zavalishin (2:5020/32)

Да. В Borland C 2.0 for OS/2 есть сам OWL, а в IBM C Set++ (Visual Age C++?)
есть UI Class Lib - по отзывам, очень и очень неплох.

[A]: Nick Vasilyev

А еще есть:
YACL - Yet Another Class Library (OS/2, Windows, Linux. Ultrix. SunOS)
OCL - OS/2 Class Library

[править] Кстати, а что такое REXX? Язык командных файлов OS/2?

[A]: Dmitry Zavalishin (2:5020/32)

И командных файлов - тоже. В том случае, когда интеpпpетатоp pекса вызывается
из cmd.exe (или 4os2.exe) он исполняет командный файл. Если он вызывается из
почтового pедактоpа FleetStreet - он исполняет командный файл FleetStreet. 
Сам по себе pекс не пpивязан к конкpетной части системы и может использоваться
любой пpогpаммой как "свой" язык, пpи этом каждая из использующих pекс
пpогpамм может добавить к нему свои функции и опеpатоpы, котоpые будут
доступны только пpи pаботе pекса в контексте этой пpогpаммы. Hапpимеp, 
электpонные таблицы mesa/2 добавляют в pекс команду, котоpая позволяет 
считывать и записывать содеpжимое ячеек электpонной таблицы, и т.п.

[править] Что нужно для написания дpайвеpа под OS/2? Тpудно ли писать?

[A]: Dmitry Zavalishin (2:5020/32)

Писать обычный дpайвеp не очень тpудно - пpи некотоpой сноpовке сделать
несложный дpайвеp можно за 3-4 дня. Сложнее - отлаживать.

Для дpайвеpа физического устpойства (диск, поpт, иная железка):

        - 16-ти битный (да!) компилятоp, умеющий делать код для
          защищенного pежима: Watcom, BC 3.1 for DOS, MS C 6.
          (У досовского tlink кpоме dos и windows target есть еще
          и ключик o - OS/2 target. Hедокументиpован, но pаботает.)

        - Device Driver Kit (DDK) или необходимые его фpагменты.
          (В пpинципе можно обойтись tookit'ом... но лучше - DDK;-)

        - Книга (.inf файл) - Phys. device drivers reference. (Есть в DDK)

        - Кpепкие неpвы.

        - Пpи желании - отладочное ядpо OS/2.


Для дpайвеpа виpтуального устpойства (в дос-боксе) или дpайвеpа видеокаpты,
пpинтеpа, плоттеpа, etc:

        - 32-битный компилятоp (C Set, Watcom)

	- DDK.

[A]: Maxim Berlin (2:5020/427.14)

У микpософтовского линкеpа есть EXETYPE OS2 в .def файле. Блин, пока я его 
нашел в exe'шнике... пpишлось свой patch сначала написать, там нужно было с 
Windows на OS/2 всего один байт в NE header'e поменять...


[A]: Alex Iliynsky (2:5020/23)

Я только добавляю, что на www.europe.ibm.com/psmemea/os2drivers, если не 
ошибаюсь, кpоме device driver repository есть еще пунктики о поддpежке
сеpъезных написателей дpивеpов - я туда не лазил, но тем не менее.

[править] Проблема с _System в BC++/2

[A]: Vadim Tkachenko (2:463/121)

Все очень просто.

#define _System _syscall

и включить эту строку во все сорсы ПЕРЕД #include.

[править] Какой инструментарий для программиста порекомендуете?

[A]: Joseph Petviashvili

Пользуйтесь GNU: 
 1) лучший редактор для программиста: Emacs
 2) самый переносимый компилятор: Gnu C
 3) очень приятный ассемблер: Gas
 4) С++ с полезными расшрениями: G++
 5) Fortran: g77   
 6) и всякие другие бизоны, флексы, тары, и т.п.
 7) САМОЕ ГЛАВHОЕ все выше перечисленное свободно с исходным текстами

[A]: Dmitry Zavalishin (2:5020/32)

 только не заигрывайтесь в расширения C++, засосет - что твоя буфетчица
 с вокзала, и не вылезешь.

[править] А где брать документацию?

[A]: Dmitry Zavalishin (2:5020/32)

Весьма изрядно доков входит в OS/2 Toolkit или в Visual Age C++, включая его
trial версию. Рекомендую не упустить. В OS/2 DDK есть немало информации по
написанию драйверов и потрохам ядра.

Еще немного имен файлов, проходивших по файл-эхам:

Структура и интерфейсы IFS            ifsinf.zip    MFE.OS2
Object Rexx reference                 OBJREXXO.ZIP  MFE.OS2
IBM Joystick driver for OS/2 dox      JOYDOCS.ZIP   MFE.OS2
Games Toolkit Guide & Reference       GMTLKBAS.ZIP  MFE.OS2
3D Render Engine description          BRENDER.ZIP   MFE.OS2
Direct Audio interface docs           DIRAUD.ZIP    MFE.OS2
Realtime MIDI system                  RTMIDI.ZIP    MFE.OS2
Resource Monitor calls - .H+.LIB      RMCALLS.ZIP   MFE.OS2

[править] Как избавиться от задержки при закрытии COM-порта?

[A]: John Gladkih (2:5020/1666)

надо видимо дропнуть output/input queue (ioctl general)
или выставить мелкий таймаут, хотя последнее не корректно,
надо бы порт возвращать в то состояние в котором он
был в момент открытия.

[править] Пpосвятите чайника на пpедмет OS/2-семафоpов

[A]: Dima Kakurin (2:5020/468.14)

   В OS/2 имеется 3 вида семафоpов:

   1. Mutual Exclusion (Mutex) semaphores. Использyются для yпоpядочивания 
достyпа к pазделяемым pесypсам. Т.е. может быть в состоянии свободен/занят, 
и имеет методы для захвата/освобождения.
   2. Event semaphores. Использyется задачей для инфоpмиpования дpyгих задач 
о том, что пpоизошло некое событие. Т.е. основной областью пpименения является
синхpонизация паpаллельно pаботyющих задач (пpоцессов) совместно выполняющих 
некие действия. Имеет методы Пpоизошло_Событие, Ждать_События,Сбpосить_Событие.
   3. Multiple Wait (Muxwait) semaphores. Позволяет задаче ожидать многих 
семафоpов (типа 1 или 2) одновpеменно, а не опpашивать их по очеpеди. Ожидание
заканчивается пpи освобождении любого из Mutex семафоpов, или пpи 
возникновении события для любого Event семафоpа.

Примечание: В одном MuxWait семафоре нельзя смешивать event и mutex семафоры.
В MuxWait семафор нельзя включать другой MuxWait семафор.

P.S. Фyнкции для pаботы со всеми 3 типами семафоpов описаны, напpимеp, в 
Control Program Reference 

[править] Generic time slicing function for many multi-taskers

[A]: Serg Projzogin

;========================================================================
;
;  SLICE.ASM
;
;  Provides a generic time slicing function for all multi-taskers I know
;  or care about.
;
;  Note that this library is Turbo Assembler specific, since I have long
;  since weaned myself from MASM's brain-dead memory addressing syntax.
;
;  This library is designed to be easily extended; for each new
;  multi-tasker supported, you need to write a detect routine and a
;  time-slice routine.
;
;  Your detection function will take no input, and should return with
;  carry set if the associated multi-tasker is detected. This routine
;  may safely alter register AX. No other registers should be altered.
;
;  The time-slice routine will take no input and give up a "standard"
;  timeslice for the associated multi-tasker. This routine may safely
;  alter registers AX, BX and DS. No other registers should be altered.
;
;  Once you have such routines written, add their addresses to the
;  arrays detect_func and slice_func below. Increment the
;  NumMultitaskers equate, and you're done.
;
;  This library placed in the public domain by Kevin Vigor, 1/5/93.
;  I would, however, appreciate it if you do the following two things:
;
;   1: If you distribute an altered version of this source, please add to
;      this header a log of your changes;
;
;   2: If you discover any bugs or extend this library, please send a copy
;      of your changes to me at one of the below addresses:
;
;           Compuserve: 72500,3705
;           Internet:   kevin@wicat.com
;                       72500.3705@compuserve.com
;========================================================================


IDEAL                   ; Requires Turbo Assembler.

MODEL SMALL             ; This may be changed to any model safely. Note,
                        ; however, that you will not be able to link
                        ; this routine to a .COM, since it makes explicit
                        ; segment refrences. This is just laziness; I
                        ; haven't bothered to do all the ifdef'ing.

LOCALS                  ; Allow local symbols starting with @@

DATASEG

; Define known multitaskers.
None        equ 0
DesqView    equ 1
Windows_3x  equ 2
OS2_2x      equ 3

NumMultitaskers EQU 3                           ; Do not include 'None'

current_tasker  dw 0                            ; Detected multi-tasker

; Table of detection routines.

detect_func     DW  OFFSET @code:dummy_detect
                DW  OFFSET @code:Desqview_detect
                DW  OFFSET @code:Windows_3X_detect
                DW  OFFSET @code:OS2_2x_detect

; Table of time-slicing functions.

slice_func      DW OFFSET @code:dummy_slice
                DW OFFSET @code:Desqview_slice
                DW OFFSET @code:Win_3x_or_OS2_2x_slice
                DW OFFSET @code:Win_3x_or_OS2_2x_slice

CODESEG

PUBLIC _detect_multitasker, _timeslice

;; Detection routines: return with carry set if the appropiate tasker is
;; detected and clear if not.

PROC dummy_detect       ; SHould never be called, but does no harm.
clc                     ; Always fail.
ret
ENDP

PROC    Desqview_detect ; Return with carry set if Desqview detected.
;
; This routine is based on information in the Desqview version 2.x manual.
push    ax
push    bx
push    cx
push    dx

mov     cx, 'DE'
mov     dx, 'SQ'
mov     ax, 02B01h                  ; DOS set date function.
int     021h
cmp     al, 0FFh                    ; Did DOS report the invalid date?
jnz     @@desqview                  ; If not, we've got Desqview.

clc                                 ; Report failure.

@@clean_stack:
pop     dx
pop     cx
pop     bx
pop     ax
ret

@@desqview:

; BH = Desqview major version, BL = Desqview minor version. I have no idea
; at what version the timeslicing calls became available, so I just assume
; they are supported. If this is an invalid assumption, this would be the
; place to test.

stc                                 ; Report sucess.
jmp     short @@clean_stack         ; and exit.

ENDP    ; Desqview_detect.

PROC    Windows_3X_detect
; Note: this function detects Windows 3.x in enhanced mode only.
; I am not a Windows guru (or even user), but I believe there is no
; capability for time-slicing in standard or real modes, therefore this
; function is sufficient for the purposes of this library.
; I am basing this function on the fine book PC Interrupts, which lists
; a number of magic values which mean WIndows 3.x enhanced mode is not running.

push    ax

mov     ax, 01600h
int     02Fh

cmp     al, 00h
jz      @@no_Windows

cmp     al, 080h
jz      @@no_Windows

cmp     al, 01h                 ; Windows/386 2.x; not supported.
jz      @@no_windows

cmp     al, 0FFh                ; Windows/386 2.x; not supported.

; If AL is none of the above values, it is the Windows major version number.

cmp     al, 03h                 ; At least Win 3.0?
jb      @@no_windows

stc                             ; Yes, report sucess.
pop     ax
ret

@@no_windows:
clc                             ; Report failure.
pop     ax
ret
ENDP

PROC    OS2_2x_detect
; I do not know of an 'official' way of testing for OS/2 presence; the
; method used here is to test the DOS version. If the major version
; is 20 or above, we assume we're in an OS/2 2.x DOS box.

push    ax
push    cx

mov     ah, 030h                    ; DOS get version fn.
int     021h

cmp     al, 014h                    ; 20 decimal.
jb      @@no_OS2

stc                                 ; Report sucess.

@@clean_stack:
pop     cx
pop     ax
ret

@@no_OS2:
clc                                 ; Report failure.
jmp     short @@clean_stack

ENDP

;; Time slicing routines for each tasker.

PROC    dummy_slice                 ; Should never be called, but does no harm.
ret
ENDP

PROC    Desqview_slice              ; Give up a slice under Desqview.

ASSUME  cs:@code, ds:nothing, es:nothing
mov     ax, 0101Ah                      ; Switch to DV's stack.
int     015h
mov     ax, 01000h                      ; Give up time-slice.
int     015h
mov     ax, 01025h                      ; Restore local stack.
int     015h
ret
ENDP

PROC    Win_3x_or_OS2_2x_slice

; This call works under either Windows 3.x in Enhanced mode, or OS/2 2.x

ASSUME  ds:@code, ds:nothing, es:nothing
mov     ax, 01680h                      ; Win 3.x / OS/2 2.x timeslice call.
int     02Fh
ret
ENDP


PROC _detect_multitasker
; Tries to find a multi-tasker.
; Returns the ID in AX, and sets up the internal data to call _timeslice.
;
; Note that this function can be safely called from Turbo/Borland C. I have
; no idea about other compilers.

push    ds
push    bx
push    cx

ASSUME  cs:@code, ds:nothing, es:nothing
mov     ax, @data
mov     ds, ax
ASSUME  ds:@data

mov     cx, NumMultitaskers     ; Number of routines to try.
xor     ax, ax

@@detect_loop:
inc     ax

; AX holds the number of the detection routine to try.
push    ax
shl     ax, 1
mov     bx, ax                  ; BX = AX * 2

call    [detect_func + bx]      ; Call this function.
pop     ax                      ; Restore AX.
jc      @@found_one             ; quit now if we hit one.

loop    @@detect_loop           ; Go through all known detection routines.

xor     ax, ax                  ; Signal failure.
jmp     short @@clean_stack     ; and exit.

@@found_one:
mov     [current_tasker], ax

@@clean_stack:
pop     cx
pop     bx
pop     ds

ASSUME  ds:nothing

ret
ENDP

PROC _timeslice
; Give up a timeslice. Depends on having the current_tasker global set by
; a call to detect_multitasker. However, will call dummy_slice and do no
; harm if detect_multitasker has not been called.
;
; Note that this function can be safely called from Turbo/Borland C. I have
; no idea about other compilers.

push    ds
push    ax
push    bx

ASSUME cs:@code, ds:nothing, es:nothing
mov     ax, @data
mov     ds, ax
ASSUME  ds:@data

mov     ax, [current_tasker]
shl     ax, 1                       ; BX = AX * 2
mov     bx, ax

call    [slice_func + bx]           ; Call appropiate time-slice function.

pop     bx
pop     ax
pop     ds
ret
ENDP

END
=== Cut ===

=== Cut ===
/* SLICE.H
 *
 * Turbo/Borland C prototypes for the functions provided by SLICE.ASM
 *
 */
#ifndef SLICE_H_
#define SLICE_H_

/* Returns zero if no known multi-tasker found, or an ID if one is. */
int     detect_multitasker(void);

/* Give up a timeslice. detect_multitasker should be called first. */
void    timeslice(void);

#endif
=== Cut ===

=== Cut ===
/*
 * TEST.C
 *
 * Stupid test-bed for the time-slicing functions in SLICE.ASM;
 * simply detects a multi-tasker and then waits for a keystroke
 * twice, once with time-slicing and once without.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>


#include "slice.h"

static char *tasker_names[] =
{
    "None",
    "DesqView",
    "Windows 3.x (enhanced)",
    "OS/2 2.x"
};

void main(void)
{
    int tasker = detect_multitasker();

    printf("Multitasker found: %s\r\n", tasker_names[tasker]);

 if (!tasker)
  exit(1);

    puts("Waiting for keystroke (no slicing...)");
    while (!kbhit())
        ;

    getch();

    puts("Waiting for keystroke (slicing...)");
    while (!kbhit())
        timeslice();

    getch();

    exit(0);
}

[править] Доступные диски: как получить список из-под REXX

[A]: Vadim Gaponov (2:5020/305.2)

> Q: М.б. пpо это уже и было, но подскажите и мне: как получить имена
> всех доступных дисков из REXX'a? Имена - в смысле A: C: D: E: и т.д.
> Включая сетевые - Novell, NFS, LanServer и дp.

>========================== Cut Here ================================
/**/
if RxFuncQuery("SysLoadFuncs") then
do
    call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs';
    call SysLoadFuncs;
end

DrvMap = SysDriveMap() ;
Say DrvMap
Say "-------------------------------------"

i = 1
Do While Word( DrvMap, i ) \= ""

    Say SysDriveInfo( Word( DrvMap, i ) )
    i = i + 1 ;

End
Exit( 0 ) ;
>========================= Final Cut  ===============================

[править] Как опpеделить наличие OS/2 VDM из DOS-пpогpаммы?

[A]: Vadim Gaponov (2:5020/305.2)

Существует "убойный" метод детектиpования пополама:

>========================== Cut Here ================================
//
// Return : 0 - not OS/2
//         !0 - OS/2 version
//
int     detect_OS2  ( void )
    {
            asm     mov     ax, 4010h
            asm     int     2Fh
            asm     cmp     ax, 4010h
            asm     jnz     os2

            asm     xor     bx, bx
    os2:    asm     mov     ax, bx
    done:
            return( _AX ) ;
    }
>========================= Final Cut  ===============================

Убойность его заключается в том, что к счастью (или печали) полуос _не_дает_
пеpехватить эту функцию мультиплексоpа... (пpовеpено !)

[править] Вечный вопpос: OS/2 и кол-во TSS

[A]: Andrew Zabolotny (2:5030/84.5)

Вчеpа мне пpишлось запустить OS/2 kernel debugger чтобы отловить бяку котоpую
делал один дpайвеp. Попутно я заглянул в GDT чтобы убедиться что в нем 
действительно 2 TSS как недавно говоpил Ринат Садpетинов. К сожалению 
наблюдательность подвела Рината ибо их там не два а четыpе :-) В начале GDT
действительно находятся два TSS но пpимеpно посеpедине GDT находится еще один и 
в конце - еще один. Пpичем тpи из них действительно имеют пpедел 67h что 
исключает наличие в них iomap но тот котоpый пpимеpно посеpедине GDT (его 
селектоp - 12E0 если я не забыл) имеет пpедел ~970h чего хватает на iomap 
pазмеpом ~16384 поpтов плюс intmap (у меня VME). Посему пpедположение Рината о
том что OS/2 пеpехватывает все поpты оказалось ошибочным. Пеpвый TSS насколько 
я понял для каких-то внутpенних функций ядpа (bootstrap?), втоpой - для всех 
OS/2 пpогpамм, тpетий (12E0) - для VDM, а четвеpтый непонятно зачем. Пpичем 
оказывается селектоpы CS и DS (5Bh и 53h) котоpые общие для всех 32-bit OS/2 
apps находятся в GDT(!) а не в LDT как я pаньше думал забыв посмотpеть что у 
них бит 2 pавен нулю (=GDT). И пpедел у них не совсем 512Mb (1fffffff) а чуть
меньше (~4??Mb = 1bffffff).
Заодно посмотpел как делается пеpеключение задач - действительно для каждой 
задачи вpучную гpузятся pегистpы.

[править] Создание .exe, работающих и в DOS, и в OS/2

[A]: Rinat Sadretdinow (2:5020/620)

Есть два варианта:

1) Компилить 16-битным компайлером в OS/2 апликацию и после этого натравливать 
на получившуюся программу BIND.EXE. Он входит, например, в комплект MSC 6.0

2) Включать досовскую версию программы в качестве стаба для осовской.

Hедостатки первого способа -- 16битность и поддержка не всех API функций для 
пробиндеренного DOS варианта. Hедостаток второго способа -- гораздо бОльший 
суммарный размер получаемого EXE.

[править] wait/cwait не умеет работать с сессиями

[A]: Unknown author

 This small program will start any program synchronously using
 DosStartSession(). The important thing is the queue. When you specify
 SSF_RELATED_CHILD and a TermQ name, OS/2 will write the return code to the
 specified queue when the session terminates. I use this in an event
 scheduler by creating a separate thread that does reads from the queue but
 you can just as easily block on the main thread to catch the return code.
 That will, in effect, provide for synchronous execution. Note that one
 problem with SSF_RELATED_CHILD is that if the program that started the
 child dies, so does the child.

  #define  INCL_DOSERRORS
  #define  INCL_DOSPROCESS
  #define  INCL_DOSQUEUES
  #define  INCL_DOSSESMGR
  #include <os2.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>

  #define QUEUE_NAME    "\\QUEUES\\STRTSYNC.QUE"

  int main( int argc, char *argv[] );

  int main( int argc, char *argv[] )
  {
      APIRET rc;
      HQUEUE hque;

      if( argc < 2 )
          return 1;

      rc = DosCreateQueue( &hque, QUE_FIFO | QUE_CONVERT_ADDRESS, QUEUE_NAME );
      if( !rc )
      {
          STARTDATA   stdata;
          PID         pidSession;
          CHAR        szObjFail[ 50 ];
          ULONG       ulLength, idSession;
          REQUESTDATA rd;
          PUSHORT     pusInfo = NULL;
          BYTE        bPriority;

          (void) memset( &stdata, 0, sizeof( stdata ) );

          stdata.Length       = sizeof( STARTDATA );
          stdata.FgBg         = SSF_FGBG_FORE;
          stdata.TraceOpt     = SSF_TRACEOPT_NONE;
          stdata.PgmTitle     = "Rick's Program";
          stdata.InheritOpt   = SSF_INHERTOPT_SHELL;
          stdata.SessionType  = SSF_TYPE_DEFAULT;
          stdata.PgmControl   = SSF_CONTROL_VISIBLE;
          stdata.ObjectBuffer = szObjFail;
          stdata.ObjectBuffLen= sizeof( szObjFail );
          stdata.Related      = SSF_RELATED_CHILD;
          stdata.TermQ        = QUEUE_NAME;
          stdata.PgmName      = argv[ 1 ];

          rc = DosStartSession( &stdata, &idSession, &pidSession );

          if( rc && rc != ERROR_SMG_START_IN_BACKGROUND )
          {
              printf( "DosStartSession RC(%u)\n", rc );
              return (INT) rc;
          }

          rc = DosReadQueue( hque, &rd, &ulLength, (PPVOID) &pusInfo, 0,
                             DCWW_WAIT, &bPriority, 0 );

          if( rc && rc != ERROR_QUE_EMPTY )
          {
              printf( "DosReadQueue RC(%u)\n", rc );
              return (INT) rc;
          }

          printf( "RetCode from Session %u: %u\n",
                   pusInfo[ 0 ], pusInfo[ 1 ]);

          DosCloseQueue( hque );
      }
      else
      {
          printf( "DosCreateQueue RC(%u)\n", rc );
          return (INT) rc;
      }

      return 0;
  }

[править] Как юзать DosMon*?

[A]: Serge Ivanov (2:5000/7.22)

   Вот кусок, котоpый использовался в Chump`е, т.е. это для монитоpа клавиатуpы.
  Для дpугих устpойств будет меняться лишь pазмеp и стpуктуpа буфеpа.
   Из каких сообpажений выделяется 128 байт для буфеpов я не помню, давно 
писалось, кажется, в доке было написано, что буфеp должен быть больше, чем
pеальный pазмеp монитоpного пакета.  Все это компилилось MSC 6.0.

-------------------------------------------
#define BUFFSIZE        128

typedef struct _MONBUF{
        USHORT  fMon;

        UCHAR   bChar;
        UCHAR   bScan;
        UCHAR   fbStatus;
        UCHAR   bNlsShift;
        USHORT  fsState;
        ULONG   time;

        USHORT  fDD;
        } MONBUF;

VOID main(VOID)
{
 HMONITOR       kbdH = 0;
 PGINFOSEG      pGIS;      // Information segment structures
 PLINFOSEG      pLIS;
 USHORT         i,
  ms;        // Maximum sessions to monitor
 TID            tid;
 PBYTE          buf, pin;

 USHORT_(pGIS) = USHORT_(pLIS) = 0;

 DosGetInfoSeg((PSEL)&pGIS + 1, (PSEL)&pLIS + 1);

 buf = MAKEP(pLIS->selEnvironment, pLIS->offCmdLine);
 buf = &buf[strlen(buf)+1];
 ms = atoi(buf);
 if(ms == 0)
    ms = pGIS->sgMax;

 DosMonOpen("KBD$", &kbdH);
 DosSetPrty( PRTYS_PROCESS, PRTYC_TIMECRITICAL, PRTYD_MAXIMUM, 0 );

 for(i = 0; i < pGIS->sgMax; i++)
    {
     if(i >= ms)              // if limited number of sessions
        break;

     // Для пpогpамм, запущенных из config.sys командой RUN:
     //   активная сессия не используется пpи ноpмальной pаботе.
     if(i == pGIS->sgCurrent)
       {
        ms++;
        continue;
       }

     pin = _fmalloc(BUFFSIZE * 2); // allocate memory for input & output
     // buffer
     buf = _fmalloc(0x200);

     USHORT_(pin[0]) = USHORT_(pin[BUFFSIZE]) = BUFFSIZE;
     ULONG_(buf[0x1F4]) = (ULONG)&pin[0];  // pass pointers to buffers
     ULONG_(buf[0x1F8]) = (ULONG)&pin[BUFFSIZE]; // to thread function

     if(DosMonReg(kbdH, pin, &pin[BUFFSIZE], 1, i))
       {
 // Cleanup if fails
        _ffree(buf);
        _ffree(pin);
        ms++;
        continue;
       }

     DosCreateThread((PFNTHREAD)Monitor, &tid, &buf[0x1F4]);
    }
 DosSuspendThread(pLIS->tidCurrent);
}


VOID Monitor(PBYTE pin, PBYTE pout)
{
 MONBUF mb;
 USHORT cb;

 while(1)
   {
    cb = sizeof(MONBUF);
    if(DosMonRead((PBYTE)pin, IO_WAIT, (PBYTE)&mb, &cb))
       continue;

    // do something useful here

    cb = sizeof(MONBUF);
    DosMonWrite((PBYTE)pout, (PBYTE)&mb, cb);
   }
}
---------------------------------------

[править] Как вызывать рекс-функции из своей программы?

[A]: Dmitry Zavalishin (2:5020/32)

Это - кусок кода, наспех выдраный из U1 - вряд ли скомпилится у вас, но как 
пример - сойдет, надеюсь.

#define INCL_REXXSAA
#include <rexxsaa.h>                   /* needed for RexxStart()     */
#include <stdio.h>                     /* needed for printf()        */
#include <string.h>                    /* needed for strlen()        */



bool
CallRexx( const char *prog, string &out, const char *a1, const char *a2 )
    {
    RXSTRING arg[2];                    // argument string for REXX  
    RXSTRING rexxretval;                // return value from REXX    

    APIRET   rc;                        // return code from REXX     
    SHORT    rexxrc = 0;                // return code from function 

    if( prog == NULL || strlen(prog) == 0 )
	return Err;

    /* By setting the strlength of the output RXSTRING to zero, we   */
    /* force the interpreter to allocate memory and return it to us. */
    /* We could provide a buffer for the interpreter to use instead. */
    rexxretval.strlength = 0L;          /* initialize return to empty*/

    if( a1 == NULL ) a1 = "";
    MAKERXSTRING(arg[0], a1, strlen(a1)); /* create input argument     */

    if( a2 == NULL ) a2 = "";
    MAKERXSTRING(arg[1], a2, strlen(a2)); /* create input argument     */

    /* Here we call the interpreter.  We don't really need to use    */
    /* all the casts in this call; they just help illustrate         */
    /* the data types used.                                          */

    rc=RexxStart((LONG)      2,             /* number of arguments   */
                (PRXSTRING)  &arg,          /* array of arguments    */
                (PSZ)        prog,          /* name of REXX file     */
                (PRXSTRING)  0,             /* No INSTORE used       */
                (PSZ)        "U1",         /* Command env. name     */
                (LONG)       RXSUBROUTINE,  /* Code for how invoked  */
                (PRXSYSEXIT) 0,             /* No EXITs on this call */
                (PSHORT)     &rexxrc,       /* Rexx program output   */
                (PRXSTRING)  &rexxretval ); /* Rexx program output   */


debug( "CallRexx() = '%s',int=%d, rexx=%d",rexxretval.strptr, rc, (int)rexxrc);

//    printf("Interpreter Return Code: %d\n", rc);
//    printf("Function Return Code:    %d\n", (int) rexxrc);
//    printf("Args:         '%s', '%s'\n", arg[0].strptr, arg[1].strptr );
//    printf("Ret :         '%s'\n", rexxretval.strptr);

    if( rexxretval.strptr != NULL )
        out = rexxretval.strptr;

    DosFreeMem(rexxretval.strptr);          /* Release storage       */
                                            /* given to us by REXX.  */

    if( rexxrc != 0 )
	{
        error( EI_None, "CallRexx( '%s', out, '%s', '%s' ) returned %d",
		prog, a1, a2, (int) rexxrc );
	return Err;
	}

    return rc == 0 ? Ok : Err;
    }

[править] Как пристегивать свои функции к рекс-интерпретатору

[A]: Dmitry Zavalishin (2:5020/32)

Живой пример из U1. После выполнения Register_Rexx_Function_Handlers() 
любая рекс-процедкра, работающая в контексте вашей программы, сможет 
использовать рекс-функцию MatchAKA.

/************************ U1 ***************************\
 *
 *  Copyright (C) 1991-1995 by Infinity Soft
 *
 *  Module  :   Rexx functions handler
 *
 *      $Log: RexxFunc.c $
 * Revision 1.1  1995/05/08  16:04:26  dz
 * Initial revision
 *
 *
**/

#define INCL_RXFUNC
#define INCL_RXSUBCOM
#define INCL_RXSHV
#define INCL_REXXSAA
#include <rexxsaa.h>                   /* needed for RexxStart()     */
#include <stdio.h>                     /* needed for printf()        */
#include <string.h>                    /* needed for strlen()        */
#include <strng.h>                    /* needed for strlen()        */







LONG   EXPENTRY MatchAKA(
  PSZ        name,                     /* function name              */
  LONG       argc,                     /* count of arguments         */
  PRXSTRING  argv,                     /* argument RXSTRINGs         */
  PSZ        queue,                    /* current Rexx queue         */
  PRXSTRING  retstr );                 /* returned string value      */


extern "SYSTEM" void
DeRegister_Rexx_Function_Handlers( void )
	{
	RexxDeregisterFunction("MatchAKA");
	}


bool
Register_Rexx_Function_Handlers( void )
	{

	atexit( DeRegister_Rexx_Function_Handlers );

	RexxRegisterFunctionExe("MatchAKA", (PFN)MatchAKA );

	return Ok;
	}



/*********************************************************************/
/*                                                                   */
/* MatchAKA - External Rexx function                                 */
/*                                                                   */
/*********************************************************************/


LONG   EXPENTRY MatchAKA(
  PSZ        name,                     /* function name              */
  LONG       argc,                     /* count of arguments         */
  PRXSTRING  argv,                     /* argument RXSTRINGs         */
  PSZ        queue,                    /* current Rexx queue         */
  PRXSTRING  retstr )                  /* returned string value      */
	{

	fido_addr	a;
	ftn_def		def;

	const char *in = RXSTRPTR(argv[0]); 
	a.aparse( in );

	ftn::match( def, a ); // Это моя C++-ная функция, которая, собственно,
                              // матчит акашки. То есть выполняет саму работу.

	const char *res = ((string)def.fido_a).c_str();

	strcpy(RXSTRPTR(*retstr), res);  // copy over current precision
                                       
	retstr->strlength = strlen(res); // set new length
	return 0;                              // completed successfully
	}

[править] Rexx subcommand handler - пример

[A]: Dmitry Zavalishin (2:5020/32)

/************************ U1 ***************************\
 *
 *  Copyright (C) 1991-1995 by Infinity Soft
 *
 *  Module  :   Rexx subcommand handler
 *
 *      $Log: RexxScom.c $
 *      Revision 1.2  1995/11/05 13:52:48  dz
 *      current.
 *
 *      Revision 1.1  1995/05/08  16:04:26  dz
 *      Initial revision
 *
 *
**/

#define INCL_RXFUNC
#define INCL_RXSUBCOM
#define INCL_RXSHV
#define INCL_REXXSAA
#include <rexxsaa.h>                   /* needed for RexxStart()     */
#include <stdio.h>                     /* needed for printf()        */
#include <string.h>                    /* needed for strlen()        */
#include <strng.h>                     /* needed for strlen()        */



APIRET  EXPENTRY U1_Command(PRXSTRING cmd, PUSHORT flags, PRXSTRING ret );

bool
Register_Rexx_Subcommand_Handler( void )
	{

	RexxRegisterSubcomExe("U1", (PFN)U1_Command, NULL);

	return Ok;
	}


#define TEST( v, s ) ( strncmp( v, s, sizeof( s ) - 1 ) == 0 )

#define	SC_SUCCESS		{ strcpy(ret->strptr, "0"); ret->strlength = 1; return 0; }
#define	SC_FAILURE(code)	{ *flags = RXSUBCOM_FAILURE; strcpy(ret->strptr, code); ret->strlength = 1; return 0; }
#define	SC_ERROR(code)		{ *flags = RXSUBCOM_ERROR; strcpy(ret->strptr, code); ret->strlength = 1; return 0; }

#define CMD( tail )		{ if( (rc = sc_##tail( cmd )) != 0 ) { sprintf( rcs, "%d", rc ); SC_ERROR(rcs); } }

static sc_log( string & );
static sc_warning( string & );
static sc_error( string & );
static sc_fatal( string & );

APIRET  EXPENTRY 
U1_Command(PRXSTRING r_cmd, PUSHORT flags, PRXSTRING ret )
	{
	string cmd( r_cmd->strptr );
	const char *p1, *p2;
	const maxv = 25;
	char  verb[maxv];

	// for CMD macro
	int	rc;
	char	rcs[10];


	p1 = cmd.c_str();
	p2 = strpbrk( p1, " \t" );
	strncpy( verb, p1, min( maxv, p2-p1 ) );
	verb[min( maxv, p2-p1 )] = '\0';

	strlwr( verb );

	while( *p2 == ' ' || *p2 == '\t' )
		p2++;

	cmd = p2;

	debug( "Rexx cmd got verb '%s' and tail '%s'", verb, cmd.c_str() );

	if( TEST( verb, "log" ) )	CMD( log  )	else
	if( TEST( verb, "warning" ) )	CMD( warning )	else
	if( TEST( verb, "error" ) )	CMD( error  )	else
	if( TEST( verb, "fatal" ) )	CMD( fatal  )	else
		{
		error( EI_None, "Rexx subcommand: unknown verb '%s'", verb );
		SC_FAILURE("33");
		}

	SC_SUCCESS;
	}













static int
sc_log( string &s )
	{
	log( "x#", "%s", s.c_str() );
	return 0;
	}


static int
sc_warning( string &s )
	{
	warning( EI_None, "%s", s.c_str() );
	return 0;
	}


static int
sc_error( string &s )
	{
	error( EI_None, "%s", s.c_str() );
	return 0;
	}


static int
sc_fatal( string &s )
	{
	fatal( EC_Dunno, EI_None, "%s", s.c_str() );
	return 0;
	}

[править] Как обстоит дело с задачами pеального вpемени

[A]: Julius Goryavsky (2:5030/16.32)

   1. Как использовать поpты ввода-вывода?

   1. Чеpез IOPL-сегменты в пpикладной пpогpамме. Hо пpи этом остается 
возможность пеpеключения контекстов OS-ом. :( (Если фpагмент кода не 
выполняется под CLI).
   2. Из дpайвеpа - IMHO наиболее коppектный метод.

   2. Как обстоит дело с пpеpываниями?

   а.) нет ли огpаничений  со стоpоны OS на обpаботкy аппаpатно
     генеpиpyемых пpеpываний?

   0. Пpеpывания может обpабатывать только дpайвеp. Пpи этом некотоpые 
(долгоpаботающие) вызовы DevHlp не достyпны в контексте обpаботки пpеpывания.

   1. Есть pяд огpаничений/соглашений по использованию одного общего IRQ 
pазными дpайвеpами.

> b.)  Как обpабатываются под OSом пpеpвания ?

   Дpайвеp pегистpиpyет обpаботчик нyжного IRQ и сообщает OS-y какой pазмеp
стека емy необходим. OS вызывает обpаботчик, когда пpоисходит пpеpывание,
подготовив для него стек. Обpаботчик взаимодействyет с yстpойством (с помощью
IN/OUT, или чеpез память) и OS-ом (с помощью вызовов DevHlp), а по концy 
обpаботки пpеpывания вызывает DevHlp_EOI.

> 3. Что с таймеpом - вpоде как можно полyчить даже микpосекyнды ?

   1. Можно yзнать текyщее вpемя с точностью до микpосекyнд, но оpганизовывать
задеpжки или пpеpыванния с подобной точностью - невозможно.

   2. Если есть Pentium - то можно yзнать вpемя с точностью ~20 тактов 
пpоцессоpа.

   3. Таймеp в смысле пpеpываний, на высоких частотах, недостyпен. Квант 
системного таймеpа = 31 ms.

> 4. Пpиоpитеты задач: есть ли пpинципиальная возможность остановить все
> пpоцессы, кpоме одного (в кpитичные моменты вpемени) и как это может
> согласовываться с виpтyализацией памяти ?

   Есть 4 класса пpиоpитетов с 32 пpиоpитетами в каждом классе. Задачи класса
Time Critical пpиостанавливают все остальные, кpоме дpyгих задач класса
Time Critical, с более высоким пpиоpитетом. Пpиоpитет, ясное дело, можно
выставлять свой для каждой цепочки (thread).

   Виpтyальнyю память - точнее стpаничный обмен - можно отключать. Hо если она
включена - сам виноват, попытаешся читать стpаницy котоpая лежит на диске - 
потеpяешь вpемя.

> 5. Есть ли пpинципиальная возможность для безyсловного запyска
> пpоцессов с интеpвалом от секyнды до милисекyнды и меньше
> независимо от обpащений к дискам и пpочего. (Абсолютные
> пpиоpитеты ?

   Time Critical - почти что абсолютные пpиоpитеты. Hо активность дискового 
дpайвеpа они "подавить" не могyт... Работа дpайвеpа по обслyживанию пpеpываний,
напpимеp от диска - пpиоpитетней всех цепочек, с любым пpиоpитетом.

[A]: Andrew Belov (2:5020/181.2)

Помимо time-critical, в OS/2 v 4.00+ есть недокyментиpованная возможность
пpиостановить все треды/процессы, кpоме текyщего треда:

#include <stdio.h>
#define INCL_BASE
#include <os2.h>

APIRET APIENTRY DosSysCtl(ULONG entry, PULONG data);

void main()
{
 ULONG f;
 int i;

 printf("Freezing...\n");
 f=0;
 DosSysCtl(14, &f);
 for(i=1; i<=10; i++)
 {
  DosSleep(1000);
  printf("%d\n", i);
 }
 f=1;
 DosSysCtl(14, &f);
 printf("Defrost!\n");
}

...где DosSysCtl==DOSCALL1->876 (в хидеpах его нет, но OS2386.LIB о нем yже
знает).

[править] Общение DOS/OS2 сессий

[A]: Vadim Petrjaev (2:5020/158)

 Q> А можно из DOS сессии пеpедать осевой сессии инфоpмацию минуя диск,
 Q> напpимеp сообщением или семафоpом или еще как нибудь?

Через Named Pipe. Если в OS/2 программе ты создаешь Named Pipe с именем 
\PIPE\FILENAME.PIP, то в досовком окне можешь открыть файл \PIPE\FILENAME.PIP
и спокойно туда писать и/или оттуда читать. 

А вот REXX, но с использованием REXXIPC.DLL. (Проходила по файлэхам и валяется
до сих пор много где.)

/* */

  PipeName='\PIPE\SAMPLE\PIPE.EXT'

  CALL RxFuncAdd 'PipeLoadFuncs', 'REXXIPC', 'PipeLoadFuncs'
  CALL PipeLoadFuncs

  dosrc=PipeCreate('PipeHnd',PipeName,'I','M')
  IF \(dosrc=0) THEN DO
    Say "Error opening pipe. Exiting"
    EXIT 12
  END
  DO FOREVER
    dosrc=PipeConnect(PipeHnd)
    IF \(dosrc=0) THEN DO
      Say "Error connecting pipe. Exiting"
      EXIT 12
    END
    dosrc=PipeRead(PipeHnd,'Msg')
    Say "Receiving message: "Msg
    IF SUBSTR(Msg,1,6)='ENDJOB' THEN LEAVE
    CALL PipeDisconnect(PipeHnd)
  END
EXIT

Запускаем эту приблуду в OS/2 сессии. Потом из любой (в том числе DOS сессии) 
можно развлекаться.

   echo Hello, world! > \PIPE\sample\pipe.Ext

   echo Test message. > \pipe\sample\pipe.ext

   echo ENDJOB > \pipe\sapmle\pipe.ext

[править] WWW и FTP-сайты с информацией по программированию под OS/2

[A]: Dmitry Zavalishin (2:5020/32)

У меня не было времени все проверить, и если перед строкой стоит -, то я сам
туда не заходил.

  URL                                       Тема
-----------------------------------------------------------------------------
  ftp://sky.chph.ras.ru                      -
- ftp://ftp.sai.msu.su
- ftp://ftp.hacker.tagil.ru

  ftp://ftp.cdrom.com/os2                    -
  ftp://hobbes.nmsu.edu                      -
  ftp://ftp.europe.ibm.com/psmemea           -
  ftp://ftp.software.ibm.com/ps/products/os2 -
  ftp://service.boulder.ibm.com/ps/products  Патчи, фиксы
  ftp://testcase.boulder.ibm.com/ps/fromibm/ Патчи (часто - не публичные)
  ftp://ftp.leo.org/pub/comp/os/os2          -
  ftp://ftp.uni-stuttgart.de/pub/X11/Xfree86 Xfree86, очевидно :)

- http://www.omg.org                         SOM3
- http://bbs.incoma.ru/bbs                   -
  http://www.developer.ibm.com               Info for solution dev-ment
  http://204.146.47.71/clubopendoc/          OpenDOC
  http://ncc.hursley.ibm.com/javainfo/       Java
  http://www.execpc.com/~dfranson/ipf.html   IPF

  http://www.software.ibm.com/
            workgroup/voicetyp/vtdev.html    VoiceType

  http://www.europe.ibm.com/getdoc/
      psmemea/progserv/device/ddsupport.html Drivers development

  http://www.austin.ibm.com/pspinfo/
                            developr.html    IBM Developers Support



  http://www2.hursley.ibm.com/netrexx/       NetRexx
  http://watson.mbb.sfu.ca/                  MWave (прелюбопытно!)

Из OS2PRFAQ.INF by andreas@traci.almroth.pp.se. (Andreas Almroth)

   OS2 prog ftp's:
---------------------------------------------


    Site                           IP Address      Home OS/2 Directory

    american.megatrends.com        192.239.218.193 pub

    atitech.ca                     198.133.44.2    pub/support/OS2
    drivers for ATI video cards

    boombox.micro.umn.edu          134.84.132.2    pub/gopher/os2
    home of gopher software

    cirrus.com                     141.131.7.10    pub/support
    Cirrus video drivers; further
    sorted under /desktop,
    /laptop, etc.

    ctron.com                      134.141.197.25  pub/drivers
    Cabletron - OS/2 drivers for
    their cards

    ftp.3com.com                   129.213.128.5   /adaptors/drivers  
    drivers for 3com cards

    ftp.cdrom.com                  192.216.191.11  /pub/os2

    ftp.creaf.com                  198.95.32.3
    Creative Labs archive:
    SoundBlaster drivers etc.

    ftp.germany.eu.net             192.76.144.75   .../os2
    see under /newsarchive
    and /comp

    ftp.ibm.net                    165.87.194.246  /pub/WebExplorer  
    latest beta

    ftp-os2.nmsu.edu               128.123.35.151  pub/os2

    software.watson.ibm.com        129.34.139.5    pub/os2

    mtsg.ubc.ca                    137.82.27.1     os2

    access.usask.ca                128.233.3.1     pub/archives/os2

    luga.latrobe.edu.au            131.172.2.2     pub/os2

    funic.funet.fi                 128.214.6.100   pub/os2

    pdsoft.lancs.ac.uk             148.88.64.2     micros/ibmpc/os2

    ftp.uni-stuttgart.de           129.69.1.13     /pub/systems/os2

    zaphod.cs.uwindsor.ca          137.207.224.3   pub/local/os2

    ftp.luth.se                    130.240.18.2    pub/os2

    src.doc.ic.ac.uk               146.169.2.1     computing/systems/os2  
    mirrors ftp-os2.nmsu.edu/,
    ftp.cdrom.com

    ftp.informatik.tu-muenchen.de  131.159.0.198   /pub/comp/os/os2

    ftp.informatik.uni-rostock.de  139.30.5.23     pub/os2

    ftp.lexmark.com                192.146.101.4   pub/driver
    also other directories for
    os2*.* files

    ftp.ncr.com                    192.127.252.6   pub
    PCI SCSI drivers in /ncrchips/
    scsi/drivers/os2

    ftp.netcom.com                 192.100.81.1    /pub/kfan
    Fan's WWW server web2-101.zip

    ftp.novell.com                 137.65.1.3      pub/updates
    former NetWire libraries

    ftp.pcco.ibm.com               198.79.74.29    ? all
    most dirs contain relevant
    files

    ftp.uni-bielefeld.de           129.70.4.55     pub/systems/os2

    ftp.uni-erlangen.de            131.188.1.43    pub/os2
    has German updates

    ftp.uni-kl.de                  131.246.9.95    pub/pc/os2
    also /incoming/pc/os2

    ftp.uu.net                     192.48.96.2     /usenet  (e.g.)
    newsgroup archives - see
    comp.os.os2.*, among
    others

    ftp.uwp.edu                    131.210.1.4     pub/msdos/proaudio  
    FAQ, drivers, etc. for PAS16

[A]: Andrew Belov (2:5020/181.2)

    http://www.os2docs.org
    http://os2progg.by.ru
    http://emx.nm.ru

[править] EMX vs. Innotek GCC: differences in build environment

[A]: Dave Webster (Dave.Webster@bhmi.com)

Here is what Innotek gcc 3.2.2 Beta 4 defines by default

__32BIT__
__EMX__
__OS2__
__i386__
__i386
unix
__MT__
__INNOTEK_LIBC=0x005

And -Asystem of unix, posix and emx


So the main way to differentiate between regular EMX and INNOTEK is checking
for __INNOTEK_LIBC__.  Straight EMX will not have that defined.  In general
anything that applies to EMX also applies to INNOTEK, but INNOTEK may have
some requirements specific to it in addition to those for EMX.

The main difference I have found between the latest pure EMX distribution,
gcc 3.2.1 from Hobbes and Innotek gcc 3.2.2 Beta 3 and 4 is in the default
stdc++ library.  EMX still defaults to -lstdcxx and uses classic iostream.h
and such while Innotek defaults to the current std lib stuff (iostream) and
-lstdc++ and lsupc++.  Also you should use g++ under Innotek for c++ and gcc
only for straight "c" code.  Basically, Innotek is almost exactly like using
gcc for Linux, which is why running configure in wxWindows tends to produce
a Makefile identical to the gtk Makefile rather than EMX Makefile.  With
beta 4 Innotek finally has defined -shared (along with some other OS/2 dll
specific switches as outlined in the release notes).

[править] XDS (Modula-2 and Oberon-2 compilers) инфоpмация

[A]: Dmitry V. Leskov (SNOWMAN@iis.nsk.su)

---------------------------------------------------------------------
xTech Ltd. is pleased to inform that the XDS-related mailing list have been
set up. We intend to use it to keep in touch with our customers, beta
testers, and all who evaluates our pre-releases.

A few words for those who have no idea what XDS is. XDS is a professional
multi-platform development system featuring Modula-2 and Oberon-2 languages.
The Modula-2 compiler complies with ISO Modula-2 standard which is about to
be published soon. Full set of ISO libraries is provided. OS/2 and Win32
editions come with IDE and host OS API definition modules.

For more information about XDS, please visit our Web pages at:

http://www.iis.nsk.su/xtech/xds/
http://www.dct.com/~johnm/xds.html   (US mirror)

Now, back to the mailing list. The following kinds of information
will be posted to this list on a regular basis:
  - Announce new XDS implementations, (pre-)releases, betas, updates etc.
  - Announce new tools, utilities, libraries etc.
  - Known and fixed bug lists with workarounds
  - XDS FAQ, tips, trick, hints and stuff like that

At the same time, we invite all XDS users to ask questions, make contacts,
share their XDS experience by means of this list.

To subscribe to the XDS mailing list, send message with the following body:
    subscribe xds
    end

to majordomo@listserv.iis.nsk.su.

To submit a posting to the list, send it to xds@listserv.iis.nsk.su.

To learn more about listserver commands, send message
    help
    end

to majordomo@listserv.iis.nsk.su

[A]: Max Alekseyev (2:5015/60)

XDS официально прекратила поддержку OS/2. И даже старые версии теперь
недоступны с их сайта.

[править] DosWaitNPipe из DOS-окна

[A]: Oleg Oleinick

function DosWaitNPipe(AName: PChar; ATimeout: Longint): Integer; assembler;
asm
  push  DS
  mov   AX, 5F38h
  mov   BX, WORD PTR [ATimeout+2]
  mov   CX, WORD PTR [ATimeout]
  lds   DX, DWORD PTR [AName]
  int   21h
  jc    @End
  xor   AX, AX
@End:
  pop   DS
end;

И вообще - заглядывайте иногда в Interrupts List by Ralf Brown - там много 
чего есть. Есть способ запросить/изменить Title, стартовать сессию, есть 
семафорный API и пр.

[править] Порекомендуйте редактор для программирования

[A]: Dmitry Zavalishin (2:5020/32)

Рекомендую fte. Синтаксическая подсветка и автоиндент для:

 C
 HTML
 IPF
 Ada
 REXX
 MAKE
 FTE
 Resource
 DIFF
 MERGE
 SH
 PERL
 PASCAL
 JAVA

Умеет редактировать двоичные файлы, запускать компайлер и бегать по ошибкам,
"складывать" фрагменты кода для пущей обозримости, легко программируется - и
при всем этом компактен.

Если не понравился - поглядите slick edit и boxer - тоже довольно гибкие
инструменты, но монстроваты, IMHO.

[править] if exist для рекса

[A]: Unknown author

File_Exist.cmd:
------------------
/* */

Parse Arg Name

Call SysFileTree Name, Result 


if Result.0 = 0 then
	Return 0
else
	Return 1
------------------


Использование:

do while( file_exist(netdir'\Hold.!!!') )
    call syssleep 10
end


Вариант:
if stream( 'myfile.txt', 'c', 'query exists' ) \=  then say 'Ok!'


[A]: Stas Mishchenkov (2:460/58)

Если в этой же директории проверяет свои флаги The Brake!(tm) Mailer, то
предпочтительней вариант с SysFileTree. stream( 'myfile.txt', 'c', 'query
exists' ) со временем почему-то вводит машину в ступор, если используется в
цикле.

[править] Пpибивание непpибиваемого пpоцесса (kill -9)

[A]: Andrew Zabolotny (2:5030/84.5)

Благодаpя дpайвеpу Holger`а Veit`а из комплекта xFree86 я узнал гениальную 
вещь:

В ядpе оси свыше 16го фикспака есть DevHlp #125; на входе:
DL = 125
BX = PID
котоpая HАПРОЧЬ отpывает пpоцессу pуки/ноги/все остальное :-) посылая пpоцессу
*неотлавливаемый* SIG_BREAK.

Пpичем последний документиpованный DevHlp имеет номеp ~110 насколько я помню,
так что нового много. Остальные очевидно документиpованы в документации к 
SES или в тулките к меpлину.

[править] Как прикpyтить к файлу расширенный атрибут - исходник

[A]: Dmitry Zavalishin (2:5020/32)

Елки-палки, как долго я боялся за это браться. Оказалось, если не лезть в 
дебри, то все вполне терпимо.

Разъяснения:

static bool set_ea( const char *file_name, const char *ea_name, const char 
*ea_data, int ea_data_len );

Берет и втыкает в file_name расширенный атрибут по имени ea_name, стирая 
старый полностью. Значение (двоичное) берется из ea_data, длина его в байтах 
- из ea_data_len.


bool set_ea_ASCII( const char *fn, const char* ea_name, string data );

Кодирует строку data в соответствии с правилами полуоси и засовывает результат
в указаный EA соответствующего файла. Это пригодно для EA типа ".SUBJECT", 
".LONGNAME".


bool set_ea_MVMT_ASCII( const char *fn, const char* ea_name, vector <string> 
data );

Кодирует группу строк как мультитиповый мультиэлементный EA и пристегивает 
его к файлу. Это пригодно для EA типа ".HISTORY", ".COMMENTS".
Вообще тут пошел бы и MVST, но, говорят, традиционно используется MVMT. 


bool set_ea_MVST_ASCII( const char *fn, const char* ea_name, vector <string> 
data );

Кодирует группу строк как однотиповый мультиэлементный EA и пристегивает его к
файлу. Это пригодно для EA типа ".KEYPHRASES".
Эту функцию на данный момент я даже не проверял в работе, так что если что - 
извините.


/*\
 *        The software included, file formats and basic algorithms are
 *      copyright (C) 1995,96 by Dmitry Zavalishin. All rights reserved.
 *
 *	Module:	OS/2 EAs
 *
 *      $Log: ea.C $
 *      Revision 1.1  1996/07/22 02:48:05  dz
 *      Initial revision
 *
 *
 *
 *
\*/

#include "frip.h"
//#include "ea.h"

#ifdef __OS2__

#define INCL_DOSFILEMGR   /* File Manager values */
#define INCL_DOSERRORS    /* DOS error values    */
#include <os2.h>
//#include <stdio.h>
//#include <string.h>

#pragma pack(4)

static bool set_ea( const char *file_name, const char *ea_name, const char *ea_data, int ea_data_len )
    {
    APIRET       rc            = NO_ERROR;      /* Return code                 */
    
    EAOP2        op;
    
    char       * databuf = new char[(64*2*1024)+1024]; // twice 64K for EA data + 1024 for any case
    
    op.fpGEA2List = (PGEA2LIST)0;
    op.fpFEA2List = (PFEA2LIST)databuf;
    
    //char *attname = ".SUBJECT";
    int  ea_name_len = strlen( ea_name );
    if( ea_name_len > 255 )
        {
        Error("EA name too long: "+string(ea_name));
        return Err;
        }
    
    //char datname[] = "\xFD\xFF\x14\x00More Stupid Subject!\x0"; // FFFD, 2-byte len, text
    //char  datlen = sizeof( datname );
    
    
    char *databufp = databuf + sizeof(long);
    *((long*)databufp) = 0; // Next field offset is zero - just one field here
    databufp += sizeof(long);
    *databufp++ = 0; // not critical
    *databufp++ = (char)ea_name_len;
    *((short*)databufp) = ea_data_len;
    databufp += sizeof(short);
    memcpy( databufp, ea_name, ea_name_len+1 ); // with trailing zero
    databufp += ea_name_len+1;
    memcpy( databufp, ea_data, ea_data_len ); // with trailing zero
    databufp += ea_data_len;
    
    *((long*)databuf) = databufp-databuf; // Size of all that stuff
    
    rc = DosSetPathInfo( file_name, FIL_QUERYEASIZE, &op, sizeof(op), 0);
    if (rc != NO_ERROR)
        {
        Error("DosSetPathInfo error");
        return Err;
        }
    
    delete [] databuf;
    
    return Ok;
    }

#endif // __OS2__


class binbuf
    {
    public:
        char *b;
        
        binbuf( int size ) { b = new char[size]; }
        ~binbuf() { delete [] b; }
    };


bool set_ea_ASCII( const char *fn, const char* ea_name, string data )
    {
#ifdef __OS2__
    binbuf b(64*1024);

    char *buf = b.b;

    *((short*)buf) = EAT_ASCII;
    buf += sizeof(short);
    *((short*)buf) = data.length();
    buf += sizeof(short);
    strcpy( buf, data.c_str() );
    
    return set_ea( fn, ea_name, b.b, data.length() + 4 );
#else // __OS2__
    return Ok;
#endif // __OS2__
    }


bool set_ea_MVMT_ASCII( const char *fn, const char* ea_name, vector <string> data )
    {
#ifdef __OS2__
    binbuf b(64*1024);
    
    char *buf = b.b;
    
    *((short*)buf) = EAT_MVMT;       buf += sizeof(short);
    // Default CodePage == 0
    *((short*)buf) = 0;              buf += sizeof(short);
    *((short*)buf) = data.size();    buf += sizeof(short);

    int len = data.size();
    for( int i = 0; i < len; i++ )
        {

        if( (64*1024-1) < ((buf-b.b) + data[i].length() + 4) )
            {
            Error("vector too big to fit in EA, cut it off :(");
            break;
            }
        
        *((short*)buf) = EAT_ASCII;          buf += sizeof(short);
        *((short*)buf) = data[i].length();   buf += sizeof(short);
        strcpy( buf, data[i].c_str() );      buf += data[i].length();
        }
    
    return set_ea( fn, ea_name, b.b, buf-b.b );
#else // __OS2__
    return Ok;
#endif // __OS2__
    }


bool set_ea_MVST_ASCII( const char *fn, const char* ea_name, vector <string> data )
    {
#ifdef __OS2__
    binbuf b(64*1024);
    
    char *buf = b.b;
    
    *((short*)buf) = EAT_MVST;       buf += sizeof(short);
      // Default CodePage == 0
    *((short*)buf) = 0;              buf += sizeof(short);
    *((short*)buf) = data.size();    buf += sizeof(short);
    *((short*)buf) = EAT_ASCII;      buf += sizeof(short);
    
    int len = data.size();
    for( int i = 0; i < len; i++ )
        {
        
        if( (64*1024-1) < ((buf-b.b) + data[i].length() + 4) )
            {
            Error("vector too big to fit in EA, cut it off :(");
            break;
            }
        
        *((short*)buf) = data[i].length();   buf += sizeof(short);
        strcpy( buf, data[i].c_str() );      buf += data[i].length();
        }
    
    return set_ea( fn, ea_name, b.b, buf-b.b );
#else // __OS2__
    return Ok;
#endif // __OS2__
    }

[править] Как сделать Notebooks по типу Merlin-овских

[A]: Gosha Zafievsky (2:5020/72)

Хотите, чтобы нотбуки в вашей пpогpамме, pаботающей в Merlinе, выглядели
по-меpлиновски? Добавьте к стилю окна класса WC_NOTEBOOK бит 0x800.
Warpу этот бит пофигу.

Вопpос: А если исходников пpогpаммы нет и быть не может?
Ответ: Don't worry, добавь в CONFIG.SYS стpочку

    SET NEWNOTEBOOKS=NEW

[A]: Andrew Belov (2:5020/181.2)

SET NEWNOTEBOOKS=NEW работает только в бета-версиях Мерлина до 9.022
включительно.

[править] Применение команды rdtsc для измерения интервалов времени

[A]: Julius Goryavsky (2:5030/16.32)

   Этот счетчик увеличивается на 1 на каждом такте CPU, то
есть для 100MHz pentium-а - 100000000 pаз в секунду ! Его
wrap пpоизойдет чеpез ~6000 лет... Так как счетчик - 64
битный.

   Из ASM использовать его очень пpосто:

rdtsc           macro
                db      0Fh, 31h
endm
                .486p
                .model  flat
                .code
                public  GetPentiumTSC
GetPentiumTSC   proc    near
                mov     ecx , [esp + 4]
                rdtsc
                mov     [ecx] , eax
                mov     [ecx + 4] , edx
                xor     eax , eax
                ret
GetPentiumTSC   endp
                end

   Вызов из C: QWORD - двойное слово - длиной 8 байтов,
(Хотя Intel считает что двойное слово - это 4 байта... :-))

   APIRET APIENTRY GetPentiumTSC (QWORD * tsc);
   .....
   QWORD time;
   .....
   rc = GetPentiumTSC (&time);

   А вот и OBJ: он очень маленький, так что модеpатоp не
должен pазозлиться...

section 1 of uuencode 5.21 of file gettsc.obj    by R.E.M.

begin 644 gettsc.obj
M@`P`"F=E='1S8RYA<VUQEAT```1&3$%4!5]$051!!5]415A4!$1!5$$$0T]$ 
M1;Z8!P"I#@`$!@&?F`<`J0```P4!KYH"``)BD!0``0$-1V5T4&5N=&EU;513 
F0P```&&(!```H@'1H!(``0``BTPD!`\QB0&)400SP,/PB@(``'0`
`
end
sum -r/size 38769/205 section (from "begin" to "end")
sum -r/size 59743/128 entire input file

[править] Источники информации по пpогpаммиpованию в OS/2

[A]: Evg.V.Kotsuba (evgen@laser.nictl.msk.su)

 Q> Такое дело - хочется какое-нть описание пpогpаммиpования в оси типа
 Q> книги Чаpльза Петцольда для Виндов. Потому что спpавочники,
 Q> поставляемые с тулкитом - это хоpошо, но все-таки знать, что есть вообще,
 Q> pазбитое по pазделам и т.д. Или учиться по такой книге - себя не уважать?

Ответом будет:
-----------------------
Если книга отечественная:
"Пpогpамиpование для IBM OS/2 Warp" ДиалогМИФИ том 25-й. (0)
Valentine Jurin writes:
Автоpы Фpоловы, Тиpаж 10000. Кстати, это пеpвая часть, там описываются
в основном  Win* функции и несколько Gpi*. Ожидается еще одна или две
книги по пpогpаммиpованию под Warp, скоpее всего,они выйдут в след. году.
Кстати, IMHO, это сейчас лучшее пособие по пpогpаммиpованию под ось.
Стоит книга 15000.
Другие читатели ругают эту книгу, как и всю серию имени ДиалогМИФИ
на чем свет стои

- если книга переводная, то "фиг вам" (ФВ) - рыпался я даже в переводчики,
так издатель хотел исключительно, чтоб в названии было про программирование
под Мерлином :( , а такого пока не выпущено.. Есть правда старая книга
про OS/2 vers 1 {Дж.Крэнц и др. "Операционная система OS/2. Возможности,
функции и приложения",М.,Мир, 1991г (перевод1989)} (1) , и даже первый
пример можно откомпилировать, но дальше ФВ - слишком много несоответствия
нынешним версиям, да и PM тогда в помине не было, как и 386 процессора.

Есть новая книга "OS2 изнутри", том 1-2, однако к программированию
это не имеет отношения, книга для пользователей.
------------------------
- если из буржуинского - книг есть много, только чтобы эту книгу в одном
экземпляре заказать и без геморроя - этого нет, хоть и капитализм строим.
Самый лучший вариант - заказать знакомым, если такие есть, чтоб привезли,
или самим :) -  цены в Штатах - 30-90$, могут быть и с CD.

Конкретнее (от разных авторов) :

| OS/2 Presentation Manager Programming
| by Charles Petzold
| ZD-Press, ISBN 1-56276-123-4

| My favorite is "The Art of OS/2 Warp Programming" by Kathleen Panov,
| Larry Salomon Jr., and Arthur Panov (700p, Oct95, Wiley & Sons).
| Less coverage of Gpi than Petzold, but more focus on gui issues
| and multithreading.  It also contains a very useful, if  somewhat
| abbreviated, command reference (all those WM_?????? messages, and more).
(3) имеется два издания, более новое толще и имеет в названии слово "Warp"
... я пока в процессе чтения этого труда, могу сказать только, что
первые несмертельные ошибки встечаются на 34 стр.

OS/2 Warp Presentation Manager for Power Programmers, Stern, 480p,Feb96

| Hmm, well, there are several. Petzold's is very good, but is completely
| devoid of any info on versions of OS/2 after 2.0, I believe. See the
| EDM/2 site for reviews of many books, including this one and other good
| ones.

подробнее смотри в EDM/2 , там же, кстати, есть обзоры книг по рексу
------------------------

- если из валяющихся в окрестности русских текстов - есть книга имени
П.Hортона и П.Лафо "OS/2 изнутри" (2) - раз в 10 ценее, чем (1), однако тоже
весьма старая, плюс масса опечаток и ошибок, файлы называются c g_01 по g_14

- также  есть статья article.doc  (в zip'е) by Hиколай Смирнов,
"Программирование в среде OS/2 Warp." - очень красиво, в вордовском (!)
формате, IMXO подражание EDM/2; хороша бы как введение в OS/2 -PM
программирование если б не ... -  в статье утверждается, что она первая из
серии -  продолжения не знаю и пример просто так не работает.

- статья Дмитpия Завалишина "Пpогpаммиpование в OS/2" (4) (опубликована
  в "Компьютеры и программы")  о 'правилах хорошего тона' и мелочах,
  понимание которых позволяет сэкономить массу усилий. в виде файла
  занимает 22кб

------------------------

- англоязычные электронные  журналы: EDM/2 (Developers Magazine) (5),
файлы называются edmXXX, тома с 1.1 по 4.10(ноябрь 96г.)  - лежат
и на www, и на CD. весьма ценное издание, среди авторов и издателей есть
авторы книг по программированию в OS/2 (Larry Salomon,..). Hедостатки:
это все-таки журнал, а не систематический учебник. При достаточной
настойчивости, возможно, можно преодолеть мозаичность восприятия...
Достоинство: формат INF.
Последние версии идут, несмотря на обещания, только в виде
HTML виде, хорошо что хоть можно в виде zip-а списать.
Прочие онлайновые журналы: как-то не воспринял, особенно при отсутствии
возможности списать в виде одного файла и дефицита времени..

--
------------------------
по языку REXX довольно много разного рода описаний -
 в хелпах от OS2, от русского IBM PC DOS 7.0, от Watcom VX-REXX,
 также ищите файл:
- rexx.arj - русское описание языка REXX (автор неизвестен)
------------------------
Где все это можно найти ?
на желтых и красных CD; по интернету в описанных выше и ниже местах,
на HOBBES http://www.cdrom.com;
кроме того, можно купить у продавцов лицензионных CD диск
HOBBES OS/2 от Walnut Creek, только смотрите, чтобы он был поновее -
они выходят раз в квартал.
-------------------------
А еще где может быть полезная информация ?
ищите:
- в хелпах и примерах компиляторов, народ хвалит Visual Age.
- во всевозможных INF-ах : progfaq.inf и т.п.
- в телеконференциях (эхах в терминологии FIDO):
    relcom.comp.os.os2.prog,               (OS2.PROG)
    relcom.fido.su.c-cpp.visualage,        (VISUALAGE),
- в интернетовской иерархии comp.os.os2.*
- есть фидошный OS/2 FAQ-сервер:
    Relcom/Internet адрес:  FAQ@phantom.ru
    FIDO адрес:             юзер FAQ по адресу 2:5020/32
    пошлите ему письмо с subj: OS2.prog 0 7 14 15 30 31
  (в статье 0 будет список вопросов, остальные я рекомендую)
  статью 40 вы в данный момент читаете.
- на WWW и FTP (список в 30 статье)
- Первоисточники от IBM online (6)
---------------------------------
Пожелания, замечания и новые книги ;) можно направлять мне.

SY,
"Evg.V.Kotsuba" <evgen@laser.nictl.msk.su>

-----------------------------------------------------------

Приложение:
Библиография по программированию в OS/2.

0.
"Пpогpамиpование для IBM OS/2 Warp", ДиалогМИФИ том 25-й.
Автоpы Фpоловы, Тиpаж 10000.

1.
Дж.Крэнц и др.
"Операционная система OS/2. Возможности,функции и приложения",
М.,Мир, 1991г (перевод1989)


2. РОБЕРТ ЛАФО   ПИТЕР HОРТОH  "OS/2 изнутри"
   Hаписано для OS/2 версии ниже 2.0, т.е. весьма старая
   и про PM (это так называется родной попаламный Windows) не слова,
   масса опечаток и ошибок, которые тем не менее можно найти,
   файлы называются c g_01 по g_14


Общий обзор ОS/2
Быстрое начало
Управление клавиатурой и экраном.
Процессы
Цепи
Семафоры
Директории
Файловая система
Файловая система и мультизадачность
Управление памятью
Связь между процессами
Мониторы устройств и сигналы
Маус и сигналы
Динамическое редактирование связей


3. "The Art of OS/2 Warp Programming" by Kathleen Panov,
    Larry Salomon Jr., and Arthur Panov (Wiley & Sons).

Tools
Memory Management
Multitasking
File I/O and Extended Attributes
Interprocess Communication
DLLs
Exception Handling
Interfacing with OS/2 Devices
Introduction to Windows
Window Management
Window Messages and Queues
Resources
Dialog Boxes
Menus
List Boxes
Buttons
Entry Fields
Multiline Edit Controls
Other Window Classes
Drag and Drop
Value Set
Notebook
Containers
Spin buttons
Sliders
Font and File Dialogs
Subclassing Windows
Presentation Manager Printing
Help Manager
Multithreating in Presentation Manager Application
Appendix A - Window Messages
Appendix B - References
Index

4.  статья "Пpогpаммиpование в OS/2" Дмитpий Завалишин

Тем, кто писал только для DOS
Пpоблема пеpвая: опpос клавиатуры, мыши, часы и другие мелочи
Пpоблема втоpая и втоpичная (синхронизация процессов)
Пpоблема, вызванная отсутствием пpоблем с памятью
Пpоблема с последовательными поpтами или 'где мой fossil' ?
Пpоблема с пpямым доступом к диску.
Пpоблема с пpямым доступом к экpану
DIVE: Игры по-цивилизованному, с оконным соусом
... Легко pазpешимые пpоблемы общения
Общение: пути и методы
Традиционные каналы
Именованные каналы
Именованные семафоры

5. EDM/2

Carsten Whimster             EDM Associate Editor, Book Reviewer
carsten_whimster@iqpac.com   EDM Site:     http://www.iqpac.com/
The OS/2 API Project         http://www.iqpac.com/edm2/os2api/
My Webpage    http://www.undergrad.math.uwaterloo.ca/~bcrwhims/


6. Первоисточники от IBM online

по по такому длиннющему  адресу:
 >начало<
http://www2.ibmlink.ibm.com/cgi-bin/master?xh=bVHa4f*0G9eH740USenGn9332&request=i
bmmanuals&parms=l8&xhi=usa%2emain
 >конец<

сидит вот что:

IBM Information and Services

PWS - Programmable Workstations (OS/2 V2, LAN, MMPM/2) - GUEST

ej6b4b01 - OS/2 Warp V3 Workplace Shell Programming Guide
ej6b5b01 - OS/2 Warp V3 PM Prog Ref Vol I Functions
ej6b6b01 - OS/2 Warp V3 GPI Programming Ref
ej6b7b02 - OS/2 Warp V3 Workplace Shell Programming Ref
ej6b8b01 - OS/2 Warp V3 GPI Programming Guide
ej6b9b01 - OS/2 Warp V3 Control Program Programming Guide
ej6c0b01 - OS/2 Warp V3 PM Basic Programming Guide
ej6c1b01 - OS/2 Warp V3 Control Program Programming Ref
ej6c2b01 - OS/2 Warp V3 IPF Programming Guide
ej6c4b01 - OS/2 Warp V3 Multimedia Programming Ref
ej6c5b01 - OS/2 Warp V3 Multimedia App Programming Guide
ej6c6b01 - OS/2 Warp V3 Multimedia Subsystem Programming Guide
ej6c7b01 - OS/2 Warp V3 PM Advanced Programming Guide
ej6d1b01 - OS/2 Warp Tools Ref
ej6d6b01 - OS/2 Warp V3 PM Prog Ref Vol II Msgs & Related Info
[..остальное про железо отгрызено ]
Total books = 63

все можно прочитать, HО: это какой-то фашист придумал -
довел до полного абсурда идею гипертекста, особенно с учетом длины
адреса. Hапример только оглавление для ej66c0b01 занимает больше ста кил.

[править] New API's in Warp 4

[A]: Richard Reuters (2:2433/601.11)

Here is a (uncomplete) list of new API's in Warp 4:

DosQueryThreadContext
FFSTProbe                               FFST.H
FFSTQueryConfiguration                  FFST.H
FFSTSetConfiguration                    FFST.H
LayoutCreateObject                      LAYOUT.H
LayoutDestroyObject                     LAYOUT.H
LayoutSetValues                         LAYOUT.H
LayoutQueryValues                       LAYOUT.H
LayoutTransformText                     LAYOUT.H
LayoutEditShape                         LAYOUT.H
LogOpenFile                             LFDEF.H
LogCloseFile                            LFDEF.H
LogReadEntry                            LFDEF.H
LogFormatEntry                          LFDEF.H
LogOpenEventNotification                LFDEF.H
LogCloseEventNotification               LFDEF.H
LogChangeEventFilter                    LFDEF.H
LogWaitEvent                            LFDEF.H
PrtNewPage                              PMSPL.H
PrtResetAbort                           PMSPL.H
WinDBCSIMEControl                       OS2NLS.H
WinDBCSLoadFontDriver                   OS2NLS.H
WinDBCSModeControl                      OS2NLS.H
WinDBCSQueryFDDescription               OS2NLS.H
WinDBCSUnloadFontDriver                 OS2NLS.H
DevPostEscape                           PMDEV.H
GpiBeginInkPath                         PMGPI.H
GpiCreateEllipticRegion                 PMGPI.H
GpiCreatePolygonRegion                  PMGPI.H
GpiCreateRoundRectRegion                PMGPI.H
GpiEndInkPath                           PMGPI.H
GpiQueryFontMappingFlags                PMGPI.H
GpiQueryNearestPaletteIndex             PMGPI.H
GpiQueryRasterizerCaps                  PMGPI.H
GpiQueryTabbedTextExtent                PMGPI.H
GpiResizePalette                        PMGPI.H
GpiResumePlay                           PMGPI.H
GpiSetFontMappingFlags                  PMGPI.H
GpiStrokeInkPath                        PMGPI.H
GpiSuspendPlay                          PMGPI.H
GpiTabbedCharStringAt                   PMGPI.H
PrfCreateGroup                          PMSHL.H
PrfQueryProgramCategory                 PMSHL.H
PrfQueryProgramHandle                   PMSHL.H
SplQpClose                              PMSPL.H
SplQpControl                            PMSPL.H
SplQpInstall                            PMSPL.H
SplQpOpen                               PMSPL.H
SplQpPrintSeparator                     PMSPL.H
SplQpPrint                              PMSPL.H
SplQpQueryDt                            PMSPL.H
SplQpQueryFlags                         PMSPL.H
SplQueryDriver                          PMSPL.H
SplSetDriver                            PMSPL.H
DrgQueryFormat                          PMSTDDLG.H
WinQueryClipRegion                      PMWIN.H
WinSetClipRegion                        PMWIN.H
WinNotebookButtonFromID                 WPOBJECT.H
WinWaitForShell                         WPOBJECT.H
ShlGetUserWordPtr                       WPOBJECT.H

[править] Как DOS-сессиям отдавать вpемя (замысловато)

[A]: Anton Shuko (2:5005/28.66)

Для начала небольшой экскуpс:

Году в 94м мне потpебовалось, чтобы мои дос-пpоги могли пpавильно отдавать
тики под осью. Фиды и pелкома у меня не было, не было и факов (а были ли
они тогда ? :)  Почесав pепу я нашел некий неплохой способ (о нем ниже),
котоpый пpименим не только к оси. Hо был махонький недостаток - иногда
пpи вводе pусского текста пpоскакивали английские (долгое вpемя я и юзеpы
это теpпели). Hедавно теpпению пpишел конец и я стал листать факи и тpясти
знакомых. Пpобовал ax=1680, int2f - отдает неплохо, но абсолютно не подходит
для задач котоpые чего-то делают, а интеpфейс с ними минимален - эта задача
засыпает до нажатия на клаву или до активизации мыши (кpучу в цикле
пpоцессы, пpовеpку на клаву, мышь, а затем отдаю тики - пpи отсутсвии 
активности фоновые пpоцессы вызываются 2 pаза в секунду :(  а мне иногда
нужно активизиpоваться pаз так 100 в секунду), пpи таком способе отдачи
слайсов "засыпает" мышь - в гpафической моде ее движения вялые и дискpетные.
Hlt тоже не помог - пpосто hlt, даже в цикле:
        mov     cx, 10000
l:
        hlt
        loop    l

ничего не отдавал, а если юзать:
        mov     ax, xx
        mov     dx, yy
        hlt
        db      035h
        db      0CAh
(это я по памяти пишу - мог и ошибиться)
у меня выскакивал тpап (я пишу под 16 pазpядным экстендеpом, а он два
байтика после hlt в этом pежиме тpапают), так что я даже не смог
пpовеpить насколько это эффективно.

Пpишлось мне напpячь мозги и быстpенько понять, куда деваются pусские
буковки, после чего я испpавил свой механизм и пpедлагаю его вам. :)


Механизм такой: пpогpамма всегда ждет ввода с клавиатуpы (int16, функция 0
или досовскими или C функциями) пpичем именно ждет, а не опpашивает,
есть ли там следующий символ или нет. Для того чтобы пpогpамма могла
вовpемя pеагиpовать на мышь я добавил к ее дpайвеpу обpаботчик (добавляется
какой-то функцией) в этом обpаботчике делается то что надо и ПОСЫЛАЕТСЯ
в БУФЕР КЛАВИАТУРЫ какой-то левый символ (я использую 0xFFFx ).
В буфеp посылается пpосто - есть в биосе два указателя на этот буфеp,
как пользоваться написано в литеpатуpе. И ось (2.11, 3.0, 4.0) и win и
win95 и пpосто дос это отслеживают! Пpичем как под осью, так и под
фоpточками данная пpога ждет ввода и гpамотно отдает свои тики. Для
запуска паpаллельных пpоцессов я пеpехватываю int8 - он pегуляpно запускает
цикл обpаботки событий посылкой левого кода в буфеp. Точно так же с
ком-поpтами и пpочим. Для того чтобы обеспечить непpеpывное исполнение
некотоpых пpоцессов (когда надо сожpать максимум вpемени в данный момент)
очеpедь подстегивается пpинудительной посылкой символа в буфеp клавиатуpы.
Тепеp тонкость, из-за котоpой pусификатоpы (pазные) глюкали:
если идет обpаботка int9, а в этот момент вызывается дpугое пpеpывание,
котоpое сыпет в буфеp символ, имеется веpоятность что обpаботка int9 может
завеpшиться непpавильно. Поэтому я отлавливал int9 и обpабатывал так:

void  int9(){

        keyBusy=YES;
        (*oldInt9)();
        keyBusy=NO;
}

И пока keyBusy=YES в дpугих обpаботчиках в буфеp ничего нельзя добавлять.


Метод конечно сложный, тpебует хоpошего знания пpеpываний и тpебует
некотоpой наpаботки и отладки, но если больше ничего не помогло можно
попpобовать сделать это таким обpазом.

Я без всяких пpоблем пpогpаммиpовал таймеp на 182 Гц (стаpому обpаботчику
отдавал каждый десятый тик), втыкал это в пpогу с гpафическим интеpфесом,
паpаллельными пpоцессами и активным использованем мыши, все это бегало под
осью (пpичем висело несколько таких сессий) и нагpузка на пpоцессоp была 
минимальна. Без всяких пеpеделок это ходит под win95 (и так же с минимальной 
нагpузкой) и под голым досом. Если нет необходимости таймеp лучше не
тpогать (не пеpепpогpаммиpовать частоту). У меня есть несколько демонов,
котоpые запускаются по pазным поводам и чего-то делают - остальное вpемя
они спят и никому не мешают - пульс на dx80 - по нулям. Даже когда идет
активный ввод (откpывание, пеpемещение, закpывание окошек, менюшек - это
все в гpафике - в текстовой моде загpузка минимальна) загpузка пpоцессоpа
по пульсу невысока.

ЗЫ: скоpо под ось поеду но пока бегаю под досом - стаpых наpаботок много.
Hо пока что с экстендеpом + гpафический мышиный интеpфейс + ноpмальная pабота
под осью и чикой (почти как pодная пpога) мне ноpмально живется без
всяких пеpеездов :)

[править] Как узнать, в FS ли DOS-сессия?

[A]: Alexander Perezhogin (2:5007/2.1)

 INT 2F C - OS/2 compatibility box - SWITCHING DOS TO BACKGROUND

         AX = 4001h
 Note:   called by OS/2 when the DOS box is about to be placed in the
         background and the video driver should save any necessary state
 SeeAlso: AX=4002h,AX=4005h

 INT 2F C - OS/2 compatibility box - SWITCHING DOS TO FOREGROUND

         AX = 4002h
 Note:   called by OS/2 when the DOS box is about to be placed in the
         foreground and the video driver should restore the previously-saved
         state
 SeeAlso: AX=4001h,AX=4006h

[править] Где скачать Aurora DDK?

С февраля 2004 г. DDK официально свернут. Последнюю версию можно скачать с magaupload.

Содержимое:

May  4  1998  alpbook.zip    424K  Описание ALP (в Toolkit'е новее)
May  4  1998  ap2book.zip      9K  Описание Audio Test Tool
Feb  3  2003  cdrom.zip      526K  Исходники OS2CDROM/IBMIDECD/...
Sep 12  2002  combas32.zip   899K  Среда компиляции для Aurora (KEE+new DH_*)
Feb  4 13:21  combase.zip   4837K  Общая среда компиляции (для 9.xxx)
Feb  4 13:22  comdbcs.zip   2636K  Среда компиляции DBCS'ных компонентов
Feb  4 13:29  commme.zip    1156K  Среда компиляции драйверов под MMPM/2
Nov 17 14:27  comprint.zip  3972K  Среда компиляции PM'ных драйверов принтера
Feb  4 13:32  comvideo.zip  5452K  Среда компиляции видеодрайверов/BVH/SCREEN*
Feb  4 13:35  comwpsh.zip    779K  Среда компиляции для *.QPR
Feb  3  2003  dasd.zip      1034K  Исходники IBM1S506/IBM1FLPY/OS2DASD...
Sep 12  2002  dasd32.zip     175K  Исходники 32-bit OS2DASD.DMD (Aurora).
May  4  1998  dasdbook.zip   285K  Описание интерфейсов DASD (Merlin-only)
Feb  4 13:22  dbcs.zip      4712K  Исходники DBCS (поддержка ввода иероглифов)
Feb 12 13:32  ddsc      Directory  Архив материалов техподдержки (1993-2001)
May  4  1998  ddtt.zip       267K  Device Driver Test Tool
May  4  1998  dispbook.zip   571K  Описание PM-видеодрайверов (PMI)
Sep 23  1999  gradbook.zip   268K  Описание PM-видеодрайверов (GRADD)
Feb  4 13:27  ibmtool.zip     67K  IBM Test Tool для драйверов NIC
Feb  6 08:44  icatos2.zip   4952K  ICAT Debugger v 4.06 от 24/09/2002
May  4  1998  inbook.zip     381K  Описание архитектуры I/O-драйверов (без USB)
Feb  4 13:26  inout.zip     5027K  Исходники USB/Kbd/Mouse/COM/PCMCIA... + VDD
Jan 23  2001  io.zip          58K  Материалы по I/O-драйверам с DDSC
May  4  1998  ipfcbook.zip   233K  Описание формата самого себя (IPF)
Feb  4 13:26  irda.zip       512K  Исходники IrDA
May  4  1998  masm60.zip    2659K  MASM v 6.00
May  4  1998  mmpmbook.zip   488K  Описание интерфейсов MMPM/2 (SH, ...)
Feb  4 13:29  mmpmdd.zip    3144K  Исходники драйверов видео/аудио под MMPM/2
Feb  4 13:29  mmpmetc.zip    236K  Поддержка MPEG
Feb  4 13:26  mouse.zip      246K  Исходники драйвера "Single Mouse"
May  4  1998  msc60.zip     3431K  MS C v 6.00 beta for DDK
Feb  4 13:27  nddk.zip       182K  Тестовый комплект для сетевых плат
Feb  4 13:27  ndiss.zip       11K  Спецификация NDIS
Jan 23  2001  network.zip     25K  Материалы DDSC по сетевым драйверам
Feb  4 13:27  nicsample.zip  204K  Пример драйвера сетевой платы
Jan 23  2001  other.zip      297K  Прочие материалы DDSC
Feb  4 13:31  pccard.zip    1604K  Исходники драйверов для Cardbus (не PCMCIA)
Sep  9  1998  pddbook.zip    529K  Общее руководство по драйверам
May  4  1998  pdrbook.zip   1132K  Общее описание драйверов для графустройств
May  4  1998  penbook.zip    107K  Описание драйверов светового пера/стилуса
Nov 17 14:27  print.zip     9054K  Исходники PM'ных принтерных драйверов
Jan 23  2001  printer.zip     32K  Материалы DDSC по принтерным драйверам
May  4  1998  prntbook.zip   337K  Описание принтерных драйверов
May  4  1998  tcapm.zip      738K  Тестовый комплект для APM
May  4  1998  tccomm.zip     530K  Общий тестовый комплект для драйверов
Feb  4 13:32  tcdisp.zip    1836K  Тестовый комплект для видеодрайверов
May  4  1998  tcio.zip        87K  Тестовый комплект для I/O-драйверов
Feb  4 13:29  tcmm.zip       793K  Тестовый комплект для драйверов MMPM/2
Feb  4 13:29  tcmmdata.zip 46278K  Мультимедийный фарш для TCMM.ZIP
Feb  4 13:35  tcprt.zip     1514K  Тестовый комплект для принтерных драйверов
May  4  1998  tcstor.zip     819K  Тестовый комплект для драйверов DASD
Feb  4 13:19  tools.zip      580K  ALP, NMAKE, скрипты для установки C/MASM...
Feb 12  1999  useddk.zip      99K  "Using your DDK" - введение
May  4  1998  vddbook.zip    358K  Описание virtual device-драйверов для MDOS
Feb  4 13:32  video.zip     7607K  Исходники видеодрайверов
Jan 23  2001  videoqa.zip    111K  Материалы DDSC по видеодрайверам
Feb  4 13:27  wedge.zip       67K  Wedge Test Tool для NIC
Feb  4 13:35  wpsh.zip       362K  Драйвера очередей и конверторов для WPS
Jun 30  1998  wpshell.zip    344K  Старая версия WPSH.ZIP

Полезные дополнения к комплекту:

1. Netlabs: DDK/2 (для Watcom), USBRESMG/LIBUSB by Markus Montkowski

:pserver:guest@www.netlabs.org:/netlabs.cvs/usb

2. Интерфейсы USB-стека: http://os2power.dnsalias.com/usb.zip 3. Собственные драйверные хелперы и подсистемы - DR/2 (dr2last.zip), MWDD32 (32drv170.zip) 4. Хидеры для внутриядерных интерфейсов (VMM и т.д.):

   - Odin -> Win32K
   - EDDKBE.ZIP или COMOSF.ZIP (in selected theatres)
   - Redbook #SG24-4640, KGUIDE20.INF (where available) - в качестве описания

5. OpenGL DDK - in selected theatres:

   COMOGL.ARJ   2725783 28-Apr-98 OpenGL build environment
   OGL.ARJ       715858 05-May-98 OpenGL source code
   OGLBIN.ARJ   4754784 05-May-98 OpenGL run-time library
   OGLBOOK.ARJ   359365 10-Oct-01 OpenGL documentation
   TCOGL.ARJ     287317 28-Apr-98 OpenGL test suite

6. IFS Kit - берется на Hobbes'е (ifsinf.zip), авроровские хидеры в OpenJFS, доступные примеры IFS - FAT32/JFS/Ext2 (локальные), RAMFS (дистанционная).

7. PMWINP.H (where available) - писателям presentation-драйверов

8. OS/2 v 2.x OEMI distribution - PerfView, ABIOS, OEMHLP

9. LXAPI32.SYS by Stefan Milcke для портирования I/O-драйверов из Linux

[править] Как полyчить window handle для os/2 window session?

[A]: Rinat Sadretdinow (2:5020/620)

SWBLOCK содержит в себе массив SWENTRY, каждый из которых содержит в
себе SWCNTRL, который в свою очередь содержит поле hwnd. Ага?

[A]: Sergey Eremin (2:451/1)

 Q> вот тут возник вопpос: каким обpазом получить список активных
 Q> задач ? собственно, это вопpос не мой, а автоpа OS/2 Commander'а
 Q> :) он сказал, что сделает task switcher (как в Capitan Nemo),
 Q> если ему pасскажут как получить этот самы список.

Вот сейчас выдpал кусочки из dv2... Пускай делает. Copyright он может не
вставлять, но thanx в доке может написать :)

-------------------------- >% swl_exam.cpp %< -----------------------
#define  INCL_DOSPROCESS
#define  INCL_DOSINFOSEG
#define  INCL_WINSWITCHLIST
#define  INCL_NOCOMMON
#define  INCL_SUB
#include <os2.h>
#include <string.h>
#include <stdio.h>

/**************************************************************
 Written by Sergey Eremin. (c) 1994
 2:451/1@fidonet
 se@prior.belpak.grodno.by
 **************************************************************/

static PSWBLOCK pswb;
static LONG current;

enum { ATTR_BORDER=0x07, ATTR_NORMAL=0x17, ATTR_SELECT=0x71 };

int count( void )
{
  return (pswb) ? pswb->cswentry : -1;
}

int fill_session_list( void )
{
   ULONG cbItems,
         all_cbItems,
         cbBuf;
   PSWBLOCK tmp_pswb;

   if (pswb)
      delete pswb;

   //
   // get all switch list entries
   all_cbItems = WinQuerySwitchList( 0, 0, 0);
   cbBuf = (all_cbItems * sizeof(SWENTRY)) + sizeof(HSWITCH);
   tmp_pswb = (_SWBLOCK*) new char[cbBuf];
   WinQuerySwitchList( 0, tmp_pswb, cbBuf);
   //
   // count VISIBLE entries
   cbItems = 0;
   for ( int i=0; i <= tmp_pswb->cswentry; i++ )
      if ( tmp_pswb->aswentry[i].swctl.uchVisibility == SWL_VISIBLE )
         cbItems++;
   // allocate memory for visible entries
   cbBuf = (cbItems * sizeof(SWENTRY)) + sizeof(HSWITCH);
   pswb = (_SWBLOCK*) new char[cbBuf];
   //
   // copy only visible entries to our array
   int k = i = 0;
   do {
      if ( tmp_pswb->aswentry[i].swctl.uchVisibility == SWL_VISIBLE )
         memcpy( (void*)(&pswb->aswentry[k++]),
                 (void*)(&tmp_pswb->aswentry[i]),
                 sizeof(SWENTRY) );
      i++;
      }
   while ( all_cbItems-- );
   pswb->cswentry = cbItems;
   current = 0;
   delete tmp_pswb;
   return 1;
}

void draw_list( void )
{
   BYTE abCell[2];
   char temp[120];
   int  usLeft,
        usTop,
        len,
        menuWidth = 0,
        menuHeight = 0;
   BYTE bAttr;

   int entries = count();
   int i = 0;
   do
      {
      if ((len=strlen(pswb->aswentry[i++].swctl.szSwtitle)) > menuWidth)
         menuWidth=len;

      menuHeight++;
      }
   while ( entries-- );

  /* Leave space for the border */

  menuWidth += 4 + 3;
  menuHeight += 2;

  usLeft= 0; usTop= 0;

  /* Draw the top border */

  abCell[1]=ATTR_BORDER;
  abCell[0]='▐'; VioWrtNCell(abCell, 1, usTop, usLeft, 0);
  abCell[0]='▌'; VioWrtNCell(abCell, 1, usTop, usLeft+menuWidth-1, 0);
  abCell[1]=ATTR_NORMAL;
  abCell[0]='▀'; VioWrtNCell(abCell, menuWidth-2, usTop, usLeft+1, 0);
  usTop++;

  /* Draw the switch entries */
  for (i=0; i < count(); i++)
  {

    /* left border */

    bAttr=ATTR_BORDER;
    VioWrtCharStrAtt("▐", 1, usTop, usLeft, &bAttr, 0);

    /* Draw the application name */

    bAttr=(BYTE)((i==current) ? ATTR_SELECT : ATTR_NORMAL);
    sprintf(temp, " %-*s %2d ", menuWidth-4-3,
            pswb->aswentry[i].swctl.szSwtitle, i );
    VioWrtCharStrAtt(temp, menuWidth-2, usTop, usLeft+1, &bAttr, 0);

    /* right border */

    bAttr=ATTR_BORDER;
    VioWrtCharStrAtt("▌", 1, usTop, usLeft+menuWidth-1, &bAttr, 0);

    /* draw shadow */

    bAttr=7;
    VioWrtNAttr(&bAttr, 1, usTop, usLeft+menuWidth, 0);

    usTop++;
  }

  /* bottom border */
  abCell[0]='▄';  VioWrtNCell(abCell, menuWidth-2, usTop, usLeft+1, 0);
  abCell[1]=ATTR_BORDER;
  abCell[0]='▐';  VioWrtNCell(abCell, 1, usTop, usLeft, 0);
  abCell[0]='▌';  VioWrtNCell(abCell, 1, usTop, usLeft+menuWidth-1, 0);

  /* Draw bottom of shadow */

  abCell[1]=7;
  abCell[0]=' ';  VioWrtNAttr(&bAttr, 1, usTop, usLeft+menuWidth, 0);

  bAttr=7;        VioWrtNAttr(&bAttr, menuWidth, usTop+1, usLeft+1, 0);

}

/*
 for switching to the task in list use
 ...
 WinSwitchToProgram( pswb->aswentry[current].hswitch );
 ...
*/

void main(void)
{
  fill_session_list();
  draw_list();
  delete pswb;
}
---------------------- >% swl_exam.cpp %< --------------------------------

[править] Отдача таймслайсов. Паскаль с ассемблером.

[A]: Vadim Rumyantsev (2:5030/301)

Более новая версия с пофиксенным зависанием при редком стечении обстоятельств
в полночь в ДОСе :) И ещё чуть-чуть список операционных систем расширен.

──────────────────────────────────[Cut Here]──────────────────────────────────

{ Written by Vadim Rumyantsev,  2:5030/301. }
{ Generic DELAY unit -- release  timeslices }
{ if under OS/2 2.0, Windows 3.0, DesqView, }
{ DoubleDOS and probably DOS 5.0 (?!), else }
{ do nothing.                               }
{ It is assumed that program  receives time }
{ quantums every day...  so, don't run this }
{ unit on slow systems!   ;-)               }
{ Virtual Pascal compatible now!            }
{ Delphi 2.0 compatible now.                }
{ You may use this **without restrictions** }



UNIT USLDelay;

{$I-}

INTERFACE



type
  OS_Type = (OS_MSDOS, OS_DOUBLEDOS, OS_TOPVIEW, OS_DESQVIEW,
             OS_OS2_1, OS_OS2_2, OS_WINDOWS, OS_WIN32, OS_MACOS);

const
  AccessDenied : set of byte = [5 {$IFNDEF DOS} , 32 {$ENDIF} ];

var
  Running_OS_Name : string;

{$IFDEF OS2}
const
  Running_OS = OS_OS2_2;
{$ENDIF}
{$IFDEF WIN32}
const
  Running_OS = OS_WIN32;
{$ENDIF}
{$IFDEF MSDOS}
var
  Running_OS : OS_Type;
{$ENDIF}
{$IFDEF DPMI}
var
  Running_OS : OS_Type;
{$ENDIF}


procedure Delay (n : longint);



IMPLEMENTATION

{$IFDEF OS2}

uses {$IFDEF VIRTUALPASCAL} Os2base {$ELSE} Doscalls {$ENDIF};

var
  Buf : packed array [5..12] of longint;
  Sgn : string;
  f : file;
  fp : longint;
  sp : longint;
  p1, p2 : integer;

{$ENDIF}

{$IFDEF WIN32}

uses SysUtils, Windows;

const
  UnknownPlatform = 'Win32';
  UnknownWin95    = 'Win9x';

var
  VersionInfo : TOsVersionInfoA;
  vb : string [10];

{$ENDIF}

{$IFDEF MSDOS}

uses Dos;

{ Define Seg0040 for backward compatibility with TP 4.0 .. TP 6.0 }

const
  Seg0040 = $0040;


var
  r : Registers;
  dosvh, dosvl : byte;
  osvh, osvl : byte;
  vendor : string [3];

  {$DEFINE DOSMODE}

{$ENDIF}

{$IFDEF DPMI}

uses Dos;

{ Define Seg0040 for backward compatibility with TP 4.0 .. TP 6.0 }

var
  r : Registers;
  dosvh, dosvl : byte;
  osvh, osvl : byte;
  vendor : string [3];

  {$DEFINE DOSMODE}

{$ENDIF}


function Version (vh, vl : longint) : string;

var
  vhs, vls : string [2];

begin

  str (vh, vhs);
  str (vl, vls);
  if length (vls) = 1 then
    vls := '0' + vls;
  if vls [length (vls)] = '0' then
    dec (vls [0]);
  Version := vhs + '.' + vls

end;


{$IFDEF OS2}

procedure Delay;

begin

  if DosSleep (n) <> 0 then;

end;

BEGIN

  Running_OS_Name := 'OS/2';

  if DosQuerySysInfo (5, 12, Buf, sizeof (Buf)) = 0 then begin

    FileMode := open_access_ReadOnly + open_share_DenyNone;
    assign (f, chr (64 + Buf [5]) + ':\OS2KRNL');
    reset (f, 1);
    seek (f, $3C);
    blockread (f, fp, 4);
    seek (f, fp+$88);
    blockread (f, fp, 4);
    seek (f, fp);
    blockread (f, Sgn [0], 1);
    blockread (f, Sgn [1], length (Sgn));
    p1 := pos ('@#', Sgn);
    p2 := pos ('#@', Sgn);
    if (IoResult = 0) and
       (p1 <> 0) and (p2 <> 0) and (p2 > (p1+2))
    then begin
      Sgn := copy (Sgn, p1+2, p2-p1-2);
      p1 := pos (':', Sgn);
      if p1 <> 0 then
        Sgn := copy (Sgn, p1+1, 255);
      Running_OS_Name := Running_OS_Name + ' Revision ' + Sgn
    end
    else begin
      Buf [11] := Buf [11] div 10;
      if (Buf [11] = 2) and (Buf [12] >= 30) and (Buf [12] < 90) then begin
        Buf [11] := Buf [12] div 10;
        Buf [12] := Buf [12] mod 10
      end;
      Running_OS_Name := Running_OS_Name + ' ' + Version (Buf [11], Buf [12])
    end;

    close (f);
    if IoResult <> 0 then;

  end;

{$ENDIF}


{$IFDEF WIN32}

procedure Delay;

begin

  Sleep (n);

end;

BEGIN

  with VersionInfo do begin
    dwOsVersionInfoSize := sizeof (VersionInfo);
    if not GetVersionExA (VersionInfo) then
      Running_OS_Name := UnknownPlatform
    else begin
      str (dwBuildNumber and $FFFF, vb);
      case dwPlatformId of
        VER_PLATFORM_WIN32_WINDOWS:
          if (dwMajorVersion = 4) and (dwMinorVersion = 0) then
            Running_OS_Name := 'Windows 95'
          else if (dwMajorVersion = 4) and (dwMinorVersion = 10) then
            Running_OS_Name := 'Windows 98'
          else if (dwMajorVersion = 4) and (dwMinorVersion = 90) then
            Running_OS_Name := 'Windows Me'
          else
            Running_OS_Name := UnknownWin95;
        VER_PLATFORM_WIN32_NT:
          if (dwMajorVersion = 5) then
            Running_OS_Name := 'Windows 2000'
          else
            Running_OS_Name := 'Windows NT'
        else
          Running_OS_Name := UnknownPlatform
      end;
      Running_OS_Name := Running_OS_Name + ' ' +
                         Version (dwMajorVersion, dwMinorVersion) +  '/' + vb;
      if szCsdVersion [0] <> #0 then
        Running_OS_Name := Running_OS_Name + ' ' + StrPas (@szCsdVersion [0])
    end
  end;

{$ENDIF}


{$IFDEF DOSMODE}

procedure Delay (n : longint);

const
  TicksPerDay = 1572480;

var
  DelayQnt : longint;
  DoneTime : longint;
  LastTime : longint;
  ThisTime : longint;
  DateFlag : boolean;
  nh, nl   : word;

begin

  if Running_OS = OS_OS2_2 then begin
    {$IFDEF VER70}
      nh := n shr 8 shr 8;
    {$ELSE}
      nh := n shr 16;
    {$ENDIF}
    nl := n and $FFFF;
    asm
      mov    dx, nh;
      mov    ax, nl;
      hlt;
      db     $35,$CA
    end;
    exit
  end;

  DoneTime := MemW [Seg0040:$006C];                  { What time is it?     }
  DelayQnt := round (n / 1000 * 18.2);               { How many ticks wait? }
  DateFlag := (DoneTime + DelayQnt) >= TicksPerDay;  { Skip midnight?       }
  DoneTime := (DoneTime + DelayQnt) mod TicksPerDay; { When we'll finish?   }

  LastTime := MemW [Seg0040:$006C];

  while (DateFlag or (LastTime < DoneTime)) do begin

    { probably fixed damned midnight freeze }

    ThisTime := MemW [Seg0040:$006C];
    if ThisTime < LastTime then   { A new day! }
      DateFlag := false;
    LastTime := ThisTime;

    { Release timeslice }

    case Running_OS of

      OS_TOPVIEW, OS_DESQVIEW:
        begin
          r.AX := $1000;
          Intr ($15, r)
        end;

      OS_DOUBLEDOS:
        begin
          r.AH := $EE;
          if DelayQnt > 767 then
            r.AL := $FF
          else
            r.AL := DelayQnt div 3;
          dec (DelayQnt, r.AL * 3);
          Intr ($21, r)
        end

      else
        begin
          r.AX := $1680;
          Intr ($2F, r)
        end;
    end
  end

end;



BEGIN

  r.AX := $3000;
  MsDos (r);
  dosvh := r.AL;
  dosvl := r.AH;
  if r.BH = $00 then
    vendor := 'PC'
  else if r.BH = $66 then
    vendor := 'PTS'
  else if r.BH = $FF then
    vendor := 'MS'
  else
    vendor := 'OEM';

  { Check for Novell NetWare to eliminate conflict with DoubleDOS detection }

  r.AX := $DC00;
  Intr ($21, r);

  if r.AL = 0 then begin
    { NetWare is not installed, so we can check for DoubleDOS }
    r.AX := $E400;
    Intr ($21, r);
    if r.AL <> 0 then begin   { Yes, DoubleDos }
      Running_OS := OS_DOUBLEDOS;
      Running_OS_Name := 'DoubleDos';
      exit
    end;
  end;

  { Check for DesqView }

  r.AX := $1022;
  r.BX := $0000;
  Intr ($15, r);

  if r.BX <> 0 then begin   { Yes, DesqView or TopView }
    if r.BX <> $0A01 then begin
      Running_OS := OS_TOPVIEW;
      Running_OS_Name := 'TopView ' + Version (r.BL, r.BH)
    end
    else begin
      Running_OS := OS_DESQVIEW;
      r.CX := $4445;   { 'DE', Serg Projzogin uses it }
      r.DX := $5351;   { 'SQ', Serg Projzogin uses it }
      r.AX := $2B01;
      Intr ($21, r);
      Running_OS_Name := 'DesqView ' + Version (r.BH, r.BL)
    end;
    exit
  end;

  { Check for OS/2 }

  r.AX := $4010;
  r.BX := $0000;
  Intr ($2F, r);

  if r.BX <> 0 then begin   { Yes, OS/2 }
    if r.BH >= 20 then
      Running_OS := OS_OS2_2
    else
      Running_OS := OS_OS2_1;
    Include (AccessDenied, 162);
    if (r.BH <> dosvh) or (r.BL <> dosvl) then begin { DOS VMB under OS/2 }
      osvh := r.BH div 10;
      osvl := r.BL;
      if (osvh = 2) and (osvl >= 30) and (osvl < 90) then begin
        osvh := osvl div 10;
        osvl := osvl mod 10
      end;
      Running_OS_Name := vendor + ' DOS ' + Version (dosvh, dosvl) +
                         ' under OS/2 ' + Version (osvh, osvl);
      exit
    end;
    dosvh := dosvh div 10;
    if (dosvh = 2) and (dosvl >= 30) and (dosvl < 90) then begin
      dosvh := dosvl div 10;
      dosvl := dosvl mod 10
    end;
    Running_OS_Name := 'OS/2 ' + Version (dosvh, dosvl);
    exit
  end;

  r.AX := $1600;
  Intr ($2F, r);

  if r.AL <> 0 then begin   { Yes, Windows }
    Running_OS := OS_WINDOWS;
    if r.AX = $0004 then
      Running_OS_Name := 'Windows 95'
    else if r.AX = $0A04 then
      Running_OS_Name := 'Windows 98'
    else if r.AX = $5A04 then
      Running_OS_Name := 'Windows Me'
    else
      Running_OS_Name := 'Windows ' + Version (r.AL, r.AH);
    exit
  end;

  Running_OS := OS_MSDOS;
  Running_OS_Name := vendor + ' DOS ' + Version (dosvh, dosvl);

{$ENDIF}

END.

──────────────────────────────────[Cut Here]──────────────────────────────────

[править] Сопоставление с шаблоном. Звёздочки, вопросики. Паскаль.

[A]: Vadim Rumyantsev (2:5030/301)


UNIT UslPatrn;



INTERFACE



function MatchLineOk (pattern, line : string) : boolean;
function MatchFileOk (pattern, name : string) : boolean;



IMPLEMENTATION



uses Dos;



function MatchLineOk;



function SubOk (ppos, lpos : byte) : boolean;

begin

  if ppos > length (pattern) then
    SubOk := lpos > length (line)
  else if lpos > length (line) then
    SubOk := (pattern [ppos] = '*') and SubOk (ppos+1, lpos)
  else if pattern [ppos] = '*' then begin
    SubOk := false;
    for lpos := length (line) + 1 downto lpos do
      if SubOk (ppos+1, lpos) then begin
        SubOk := true;
        break
      end
  end
  else
    SubOk := ((pattern [ppos] = '?') or
              (pattern [ppos] = line [lpos])) and
             SubOk (ppos+1, lpos+1)

end;



begin

  MatchLineOk := SubOk (1, 1)

end;



function MatchFileOk;

var
  pd, nd : DirStr;
  pn, nn : NameStr;
  px, nx : ExtStr;

begin

  FSplit (pattern, pd, pn, px);
  FSplit (name,    nd, nn, nx);

  MatchFileOk := ((pd = ) or (pd = nd)) and
                 MatchLineOk (pn, nn) and
                 MatchLineOk (px, nx)

end;



END.

[править] class Buffer - "резиновый буфер"

[A]: John Gladkih (2:5051/16)

--- UUEncode - Start - buffer.zip - 1347 Bytes -
begin 644 buffer.zip
M4$L#!!0````(`'%-D"$JS'#W-`,``&8)```*````8G5F9F5R+F-P<*U574_;
M,!1]'A+_P8!$$M*BM&-C:TBEL3$)B3VQM]*'D#C$74BJQ!U%T/^^>Z^=U&F;
MH4E[<G)][M<YU_:1R*-L$7-V4<DX$_>GZ7A_[Z@Q/O+'HGPFHV$^O%\D"2]/
MTT,T5S*4(F)1&I8LY<M;68K\83)E`3OT!L/W9Q\^GG_Z_.7RZ[>K[X<^.ER2
M]VBD5IN)7+*H1TO,'#;:WV,L6I0W/+=9Q)P>_L^+RF:>_HEY)D,;P?M[+V@0
MB<T.R(HFQC0$2AAXE%)#5-0:H_\"!=:X2I9@R?D3-32I05,?-TM><6D[\+U"
M].]"Q*SN9KZ0U[DL;$5$E+:*@_*#P,S^HDM`[$F1Q38E=G01FV6PN@Y7]35M
M<"!0-'\F[QZ#.+VZ8,=O`%@S`ERUU6->3_.SSJ>]W#49FD4N.<8EPZJA:((=
MN2Y#E:.TBP\;"'L0E>2ETGC-2?4D9)3:VD1TD.IAQ9DW4LD;0KVFF?N2A[]\
M`VO=Y=:H<Z^T-D-9K];.8#%/PD4F-1P5B](+;SGTV.LK?(Z]Y7E2CXV6SHQZ
M=[<.:]J7.\WK0\)LB#T^<XZ]I9<`F7\'1ZF)4\B56GA6\2U7G!Q(X.BPJPZ5
M5'A#*S64-(]:KJ2`8^J3S5_'/[%QJ%R(SSJ/Q-6/V^NW0[?W83`\QX<E.*&Q
MA@&C\75K!90^06!-+:4/?*ZL;GUPRK:9-:P&B[O%YTT>DOI?!^'_*/ZVWATZ
M`'EB?B-BN&QKVMN,$\`>.'YK"\_L#*50P]96"C<%Z20NX"Z`I:T/A=QB2N],
MQ/0@H+-8;P#BG7()&%[9^#.9N2Y>,,JA(6K5R<0NG_H&GAT$4&;K\C6OQAG=
MBH#HSQJN$1^P6??AH8)_EJ'(=C&K&**80]8B$<@:!QX[/M9E!L@%&/O]!H<E
MDZOH#\9>S9-9L7`'3<T`:CQ5U<(=[AP%_8+I6A76HPZ-V!37>$>VPV0\D;>I
M2*1ZO=/BJ?7<P?^X81LID8LRIRQKN33.D&7K/<,V`:)ZI!Q&C_T`W3=+=V'+
M*+]/P>L6L-2Z@V+.RU`6Y62J6A!YS)>M)L@R#K;Z8/W!1BO:#F%L$A0=IWC$
MDT2E_@-02P,$%`````@`'4V0(;0(R`D]`0``=@(```@```!B=69F97(N:'51
M36O"0!"]!_(?1KPD14%OI>*A@E)!+[4]%)&09F?-0+H;-I.V5NQO;W:SK4;H
M90_O:^;-]DE"3Z`DA2)*UB_)['FQF#\F#W$8A$&_9>"2L'A6I%4%LUI*-&%P
M#`.`BKXP8<AJLT(U@%)7`Q!8<#JQAK)^+2B[L\(L3PW<5&P<`3XE`E(,%:>&
M&__T=C1P@$M8*N+I>`3QQ.J_O2&&HZ61$6P8G-JX=TT"RIJ7BG74#LMR;_WE
MVF%=N,F@\LFD5-CL*WQ%HHLV(9N&4/OHW.=JR'R]6?[#&JR0+^,*E+S)2?K-
M<OTQ'3M#=XU[HVLE7/.K=;MKVEN`2\*WD@_.8)!KHZ#7"+>CG9?X3RM0[3F_
ME#7?YR7GZ;,#H].0C*P`8OL.AW^GMP-UB29E;;:[M@HI@9^NRLG5Z:,2)'\`
M4$L!`A4&%`````@`<4V0(2K,</<T`P``9@D```H``````````0`@`("!````
M`&)U9F9E<BYC<'!02P$"%084````"``=39`AM`C("3T!``!V`@``"```````
J```!`"``@(%<`P``8G5F9F5R+FA02P4&``````(``@!N````OP0`````
end
size 1347

[править] Скомпиленная TP 6.0 программка дает 100% загрузку мерлина

[A]: Alexander Samuylov (2:5030/39)

#include <dos.h>
void interrupt ( *OldInt28)(void);
void interrupt int28(void)
{
    OldInt28();
    enable();
    _AX=0x1680;geninterrupt(0x2f);
}
void main(void)
{
    OldInt28 = getvect(0x28);
    setvect(0x28, int28);
   _dos_keep(0, (_SS + (_SP/16) - _psp));
}

[править] Мини-FAQ по AVIO

[A]: Serge Ivanov (2:5000/7.22)

Q: Как получить список шpифтов, доступных для AVIO?
A:  Это уже обсуждалось здесь и было найдено единственно пpавильное pешение:
---
Я pазобpался. Это должно делаться не чеpез VioQueryFonts(), а чеpез
DevEscape(hdc, DEVESC_QUERYVIOCELLSIZES, 0, 0, &dataLen, (PBYTE)data);
а зачем вообще нyжен VioQueryFonts() - хз.

---
Q: Как вычислить pазмеp AVIO-окна.
A:  Размеp шpифта можно узнать чеpез VioGetFont.  Поскольку это эмуляция
text-mode никаких межсимвольных/межстpочных пpомежутков там _нет_.

Q:  Какими могут быть pазмеpы AVIO-окна? Как их изменять?
A:   Размеpы по любой из осей могут быть любыми, огpаничение накладывается на
объем памяти, тpебуемый для сохpанения буфеpа.  Поскольку Vio/Avio интеpфейс
16-битный, то как и следовало ожидать pазмеp буфеpа не может пpевышать 64Kb.
    Изменить pазмеp окна нельзя.  Я у себя делал так:  создавал новый буфеp
(VioCreatePS -> VioAssociate -> VioSetDeviceCellSize -> VioGetBuf)  копиpовал
содеpжимое и убивал стаpое окно.

Q: Как получить доступ к физическому видеобуфеpу?
A: Пpимеpно так:
---
 VIOPHYSBUF  phys;
PUCHAR    __vbuf0;

 phys.pBuf = (PBYTE)0xA0000ul;
 phys.cb   = 65536;

 if((rc = VioGetPhysBuf(&phys, 0)) != 0)
    return rc;

 __vbuf0 = MAKEP(phys.asel[0], 0);  /* возможно вы забывали делать это */
---

Q: Где пpо это пpочитать?
A: Частично в prcp.inf (скоpее всего это стандаpтная дока от стаpой (1.3) оси). 
Частично у Петцольда.

Если еще что не понятно - спpашивайте.

ЗЫ: Джон, pазмеpы фpэйма на основании pазмеpов клиента (и обpатно) вычисляются
функцией WinCalcFrameRect. Беусловно, окно уже должно быть создано.

[править] Как сделать COPY file CON | MORE

[A]: Sergey Ayukov (asv@crydee.sai.msu.ru)

Q: Хоpошо, тогда скажите мне чем отличаются CON и stdout, или всем

A: не может быть, чтобы "всем", - на консоль-то попадает...

Q: ну тогда ткните меня носом, как чеpез DosWrite в stdout написать и где
   пpо это в тулките написано.

A: DosWrite (1, ...) если я правильно понимаю. Тулкит у меня не установлен,
   поэтому не знаю, где там написано.

Q: Пpавильно ли будет тогда такое утвеpждение:
   если где-то в пpогpамме стоит
    char *file;
   [...]
    fp = fopen(file,...);

то чего бы мы не писали в file, fp всегда будет отличаться от stout,

A: Да. stdout - это хэндл, открытый runtime и равный 1. Причем если в
   командной строке задано перенаправление, то открывается не CON (!),
   а пайп или через чего там это перенаправление сделано (в DOS -
   временные файлы). Если хочется, потом его можно переоткрыть (см. dup2()).
   и, если пpогpамма имеет интеpфейс командной стpоки, чеpез котоpый
   пеpедается file, то для откpытия stdout нам нужен отдельный ключик и
   констpукция вpоде

     int is_stdout = ключик есть  ? 1 : 0;
     if(is_stdout)
           fp = stdout;
     else
           fp = fopen(file,...);
    .....
     if(!is_stdout)
          fclose(fp);

   Hаверное, это один из самых простых путей. Более логичным будет (раз уж
   пошел разговор про stdout) сделать по умолчанию вывод в stdout, а при
   необходимости перенаправлять его.

Q: как сделать "copy file stdout" ?

A: type file

   cat file

Q: и чего же будет, если файл двоичный ?

A: Будет то, что файл при этом попадет на экран как есть. Однако если
   сделать 'cat cmd.exe >cmd1.exe', то cmd1.exe будет идентичен cmd.exe,
   а с 'type.cmd.exe >cmd1.exe' такой фокус не пройдет.

[править] About priority levels in a nutshell

[A]: Peter Knapper (3:772/1)

 Q> Aha...there's my problem. So, LOWER Priority numbers are HIGHER Priority?

Nope, lower = lower.....;-) Actually the lowest (and default) value is 1, BUT
before you start tinkering with this it may be useful to understand what affect
the ymay have. Here is an overview of how OS/2 processes are categorised.

OS/2 provides 2 main methods for allowing a PROCESS to control how OS/2 services
that processes needs, as a PRIORITY CLASS and a LEVEL within that CLASS, however
not all PRIORITIES have levels... Confused? There is a logical reason why...

There are 4 PRIORITY classes for OS/2 programs (lets leave device drivers, etc
out of this, we are only talking about applications here). NOTE: Here the term
"WINDOW" includes full screen tasks, they are actually "Full Screen Windows" in
the system, similar to a Window on the Desktop... In decending order of
importance -

 - Time Critical
   This is best used for sections of code that require very close
   interaction with other components within the machine. A good
   example is a Data communications application for processing FAX
   messaging, the FAX protocol requires time dependant responses so
   applications that "talk FAX" need CPU time NOW, so the probably
   use this PRIORITY. A CLASS 1 FAX puts this processing in the S/W
   rather than the modem so it is most dependant on getting CPU
   time. A CLASS 2 FAX puts some of the critical parts back in the
   modem, so the applicaiton does not need to be so demanding on
   CPU time. Moral, always go for CLASS 2 capable FAX devices
   wherever possible.

 - Foreground
   When a window on the desktop is the ACTIVE window, then it is at
   this PRIORITY. IMPORTANT: Because only 1 WINDOW can be the ACTIVE
   window at a time, there is no point in using a LEVEL value here,
   and in fact althjough it can be specified, it is ignored whenever
   the Window is ACTIVE.

 - Regular
   Windows that are not the ACTIVE window, normally reside at this
   priority LEVEL. These applications can select a LEVEL that will
   be used whenever they are NOT the ACTIVE Window.

 - Idle
   Tasks that perform "tidy up" tipe functions and are not dependant
   on having processor time available. An example here would be an
   application that displays CPU time usage, to know how much time
   everything else is using, it would run at the LOWEST possible
   level and thereby see how much processing power was left over.

So you can see how a LEVEL may or may not affect applications with a different
PRIORITY, and LEVEL only applies when that task is NOT the foreground task.

[править] OS/2 vs. NT: paging subsystem

[A]: Jonathan de Boyne Pollard (2:257/609.3)

It's worth noting some interesting things about Windows NT when compared to
OS/2 Warp in this respect.  The "portable executable", PE, format for
executable files used in Win32 *does* contain an exact image in the file of the
page as it is to be loaded into memory.  When Windows NT demand loads a page,
it doesn't need to uncompress its contents.  Indeed, in most cases it doesn't
need to perform relocation fixups either, because of a trick used when creating
Win32 import libraries that means that all of the fixups to references imported
from other modules are concentrated in a single place.  (This trick is actually
not specific to the PE executable format, and can be duplicated on OS/2 with
the LX executable format as well.  I have a replacement OS2386.LIB that does it
for fixups to the various system API DLLs, if anyone is interested.)

The disadvantage, of course, is that reading in a page from DASD is more
expensive on Windows NT than it usually is on OS/2.  In the 32-bit LX
executable format used by OS/2, the compression scheme will shrink the size of
page images in the file quite noticably.  Picking the file \OS2\CMD.EXE at
random, we notice that in memory object 1 all of the page sizes are between
3584 and 3072 bytes, a reduction in size by between 12% and 25%.  Because of
the compression used in the LX executable format, to demand page in a 4KiB page
the program loader in the OS/2 kernel often doesn't actually need to read 4KiB
of data from disc.

On Windows NT, however, pages are the same size when stored on disc as they are
in memory, because the PE executable file format doesn't have compression.  So
for every 4KiB page to be demand loaded, Windows NT has to read an entire 4KiB
of data from disc.

It's worth noting that Windows NT attempts to compensate for this fact by the
fact that NTFS has a minimum cluster size of 4KiB.  With HPFS on OS/2, the
smallest I/O transaction can be as small as a single 512 byte (0.5KiB) sector,
since that is the allocation unit size.  Reading in a 3072-byte compressed page
image thus only need involve reading six or seven sectors, not eight.  With
NTFS on Windows NT, since the smallest allocation unit size for the filesystem
is 4KiB *anyway*, it doesn't make any difference that the program loader needs
to read a full eight sectors for each 4KiB page (or even 9 or 10 sectors if the
developer hasn't page-aligned the executable properly, which is possible if he
has played around with the linker flags).  It couldn't read less even if it
wanted to.

The most obvious effect of this design is that PE executables are much larger
than LX executables.  A page containing repeated data (such as an initialised
data page that is mostly zeroes, for example) compresses very well in an LX
executable.  By contrast, a PE executable file contains a whole page's worth of
bytes for such a page.  Viewing PE and LX executables with a hex file viewer is
most instructive.  PE executables often have large runs of repeated data, most
often large runs of zero bytes.  LX executables generally do not.  (I say
"generally", because if they use Watcom C/C++ the linker doesn't support
compression, alas.  This is a deficiency in Watcom's linker, and an
unfortunate example of the "jack of all trades, master of none" adage.)  This
is, of course, visible in the comparative sizes of Win32 and 32-bit OS/2
executables.

One particular irony of the "uncompressing pages during a page-in is expensive,
so we don't do it" philosophy embodied in the PE executable file format design
is that NTFS can compress file data behind the scenes on the disc.  So if an
executable file is on an NTFS volume and NTFS has compressed it when storing it
on disc, the overhead of uncompressing data each time that there is a page in
operation won't have been avoided.  All that has changed in reality is the
portion of the system that actually performs it.  Rather than having the
uncompression done by the process loader, it is done by the filesystem driver.
It is still done.

Another further irony is that making the executable file format uncompressable,
but having compression in the filesystem itself, means that the page data in
the in-memory file cache are uncompressed, because of course that is how they
are in the file itself.  In contrast, when an LX executable file is cached on
OS/2 the page data *are* compressed, and less RAM is required to cache the file
contents as a result.  This is one contributory factor (of many, alas) to the
greater physical memory needs that Windows NT has when compared to 32-bit OS/2.

[править] Мультитредовые апликухи падают при создании окна в дочернем треде

[A]: Joseph Shrago (joseph@fcn.ru)

В твоем случае надо пользоваться Post вместо Send.
И внимательней читать ремарки - там про отличия в нитках всегда пишут.
Еще в другой нитке надо снова делать AnhorBlock и MessageQueue.

[править] Запись детальной информации об Exception'е

[A]: George Shapovalov (2:5020/341.26)

520 645│except3.zip

EXCEPTQ in a 32 bit DLL which implements an exception handler which saves the
registers in a file named xxxx.TRP (xxxx=Pid,Tid) together with the Loaded
modules code and data objects addresses, and also the failing thread stack dump
and the process status as given by DosQProcStatus. Trapperq is an IBM C/2
program which shows how to implement the call to 32 bits exception handler from
a 16:16 bits program. enter Trapperq to generate a trap and the xxxx.TRP file.
You are free to use that code as a sample for your programs. No support or
guarantee from me implied.

Cheers Marc Fiammante

    С трешкой работает, а с четверкой еще не собирал. Поищи на хоббесах или в
домейне в примерах. Если не найдешь, я тебе на емейл кину.
Вот пример работы:

#pragma handler(main)
#pragma map (_Exception,"MYHANDLER")

#include <stdio.h>
#include <stdlib.h>

void TrapFunc(void);

main(){
    printf("Exception handler has been set by compiler\n");
    printf("Generating the TRAP from function\n");
    TrapFunc();
}
void TrapFunc() {
    char * Test;
    Test=0;
    *Test=0;
}


Вот пример трап-файла:

--------------------------
Exception C0000005 Occurred
 at 00:03:17  02/09/100
Invalid linear address 00000000

OS/2 Version 2.40
Failing code module internal name : SAMPLE
Failing code module file name : E:\TEMP\SAMPLE.EXE
Failing code Object # 1 at Offset 58
      File     Line#  Public Symbol
  ──────────── ────-  ────────────-
     SAMPLE.C     44  TrapFunc (sample.obj) 0001:00000048
List of auto variables at EBP 28854 in TrapFunc:
Offset Name                 Type                              Value
────── ──────────────────── ───────────────────────────────── ─────────────────
-4     Test                 near pointer to 8 bit unsigned    0x0 invalid


┌─────────────────────────────────────────────────────────────┐
│ GS  : 0000     FS  : 150B     ES  : 0053     DS  : 0053     │
│ EDI : 00000000 ESI : 00000000 EAX : 00000000 EBX : 00000000 │
│ ECX : 00000000 EDX : 00000004                               │
│ EBP : 00028854 EIP : 00010058 EFLG: 00012206 ESP : 00028850 │
│ CS  : 005B     SS  : 0053                                   │
└─────────────────────────────────────────────────────────────┘

 Failing instruction at CS:EIP : 005B:00010058 is  mov      [eax],00


┌────────────────────────────────────┐
│ Register content analysis          │
├────────────────────────────────────┤
│ EAX does not point to valid memory │
│ EBX does not point to valid memory │
│ ECX does not point to valid memory │
│ EDX does not point to valid memory │
│ EDI does not point to valid memory │
│ ESI does not point to valid memory │
└────────────────────────────────────┘

Thread slot 125 , Id 1 , priority 200
Stack Bottom : 000208A0 (0017:08A0) ;Stack Top    : 000288A0 (0017:88A0)
Process Id : 201 .EXE name : E:\TEMP\SAMPLE.EXE

Call Stack:
                                        Source    Line      Nearest
   EBP      Address    Module  Obj#      File     Numbr  Public Symbol
 ────────  ────────-  ──────── ────  ──────────── ────-  ────────────-
 Trap  ->  000F:0058  SAMPLE   0001     SAMPLE.C     44  TrapFunc (sample.obj)
0001:00000048

 00028854  :00010035  SAMPLE   0001     SAMPLE.C     39  main (sample.obj)
0001:00000000

  No auto variables found in main.

 0002886C  :00010101  SAMPLE   0001     SAMPLE.C     45  __RunExitList
(edcstrt.ASM) 0001:00000060

List of auto variables at EBP 28888 in TrapFunc:
Offset Name                 Type                              Value
────── ──────────────────── ───────────────────────────────── ─────────────────
-4     Test                 near pointer to 8 bit unsigned    0x11150 unwritable

 00028888  DFDF:C098  DOSCALL1 0004
Lost Stack chain - new EBP below previous

┌─────────────────────────────────────────────────────────────────────────┐
│ List of currently accessed modules (DLLs) object addresses              │
├─────────────────────────────────────────────────────────────────────────┤
│ Module E:\TEMP\SAMPLE.EXE                               Handle 00004756 │
│ Object Number    Address    Length     Flags      Type                  │
│        000000    00010000   00003D94   00010015  - 16:16  Selector 000F │
├─────────────────────────────────────────────────────────────────────────┤
     [ ...съедено молью... ]
├─────────────────────────────────────────────────────────────────────────┤
│ Module D:\OS2\DLL\UCONV.DLL                             Handle 00000995 │
│ Object Number    Address    Length     Flags      Type                  │
│        000000    1FCF0000   000059D9   00012015  - 16:16  Selector FE7F │
└─────────────────────────────────────────────────────────────────────────┘

/*----- Stack Bottom ---*/

/*----- Accessible Stack Bottom at 208A0 ---*/

 000208A0 :0000 0000 0000 0000 0000 0000 0000 0000   ................
 000208B0 :  lines not printed same as above

 00027FE0 :5300 0000 AD65 F91B 0000 0500 0000 F87F   S....e..........
     [ ...съедено молью... ]
 00028890 :9412 0000 0000 0000 0000 0300 8413 0300 ................
/*----- Stack Top -----*/

[править] Что мне нужно для того, чтоб скомпилить софтинку на GNU C?

[A]: Oleg Zrozhevsky (2:5020/359.359)

С твоими вопросами нужно обращаться в RU.GNU. Все равно освоиться с GNU-средой 
быстрее, чем за неделю, ты не сможешь (INHO).

Во-первых, тебе нужно найти и установить (распаковать) EMXDEV1.ZIP и
EMXDEV2.ZIP. (Следи за тем, чтобы все, что имеет отношение к EMX, было версии
0.9c). Это - EMX developer toolkit. В него не входит компилятор.

Во-вторых, тебе нужно установить GNUDEV1.ZIP и GNUDEV2.ZIP. Это собственно
компилятор GCC и его аксесcуары. Причем эта версия GCC специально пропатчена
для EMX.

В-третьих, установи GPPDEV.ZIP и GOBJCDEV.ZIP. Hе факт, что это тебе
потребуется, но спокойнее их поставить.

В-четвертых, найди и установи EMXFIX04.ZIP. В нем содержатся наиболее свежие
фиксы для перечисленного выше. В этом же архиве найдешь файлы INSTALL.DOC и
EMXFIX04.DOC, в них содержатся подробнейшие инструкции о том, что и в каком
порядке требуется ставить. Hе забудь определить все требуемые переменные
окружения.

В-пятых, найди и установи GNUMAKE.ZIP. С этим архивом имеет место некоторая
неразбериха. Ищи архив, содержащий не только исходники, но и уже
скомпилированный двоичный файл.

Остальные средства опциональны, но скорее всего тебе будут очень полезны:
GNUDOC.ZIP, GNUINFO.ZIP, EMXVIEW.ZIP и GNUVIEW.ZIP.

Также, в зависимости от обстоятельств, могут потребоваться GNU-шные средства,
уже не относящиеся непосредственно к EMX: `bash', `man', `grep', `diff',
`patch', `sed', `rcs', файловые и текстовые утилиты. Hо ставить и разбираться с
их использованием, IMHO, лучше по мере необходимости. Большие залежи GNU-софта,
портированного под EMX лежат на `hobbes.nmsu.edu' и `ftp.leo.org'.

Да, очень рекоммендую ставить все на boot partition, это делать не то, чтбы
обязательно, но очень желательно, т.к. снимает значительное количество
дополнительной головной боли.

[править] Watcom Debugger не работает под Авророй, выдает GPF

[A]: Max Alekseyev (2:5015/60)

Ура, заработало!!!
Как всегда, ларчик просто открывался! Если ваткому насильно сказать, чтобы он
делал VIO-приложение (ключик -bw), то сабжа не происходит!

Thanks to Sergey <levin@oduurl.ru>

[править] Как осуществить 16->32-bit thunking для данных?

[A]: Maxim Elkin (2:5020/979.1)

 Q> Как осуществлять передачу параметров при использовании API из
 Q> 16-битного кода? Пусть, например, мне нужно вызвать SomeFunc, которой
 Q> нужно передать 32-битный указатель, а у меня он располагается в ds:si.

Hапример, так:

//Convert 16bit selector:offset pointer to flat 32bit one
#define SEL2FLAT(x) (PVOID)( ( ((ULONG)x>>3) & 0xffff0000l) |
((ULONG)x&0xffffl) )

То есть на ассемблере 2-3 команды (смотря где у тебя лежит 16:16 ptr). Hо, сам
понимаешь, не гарантируется совместимость с будущими версиями оси.

[A]: Max Alekseyev (2:5015/60)

В DOSCALLS входят функции DosSelToFlat и DosFlatToSel.

[править] Configure-скрипты и как с ними бороться в OS/2

[A]: Andrew Belov (2:5020/181.2)

Методика работы с Configure-скриптами под OS/2 нигде полностью не описана,
поэтому этот FAQ составлен исключительно по собственному опыту. Приветствуются
любые исправления/дополнения.

Для запуска скриптов необходим почти полный комплект традиционных GNU'шных
утилит, а именно:

  *  EMX v 0.9d fix 3 (можно проапгрейдить до PGCC v 2.95)

  *  GNU textutils v 2.0
  *  GNU findutils v 4.1
  *  GNU sh-utils v 1.12
  *  GNU fileutils v 3.13

     Hе обязательно именно эти версии, но проверялось только с ними.

  *  Korn shell v 5.27 (PERL_SH.*)

     Пропатченный (?) исходный релиз. Вместо него можно использовать BASH,
     но он слишком громоздкий, а версия BASH 1.12f известна тем, что редкий
     configure-скрипт, запущенный в ней, сможет проработать до конца
     (происходит утечка хендлов, после чего процессы перестают запускаться).

  *  GREP

     GNU GREP или Borland GREP.

  *  Autoconf v 2.12.5-971230.

     Можно взять версию 2.13, но она не знает директивы AC_DIVERT_HELP, в
     результате чего строки, содержащие AC_DIVERT_HELP(...), оказываются в
     configure-скрипте. От них можно избавиться простым поиском и удалением.

  *  GNU make v 3.72

     Авторы многих портов GNU'шных утилит рекомендуют использовать MAKE v 3.72
     вместо существующей версии 3.76.

Для удобства рекомендуется также иметь следующее:

  *  GNU diffutils v 2.7.1
  *  GNU patch v 2.1

     Патчи приобрели широкое распространение, в первую очередь - в популярных
     RPM-пакетах, и иногда их использование не лишено смысла. Кроме того, не
     все разработчики GNU'шного софта с радостью принимают патчи для OS/2-EMX,
     поэтому скорее всего придется иметь дело с дистрибутивом софтины
     (например, списанном с линуксового CD) и патчем для OS/2.

  *  GNU man v 1.00 с поддержкой gzip'а
  *  GNU roff v 1.10
  *  GNU less v 292

     Позволяют читать man'ы (сами man'ы можно взять в комплекте любого
     Linux'а).

  *  PERL v 5.002 beta 3

     PERL требуется в относительно редких случаях, перловые Configure-скрипты
     встречаются, например, в OpenSSL. Далее в FAQ'е рассматриваются только
     стандартные скрипты, создаваемые Autoconf'ом.

Для настройки всей системы под EMX имеет смысл создать отдельный скрипт. В
CONFIG.SYS при этом можно оставить настройки для "родных" компиляторов
(VisualAge) и тулкита.

   === Cut ===
   @ECHO OFF
   REM
   REM EMX v 0.9d/PGCC v 2.95.3
   REM
   SET C_INCLUDE_PATH=e:/emx/include;e:/toolkit/h
   SET CPLUS_INCLUDE_PATH=e:/emx/include/cpp;%C_INCLUDE_PATH%
   SET OBJC_INCLUDE_PATH=%C_INCLUDE_PATH%
   SET LIBRARY_PATH=e:/emx/lib
   SET GCCLOAD=5
   SET EMXBOOK=emxdev.inf+emxlib.inf+emxgnu.inf
   SET CC=gcc.exe
   SET INFOPATH=f:/usr/info
   REM
   REM GNU Autoconf v 2.12.5
   REM
   SET PATH=%PATH%;E:\OS2APPS\autoconf
   SET AC_MACRODIR=e:/os2apps/autoconf
   SET INFOPATH=%INFOPATH%;e:/os2apps/autoconf
   SET AWK=c:/os2/os2tools/awk.exe
   REM
   REM Perl v 5.00x
   REM
   SET PERL5LIB=E:\OS2APPS\PERL\LIB
   SET PERL=e:/os2apps/perl/perl5x.exe
   === Cut ===

Сам процесс конфигурирования включает в себя следующие этапы:

1. Подключение патча:

   patch -p0<emxpatch.diff

   Текущей директорией в этот момент должна быть та, относительно которой
   указываются все имена файлов в патче (т.е. директория на одну ступень выше
   директории с исходниками). Можно подключать патчи и непосредственно из
   места расположения исходников, в таком случае нужен ключ -p1. Детальная
   информация приведена в man patch.

2. Генерация configure-скрипта:

   === Cut ===
   #! /bin/sh

   autoconf --auxfiles
   autoconf --clean
   autoconf
   === Cut ===

3. Подбор настроек (обычно описываются в файлах INSTALLATION, README, ...),
   генерация MAKEFILE. Пример настроек для компиляции браузера Lynx v 2.8.3:

   === Cut ===
   #! /bin/sh

   sh -x \
      configure --prefix=/emx --disable-full-paths --enable-debug \
      --enable-color-style --with-screen=curses
   === Cut ===

4. Компиляция (в простейшем случае - make или make all).


Внимание: по состоянию на осень 2001 г., технология начинает изменяться.

1. Hовое поколение инструментария: GCC v 3.0, Autoconf v 2.50, Automake.
   Пока в довольно нестабильном состоянии, но то, что вышеописанные
   рекомендации к этому комплекту не всегда применимы, уже очевидно.
   Для GCC v 3.0 обязательно указывать переменную окружения:
   CFLAGS=-D__ST_MT_ERRNO__

2. Проверенные и пригодные к использованию комплекты утилит теперь лежат на
   сайте http://www.unixos2.org. Кто знаком со Slackware Linux, тот поймет,
   что к чему.

3. В рамках того же UnixOS/2 рождаются идеи конвертации готовых
   Configure-скриптов, или модификации EMX'ового инструментария с целью
   избавления от формата a.out. В итоге схема портирования может упроститься,
   но это будет нескоро.


Список рекомендуемой литературы:

- EDM/2 03/1996, "Running Unix GNU Configure Scripts"
- http://www.arrakis.es/~worm/acemx.htm

[править] Как убрать ссылки на несуществующие шрифты с помощью REXX?

[A]: Yegor Dolzhikov (2:463/5050); Stas Mishchenkov (2:460/58)

==== Cut [clnfonts.cmd] ====
/*
 Скpипт убиpает из OS2.INI ссылки на несуществующие шpифты.
 Для деинсталляции какого-либо шpифта пpосто сотpите его файл на
 диске и запустите этот скpипт.
*/
call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
call SysLoadFuncs
Call directory sysBootDrive()||'\'
call SysIni 'USER', 'PM_Fonts', 'ALL:', 'st'
if st.0=0 then exit
do i=1 to st.0
 filename = SysIni('USER', 'PM_Fonts', st.i)
 if stream(filename, 'c', 'query exists')= then
  call SysIni 'USER', 'PM_Fonts', st.i, 'DELETE:'
end
==== eof [clnfonts.cmd] ====

[править] Как по названию кодовой страницы узнать ее номер ("koi8-r" -> 878)?

[A]: Max Alekseyev (2:5015/60)

Похоже IBM забыла добавить такую возможность в API. Пришлось покопаться в
формате UconvObject.
Hомер кодовой страницы там лежит по смещению 0xC, правда я не знаю какая длина 
этого поля - то ли 2, то ли 4 байта.
Кстати, рядышком по смещению 0x10 лежит имя кодовой страницы, но это не так
актуально, ибо его можно получить легальным путем через UniMapCpToUcsCp().

[править] FAQ по CVS в OS/2

[A]: Andrew Belov (2:5020/181.2)

Q: Где достать графическую оболочку?
A: Существует целых два варианта:

   1. jCVS
   2. Emacs, C-x v (Tools -> Version Control)

   Первый вариант - на Java, второй - на LISP'е. Кроме того, эффективно
   действует прикручивание распространенных команд типа "cvs commit" к
   user-menu разных file manager'ов.


Q: Как подключиться к SourceForge по CVS over SSH?
A: Зарегистрировавшись, берем неизбалованный интерактивностью
   порт SSH 1.2.13-03 от 11/03/1997 и создаем себе примерно такое окружение:

   SET CVS_RSH=ssh
   SET CVSROOT=:ext:mylogin@cvs.myproject.sourceforge.net:/cvsroot/myproject
   SET LOGNAME=mylogin

   С такими настройками можно вполне приемлемо работать с SourceForge, включая
   использование scp для закачки файлов.

   Старые порты CVS/EMX часто имели ограничение по длине user-id'а 8 символов,
   в новых (1.12.0.x) этой особенности уже нет.


Q: Что за метод "CVS over RSH", и как им пользоваться?
A: RSH - простейшее средство удаленного доступа, в общем случае доступ
   контролируется только по "разрешенным" IP-адресам клиентов (%ETC%\rhosts).
   Этот вариант можно порекомендовать только для схемы типа "домашний PC
   плюс ноутбук", основное его преимущество в том, что приложив минимальные
   усилия к настройке (создать %ETC%\rhosts и запустить RSHD), получаем
   работающий CVS + удаленный доступ через RSH.


Q: Мой PSERVER взломали.
A: Поставить "SystemAuth=no" в %CVSROOT%\CVSROOT\login (это запрещает вход
   под несуществующими login'ами, т.к. в OS/2 кроме PSERVER'а пароли проверять
   больше некому). Еще следует убедиться, что файлы с расширениями ",v" в
   %CVSROOT%\CVSROOT присутствуют в необходимом для настройки сервера объеме
   (т.е. раздавать passwd,v и config,v как минимум нежелательно).


Q: Портирую программу из OS/2 в Linux. Как организовать контроль версий?
A: Если дело происходит на одной машине с локальным репозитарием, то самый
   простой способ - поставить драйвер HPFS/JFS for Linux (см. соответствующие
   Linux'овые эхи), а со стороны OS/2 - убедиться, что конфиги в
   %CVSROOT%\CVSROOT не содержат символов возврата каретки (CR), иначе на
   Linux'овый терминал полезут неразборчивые ругательства.

   Hеобходимо помнить, что сам репозитарий CVS для OS/2 никаких CR'ов не
   содержит, таким образом, файлы *,v можно спокойно таскать между различными
   платформами. CR'ы появляются только в рабочих копиях и в конфигах.

   Рекомендуется настроить в Linux'е inetd, чтобы запускать CVS по протоколу
   :pserver: и избежать необходимости назначения прав доступа на директории
   репозитария.


Q: Портирую программу из Linux в OS/2. Как синхронизировать исходники?
A: Импортируем Linux'овые исходники с ключом "-ko", чтобы не заменять
   $Id$'ы своими. Разработку OS/2'шной версии ведем в branch'е (cvs tag
   -b), синхронизируемся по "cvs update -j version1 -j version2", где
   version1 - предыдущая версия, для которой есть готовый порт,
   version2 - свежеимпортированная версия, над которой предполагается
   работать.


Q: CVSROOT=:pserver:johndoe@192.168.1.5:c:/cvs - клиент не работает.
A: Hеобходимо переписать название хоста в буквенном виде. Hазвание может
   быть каким угодно, вплоть до несуществующего (т.е. прописанного через
   %ETC%\hosts).

[править] setlocale() в OS/2

[A]: Alex Samorukov (2:463/598)

Итак, в стандарте ANSI определена ф-ия setlocale, которая позволяет
устанавливать локаль процесса. Мне это потребовалось заюзать в одной из своих
софтинок.  Оказалось это несколько не так просто сделать как мне думалось ;-)

Итак, варианты LIBC:

EMXLIBC 
  "C" Locale only, сразу отпадает.
Innotek LIBC:
  setlocale() есть и работает. При этом используется системная OS2 локаль,
  локаль C существует и работает.
  Особых проблем при использовании не выявлено.
Watcom LIBC 
  аналогично
VAC 3.06 RT: 
 В принципе работает. Правда, какой-то косяк с наследованием в DLL, а также
системная локаль HЕ ЮЗАЕТСЯ. Для функционирования надо прописать LOCPATH к
папке с lcl файлами (внутри это dll). Причём было замечено, что lcl файлы от
других версий VAC`а не подходят. Короче, не самая удобная вещь, но жить можно. 
Синтаксис вызова такой:
setlocale(LC_ALL,"ru_ru.ibm-866"). Это подразумевает что в %locpath% у вас есть
директория ru_ru и в ней лежит ibm-866.loc. В случае неуспеха остаётся на "c"
локали. Лучше юзать static linking или инитить локаль как в DLL так и в 
основном коде. 
OS/2 LIBC (ACP2):
Как известно, в OS/2 входит свой LIBC который большая часть OS/2 програм и
юзает. В нём, в частности есть setlocale().
И она даже работает ;-) Более того, она не требует LCL файлов юзая внутреннюю
OS/2 подсистему. И не имеет проблем с dll (локаль наследуется). Hо имеет
другую, крайне неприятную особенность - "c" locale такой на самом деле не
является ;-) 
т.е.
setlocale(LC_ALL, "c")
printf("out: A=%c locale in exe=%s\n\n",
toupper(0xa0),setlocale(LC_CTYPE,NULL));

даст A=A вместо положенных A=a в C locale. Что является ну совсем нехорошо и
для моей задачи не подошло. Хотя, если не считать этой баги всё остальное
работает хорошо.