seldes.pp 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. {$mode delphi}
  2. uses
  3. crt,
  4. go32;
  5. const
  6. maxx = 80;
  7. maxy = 25;
  8. bytespercell = 2;
  9. screensize = maxx * maxy * bytespercell;
  10. linB8000 = $B800 * 16;
  11. type
  12. string80 = string[80];
  13. var
  14. text_save : array[0..screensize-1] of byte;
  15. text_oldx, text_oldy : Word;
  16. text_sel : Word;
  17. procedure status(s : string80);
  18. begin
  19. gotoxy(1, 1); clreol; write(s); readkey;
  20. end;
  21. procedure selinfo(sel : Word);
  22. begin
  23. gotoxy(1, 24);
  24. clreol; writeln('Descriptor base address : $',
  25. hexstr(get_segment_base_address(sel), 8));
  26. clreol; write('Descriptor limit : ', get_segment_limit(sel));
  27. end;
  28. function makechar(ch : char; color : byte) : Word;
  29. begin
  30. result := byte(ch) or (color shl 8);
  31. end;
  32. begin
  33. seg_move(dosmemselector, linB8000, get_ds, longint(@text_save),
  34. screensize);
  35. text_oldx := wherex; text_oldy := wherey;
  36. seg_fillword(dosmemselector, linB8000, screensize div 2,
  37. makechar(' ', Black or (Black shl 4)));
  38. status('Creating selector ''text_sel'' to a part of ' +
  39. 'text screen memory');
  40. text_sel := allocate_ldt_descriptors(1);
  41. set_segment_base_address(text_sel,
  42. linB8000 + bytespercell * maxx * 1);
  43. set_segment_limit(text_sel, screensize - 1 - bytespercell *
  44. maxx * 3);
  45. selinfo(text_sel);
  46. status('and clearing entire memory selected by ''text_sel''' +
  47. ' descriptor');
  48. seg_fillword(text_sel, 0, (get_segment_limit(text_sel)+1) div 2,
  49. makechar(' ', LightBlue shl 4));
  50. status('Notice that only the memory described by the' +
  51. ' descriptor changed, nothing else');
  52. status('Now reducing it''s limit and base and setting it''s ' +
  53. 'described memory');
  54. set_segment_base_address(text_sel,
  55. get_segment_base_address(text_sel) + bytespercell * maxx);
  56. set_segment_limit(text_sel,
  57. get_segment_limit(text_sel) - bytespercell * maxx * 2);
  58. selinfo(text_sel);
  59. status('Notice that the base addr increased by one line but ' +
  60. 'the limit decreased by 2 lines');
  61. status('This should give you the hint that the limit is ' +
  62. 'relative to the base');
  63. seg_fillword(text_sel, 0, (get_segment_limit(text_sel)+1) div 2,
  64. makechar(#176, LightMagenta or Brown shl 4));
  65. status('Now let''s get crazy and copy 10 lines of data from ' +
  66. 'the previously saved screen');
  67. seg_move(get_ds, longint(@text_save), text_sel,
  68. maxx * bytespercell * 2, maxx * bytespercell * 10);
  69. status('At last freeing the descriptor and restoring the old '+
  70. ' screen contents..');
  71. status('I hope this little program may give you some hints on '+
  72. 'working with descriptors');
  73. free_ldt_descriptor(text_sel);
  74. seg_move(get_ds, longint(@text_save), dosmemselector,
  75. linB8000, screensize);
  76. gotoxy(text_oldx, text_oldy);
  77. end.