buffer.pas 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. { example for :
  2. global_dos_alloc()
  3. global_dos_free()
  4. trealregs / registers record
  5. realintr()
  6. DOS memory access
  7. dosmemput()
  8. dosmemget()
  9. int31error variable
  10. }
  11. { This program demonstrates the usage of DOS real mode memory by executing a
  12. software interrupt which needs a buffer to store data into. Because these
  13. interrupts are real mode funcs, the buffer must be located in real mode
  14. memory space (first MB of memory). Such memory can only be allocated by
  15. the global_dos_alloc() and global_dos_free() functions of the GO32 unit.
  16. In more detail this program tries to detect a VESA 2.0 BIOS extension of
  17. your graphics card and outputs its version.
  18. Here's the necessary interrupt call description:
  19. Int 10h 4f00h : VESA BIOS extension installation check
  20. Input : AX = 4F00h
  21. ES:DI = pointer to 512 byte information buffer
  22. Output : AX = 004Fh if successful
  23. ES:DI = pointer to filled buffer
  24. Buffer structure : (relevant to this example)
  25. must be 'VESA' in the first 4 chars of the buffer to be valid
  26. VBE version in the next word
  27. Note : to request VBE 2.0 information, the first 4 bytes of the buffer must
  28. contain 'VBE2' prior to the interrupt call.
  29. (this makes the problem a bit tougher; we first have to copy the
  30. buffer with the 'VBE2' id to dos memory...)
  31. }
  32. uses go32;
  33. { The following 2 functions are wrappers to the GO32 global_dos_alloc() and
  34. global_dos_free() functions to simplify their usage }
  35. { Function : dosalloc }
  36. { Input : size of a real mode location }
  37. { Output : selector and segment of a real mode location }
  38. procedure dosalloc(var selector : word; var segment : word; size : longint);
  39. var res : longint;
  40. begin
  41. { try to allocate real mode memory }
  42. res := global_dos_alloc(size);
  43. { the lower 16 bits of the result contain the selector to the allocated
  44. memory block }
  45. selector := word(res);
  46. { the upper 16 bits contain the real mode segment address of this block;
  47. the offset is always 0, so we don't need to return this }
  48. segment := word(res shr 16);
  49. end;
  50. { Function : dosfree }
  51. { Input : selector of a real mode block }
  52. { Output : none }
  53. { Description : de-allocates a previously allocated real mode memory }
  54. procedure dosfree(selector : word);
  55. begin
  56. { call the GO32 function with the selector }
  57. global_dos_free(selector);
  58. end;
  59. type VBEInfoBuf = record
  60. Signature : array[0..3] of char; { contains 'VESA' if successful }
  61. Version : Word;
  62. reserved : array[0..505] of byte; { pad to 512 bytes length }
  63. end;
  64. var selector, { selector to our real mode buffer }
  65. segment : Word; { real mode segment address of buffer }
  66. r : trealregs; { register structure to issue a software interrupt }
  67. infobuf : VBEInfoBuf;
  68. begin
  69. { first we reset the registers and infobuf variable }
  70. fillchar(r, sizeof(r), 0);
  71. fillchar(infobuf, sizeof(VBEInfoBuf), 0);
  72. { allocate real mode memory }
  73. dosalloc(selector, segment, sizeof(VBEInfoBuf));
  74. { check if an error occured during allocation }
  75. if (int31error<>0) then begin
  76. Writeln('Error while allocating real mode memory, halting');
  77. halt;
  78. end;
  79. { request VBE 2.0 information, fill out information buffer }
  80. infobuf.Signature := 'VBE2';
  81. { copy buffer to the allocated real mode memory }
  82. dosmemput(segment, 0, infobuf, sizeof(infobuf));
  83. { issue the interrupt; remember : DI = 0 }
  84. r.ax := $4f00; r.es := segment;
  85. realintr($10, r);
  86. { copy buffer to our infobuf variable again }
  87. dosmemget(segment, 0, infobuf, sizeof(infobuf));
  88. { free allocated real mode memory, because we don't need it anymore }
  89. dosfree(selector);
  90. { check if interrupt call was successful }
  91. if (r.ax <> $4f) then begin
  92. { write message and exit, because the infobuf doesn't contain any
  93. useful data we could tell the user }
  94. Writeln('VBE BIOS extension not available, function call failed');
  95. halt;
  96. end;
  97. { check if buffer is valid }
  98. if (infobuf.signature[0] = 'V') and (infobuf.signature[1] = 'E') and
  99. (infobuf.signature[2] = 'S') and (infobuf.signature[3] = 'A') then begin
  100. Writeln('VBE version ', hi(infobuf.version), '.', lo(infobuf.version), ' detected');
  101. end;
  102. end.