michael 26 years ago
parent
commit
ac1563bb64
3 changed files with 0 additions and 319 deletions
  1. 0 72
      docs/go32ex/int_pm.pas
  2. 0 120
      docs/go32ex/rmpm_int.pas
  3. 0 127
      docs/go32ex/sel_des.pas

+ 0 - 72
docs/go32ex/int_pm.pas

@@ -1,72 +0,0 @@
-{ example for :
-          set_pm_interrupt()
-          get_pm_interrupt()
-          Interrupt redirection
-          Software interrupt
-          tseginfo record
-          get_cs()
-}
-
-{ This example shows how to redirect a software interrupt by changing the
-  protected mode handler of the DPMI host.
-
-  In more detail it hooks interrupt 1Ch which is called every time the timer
-  interrupt (int 08) is executed. This is the preferred way to hook the timer,
-  because int 1Ch is a software interrupt which doesn't need so much
-  initialization stuff compared to hooking a hardware interrupt.
-}
-
-uses crt, { wherey(), keypressed() }
-     go32;
-
-const int1c = $1c; { interrupt number we want to hook }
-
-var oldint1c : tseginfo; { 48 bit pointer to old interrupt handler }
-    newint1c : tseginfo; { 48 bit pointer to new interrupt handler }
-
-    int1c_counter : Longint; { increased every time the interrupt is called  }
-
-{$ASMMODE DIRECT}
-{ the actual handler code }
-procedure int1c_handler; assembler;
-asm
-   cli
-{ save all registers }
-   pushw %ds
-   pushw %ax
-{ prepare segment registers for FPC procedure }
-   movw %cs:INT1C_DS, %ax
-   movw %ax, %ds
-{ simply increase the counter by one }
-   incl _INT1C_COUNTER
-{ restore registers }
-   popw %ax
-   popw %ds
-   sti
-   iret
-INT1C_DS: .word 0
-end;
-
-var i : Longint;
-
-begin
-     { insert right handler data into new handler variable }
-     newint1c.offset := @int1c_handler;
-     newint1c.segment := get_cs;
-     { get the old handler }
-     get_pm_interrupt(int1c, oldint1c);
-     { store necessary data into the handler }
-     asm
-        movw %ds, %ax
-        movw %ax, INT1C_DS
-     end;
-     Writeln('-- Press any key to exit --');
-     { set new handler }
-     set_pm_interrupt(int1c, newint1c);
-     { write the number of interrupts occured }
-     while (not keypressed) do begin
-           gotoxy(1, wherey); write('Number of interrupts occured : ', int1c_counter);
-     end;
-     { restore old handler }
-     set_pm_interrupt(int1c, oldint1c);
-end.

+ 0 - 120
docs/go32ex/rmpm_int.pas

@@ -1,120 +0,0 @@
-{ example for :
-          interrupt redirection
-          software vs. hardware interrupts
-          set_pm_interrupt()
-          get_pm_interrupt()
-          get_cs()
-          tseginfo
-          trealregs
-          processor access
-          get_cs(), get_ds(), get_ss()
-}
-
-{ This example shows the difference between protected and real mode
-  interrupts; it redirects the protected mode handler to an own handler which
-  returns an impossible function result and calls it afterwards. Then the real
-  mode handler is called directly, to show the difference between the two.
-
-  Used Interrupt:
-  get DOS version Int 21h / function 30h
-       Input: AH = $30
-              AL = $1
-       Return: AL = major version number
-               AH = minor version number
-
-}
-
-uses crt, { used for clreol(), gotoxy() }
-     go32;
-
-{$ASMMODE DIRECT}
-
-var r : trealregs;
-    axreg : Word; { temporary variable used for the protected mode int call }
-
-    oldint21h : tseginfo;
-    newint21h : tseginfo;
-
-{ this is our int 21h protected mode interupt handler. It catches the function
-  call to get the DOS version, all other int 21h calls are redirected to the
-  old handler; it is written in assembly because the old handler can't be
-  called with pascal }
-procedure int21h_handler; assembler;
-asm
-   cmpw $0x3001, %ax
-   jne CallOld
-   movw $0x3112, %ax
-   iret
-
-CallOld:
-   ljmp %cs:OLDHANDLER
-
-OLDHANDLER: .long 0
-            .word 0
-end;
-
-{ a small helper procedure, which waits for a keypress }
-procedure resume;
-begin
-     Writeln;
-     Write('-- press any key to resume --'); readkey;
-     gotoxy(1, wherey); clreol;
-end;
-
-begin
-     { see the text messages for further detail }
-     clrscr;
-     Writeln('Executing real mode interrupt');
-     resume;
-     r.ah := $30; r.al := $01;  realintr($21, r);
-     Writeln('DOS v', r.al,'.',r.ah, ' detected');
-     resume;
-     Writeln('Executing protected mode interrupt without our own handler');
-     Writeln;
-     asm
-        movb $0x30, %ah
-        movb $0x01, %al
-        int $0x21
-        movw %ax, _AXREG
-     end;
-     Writeln('DOS v', r.al,'.',r.ah, ' detected');
-     resume;
-     Writeln('As you can see the DPMI hosts default protected mode handler');
-     Writeln('simply redirects it to the real mode handler');
-     resume;
-     Writeln('Now exchanging the protected mode interrupt with our own handler');
-     resume;
-
-     newint21h.offset := @int21h_handler;
-     newint21h.segment := get_cs;
-     get_pm_interrupt($21, oldint21h);
-     { storing old handler address in interrupt handler }
-     asm
-        movl _OLDINT21H, %eax
-        movl %eax, OLDHANDLER
-        movw 4+_OLDINT21H, %ax
-        movw %ax, 4+OLDHANDLER
-     end;
-     set_pm_interrupt($21, newint21h);
-
-     Writeln('Executing real mode interrupt again');
-     resume;
-     r.ah := $30; r.al := $01; realintr($21, r);
-     Writeln('DOS v', r.al,'.',r.ah, ' detected');
-     Writeln;
-     Writeln('See, it didn''t change in any way.');
-     resume;
-     Writeln('Now calling protected mode interrupt');
-     resume;
-     asm
-        movb $0x30, %ah
-        movb $0x01, %al
-        int $0x21
-        movw %ax, _AXREG
-     end;
-     Writeln('DOS v', lo(axreg),'.',hi(axreg), ' detected');
-     Writeln;
-     Writeln('Now you can see that there''s a distinction between the two ways of ');
-     Writeln('calling interrupts...');
-     set_pm_interrupt($21, oldint21h);
-end.

+ 0 - 127
docs/go32ex/sel_des.pas

@@ -1,127 +0,0 @@
-{ example for :
-          Selectors and descriptors
-          DOS memory access
-          allocate_ldt_descriptors()
-          free_ldt_descriptors()
-          get_segment_base_address()
-          set_segment_base_address()
-          get_segment_limit()
-          set_segment_limit()
-          seg_move()
-          seg_fillword()
-}
-{ This example demonstrates the usage of descriptors and the effects of
-  changing its limit and base address.
-
-  In more detail, the program fills the region described by an allocated
-  descriptor in text screen memory with various characters.
-  Before doing this it saves the entire screen contents to the heap and
-  restores it afterwards.
-
-  Some additional background:
-
-  The text screen of a VGA card has it's address space at $B800:0; screen
-  memory is organized in a linear fashion, e.g. the second line comes
-  directly after the first, where each cell occupies 2 bytes of memory
-  (1 byte character data, 1 byte attributes). It is 32 kb in size.
-
-  Hence the offset of a single memory cell from its origin is:
-
-     Y * columns * 2 + X * 2
-
-  where X and Y mark the point and columns is the number of character cells
-  per line
-}
-
-uses crt,  { color constants, clreol(), gotoxy(), wherex(), wherey() }
-     go32;
-
-const maxx = 80; { screen x and y dimensions }
-      maxy = 25;
-      bytespercell = 2; { bytes used for every character cell }
-      screensize = maxx * maxy * bytespercell; { screen size in bytes }
-
-      linB8000 = $B800 * 16; { the linear address of $B800:0 }
-
-type string80 = string[80];
-
-var
-    text_save : array[0..screensize-1] of byte; { holds the old screen contents }
-    text_oldx, text_oldy : Word; { old cursor x and y coordinates }
-
-    text_sel : Word; { selector to the text mode screen }
-
-{ prints a status message on the first line of the screen and then waits for
-  a keypress }
-procedure status(s : string80);
-begin
-     gotoxy(1, 1); clreol; write(s); readkey;
-end;
-
-{ writes some descriptor info on the last 2 lines }
-procedure selinfo(sel : Word);
-begin
-     gotoxy(1, 24);
-     clreol; writeln('Descriptor base address : $', hexstr(get_segment_base_address(sel), 8));
-     clreol; write('Descriptor limit : ', get_segment_limit(sel));
-end;
-
-{ returns a 2 byte character cell, which includes character data and its
-  color attributes }
-function makechar(ch : char; color : byte) : Word;
-begin
-     result := byte(ch) or (color shl 8);
-end;
-
-begin
-     { save original screen contents to variable, this time by using seg_move()
-       and the dosmemselector variable }
-     seg_move(dosmemselector, linB8000, get_ds, longint(@text_save), screensize);
-     { additionally we have to save the old screen cursor coordinates }
-     text_oldx := wherex; text_oldy := wherey;
-     { clear the whole screen }
-     seg_fillword(dosmemselector, linB8000, screensize div 2, makechar(' ', Black or (Black shl 4)));
-     { output message }
-     status('Creating selector ''text_sel'' to a part of text screen memory');
-     { allocate descriptor }
-     text_sel := allocate_ldt_descriptors(1);
-     { set its base address to the linear address of the text screen + the
-       byte size of one line (=maxx * bytespercell * 1) }
-     set_segment_base_address(text_sel, linB8000 + bytespercell * maxx * 1);
-     { the limit is set to the screensize reduced by one (a must be) and the
-       number of lines we don't want to have touched (first line + lower 2 lines) }
-     set_segment_limit(text_sel, screensize - 1 - bytespercell * maxx * 3);
-     { write descriptor info  }
-     selinfo(text_sel);
-
-     status('and clearing entire memory selected by ''text_sel'' descriptor');
-     { fill the entire selected memory with single characters }
-     seg_fillword(text_sel, 0, (get_segment_limit(text_sel)+1) div 2, makechar(' ', LightBlue shl 4));
-
-     status('Notice that only the memory described by the descriptor changed, nothing else');
-
-     status('Now reducing it''s limit and base and setting it''s described memory');
-     { set the base address of the descriptor (increase it by the byte size of one line) }
-     set_segment_base_address(text_sel, get_segment_base_address(text_sel) + bytespercell * maxx);
-     { decrease the limit by byte size of 2 lines (1 line because base address changed,
-       one line on the lower end) }
-     set_segment_limit(text_sel, get_segment_limit(text_sel) - bytespercell * maxx * 2);
-     { write descriptor info  }
-     selinfo(text_sel);
-     status('Notice that the base addr increased by one line but the limit decreased by 2 lines');
-     status('This should give you the hint that the limit is relative to the base');
-     { fill the descriptor area }
-     seg_fillword(text_sel, 0, (get_segment_limit(text_sel)+1) div 2, makechar(#176, LightMagenta or Brown shl 4));
-
-     status('Now let''s get crazy and copy 10 lines of data from the previously saved screen');
-     { copy memory from the data segment to screen }
-     seg_move(get_ds, longint(@text_save), text_sel, maxx * bytespercell * 2, maxx * bytespercell * 10);
-
-     status('At last freeing the descriptor and restoring the old screen contents..');
-     status('I hope this little program may give you some hints on working with descriptors');
-     { free the descriptor so that it can be used for things }
-     free_ldt_descriptor(text_sel);
-     { restore old state  }
-     seg_move(get_ds, longint(@text_save), dosmemselector, linB8000, screensize);
-     gotoxy(text_oldx, text_oldy);
-end.