佳礼资讯网

 找回密码
 注册

ADVERTISEMENT

查看: 1207|回复: 19

谁要.PAS源代码?

[复制链接]
发表于 4-3-2011 07:32 AM | 显示全部楼层 |阅读模式
本帖最后由 FlierMate. 于 4-3-2011 01:51 PM 编辑

我有一些十多年前利用Turbo Pascal 7开发的程序现在找回源代码,想与感兴趣人士分享。

请回复,同时告知你要的模块。另外有适合学院生参考的数据库程序。


大概有这些,请看目录。(下载点我将另外提供)
回复

使用道具 举报


ADVERTISEMENT

 楼主| 发表于 4-3-2011 06:19 PM | 显示全部楼层
这里有一个示例:

其实文本文件如果没有使用Extended ASCII,是可以Strip掉第8个比特(Bit)的,变相另外一种压缩原理。------概念来自书本,我只是编写出来而已:


压缩:

  1. {
  2.   File Packer
  3.   Programmed by Boo Khan Ming

  4.   E-mail: bookm@tm.net.my
  5.   WWW:    http://www.geocities.com/SiliconValley/Horizon/3409/

  6.   This program was initially written in 1995.8.21
  7.   Revised in 1999.6.20

  8.   --------------------------------------------------------------------------

  9.   This program compresses plain text file only, by stripping off the highest
  10.   unused bit, that is, 8-bit character is truncated to 7-bit character,
  11.   since the highest bit is unused for plain text (ASCII below 128).

  12.   During the packing, every 8 bytes is compact to 7 bytes, as the highest
  13.   unused bit of every 7 bytes exactly fit another 7-bit character.

  14.   This method of compression always saves 12.5% (1/8).
  15.   Works on plain text file only.
  16. }

  17. var
  18.   OutputFileName,InputFileName:string;
  19.   InputFile,OutputFile:file of byte;
  20.   InputCode,OutputCode:byte;
  21.   Done:boolean;
  22.   Counter:byte;

  23. begin
  24.   WriteLn('File Packer');
  25.   WriteLn('Developed by Boo Khan Ming');
  26.   WriteLn;

  27.   if ParamCount<>2 then
  28.   begin
  29.     WriteLn('Usage:  PACK <input filename> <output filename>');
  30.     Halt(255);
  31.   end;

  32.   InputFileName:=ParamStr(1);
  33.   OutputFileName:=ParamStr(2);

  34.   {$I-}
  35.   Assign(InputFile,InputFileName);
  36.   Reset(InputFile);
  37.   {$I+}
  38.   if IOResult<>0 then
  39.   begin
  40.     WriteLn('Unable to open input file.');
  41.     Halt(1);
  42.   end;

  43.   {$I-}
  44.   Assign(OutputFile,OutputFileName);
  45.   Rewrite(OutputFile);
  46.   {$I+}
  47.   if IOResult<>0 then
  48.   begin
  49.     WriteLn('Unable to create output file.');
  50.     Halt(2);
  51.   end;

  52.   Done:=False;

  53.   repeat
  54.     Read(InputFile,InputCode);

  55.     if EOF(InputFile) then
  56.       Done:=True
  57.     else
  58.     begin
  59.       { Shift off leftmost unused bit }
  60.       InputCode:=InputCode shl 1;

  61.       for Counter:=0 to 6 do
  62.       begin
  63.         if EOF(InputFile) then
  64.         begin
  65.           OutputCode:=0;
  66.           Done:=True;
  67.         end
  68.         else
  69.         begin
  70.           Read(InputFile,OutputCode);

  71.           { Turn off top bit }
  72.           OutputCode:=OutputCode and 127;

  73.           { Pack bit }
  74.           OutputCode:=OutputCode or ((InputCode shl Counter) and 128);

  75.           Write(OutputFile,OutputCode);
  76.         end;
  77.       end;
  78.     end;
  79.   until Done;

  80.   Close(InputFile);
  81.   Close(OutputFile);
  82. end.
复制代码



解压缩:

  1. {
  2.   File Depacker
  3.   Programmed by Boo Khan Ming

  4.   E-mail: bookm@tm.net.my
  5.   WWW:    http://www.geocities.com/SiliconValley/Horizon/3409/

  6.   This program was initially written in 1995.8.21
  7.   Revised in 1999.6.20

  8.   --------------------------------------------------------------------------

  9.   This program compresses plain text file only, by stripping off the highest
  10.   unused bit, that is, 8-bit character is truncated to 7-bit character,
  11.   since the highest bit is unused for plain text (ASCII below 128).

  12.   During the packing, every 8 bytes is compact to 7 bytes, as the highest
  13.   unused bit of every 7 bytes exactly fit another 7-bit character.

  14.   This method of compression always saves 12.5% (1/8).
  15.   Works on plain text file only.
  16. }

  17. var
  18.   OutputFileName,InputFileName:string;
  19.   InputFile,OutputFile:file of byte;
  20.   InputCode,OutputCode:byte;
  21.   Done:boolean;
  22.   Counter:byte;
  23.   ByteArray:array [1..7] of byte;

  24. begin
  25.   WriteLn('File Depacker');
  26.   WriteLn('Developed by Boo Khan Ming');
  27.   WriteLn;

  28.   if ParamCount<>2 then
  29.   begin
  30.     WriteLn('Usage:  DEPACK <input filename> <output filename>');
  31.     Halt(255);
  32.   end;

  33.   InputFileName:=ParamStr(1);
  34.   OutputFileName:=ParamStr(2);

  35.   {$I-}
  36.   Assign(InputFile,InputFileName);
  37.   Reset(InputFile);
  38.   {$I+}
  39.   if IOResult<>0 then
  40.   begin
  41.     WriteLn('Unable to open input file.');
  42.     Halt(1);
  43.   end;

  44.   {$I-}
  45.   Assign(OutputFile,OutputFileName);
  46.   Rewrite(OutputFile);
  47.   {$I+}
  48.   if IOResult<>0 then
  49.   begin
  50.     WriteLn('Unable to create output file.');
  51.     Halt(2);
  52.   end;

  53.   Done:=False;

  54.   repeat
  55.     InputCode:=0;

  56.     for Counter:=1 to 7 do
  57.     begin
  58.       if EOF(InputFile) then
  59.         Done:=True
  60.       else
  61.       begin
  62.         Read(InputFile,OutputCode);

  63.         { Turn off top bit }
  64.         ByteArray[Counter]:=OutputCode and 127;

  65.         { Clear lower bit and depack bit }
  66.         OutputCode:=(OutputCode and 128) shr Counter;

  67.         { Build up the 8th byte }
  68.         InputCode:=InputCode or OutputCode;
  69.       end;
  70.     end;

  71.     Write(OutputFile,InputCode);

  72.     for Counter:=1 to 7 do
  73.       Write(OutputFile,ByteArray[Counter]);
  74.   until Done;

  75.   Close(InputFile);
  76.   Close(OutputFile);
  77. end.
复制代码
回复

使用道具 举报

 楼主| 发表于 4-3-2011 06:29 PM | 显示全部楼层
这是另外一个很原始的音效卡‘完全攻略’。当年用RM10买了Creative Labs Sound Blaster 16的Technical Reference,结果就用Turbo Pascal编写出一个模块(.TPU)。此原理也可以将你的SB16(当然现在怎么有人用)变成Digital Signal Analyser(实验室用着的咧),因为Sound Card本身就有DAC(Digital-Analog Converter)。

  1. unit Sound;
  2. {
  3.   Sound Service Unit
  4.   Revision 2 (1997-1998)
  5.   Developed by Boo Khan Ming

  6.   Provide direct access to Sound Blaster compatible sound card.

  7.   Featuring hardware diagnostic, full control of mixer settings and various
  8.   recording preferences.

  9.   Support sample playing and recording.
  10. }

  11. interface

  12. const
  13.   DirectSoundFormatID='DLS';

  14.   Mic=0;
  15.   CD=1;
  16.   Line=3;

  17. type
  18.   DirectSoundFormatType=record
  19.     ID:string[3];
  20.     Version:word;
  21.     Description:string;
  22.     HardwareRevision:word;
  23.     Frequency:word;
  24.     MasterVolume:word;
  25.     VoiceVolume:word;
  26.   end;

  27. var
  28.   MasterSignal,SlaveSignal:boolean;
  29.   VoicePointer,VoiceLength:longint;
  30.   RecordLength:word;
  31.   SoundCardBasePort:word;
  32.   DirectSoundFormat:DirectSoundFormatType;

  33. function AutoDetectSoundCard(var BasePort:word):boolean;
  34. procedure ResetDSP;
  35. procedure OutputDataDSP(Data:byte);
  36. function InputDataDSP:byte;
  37. procedure CheckDSPVersion(var Major,Minor:byte);
  38. function CheckSoundCardType:string;
  39. procedure NewTimerHandler; interrupt;
  40. procedure ChangeTimerFrequency(Frequency:word);
  41. procedure StartTimerHandler(NewVector:pointer;Frequency:word);
  42. procedure RestoreTimerHandler;

  43. procedure ResetVolumeSettings;
  44. procedure ChangeMasterVolume(Left,Right:byte);
  45. procedure ChangeVoiceVolume(Left,Right:byte);
  46. procedure ChangeMIDIVolume(Left,Right:byte);
  47. procedure ChangeCDVolume(Left,Right:byte);
  48. procedure ChangeLineVolume(Left,Right:byte);
  49. procedure ChangeMicVolume(Balance:byte);
  50. procedure CheckMasterVolume(var Left,Right:byte);
  51. procedure CheckVoiceVolume(var Left,Right:byte);
  52. procedure CheckMIDIVolume(var Left,Right:byte);
  53. procedure CheckCDVolume(var Left,Right:byte);
  54. procedure CheckLineVolume(var Left,Right:byte);
  55. procedure CheckMicVolume(var Balance:byte);

  56. procedure SelectVoiceInput(Source:byte);
  57. procedure EnableInputFilter;
  58. procedure DisableInputFilter;
  59. procedure EnableOutputFilter;
  60. procedure DisableOutputFilter;
  61. procedure SelectStereoOutput;
  62. procedure SelectMonoOutput;
  63. procedure SelectHighPassFilter;
  64. procedure SelectLowPassFilter;
  65. procedure ChangeSamplingRate(Rate:longint);

  66. function PrepareRecordVoice:boolean;
  67. procedure ShutRecordVoice;
  68. procedure RecordVoice;
  69. procedure PlayVoice;
  70. function SaveVoice(FileName:string;Description:string):boolean;
  71. function OpenVoice(FileName:string;Manual:boolean;var Description:string):boolean;

  72. implementation

  73. uses DOS,Swap,Mouse,Error;

  74. const
  75.   TemporaryVector=100;

  76.   ResetRegister=$06;
  77.   ReadDataRegister=$0a;
  78.   WriteCommandRegister=$0c;
  79.   WriteBufferRegister=$0c;
  80.   DataAvailableRegister=$0e;

  81.   ChannelRegister=$02;
  82.   MasterRegister=$22;
  83.   VoiceRegister=$04;
  84.   MIDIRegister=$26;
  85.   CDRegister=$28;
  86.   LineRegister=$2e;
  87.   MicRegister=$0a;

  88. var
  89.   Counter:word;
  90.   VoiceData:byte;
  91.   DirectSoundFile:file of byte;

  92. function AutoDetectSoundCard(var BasePort:word):boolean;
  93. const
  94.   RetryTime1=10;
  95.   RetryTime2=100;

  96. var
  97.   Counter1,Counter2:word;
  98.   Found:boolean;

  99. begin
  100.   BasePort:=$210;
  101.   Found:=False;
  102.   Counter1:=RetryTime1;

  103.   while (BasePort<=$260) and (not Found) do
  104.   begin
  105.     Port[BasePort+ResetRegister]:=1;
  106.     Port[BasePort+ResetRegister]:=0;

  107.     while (Counter2>RetryTime2) and (Port[BasePort+DataAvailableRegister]<128) do
  108.       Dec(Counter2);

  109.     if (Counter2=0) or (Port[BasePort+$a]<>$aa) then
  110.     begin
  111.       Dec(Counter1);

  112.       if Counter1=0 then
  113.       begin
  114.         Counter1:=RetryTime1;
  115.         BasePort:=BasePort+$10;
  116.       end;
  117.     end
  118.     else
  119.     begin
  120.       Found:=True;
  121.       SoundCardBasePort:=BasePort;
  122.     end;
  123.   end;

  124.   AutoDetectSoundCard:=Found;
  125. end;

  126. procedure ResetDSP;
  127. begin
  128.   Port[SoundCardBasePort+ResetRegister]:=1;
  129.   Port[SoundCardBasePort+ResetRegister]:=0;

  130.   while (Port[SoundCardBasePort+DataAvailableRegister] and 128)=0 do;
  131.   while not (Port[SoundCardBasePort+ReadDataRegister]=$aa) do;
  132. end;

  133. procedure OutputDataDSP(Data:byte);
  134. begin
  135.   while (Port[SoundCardBasePort+WriteBufferRegister] and 128)<>0 do;
  136.   Port[SoundCardBasePort+WriteCommandRegister]:=Data;
  137. end;

  138. function InputDataDSP:byte;
  139. begin
  140.   while (Port[SoundCardBasePort+DataAvailableRegister] and 128)=0 do;
  141.   InputDataDSP:=Port[SoundCardBasePort+ReadDataRegister];
  142. end;

  143. procedure CheckDSPVersion(var Major,Minor:byte);
  144. begin
  145.   OutputDataDSP($e1);
  146.   Major:=InputDataDSP;
  147.   Minor:=InputDataDSP;
  148. end;

  149. function CheckSoundCardType:string;
  150. var
  151.   Major,Minor:byte;

  152. begin
  153.   CheckDSPVersion(Major,Minor);

  154.   case Major of
  155.     1:CheckSoundCardType:='Sound Blaster';
  156.     2:CheckSoundCardType:='Sound Blaster Pro';
  157.     else
  158.       CheckSoundCardType:='Sound Blaster 16';
  159.   end;
  160. end;

  161. procedure ChangeTimerFrequency(Frequency:word);
  162. var
  163.   Counter:word;

  164. begin
  165.   Inline($fa);
  166.   Counter:=1193180 div Frequency;

  167.   Port[$43]:=$36;
  168.   Port[$40]:=Lo(Counter);
  169.   Port[$40]:=Hi(Counter);

  170.   Inline($fb);

  171.   DirectSoundFormat.Frequency:=Frequency;
  172. end;

  173. procedure StartTimerHandler(NewVector:pointer;Frequency:word);
  174. var
  175.   OldVector:pointer;

  176. begin
  177.   Inline($fa);

  178.   GetIntVec(8,OldVector);
  179.   SetIntVec(TemporaryVector,OldVector);
  180.   SetIntVec(8,NewVector);

  181.   ChangeTimerFrequency(Frequency);

  182.   Inline($fb);
  183. end;

  184. procedure RestoreTimerHandler;
  185. var
  186.   OldVector:pointer;

  187. begin
  188.   Inline($fa);

  189.   Port[$43]:=$36;
  190.   Port[$40]:=0;
  191.   Port[$40]:=0;

  192.   GetIntVec(TemporaryVector,OldVector);
  193.   SetIntVec(8,OldVector);

  194.   Inline($fb);
  195. end;

  196. procedure NewTimerHandler; {interrupt;}
  197. var
  198.   Register:Registers;

  199. begin
  200.   Dec(Counter);
  201.   if Counter=0 then
  202.   begin
  203.     Intr(TemporaryVector,Register);
  204.     Counter:=100 div 18;
  205.   end
  206.   else
  207.     Port[$20]:=$20;

  208.   MasterSignal:=not MasterSignal;
  209. end;

  210. procedure ResetVolumeSettings;
  211. begin
  212.   Port[SoundCardBasePort+$04]:=0;
  213.   Port[SoundCardBasePort+$05]:=0;
  214. end;

  215. procedure ChangeVolumeSettings(Left,Right:byte);
  216. begin
  217.   Port[SoundCardBasePort+$04]:=ChannelRegister;
  218.   Port[SoundCardBasePort+$05]:=(Left shl 4)+Right;
  219. end;

  220. procedure ChangeMasterVolume(Left,Right:byte);
  221. begin
  222.   Port[SoundCardBasePort+$04]:=MasterRegister;
  223.   Port[SoundCardBasePort+$05]:=(Left shl 4)+Right;
  224. end;

  225. procedure ChangeVoiceVolume(Left,Right:byte);
  226. begin
  227.   Port[SoundCardBasePort+$04]:=VoiceRegister;
  228.   Port[SoundCardBasePort+$05]:=(Left shl 4)+Right;
  229. end;

  230. procedure ChangeMIDIVolume(Left,Right:byte);
  231. begin
  232.   Port[SoundCardBasePort+$04]:=MIDIRegister;
  233.   Port[SoundCardBasePort+$05]:=(Left shl 4)+Right;
  234. end;

  235. procedure ChangeCDVolume(Left,Right:byte);
  236. begin
  237.   Port[SoundCardBasePort+$04]:=CDRegister;
  238.   Port[SoundCardBasePort+$05]:=(Left shl 4)+Right;
  239. end;

  240. procedure ChangeLineVolume(Left,Right:byte);
  241. begin
  242.   Port[SoundCardBasePort+$04]:=LineRegister;
  243.   Port[SoundCardBasePort+$05]:=(Left shl 4)+Right;
  244. end;

  245. procedure ChangeMicVolume(Balance:byte);
  246. begin
  247.   Port[SoundCardBasePort+$04]:=MicRegister;
  248.   Port[SoundCardBasePort+$05]:=Balance;
  249. end;

  250. procedure CheckMasterVolume(var Left,Right:byte);
  251. begin
  252.   Port[SoundCardBasePort+$04]:=MasterRegister;
  253.   Left:=(Port[SoundCardBasePort+$05] and $f0) shr 4;
  254.   Right:=Port[SoundCardBasePort+$05] and $0f;
  255. end;

  256. procedure CheckVoiceVolume(var Left,Right:byte);
  257. begin
  258.   Port[SoundCardBasePort+$04]:=VoiceRegister;
  259.   Left:=(Port[SoundCardBasePort+$05] and $f0) shr 4;
  260.   Right:=Port[SoundCardBasePort+$05] and $0f;
  261. end;

  262. procedure CheckMIDIVolume(var Left,Right:byte);
  263. begin
  264.   Port[SoundCardBasePort+$04]:=MIDIRegister;
  265.   Left:=(Port[SoundCardBasePort+$05] and $f0) shr 4;
  266.   Right:=Port[SoundCardBasePort+$05] and $0f;
  267. end;

  268. procedure CheckCDVolume(var Left,Right:byte);
  269. begin
  270.   Port[SoundCardBasePort+$04]:=CDRegister;
  271.   Left:=(Port[SoundCardBasePort+$05] and $f0) shr 4;
  272.   Right:=Port[SoundCardBasePort+$05] and $0f;
  273. end;

  274. procedure CheckLineVolume(var Left,Right:byte);
  275. begin
  276.   Port[SoundCardBasePort+$04]:=LineRegister;
  277.   Left:=(Port[SoundCardBasePort+$05] and $f0) shr 4;
  278.   Right:=Port[SoundCardBasePort+$05] and $0f;
  279. end;

  280. procedure CheckMicVolume(var Balance:byte);
  281. begin
  282.   Port[SoundCardBasePort+$04]:=MicRegister;
  283.   Balance:=Port[SoundCardBasePort+$05];
  284. end;

  285. procedure SelectVoiceInput(Source:byte);
  286. begin
  287.   Port[SoundCardBasePort+$04]:=$0c;
  288.   Port[SoundCardBasePort+$05]:=(Port[SoundCardBasePort+$05] and (not 7)) or ((Source shl 1) and 7);
  289. end;

  290. procedure EnableInputFilter;
  291. begin
  292.   Port[SoundCardBasePort+$04]:=$0c;
  293.   Port[SoundCardBasePort+$05]:=Port[SoundCardBasePort+$05] or 32;
  294. end;

  295. procedure DisableInputFilter;
  296. begin
  297.   Port[SoundCardBasePort+$04]:=$0c;
  298.   Port[SoundCardBasePort+$05]:=Port[SoundCardBasePort+$05] or (not 32);
  299. end;

  300. procedure EnableOutputFilter;
  301. begin
  302.   Port[SoundCardBasePort+$04]:=$0e;
  303.   Port[SoundCardBasePort+$05]:=Port[SoundCardBasePort+$05] or 64;
  304. end;

  305. procedure DisableOutputFilter;
  306. begin
  307.   Port[SoundCardBasePort+$04]:=$0e;
  308.   Port[SoundCardBasePort+$05]:=Port[SoundCardBasePort+$05] or (not 64);
  309. end;
复制代码



待续……。
回复

使用道具 举报

 楼主| 发表于 4-3-2011 06:29 PM | 显示全部楼层

……接上

  1. procedure SelectStereoOutput;
  2. begin
  3.   Port[SoundCardBasePort+$04]:=$0e;
  4.   Port[SoundCardBasePort+$05]:=Port[SoundCardBasePort+$05] or 2;
  5. end;

  6. procedure SelectMonoOutput;
  7. begin
  8.   Port[SoundCardBasePort+$04]:=$0e;
  9.   Port[SoundCardBasePort+$05]:=Port[SoundCardBasePort+$05] or (not 2);
  10. end;

  11. procedure SelectHighPassFilter;
  12. begin
  13.   Port[SoundCardBasePort+$04]:=$0c;
  14.   Port[SoundCardBasePort+$05]:=Port[SoundCardBasePort+$05] or 8;
  15. end;

  16. procedure SelectLowPassFilter;
  17. begin
  18.   Port[SoundCardBasePort+$04]:=$0c;
  19.   Port[SoundCardBasePort+$05]:=Port[SoundCardBasePort+$05] or (not 8);
  20. end;

  21. procedure ChangeSamplingRate(Rate:longint);
  22. begin
  23.   Port[SoundCardBasePort+WriteBufferRegister]:=$40;
  24.   repeat until Port[SoundCardBasePort+WriteBufferRegister]<128;
  25.   Port[SoundCardBasePort+WriteBufferRegister]:=Round(256-1000000/Rate);
  26. end;

  27. function PrepareRecordVoice:boolean;
  28. begin
  29.   DefineDefaultSwapFile('SOUND.SWP');

  30.   if EstablishVirtualMemory(ByteType,60*4*1024*RecordLength,1)<>0 then
  31.   begin
  32.     PrepareRecordVoice:=False;
  33.     Exit;
  34.   end;

  35.   PrepareRecordVoice:=True;
  36. end;

  37. procedure ShutRecordVoice;
  38. begin
  39.   DisposeVirtualMemory;

  40.   VoicePointer:=0;
  41.   VoiceLength:=0;
  42. end;

  43. procedure RecordVoice;
  44. begin
  45.   VoicePointer:=0;

  46.   repeat
  47.     Port[SoundCardBasePort+WriteBufferRegister]:=$20;
  48.     repeat until Port[SoundCardBasePort+DataAvailableRegister]>=128;

  49.     EnterDataByte(0,VoicePointer,Port[SoundCardBasePort+ReadDataRegister]);
  50.     Inc(VoicePointer);

  51.     repeat until SlaveSignal=not MasterSignal;
  52.     SlaveSignal:=MasterSignal;

  53.     if GetMouseEvent<>0 then
  54.       Break;
  55.   until VoicePointer>=(60*4*1024*RecordLength);

  56.   VoiceLength:=VoicePointer;
  57.   repeat until GetMouseEvent=0;
  58. end;

  59. procedure PlayVoice;
  60. begin
  61.   VoicePointer:=0;

  62.   repeat
  63.     Port[SoundCardBasePort+WriteBufferRegister]:=$10;
  64.     repeat until Port[SoundCardBasePort+WriteBufferRegister]<128;

  65.     Port[SoundCardBasePort+WriteBufferRegister]:=EnquireDataByte(0,VoicePointer);
  66.     Inc(VoicePointer);

  67.     repeat until SlaveSignal=not MasterSignal;
  68.     SlaveSignal:=MasterSignal;

  69.     if GetMouseEvent<>0 then
  70.       Break;
  71.   until VoicePointer>=VoiceLength;

  72.   repeat until GetMouseEvent=0;
  73. end;

  74. function SaveVoice(FileName:string;Description:string):boolean;
  75. var
  76.   Major,Minor:byte;
  77.   Left,Right:byte;
  78.   Counter:word;

  79. begin
  80.   SaveVoice:=False;
  81.   VoicePointer:=0;

  82.   {$I-}
  83.   Assign(DirectSoundFile,FileName);
  84.   Rewrite(DirectSoundFile);
  85.   {$I+}
  86.   if IOResult<>0 then
  87.     Exit;

  88.   CheckDSPVersion(Major,Minor);

  89.   DirectSoundFormat.ID:=DirectSoundFormatID;
  90.   DirectSoundFormat.Version:=(1 shl 8) or (0);
  91.   DirectSoundFormat.HardwareRevision:=(Major shl 8) or (Minor);
  92.   DirectSoundFormat.Description:=Description;

  93.   CheckMasterVolume(Left,Right);
  94.   DirectSoundFormat.MasterVolume:=(Left shl 8) or Right;
  95.   CheckVoiceVolume(Left,Right);
  96.   DirectSoundFormat.VoiceVolume:=(Left shl 8) or Right;

  97.   {$I-}
  98.   for Counter:=1 to 3 do
  99.   begin
  100.     VoiceData:=Ord(DirectSoundFormat.ID[Counter]);
  101.     Write(DirectSoundFile,VoiceData);
  102.   end;

  103.   VoiceData:=Hi(DirectSoundFormat.Version);
  104.   Write(DirectSoundFile,VoiceData);
  105.   VoiceData:=Lo(DirectSoundFormat.Version);
  106.   Write(DirectSoundFile,VoiceData);

  107.   for Counter:=1 to 255 do
  108.   begin
  109.     VoiceData:=Ord(DirectSoundFormat.Description[Counter]);
  110.     Write(DirectSoundFile,VoiceData);
  111.   end;

  112.   VoiceData:=Hi(DirectSoundFormat.HardwareRevision);
  113.   Write(DirectSoundFile,VoiceData);
  114.   VoiceData:=Lo(DirectSoundFormat.HardwareRevision);
  115.   Write(DirectSoundFile,VoiceData);

  116.   VoiceData:=Hi(DirectSoundFormat.Frequency);
  117.   Write(DirectSoundFile,VoiceData);
  118.   VoiceData:=Lo(DirectSoundFormat.Frequency);
  119.   Write(DirectSoundFile,VoiceData);

  120.   VoiceData:=Hi(DirectSoundFormat.MasterVolume);
  121.   Write(DirectSoundFile,VoiceData);
  122.   VoiceData:=Lo(DirectSoundFormat.MasterVolume);
  123.   Write(DirectSoundFile,VoiceData);

  124.   VoiceData:=Hi(DirectSoundFormat.VoiceVolume);
  125.   Write(DirectSoundFile,VoiceData);
  126.   VoiceData:=Lo(DirectSoundFormat.VoiceVolume);
  127.   Write(DirectSoundFile,VoiceData);

  128.   repeat
  129.     VoiceData:=EnquireDataByte(0,VoicePointer);
  130.     Inc(VoicePointer);

  131.     Write(DirectSoundFile,VoiceData);
  132.   until VoicePointer>=VoiceLength;

  133.   Close(DirectSoundFile);
  134.   {$I+}
  135.   if IOResult<>0 then
  136.     Exit;

  137.   SaveVoice:=True;
  138. end;

  139. function OpenVoice(FileName:string;Manual:boolean;var Description:string):boolean;
  140. var
  141.   Counter:word;

  142. begin
  143.   OpenVoice:=False;
  144.   VoicePointer:=0;

  145.   {$I-}
  146.   Assign(DirectSoundFile,FileName);
  147.   Reset(DirectSoundFile);
  148.   {$I+}
  149.   if IOResult<>0 then
  150.     Exit;

  151.   {$I-}
  152.   for Counter:=1 to 3 do
  153.   begin
  154.     Read(DirectSoundFile,VoiceData);
  155.     DirectSoundFormat.ID:=DirectSoundFormat.ID+Chr(VoiceData);
  156.   end;

  157.   if DirectSoundFormat.ID<>DirectSoundFormatID then
  158.     Exit;

  159.   Read(DirectSoundFile,VoiceData);
  160.   DirectSoundFormat.Version:=VoiceData shl 8;
  161.   Read(DirectSoundFile,VoiceData);
  162.   DirectSoundFormat.Version:=DirectSoundFormat.Version or VoiceData;

  163.   Description:='';

  164.   for Counter:=1 to 255 do
  165.   begin
  166.     Read(DirectSoundFile,VoiceData);
  167.     Description:=Description+Chr(VoiceData);
  168.   end;

  169.   Read(DirectSoundFile,VoiceData);
  170.   DirectSoundFormat.HardwareRevision:=VoiceData shl 8;
  171.   Read(DirectSoundFile,VoiceData);
  172.   DirectSoundFormat.HardwareRevision:=DirectSoundFormat.Version or VoiceData;

  173.   Read(DirectSoundFile,VoiceData);
  174.   DirectSoundFormat.Frequency:=VoiceData shl 8;
  175.   Read(DirectSoundFile,VoiceData);
  176.   DirectSoundFormat.Frequency:=DirectSoundFormat.Version or VoiceData;

  177.   Read(DirectSoundFile,VoiceData);
  178.   DirectSoundFormat.MasterVolume:=VoiceData shl 8;
  179.   Read(DirectSoundFile,VoiceData);
  180.   DirectSoundFormat.MasterVolume:=DirectSoundFormat.Version or VoiceData;

  181.   Read(DirectSoundFile,VoiceData);
  182.   DirectSoundFormat.VoiceVolume:=VoiceData shl 8;
  183.   Read(DirectSoundFile,VoiceData);
  184.   DirectSoundFormat.VoiceVolume:=DirectSoundFormat.Version or VoiceData;

  185.   if not Manual then
  186.   begin
  187.     ChangeTimerFrequency(DirectSoundFormat.Frequency);
  188.     {if Hi(DirectSoundFormat.HardwareRevision)>=2 then
  189.     begin
  190.       ChangeMasterVolume(Hi(DirectSoundFormat.MasterVolume),Lo(DirectSoundFormat.MasterVolume));
  191.       ChangeVoiceVolume(Hi(DirectSoundFormat.VoiceVolume),Lo(DirectSoundFormat.VoiceVolume));
  192.     end;}
  193.   end;

  194.   repeat
  195.     Read(DirectSoundFile,VoiceData);

  196.     EnterDataByte(0,VoicePointer,VoiceData);
  197.     Inc(VoicePointer);
  198.   until (VoicePointer>=(60*4*1024*RecordLength)) or (EOF(DirectSoundFile));

  199.   VoiceLength:=VoicePointer;

  200.   Close(DirectSoundFile);
  201.   {$I+}
  202.   if IOResult<>0 then
  203.     Exit;

  204.   OpenVoice:=True;
  205. end;

  206. begin
  207.   SoundCardBasePort:=$220;
  208.   RecordLength:=5;
  209. end.
复制代码


-完-
回复

使用道具 举报

 楼主| 发表于 4-3-2011 06:43 PM | 显示全部楼层
接下来,这是我自创的影像播放(没有采用压缩)的320x200x256格式。

影像播放模块:
  1. unit Movie;
  2. {
  3.   Direct Loading Video Service Unit
  4.   Revision 1997-1999
  5.   Researched and Developed Boo Khan Ming

  6.   Provide necessary code to display video at resolution of 320x200x256
  7.   consistently at predefined frame rate.

  8.   Video format established:

  9.          0-2            Video Format ID String (DLV)
  10.          3-4            Video Format Version Number
  11.          5-8            Total Frame
  12.          9-12           Frame Size (include palette)
  13.          13-14          Frame Rate (fps)
  14.          15-            DLP Picture (without header)


  15.   DLV Version 1.0

  16.   DLV Version 1.1      Added long description
  17.                        Added reserved space

  18.   DLV Version 1.2      Dynamic video size supported
  19.    Downward           (not necessary fixed at 320x200)
  20.     compatible
  21.     with DLV 1.1

  22.   .................

  23.   Unit Version 2.0     Total frame actual count supported

  24.   Unit Version 2.2     Enabled user frame rate

  25.   Unit Version 2.4     Reversed video playback supported

  26.                        Optimized video playback performance
  27.                        (reduced palette reprogramme jerky effect)

  28.   Unit Version 2.5     Significantly better video playback performance
  29.                        by preloading video data to extended memory (XMS)
  30. }

  31. interface

  32. type
  33.   VidHeaderRef=record
  34.     VidID:string[3];
  35.     VidVer:word;
  36.     Description:string;
  37.     Reserved:string[251];
  38.     Width:word;
  39.     Height:word;
  40.     TotalFrame:longint;
  41.     FrameSize:longint;
  42.     FrameRate:word;
  43.   end;

  44. procedure PrepareVideo;
  45. procedure ShutVideo;
  46. function OpenVideo(Filename:string):byte;
  47. procedure CloseVideo;
  48. function SeekFrame(Offset:longint):boolean;
  49. function LoadVideo:byte;
  50. procedure UnloadVideo;
  51. function PlayVideo(Mode:byte;UserFrameRate:word):boolean;
  52. function ReverseVideo(Mode:byte;UserFrameRate:word):boolean;
  53. function StepVideo(Mode:byte;StepRatio:word;UserFrameRate:word):boolean;
  54. function DiagnosticVideo(Mode:byte;StepRatio:word;var FrameRate:real;var Frame:longint):boolean;

  55. implementation

  56. uses CRT,DOS,Video,Mouse,Palette,Memory;

  57. const
  58.   VidIDRef:string[3]='DLV';

  59. type
  60.   VidPicRef=record
  61.     PicPal:array [1..768] of byte;
  62.     Pic:array [1..64000] of byte;
  63.   end;

  64. var
  65.   f:file;
  66.   r:registers;
  67.   l,c:longint;
  68.   Size:word;
  69.   VidPic:^VidPicRef;
  70.   VidHeader:VidHeaderRef;
  71.   VidHandle:word;
  72.   AdvancedPlayback:boolean;

  73. procedure PrepareVideo;
  74. begin
  75.   { prepare low resolution graphics screen }
  76.   asm
  77.     mov  ax, 0013h
  78.     int  10h
  79.   end;
  80. end;

  81. procedure ShutVideo;
  82. begin
  83.   TextMode(co80);
  84. end;

  85. function SeekFrame(Offset:longint):boolean;
  86. var
  87.   PalOfs:word;
  88.   PicSeg,PicOfs:word;
  89.   Width,Height:word;
  90.   VidOfs:longint;

  91. begin
  92.   SeekFrame:=False;

  93.   if AdvancedPlayback then
  94.   begin
  95.     VidOfs:=Offset-SizeOf(VidHeader);
  96.     TransferEMB(Longint(@VidPic^),0,VidOfs,VidHandle,VidHeader.FrameSize);
  97.     if XMSError<>0 then
  98.     begin
  99.       Exit;
  100.     end;
  101.   end
  102.   else
  103.   begin
  104.     {$I-}
  105.     Seek(f,Offset);
  106.     BlockRead(f,VidPic^,VidHeader.FrameSize);
  107.     {$I+}
  108.     if IOResult<>0 then
  109.       Exit;
  110.   end;

  111.   PalOfs:=Ofs(VidPic^.PicPal);
  112.   PicSeg:=Seg(VidPic^.Pic);
  113.   PicOfs:=Ofs(VidPic^.Pic);

  114.   Width:=VidHeader.Width;
  115.   Height:=VidHeader.Height;

  116.   if ((Width=320) and (Height=200))
  117.   or (VidHeader.VidVer<$0120) then
  118.   begin
  119.     asm
  120.       mov  ax, 1012h
  121.       xor  bx, bx
  122.       mov  cx, 256
  123.       mov  dx, PalOfs
  124.       int  10h
  125.       push ds
  126.       mov  ax, 0a000h
  127.       mov  es, ax
  128.       mov  ax, PicSeg
  129.       mov  ds, ax
  130.       xor  di, di
  131.       mov  si, PicOfs
  132.       mov  cx, 32000
  133.       rep  movsw
  134.       pop  ds
  135.     end;
  136.   end
  137.   else
  138.   begin
  139.     asm
  140.       mov  ax, 1012h
  141.       xor  bx, bx
  142.       mov  cx, 256
  143.       mov  dx, PalOfs
  144.       int  10h
  145.       push ds
  146.       mov  ax, 0a000h
  147.       mov  es, ax
  148.       mov  ax, PicSeg
  149.       mov  ds, ax
  150.       xor  di, di
  151.       mov  si, PicOfs
  152.       mov  cx, Height
  153.     @Draw:
  154.       push cx
  155.       mov  cx, Width
  156.       rep  movsb
  157.       add  di, 320
  158.       sub  di, Width
  159.       pop  cx
  160.       dec  cx
  161.       jnz  @Draw
  162.       pop  ds
  163.     end;
  164.   end;

  165.   SeekFrame:=True;
  166. end;

  167. function OpenVideo(Filename:string):byte;
  168. {
  169.   Error codes:  0=Successful
  170.                 1=Insufficient memory
  171.                 2=File open error
  172.                 3=Invalid video format
  173.                 255=Undefined error
  174. }

  175. begin
  176.   OpenVideo:=255;

  177.   AdvancedPlayback:=False;

  178.   { determine available memory }
  179.   if MaxAvail<SizeOf(VidPic^) then
  180.   begin
  181.     OpenVideo:=1;
  182.     Exit;
  183.   end;

  184.   { create new dynamic variable }
  185.   New(VidPic);

  186.   {$I-}
  187.   Assign(f,Filename);
  188.   Reset(f,1);

  189.   BlockRead(f,VidHeader,SizeOf(VidHeader));

  190.   {$I+}
  191.   if IOResult<>0 then
  192.   begin
  193.     OpenVideo:=2;
  194.     Exit;
  195.   end;

  196.   if VidHeader.VidID<>VidIDRef then
  197.   begin
  198.     OpenVideo:=3;
  199.     Exit;
  200.   end;

  201.   OpenVideo:=0;
  202. end;

  203. procedure CloseVideo;
  204. begin
  205.   {$I-}
  206.   Close(f);
  207.   {$I+}

  208.   { dispose dynamic variable }
  209.   Dispose(VidPic);
  210. end;

  211. function LoadVideo:byte;
  212. {
  213.   Error codes:  0=Successful
  214.                 1=XMS driver not installed
  215.                 2=Insufficient extended memory
  216.                 3=Unable to allocate extended memory
  217.                 4=Error encountered during video data transfer (loading)
  218.                 255=Undefined error
  219. }

  220. var
  221.   Offset:longint;

  222. begin
  223.   LoadVideo:=255;

  224.   AdvancedPlayback:=True;

  225.   if not XMSInstalled then
  226.   begin
  227.     LoadVideo:=1;
  228.     Exit;
  229.   end;

  230.   if EMBMaxAvail<(FileSize(f) div 1024) then
  231.   begin
  232.     LoadVideo:=2;
  233.     Exit;
  234.   end;

  235.   VidHandle:=AllocateEMB(FileSize(f) div 1024);
  236.   if XMSError<>0 then
  237.   begin
  238.     LoadVideo:=3;
  239.     Exit;
  240.   end;

  241.   Seek(f,SizeOf(VidHeader));
  242.   Offset:=0;

  243.   repeat
  244.     BlockRead(f,VidPic^,VidHeader.FrameSize,Size);
  245.     if Size<>0 then
  246.     begin
  247.       TransferEMB(Offset,VidHandle,Longint(@VidPic^),0,VidHeader.FrameSize);
  248.       Inc(Offset,VidHeader.FrameSize);

  249.       if XMSError<>0 then
  250.       begin
  251.         LoadVideo:=4;
  252.         Exit;
  253.       end;
  254.     end;
  255.   until (Size=0);

  256.   LoadVideo:=0;
  257. end;

  258. procedure UnloadVideo;
  259. begin
  260.   FreeEMB(VidHandle);
  261. end;

  262. function PlayVideo(Mode:byte;UserFrameRate:word):boolean;
  263. {
  264.   Modes:    0=Normal
  265.             1=Fast
  266.             2=Normal with UserFrameRate enabled
  267.             3=Fast with UserFrameRate enabled
  268. }

  269. var
  270.   VidPtr:longint;

  271. begin
  272.   PlayVideo:=False;

  273.   for l:=1 to VidHeader.TotalFrame do
  274.   begin
  275.     VidPtr:=((l-1)*VidHeader.FrameSize)+SizeOf(VidHeader);
  276.     if not SeekFrame(VidPtr) then
  277.       Exit;

  278.     if Keypressed then
  279.       Exit;
  280.     if GetMouseEvent<>0 then
  281.     begin
  282.       repeat until GetMouseEvent=0;

  283.       {PlayVideo:=True;}
  284.       Exit;
  285.     end;

  286.     if Mode=0 then
  287.       Delay(1000 div VidHeader.FrameRate)
  288.     else if Mode=2 then
  289.       Delay(1000 div UserFrameRate);
  290.   end;

  291.   PlayVideo:=True;
  292. end;

  293. function ReverseVideo(Mode:byte;UserFrameRate:word):boolean;
  294. {
  295.   Modes:    0=Normal
  296.             1=Fast
  297.             2=Normal with UserFrameRate enabled
  298.             3=Fast with UserFrameRate enabled
  299. }

  300. var
  301.   VidPtr:longint;

  302. begin
  303.   ReverseVideo:=False;

  304.   for l:=VidHeader.TotalFrame downto 1 do
  305.   begin
  306.     VidPtr:=((l-1)*VidHeader.FrameSize)+SizeOf(VidHeader);
  307.     if not SeekFrame(VidPtr) then
  308.       Exit;

  309.     if Keypressed then
  310.       Exit;
  311.     if GetMouseEvent<>0 then
  312.     begin
  313.       repeat until GetMouseEvent=0;
  314.       Exit;
  315.     end;

  316.     if Mode=0 then
  317.       Delay(1000 div VidHeader.FrameRate)
  318.     else if Mode=2 then
  319.       Delay(1000 div UserFrameRate);
  320.   end;

  321.   ReverseVideo:=True;
  322. end;

  323. function StepVideo(Mode:byte;StepRatio:word;UserFrameRate:word):boolean;
  324. {
  325.   Modes:    0=Normal
  326.             1=Fast
  327.             2=Normal with UserFrameRate enabled
  328.             3=Fast with UserFrameRate enabled
  329. }

  330. var
  331.   VidPtr:longint;

  332. begin
  333.   StepVideo:=False;

  334.   l:=1;

  335.   repeat
  336.     VidPtr:=((l-1)*VidHeader.FrameSize)+SizeOf(VidHeader);
  337.     if not SeekFrame(VidPtr) then
  338.       Exit;

  339.     if Keypressed then
  340.       Exit;

  341.     if Mode=0 then
  342.       Delay(1000 div VidHeader.FrameRate)
  343.     else if Mode=2 then
  344.       Delay(1000 div UserFrameRate);

  345.     Inc(l,StepRatio);
  346.   until l>VidHeader.TotalFrame;

  347.   StepVideo:=True;
  348. end;

  349. function DiagnosticVideo(Mode:byte;StepRatio:word;var FrameRate:real;var Frame:longint):boolean;
  350. {
  351.   Modes:    0=Normal
  352.             1=Fast
  353. }

  354. var
  355.   VidPtr:longint;
  356.   Hour,Min,Sec,Sec100:word;
  357.   OldMin,NewMin:word;
  358.   OldSec,NewSec:word;
  359.   FrameTick:real;

  360. begin
  361.   DiagnosticVideo:=False;

  362.   repeat
  363.     GetTime(Hour,Min,Sec,Sec100);
  364.   until Sec100=0;

  365.   OldMin:=Min;
  366.   OldSec:=Sec;
  367.   FrameRate:=0;
  368.   Frame:=0;

  369.   l:=1;

  370.   repeat
  371.     VidPtr:=((l-1)*VidHeader.FrameSize)+SizeOf(VidHeader);
  372.     if not SeekFrame(VidPtr) then
  373.       Exit;

  374.     if Mode=0 then
  375.       Delay(1000 div VidHeader.FrameRate);

  376.     Inc(l,StepRatio);

  377.     Inc(Frame);
  378.   until l>VidHeader.TotalFrame;

  379.   GetTime(Hour,Min,Sec,Sec100);

  380.   NewMin:=Min;
  381.   NewSec:=Sec;

  382.   if NewMin<OldMin then
  383.     NewMin:=NewMin+60;
  384.   if Sec100=0 then
  385.     Sec100:=1;

  386.   { compute frame rate using timer tick }
  387.   FrameTick:=((NewMin*60)+NewSec)-((OldMin*60)+OldSec)+(1/Sec100);
  388.   FrameRate:=VidHeader.TotalFrame/FrameTick;

  389.   DiagnosticVideo:=True;
  390. end;

  391. end.
复制代码
回复

使用道具 举报

 楼主| 发表于 4-3-2011 06:46 PM | 显示全部楼层
楼上的影像播放动用到内存模块(除了中断DOS Interrupt部分是采用别人的,其他都是自编的):

  1. {$G+}
  2. unit Memory;
  3. {
  4.   Memory Service Unit
  5.   Revision 1 (1998)
  6.   Developed by Boo Khan Ming

  7.   Provide all available functions and procedures to utilise the
  8.   XMS (Extended Memory), UMB (Upper Memory Block) and the heap.

  9.   The XMS interrupt call routines are based on external source.
  10. }

  11. interface

  12. var
  13.   XMSHandler:pointer;
  14.   XMSInstalled:boolean;
  15.   XMSError:byte;

  16. function ShrinkHeap:boolean;
  17. procedure ExpandHeap;
  18. procedure CopyMemory(Source,Destination,Count:word);
  19. function DumpMemory(Segment,Offset:word):string;
  20. function FindMemory(StartSegment,EndSegment:word;var FoundSegment,FoundOffset:word;FindString:string):boolean;

  21. function GetXMSVersion:longint;
  22. function RequestHMA(Size:word):boolean;
  23. function ReleaseHMA:boolean;
  24. function GlobalEnableA20:boolean;
  25. function GlobalDisableA20:boolean;
  26. function LocalEnableA20:boolean;
  27. function LocalDisableA20:boolean;
  28. function QueryA20:boolean;
  29. function EMBMaxAvail:word;
  30. function EMBMemAvail:word;
  31. function AllocateEMB(Size:word):word;
  32. function FreeEMB(Handle:word):boolean;
  33. function TransferEMB(DestinationOffset:longint;DestinationHandle:word;
  34.                      SourceOffset:longint;SourceHandle:word;
  35.                      Count:longint):boolean;
  36. function LockEMB(Handle:word):longint;
  37. function UnlockEMB(Handle:word):boolean;
  38. function GetEMBHandleInfo(Handle:word;var LockCount,FreeHandles:byte;var BlockSize:word):boolean;
  39. function ReallocateEMB(Handle:word;NewSize:word):boolean;
  40. function RequestUMB(Size:word):word;
  41. function ReleaseUMB(Segment:word):boolean;
  42. function UMBMemAvail:word;

  43. implementation

  44. function ShrinkHeap:boolean;
  45. var
  46.   Size:word;

  47. begin
  48.   Size:=MemW[Seg(HeapPtr):Ofs(HeapPtr)+2]-PrefixSeg+1;

  49.   asm
  50.     mov  bx, Size
  51.     mov  es, PrefixSeg
  52.     mov  ah, 4ah
  53.     int  21h

  54.     jc   @error
  55.     sub  al, al
  56.     jmp  @exit

  57.   @error:
  58.     mov  al, 01h
  59.   @exit:
  60.   end;
  61. end;

  62. procedure ExpandHeap;
  63. var
  64.   Size:word;

  65. begin
  66.   Size:=MemW[Seg(HeapEnd):Ofs(HeapEnd)+2]-PrefixSeg;

  67.   asm
  68.     mov  bx, Size
  69.     mov  es, PrefixSeg
  70.     mov  ah, 4ah
  71.     int  21h
  72.   end;
  73. end;

  74. procedure CopyMemory(Source,Destination,Count:word); assembler;
  75. asm
  76.   push ds
  77.   mov  ax, Source
  78.   mov  ds, ax
  79.   mov  ax, Destination
  80.   mov  es, ax
  81.   xor  si, si
  82.   xor  di, di
  83.   mov  cx, Count
  84.   rep  movsw
  85.   pop  ds
  86. end;

  87. function DumpMemory(Segment,Offset:word):string;
  88. var
  89.   Scan:^byte;
  90.   Range:word;
  91.   Content:string;

  92. begin
  93.   Range:=0;
  94.   Content:='';

  95.   repeat
  96.     Scan:=Ptr(Segment,Offset+Range);
  97.     if Scan^=0 then
  98.       Break;

  99.     Content:=Content+Chr(Scan^);
  100.     Inc(Range);
  101.   until Range>255;

  102.   DumpMemory:=Content;
  103. end;

  104. function FindMemory(StartSegment,EndSegment:word;var FoundSegment,FoundOffset:word;FindString:string):boolean;
  105. var
  106.   Scan:^byte;
  107.   SegmentPtr,OffsetPtr:longint;
  108.   Counter:byte;
  109.   Found:boolean;

  110. begin
  111.   FindMemory:=False;
  112.   Found:=False;

  113.   for SegmentPtr:=StartSegment to EndSegment do
  114.   begin
  115.     for OffsetPtr:=$0000 to $FFFF do
  116.     begin
  117.       Scan:=Ptr(SegmentPtr,OffsetPtr);

  118.       if UpCase(Chr(Scan^))=UpCase(FindString[1]) then
  119.       begin
  120.         for Counter:=1 to Length(FindString)-1 do
  121.         begin
  122.           Scan:=Ptr(SegmentPtr,OffsetPtr+Counter);
  123.           if UpCase(Chr(Scan^))<>UpCase(FindString[Counter+1]) then
  124.           begin
  125.             Found:=False;
  126.             Break;
  127.           end
  128.           else
  129.             Found:=True;
  130.         end;
  131.       end;

  132.       if Found then
  133.         Break;
  134.     end;

  135.     if Found then
  136.       Break;
  137.   end;

  138.   if Found then
  139.   begin
  140.     FindMemory:=True;

  141.     FoundSegment:=SegmentPtr;
  142.     FoundOffset:=OffsetPtr;
  143.   end;
  144. end;

  145. procedure XMSInterrupt; near; assembler;
  146. asm
  147.   push  SEG @DATA
  148.   pop   es
  149.   cmp   es:[XMSInstalled], 1
  150.   jnz   @fail
  151.   call  DWORD PTR es:[XMSHandler]
  152.   or    ax, ax
  153.   jnz   @success
  154.   push  ds
  155.   push  es
  156.   pop   ds
  157.   mov   XMSError, bl
  158.   pop   ds
  159. @fail:
  160.   xor   ax, ax
  161. @success:
  162. end;

  163. function GetXMSVersion:longint; assembler;
  164. asm
  165.   xor  ax, ax
  166.   xor  dx, dx
  167.   sub  ah, ah
  168.   call XMSInterrupt
  169.   xchg dx, bx
  170. end;

  171. function RequestHMA(Size:word):boolean; assembler;
  172. asm
  173.   mov  ah, 01h
  174.   call XMSInterrupt
  175. end;

  176. function ReleaseHMA:boolean; assembler;
  177. asm
  178.   mov  ah, 02h
  179.   call XMSInterrupt
  180. end;

  181. function GlobalEnableA20:boolean; assembler;
  182. asm
  183.   mov  ah, 03h
  184.   call XMSInterrupt
  185. end;

  186. function GlobalDisableA20:boolean; assembler;
  187. asm
  188.   mov  ah, 04h
  189.   call XMSInterrupt
  190. end;

  191. function LocalEnableA20:boolean; assembler;
  192. asm
  193.   mov  ah, 05h
  194.   call XMSInterrupt
  195. end;

  196. function LocalDisableA20:boolean; assembler;
  197. asm
  198.   mov  ah, 06h
  199.   call XMSInterrupt
  200. end;

  201. function QueryA20:boolean; assembler;
  202. asm
  203.   mov  ah, 07h
  204.   call XMSInterrupt
  205. end;

  206. function EMBMaxAvail:word; assembler;
  207. asm
  208.   mov  ah, 08h
  209.   call XMSInterrupt
  210. end;

  211. function EMBMemAvail:word; assembler;
  212. asm
  213.   xor  dx, dx
  214.   mov  ah, 08h
  215.   call XMSInterrupt
  216.   mov  ax, dx
  217. end;

  218. function AllocateEMB(Size:word):word; assembler;
  219. asm
  220.   mov  ah, 09h
  221.   mov  dx, Size
  222.   call XMSInterrupt
  223.   or   al, al
  224.   jz   @finish
  225.   mov  ax, dx
  226. @finish:
  227. end;

  228. function FreeEMB(Handle:word):boolean; assembler;
  229. asm
  230.   mov  dx, Handle
  231.   mov  ah, 0ah
  232.   call XMSInterrupt
  233. end;

  234. function TransferEMB(DestinationOffset:longint;DestinationHandle:word;
  235.                      SourceOffset:longint;SourceHandle:word;
  236.                      Count:longint):boolean;
  237. begin
  238.   asm
  239.     push ds
  240.     push ss
  241.     pop  ds
  242.     lea  si, Count
  243.     mov  ah, 0bh
  244.     call XMSInterrupt
  245.     mov  @Result, al
  246.     pop  ds
  247.   end
  248. end;

  249. function LockEMB(Handle:word):longint; assembler;
  250. asm
  251.   mov  ah, 0ch
  252.   mov  dx, handle
  253.   call XMSInterrupt
  254.   mov  ax, bx
  255. end;

  256. function UnlockEMB(Handle:word):boolean; assembler;
  257. asm
  258.   mov  ah, 0dh
  259.   mov  dx, Handle
  260.   call XMSInterrupt
  261. end;

  262. function GetEMBHandleInfo(Handle:word;var LockCount,FreeHandles:byte;var BlockSize:word):boolean; assembler;
  263. asm
  264.   mov  dx, Handle
  265.   mov  ah, 0eh
  266.   call XMSInterrupt
  267.   les  di, LockCount
  268.   mov  BYTE PTR es:[di], bh
  269.   les  di, FreeHandles
  270.   mov  BYTE PTR es:[di], bl
  271.   les  di, BlockSize
  272.   mov  WORD PTR es:[di], dx
  273. end;

  274. function ReallocateEMB(Handle:word;NewSize:word):boolean; assembler;
  275. asm
  276.   mov  ah, 0fh
  277.   mov  bx, NewSize
  278.   mov  dx, Handle
  279.   call XMSInterrupt
  280. end;

  281. function RequestUMB(Size:word):word; assembler;
  282. asm
  283.   mov  ah, 10h
  284.   mov  dx, Size
  285.   call XMSInterrupt
  286.   mov  ax, bx
  287. end;

  288. function ReleaseUMB(Segment:word):boolean; assembler;
  289. asm
  290.   mov  ah, 11h
  291.   mov  dx, Segment
  292.   call XMSInterrupt
  293. end;

  294. function UMBMemAvail:word; assembler;
  295. asm
  296.   mov  ah, 10h
  297.   mov  dx, 0ffffh
  298.   call XMSInterrupt
  299.   mov  ax, dx
  300. end;

  301. begin
  302.   asm
  303.     mov  ax, 4300h
  304.     int  2fh
  305.     cmp  al, 80h
  306.     jnz  @false
  307.     mov  ax, 4310h
  308.     int  2fh
  309.     mov  WORD PTR XMSHandler[0], bx
  310.     mov  WORD PTR XMSHandler[2], es
  311.     mov  XMSInstalled, 1
  312.     jmp  @true
  313.   @false:
  314.     mov  XMSInstalled, 0
  315.   @true:
  316.   end;
  317. end.
复制代码
回复

使用道具 举报

Follow Us
 楼主| 发表于 4-3-2011 06:49 PM | 显示全部楼层
除此之外,也需要用到彩色盘(Palette)的模块。
256色减至16色的颜色处理是我自研的技术。

  1. unit Palette;
  2. {
  3.   Palette Service Unit
  4.   Revision 2 (1998-1999)
  5.   Developed by Boo Khan Ming

  6.   Provide access to the video color palette and color processing options.
  7. }

  8. interface

  9. procedure SetPalette(PalReg,PalVal:byte);
  10. procedure SetPalette256(Color,Red,Green,Blue:byte);
  11. procedure GetPalette256(Color:byte;var Red,Green,Blue:byte);
  12. procedure SetIntensity(Level:byte);
  13. procedure GetIntensity;
  14. procedure InvertGraphicsPalette;
  15. procedure IncreaseBrightness;
  16. procedure DecreaseBrightness;
  17. function SimplifyColorComponent(Value:byte):byte;
  18. function DecreaseColor256(Red,Green,Blue:byte):byte;

  19. implementation

  20. type
  21.   ColorType=record
  22.     Red,Green,Blue:byte;
  23.   end;

  24. var
  25.   ColorTable:array [0..63] of ColorType;
  26.   VideoPal:array [0..255,0..2] of byte;
  27.   Color:byte;
  28.   Counter:word;
  29.   PalLevel:byte;
  30.   PalRedRatio,PalGreenRatio,PalBlueRatio:byte;

  31. procedure SetPalette(PalReg,PalVal:byte); assembler;
  32. asm
  33.   mov  ax, 1000h
  34.   mov  bl, PalReg
  35.   mov  bh, PalVal
  36.   int  10h
  37. end;

  38. procedure SetPalette256(Color,Red,Green,Blue:byte); assembler;
  39. asm
  40.   mov  dx, 03c8h
  41.   mov  al, Color
  42.   out  dx, al
  43.   inc  dx
  44.   mov  al, Red
  45.   mov  cl, 2
  46.   shr  al, cl
  47.   out  dx, al
  48.   mov  al, Green
  49.   mov  cl, 2
  50.   shr  al, cl
  51.   out  dx, al
  52.   mov  al, Blue
  53.   mov  cl, 2
  54.   shr  al, cl
  55.   out  dx, al
  56. end;

  57. procedure GetPalette256(Color:byte;var Red,Green,Blue:byte);
  58. begin
  59.   Port[$03c7]:=Color;
  60.   Red:=Port[$03c9];
  61.   Green:=Port[$03c9];
  62.   Blue:=Port[$03c9];
  63. end;

  64. procedure SetIntensity(Level:byte);
  65. begin
  66.   for Color:=0 to 63 do
  67.     SetPalette256(Color,ColorTable[Color].Red*Level div 63,
  68.                     ColorTable[Color].Green*Level div 63,
  69.                     ColorTable[Color].Blue*Level div 63);
  70. end;

  71. procedure GetIntensity;
  72. begin
  73.   for Color:=0 to 63 do
  74.     GetPalette256(Color,ColorTable[Color].Red,ColorTable[Color].Green,ColorTable[Color].Blue);
  75. end;

  76. procedure InvertGraphicsPalette;
  77. begin
  78.   for Counter:=0 to 255 do
  79.   begin
  80.     Port[$03c7]:=Counter;
  81.     VideoPal[Counter,0]:=Port[$03c9];
  82.     VideoPal[Counter,1]:=Port[$03c9];
  83.     VideoPal[Counter,2]:=Port[$03c9];
  84.   end;

  85.   for Counter:=0 to 255 do
  86.   begin
  87.     VideoPal[Counter,0]:=not VideoPal[Counter,0];
  88.     VideoPal[Counter,1]:=not VideoPal[Counter,1];
  89.     VideoPal[Counter,2]:=not VideoPal[Counter,2];

  90.     Port[$03c8]:=Counter;
  91.     Port[$03c9]:=VideoPal[Counter,0];
  92.     Port[$03c9]:=VideoPal[Counter,1];
  93.     Port[$03c9]:=VideoPal[Counter,2];
  94.   end;
  95. end;

  96. procedure IncreaseBrightness;
  97. begin
  98.   for Counter:=0 to 255 do
  99.   begin
  100.     Port[$03c7]:=Counter;
  101.     VideoPal[Counter,0]:=Port[$03c9];
  102.     VideoPal[Counter,1]:=Port[$03c9];
  103.     VideoPal[Counter,2]:=Port[$03c9];
  104.   end;

  105.   for Counter:=0 to 255 do
  106.   begin
  107.     for PalLevel:=0 to 2 do
  108.     begin
  109.       if VideoPal[Counter,PalLevel]<63 then
  110.         Inc(VideoPal[Counter,PalLevel]);
  111.     end;

  112.     Port[$03c8]:=Counter;
  113.     Port[$03c9]:=VideoPal[Counter,0];
  114.     Port[$03c9]:=VideoPal[Counter,1];
  115.     Port[$03c9]:=VideoPal[Counter,2];
  116.   end;
  117. end;

  118. procedure DecreaseBrightness;
  119. begin
  120.   for Counter:=0 to 255 do
  121.   begin
  122.     Port[$03c7]:=Counter;
  123.     VideoPal[Counter,0]:=Port[$03c9];
  124.     VideoPal[Counter,1]:=Port[$03c9];
  125.     VideoPal[Counter,2]:=Port[$03c9];
  126.   end;

  127.   for Counter:=0 to 255 do
  128.   begin
  129.     for PalLevel:=0 to 2 do
  130.     begin
  131.       if VideoPal[Counter,PalLevel]>0 then
  132.         Dec(VideoPal[Counter,PalLevel]);
  133.     end;

  134.     Port[$03c8]:=Counter;
  135.     Port[$03c9]:=VideoPal[Counter,0];
  136.     Port[$03c9]:=VideoPal[Counter,1];
  137.     Port[$03c9]:=VideoPal[Counter,2];
  138.   end;
  139. end;

  140. function SimplifyColorComponent(Value:byte):byte;
  141. begin
  142.   if Value>=52 then
  143.     SimplifyColorComponent:=63
  144.   else
  145.   if Value>=32 then
  146.     SimplifyColorComponent:=42
  147.   else
  148.   if Value>=12 then
  149.     SimplifyColorComponent:=21
  150.   else
  151.     SimplifyColorComponent:=0;
  152. end;

  153. function DecreaseColor256(Red,Green,Blue:byte):byte;
  154. const
  155.   Palette16:array [0..15,1..3] of byte=((0,0,0),(0,0,42),(0,42,0),(0,42,42),
  156.                                         (42,0,0),(42,0,42),(42,42,0),(42,42,42),
  157.                                         (0,0,21),(0,0,63),(0,42,21),(0,42,63),
  158.                                         (42,0,21),(42,0,63),(42,42,21),(42,42,63));
  159. var
  160.   Color,Component,Value:byte;
  161.   NewRed,NewGreen,NewBlue:byte;

  162. begin
  163.   DecreaseColor256:=0;
  164.   Component:=1;

  165.   repeat
  166.     case Component of
  167.       1:Value:=SimplifyColorComponent(Red div 4);
  168.       2:Value:=SimplifyColorComponent(Green div 4);
  169.       3:Value:=SimplifyColorComponent(Blue div 4);
  170.     end;

  171.     Color:=0;

  172.     while Value<>Palette16[Color,Component] do
  173.     begin
  174.       Inc(Color);

  175.       if Color>15 then
  176.       begin
  177.         Dec(Value,21);
  178.         Color:=0;
  179.       end;
  180.     end;

  181.     case Component of
  182.       1:NewRed:=Value;
  183.       2:NewGreen:=Value;
  184.       3:NewBlue:=Value;
  185.     end;

  186.     Inc(Component);

  187.   until Component>3;

  188.   for Color:=0 to 15 do
  189.     if (Palette16[Color,1]=NewRed) and (Palette16[Color,2]=NewGreen)
  190.     and (Palette16[Color,3]=NewBlue) then
  191.     begin
  192.       DecreaseColor256:=Color;
  193.       Exit;
  194.     end;
  195. end;

  196. end.
复制代码
回复

使用道具 举报

 楼主| 发表于 4-3-2011 06:53 PM | 显示全部楼层
至于另外的Video、Mouse模块很普通(大家的都是一样的),在这里就不列出来了。
回复

使用道具 举报


ADVERTISEMENT

发表于 4-3-2011 10:24 PM | 显示全部楼层
再来就是自行研发类似RLE(Run-Length Encoding)低效率的压缩技术----SqueezeTogether。

  1. unit Compress;
  2. {
  3.   Squeeze-Together(im) Compression Technology
  4.   Revision 1 (1999)
  5.   Researched and Developed by Boo Khan Ming

  6.   Compress all types of file regardless of file size.
  7. }

  8. interface

  9. function SqueezeFile(InputFileName,OutputFileName:string):byte;
  10. function StretchFile(InputFileName,OutputFileName:string):byte;

  11. implementation

  12. uses DOS;

  13. type
  14.   DataType=array [0..63999] of byte;

  15. var
  16.   Data:^DataType;
  17.   DataSize:longint;
  18.   SegmentIndex:longint;

  19.   InputFile:file;
  20.   OutputFile:file;

  21.   FrequencyTable:array [1..256] of word;
  22.   FrequencyTableSize:word;

  23.   UsedCodeList,UnusedCodeList:array [1..256] of byte;
  24.   UsedCode,UnusedCode:word;

  25.   FrequentlyUsedCodeList:array [1..256] of byte;
  26.   CodeMap:array [1..256] of longint;

  27.   Counter:longint;
  28.   Loop:word;
  29.   Code:byte;
  30.   Frequency:byte;
  31.   CollectMode:boolean;
  32.   Found:boolean;
  33.   AccessStatus:word;
  34.   FileDateTime:longint;

  35.   P1,P2:PathStr;
  36.   D1,D2:DirStr;
  37.   N1,N2:NameStr;
  38.   E1,E2:ExtStr;

  39. function SqueezeFile(InputFileName,OutputFileName:string):byte;
  40. {
  41.   Status Code
  42.   0 = Successful
  43.   1 = Insufficient Memory
  44.   2 = Unable to open input file
  45.   3 = File access error
  46.   4 = Unable to compress file
  47.   5 = Unable to create output file
  48.   255 = Undefined error
  49. }

  50.   function FetchCode(Index:longint):byte;
  51.   var
  52.     Refresh:boolean;

  53.   begin
  54.     FetchCode:=0;

  55.     if Index-1>DataSize then
  56.       Exit;

  57.     Refresh:=False;

  58.     if ((Index-1) div 64000)<>SegmentIndex then
  59.     begin
  60.       SegmentIndex:=(Index-1) div 64000;
  61.       Refresh:=True;
  62.     end;

  63.     if Refresh then
  64.     begin
  65.       {$I-}
  66.       Seek(InputFile,SegmentIndex*64000);
  67.       BlockRead(InputFile,Data^,64000,AccessStatus);
  68.       {$I+}
  69.       if IOResult<>0 then
  70.       begin
  71.         SqueezeFile:=3;
  72.         Exit;
  73.       end;
  74.     end;

  75.     FetchCode:=Data^[(Index-1) mod 64000];
  76.   end;

  77.   procedure AnalyseUsedCode;
  78.   var
  79.     Counter:longint;
  80.     Loop:word;
  81.     Found:boolean;

  82.   begin
  83.     UsedCode:=0;
  84.     FillChar(UsedCodeList,SizeOf(UsedCodeList),0);

  85.     for Counter:=1 to DataSize do
  86.     begin
  87.       Code:=FetchCode(Counter);
  88.       Inc(CodeMap[Code+1]);

  89.       Found:=False;

  90.       for Loop:=1 to UsedCode do
  91.         if UsedCodeList[Loop]=Code then
  92.         begin
  93.           Found:=True;
  94.           Break;
  95.         end;

  96.       if not Found then
  97.       begin
  98.         Inc(UsedCode);
  99.         UsedCodeList[UsedCode]:=Code;
  100.       end;
  101.     end;
  102.   end;

  103.   procedure AnalyseUnusedCode;
  104.   var
  105.     Counter:word;
  106.     Loop:word;
  107.     Found:boolean;

  108.   begin
  109.     UnusedCode:=0;
  110.     FillChar(UnusedCodeList,SizeOf(UnusedCodeList),0);

  111.     for Counter:=0 to 255 do
  112.     begin
  113.       Found:=False;

  114.       for Loop:=1 to UsedCode do
  115.         if UsedCodeList[Loop]=Counter then
  116.         begin
  117.           Found:=True;
  118.           Break;
  119.         end;

  120.       if not Found then
  121.       begin
  122.         Inc(UnusedCode);
  123.         UnusedCodeList[UnusedCode]:=Counter;
  124.       end;
  125.     end;
  126.   end;

  127.   procedure AnalyseFrequentlyUsedCode;
  128.   var
  129.     Loop1,Loop2:word;
  130.     Frequency:longint;
  131.     Index:byte;
  132.     Code:word;

  133.   begin
  134.     for Code:=1 to 256 do
  135.       FrequentlyUsedCodeList[Code]:=Code-1;

  136.     for Loop1:=2 to 256 do
  137.     begin
  138.       Frequency:=CodeMap[Loop1];
  139.       Index:=FrequentlyUsedCodeList[Loop1];

  140.       Loop2:=Loop1-1;

  141.       while (Frequency>CodeMap[Loop2]) and (Loop2>0) do
  142.       begin
  143.         CodeMap[Loop2+1]:=CodeMap[Loop2];
  144.         FrequentlyUsedCodeList[Loop2+1]:=FrequentlyUsedCodeList[Loop2];

  145.         Loop2:=Loop2-1;
  146.       end;

  147.       CodeMap[Loop2+1]:=Frequency;
  148.       FrequentlyUsedCodeList[Loop2+1]:=Index;
  149.     end;
  150.   end;

  151.   function FindReferenceIndex(Code:byte):byte;
  152.   var
  153.     Loop:word;

  154.   begin
  155.     FindReferenceIndex:=0;

  156.     for Loop:=1 to FrequencyTableSize do
  157.       if FrequentlyUsedCodeList[Loop]=Code then
  158.       begin
  159.         FindReferenceIndex:=UnusedCodeList[Loop];
  160.         Break;
  161.       end;
  162.   end;

  163.   function FindCodeIndex(Code:byte):byte;
  164.   var
  165.     Loop:word;

  166.   begin
  167.     FindCodeIndex:=0;

  168.     for Loop:=1 to FrequencyTableSize do
  169.       if UnusedCodeList[Loop]=Code then
  170.       begin
  171.         FindCodeIndex:=FrequentlyUsedCodeList[Loop];
  172.         Break;
  173.       end;
  174.   end;

  175.   procedure StoreCode;
  176.   begin
  177.     Code:=FetchCode(Counter);

  178.     BlockWrite(OutputFile,Code,1);
  179.   end;

  180.   procedure CompactCode;
  181.   begin
  182.     Code:=FindReferenceIndex(FetchCode(Counter-1));

  183.     BlockWrite(OutputFile,Code,1);
  184.     BlockWrite(OutputFile,Frequency,1);

  185.     Frequency:=0;
  186.   end;

  187. begin
  188.   SqueezeFile:=255;

  189.   if MaxAvail<64000 then
  190.   begin
  191.     SqueezeFile:=1;
  192.     Exit;
  193.   end;

  194.   {$I-}
  195.   Assign(InputFile,InputFileName);
  196.   Reset(InputFile,1);
  197.   {$I+}
  198.   if (IOResult<>0) or (FileSize(InputFile)=0) then
  199.   begin
  200.     SqueezeFile:=2;
  201.     Exit;
  202.   end;

  203.   DataSize:=FileSize(InputFile);
  204.   SegmentIndex:=0;

  205.   New(Data);

  206.   {$I-}
  207.   Seek(InputFile,SegmentIndex*64000);
  208.   BlockRead(InputFile,Data^,64000,AccessStatus);
  209.   {$I+}
  210.   if IOResult<>0 then
  211.   begin
  212.     SqueezeFile:=3;
  213.     Exit;
  214.   end;

  215.   AnalyseUsedCode;
  216.   AnalyseUnusedCode;
  217.   AnalyseFrequentlyUsedCode;

  218.   if UnusedCode=0 then
  219.   begin
  220.     SqueezeFile:=4;
  221.     Exit;
  222.   end;

  223.   P1:=InputFileName;
  224.   P2:=OutputFileName;
  225.   FSplit(P1,D1,N1,E1);
  226.   FSplit(P2,D2,N2,E2);

  227.   if (D2='') and (D1<>'') then
  228.   begin
  229.     D2:=D1;
  230.     P2:=D2+N2+E2;
  231.   end;

  232.   {$I-}
  233.   Assign(OutputFile,P2);
  234.   Rewrite(OutputFile,1);
  235.   {$I+}
  236.   if IOResult<>0 then
  237.   begin
  238.     SqueezeFile:=5;
  239.     Exit;
  240.   end;

  241.   if UnusedCode>UsedCode then
  242.     FrequencyTableSize:=UsedCode
  243.   else
  244.     FrequencyTableSize:=UnusedCode;

  245.   for Counter:=1 to FrequencyTableSize do
  246.     FrequencyTable[Counter]:=(UnusedCodeList[Counter] shl 8)+FrequentlyUsedCodeList[Counter];

  247.   BlockWrite(OutputFile,FrequencyTableSize,2);
  248.   BlockWrite(OutputFile,FrequencyTable,FrequencyTableSize*2);

  249.   Counter:=1;
  250.   Frequency:=0;
  251.   CollectMode:=False;

  252.   repeat
  253.     Found:=False;

  254.     for Loop:=1 to FrequencyTableSize do
  255.       if FetchCode(Counter)=FrequentlyUsedCodeList[Loop] then
  256.       begin
  257.         Found:=True;
  258.         Break;
  259.       end;

  260.     if CollectMode then
  261.       if FetchCode(Counter)<>FetchCode(Counter-1) then
  262.       begin
  263.         CompactCode;
  264.         CollectMode:=False;
  265.       end;

  266.     if (Found) or (CollectMode) then
  267.     begin
  268.       if Counter+2<DataSize then
  269.       begin
  270.         if (FetchCode(Counter)=FetchCode(Counter+1)) and (Frequency<252) then
  271.         begin
  272.           if (FetchCode(Counter+1)=FetchCode(Counter+2)) and (Frequency<252) then
  273.           begin
  274.             Inc(Frequency,3);
  275.             Inc(Counter,3);

  276.             CollectMode:=True;
  277.           end
  278.           else
  279.           begin
  280.             Inc(Frequency,2);
  281.             Inc(Counter,2);

  282.             CollectMode:=False;

  283.             CompactCode;
  284.           end;
  285.         end
  286.         else
  287.           CollectMode:=False;
  288.       end
  289.       else
  290.         CollectMode:=False;

  291.       if not CollectMode then
  292.         if Frequency>0 then
  293.         begin
  294.           Inc(Frequency);
  295.           Inc(Counter);

  296.           CompactCode;
  297.         end
  298.         else
  299.         begin
  300.           StoreCode;
  301.           Inc(Counter);
  302.         end;
  303.     end
  304.     else
  305.     begin
  306.       StoreCode;
  307.       Inc(Counter);
  308.     end;
  309.   until (Counter>DataSize) and (Frequency=0);

  310.   GetFTime(InputFile,FileDateTime);
  311.   SetFTime(OutputFile,FileDateTime);

  312.   Close(InputFile);
  313.   Close(OutputFile);

  314.   Dispose(Data);

  315.   SqueezeFile:=0;
  316. end;
复制代码
回复

使用道具 举报

发表于 4-3-2011 10:25 PM | 显示全部楼层

……续上

  1. function StretchFile(InputFileName,OutputFileName:string):byte;
  2. {
  3.   Status Code
  4.   0 = Successful
  5.   1 = Insufficient Memory
  6.   2 = Unable to open input file
  7.   3 = File access error
  8.   5 = Unable to create output file
  9.   255 = Undefined error
  10. }

  11.   function FetchCode(Index:longint):byte;
  12.   var
  13.     Refresh:boolean;
  14.     SeekIndex:longint;

  15.   begin
  16.     FetchCode:=0;

  17.     if Index-1>DataSize-((FrequencyTableSize*2)+2) then
  18.       Exit;

  19.     Refresh:=False;

  20.     if ((Index-1) div 64000)<>SegmentIndex then
  21.     begin
  22.       SegmentIndex:=(Index-1) div 64000;
  23.       Refresh:=True;
  24.     end;

  25.     if Refresh then
  26.     begin
  27.       SeekIndex:=((FrequencyTableSize*2)+2)+(SegmentIndex*64000);

  28.       {$I-}
  29.       Seek(InputFile,SeekIndex);
  30.       BlockRead(InputFile,Data^,64000,AccessStatus);
  31.       {$I+}
  32.       if IOResult<>0 then
  33.       begin
  34.         StretchFile:=3;
  35.         Exit;
  36.       end;
  37.     end;

  38.     FetchCode:=Data^[(Index-1) mod 64000];
  39.   end;

  40. begin
  41.   StretchFile:=255;

  42.   if MaxAvail<64000 then
  43.   begin
  44.     StretchFile:=1;
  45.     Exit;
  46.   end;

  47.   {$I-}
  48.   Assign(InputFile,InputFileName);
  49.   Reset(InputFile,1);
  50.   {$I+}
  51.   if (IOResult<>0) or (FileSize(InputFile)=0) then
  52.   begin
  53.     StretchFile:=2;
  54.     Exit;
  55.   end;

  56.   DataSize:=FileSize(InputFile);
  57.   SegmentIndex:=0;

  58.   New(Data);

  59.   {$I-}
  60.   BlockRead(InputFile,FrequencyTableSize,2);
  61.   BlockRead(InputFile,FrequencyTable,FrequencyTableSize*2);
  62.   {$I+}
  63.   if IOResult<>0 then
  64.   begin
  65.     StretchFile:=3;
  66.     Exit;
  67.   end;

  68.   {$I-}
  69.   BlockRead(InputFile,Data^,64000,AccessStatus);
  70.   {$I+}
  71.   if IOResult<>0 then
  72.   begin
  73.     StretchFile:=3;
  74.     Exit;
  75.   end;

  76.   P1:=InputFileName;
  77.   P2:=OutputFileName;
  78.   FSplit(P1,D1,N1,E1);
  79.   FSplit(P2,D2,N2,E2);

  80.   if (D2='') and (D1<>'') then
  81.   begin
  82.     D2:=D1;
  83.     P2:=D2+N2+E2;
  84.   end;

  85.   {$I-}
  86.   Assign(OutputFile,P2);
  87.   Rewrite(OutputFile,1);
  88.   {$I+}
  89.   if IOResult<>0 then
  90.   begin
  91.     StretchFile:=5;
  92.     Exit;
  93.   end;

  94.   Counter:=1;

  95.   repeat
  96.     Found:=False;

  97.     for Loop:=1 to FrequencyTableSize do
  98.       if FetchCode(Counter)=Byte(FrequencyTable[Loop] shr 8) then
  99.       begin
  100.         Code:=Byte(FrequencyTable[Loop]);
  101.         Frequency:=FetchCode(Counter+1);
  102.         Inc(Counter,2);

  103.         Found:=True;
  104.         Break;
  105.       end;

  106.     if Found then
  107.     begin
  108.       for Loop:=1 to Frequency do
  109.         BlockWrite(OutputFile,Code,1);
  110.     end
  111.     else
  112.     begin
  113.       Code:=FetchCode(Counter);
  114.       BlockWrite(OutputFile,Code,1);
  115.       Inc(Counter);
  116.     end;
  117.   until Counter>DataSize-((FrequencyTableSize*2)+2);

  118.   GetFTime(InputFile,FileDateTime);
  119.   SetFTime(OutputFile,FileDateTime);

  120.   Close(InputFile);
  121.   Close(OutputFile);

  122.   Dispose(Data);

  123.   StretchFile:=0;
  124. end;

  125. end.
复制代码


--完--
回复

使用道具 举报

发表于 4-3-2011 10:33 PM | 显示全部楼层
想在屏幕上显示比Turbo Pascal独有的WriteLn更快的字串?

我自编了DirectText。(记得Text Mode的内存地址是B800:0,所以直接写入内存就可以了)

  1. unit DirectText;
  2. {
  3.   DirectText Technology
  4.   Revision 1 (1997)
  5.   Developed by Boo Khan Ming

  6.   Enhance the text mode performance with direct video memory access.
  7. }

  8. interface

  9. procedure ChangeTextOffset(X,Y:byte);
  10. procedure ChangeTextRegion(X1,Y1,X2,Y2:byte);
  11. function RequestTextOffsetX:byte;
  12. function RequestTextOffsetY:byte;
  13. procedure ClearTextContent;
  14. procedure ChangeTextAppearance(OldColor,NewColor:byte);
  15. procedure InsertText(Content:string);
  16. procedure InsertNewText(Content:string);
  17. procedure InsertSingleText(Content:char);
  18. procedure InsertMultipleText(Content,Count:byte);
  19. procedure InsertNewMultipleText(Content,Count:byte);

  20. implementation

  21. uses CRT;

  22. const
  23.   TextContentLimitX=80;
  24.   TextContentLimitY=25;

  25. type
  26.   TextContentType=array [0..(TextContentLimitX*TextContentLimitX)-1] of word;

  27. var
  28.   TextContent:TextContentType absolute $b800:0;
  29.   TextContentOffsetX,TextContentOffsetY:byte;
  30.   TextContentLowerBoundX,TextContentLowerBoundY:byte;
  31.   TextContentUpperBoundX,TextContentUpperBoundY:byte;
  32.   CursorPosition:word absolute $0000:$0450;
  33.   Counter:byte;

  34. procedure AutoAdjustTextOffset;
  35. begin
  36.   if TextContentOffsetX<TextContentLowerBoundX then
  37.     TextContentOffsetX:=TextContentLowerBoundX;
  38.   if TextContentOffsetY<TextContentLowerBoundY then
  39.     TextContentOffsetY:=TextContentLowerBoundY;

  40.   if TextContentOffsetX>TextContentUpperBoundX then
  41.   begin
  42.     TextContentOffsetX:=TextContentLowerBoundX;
  43.     Inc(TextContentOffsetY);
  44.   end;

  45.   if TextContentOffsetY>TextContentUpperBoundY then
  46.     TextContentOffsetY:=TextContentUpperBoundY;
  47. {
  48.   asm
  49.     mov  ah, 02h
  50.     xor  bh, bh
  51.     mov  dh, TextContentOffsetY-1
  52.     mov  dl, TextContentOffsetX-1
  53.     int  10h
  54.   end;
  55. }
  56. {  CursorPosition:=(TextContentOffsetX shl 8)+TextContentOffsetY;}
  57. {  GotoXY(TextContentOffsetX,TextContentOffsetY);}
  58. end;

  59. procedure ChangeTextOffset(X,Y:byte);
  60. begin
  61.   TextContentOffsetX:=TextContentLowerBoundX+X-1;
  62.   TextContentOffsetY:=TextContentLowerBoundY+Y-1;

  63.   GotoXY(TextContentOffsetX,TextContentOffsetY);
  64. end;

  65. procedure ChangeTextRegion(X1,Y1,X2,Y2:byte);
  66. begin
  67.   TextContentLowerBoundX:=X1;
  68.   TextContentLowerBoundY:=Y1;
  69.   TextContentUpperBoundX:=X2;
  70.   TextContentUpperBoundY:=Y2;

  71.   TextContentOffsetX:=TextContentLowerBoundX;
  72.   TextContentOffsetY:=TextContentLowerBoundY;
  73. end;

  74. function RequestTextOffsetX:byte;
  75. begin
  76.   RequestTextOffsetX:=TextContentOffsetX;
  77. end;

  78. function RequestTextOffsetY:byte;
  79. begin
  80.   RequestTextOffsetY:=TextContentOffsetY;
  81. end;

  82. procedure ClearTextContent;
  83. var
  84.   CounterX,CounterY:byte;

  85. begin
  86.   for CounterX:=TextContentLowerBoundX to TextContentUpperBoundX do
  87.     for CounterY:=TextContentLowerBoundY to TextContentUpperBoundY do
  88.       TextContent[(CounterY-1)*TextContentLimitX+CounterX-1]:=255+TextAttr shl 8;
  89. end;

  90. procedure ChangeTextAppearance(OldColor,NewColor:byte);
  91. var
  92.   Counter:word;

  93. begin
  94.   Counter:=1;

  95.   repeat
  96.     if (Mem[$b800:Counter] and $f0)=(OldColor shl 4) then
  97.       Mem[$b800:Counter]:=(Mem[$b800:Counter] and $0f) or (NewColor shl 4);

  98.     Inc(Counter,2);
  99.   until Counter>4000;
  100. end;

  101. procedure InsertText(Content:string);
  102. begin
  103.   for Counter:=1 to Length(Content) do
  104.   begin
  105.     TextContent[(TextContentOffsetY-1)*TextContentLimitX+TextContentOffsetX-1]:=Ord(Content[Counter])+TextAttr shl 8;

  106.     Inc(TextContentOffsetX);
  107.     AutoAdjustTextOffset;
  108.   end;
  109. end;

  110. procedure InsertNewText(Content:string);
  111. begin
  112.   for Counter:=1 to Length(Content) do
  113.   begin
  114.     TextContent[(TextContentOffsetY-1)*TextContentLimitX+TextContentOffsetX-1]:=Ord(Content[Counter])+TextAttr shl 8;

  115.     Inc(TextContentOffsetX);
  116.     AutoAdjustTextOffset;
  117.   end;

  118.   TextContentOffsetX:=TextContentLowerBoundX;
  119.   Inc(TextContentOffsetY);
  120.   AutoAdjustTextOffset;
  121. end;

  122. procedure InsertSingleText(Content:char);
  123. begin
  124.   TextContent[(TextContentOffsetY-1)*TextContentLimitX+TextContentOffsetX-1]:=Ord(Content)+TextAttr shl 8;

  125.   Inc(TextContentOffsetX);
  126.   AutoAdjustTextOffset;
  127. end;

  128. procedure InsertMultipleText(Content,Count:byte);
  129. begin
  130.   for Counter:=1 to Count do
  131.   begin
  132.     TextContent[(TextContentOffsetY-1)*TextContentLimitX+TextContentOffsetX-1]:=Ord(Content)+TextAttr shl 8;

  133.     Inc(TextContentOffsetX);
  134.     AutoAdjustTextOffset;
  135.   end;
  136. end;

  137. procedure InsertNewMultipleText(Content,Count:byte);
  138. begin
  139.   for Counter:=0 to Count do
  140.   begin
  141.     TextContent[(TextContentOffsetY-1)*TextContentLimitX+TextContentOffsetX-1]:=Ord(Content)+TextAttr shl 8;

  142.     Inc(TextContentOffsetX);
  143.     AutoAdjustTextOffset;
  144.   end;

  145.   TextContentOffsetX:=TextContentLowerBoundX;
  146.   Inc(TextContentOffsetY);
  147.   AutoAdjustTextOffset;
  148. end;

  149. begin
  150.   TextContentLowerBoundX:=1;
  151.   TextContentLowerBoundY:=1;
  152.   TextContentUpperBoundX:=TextContentLimitX;
  153.   TextContentUpperBoundY:=TextContentLimitY;

  154.   TextContentOffsetX:=TextContentLowerBoundX;
  155.   TextContentOffsetY:=TextContentLowerBoundY;
  156. end.
复制代码
回复

使用道具 举报

发表于 4-3-2011 11:06 PM | 显示全部楼层
回复 9# FlierMate_


    不过实不相瞒,这套自创压缩原理分分钟有可能不是压缩文件,而是扩展文件(Negative Compression)使到压缩后的文件比原有的文件更大。见笑了,没有商业用途。

   除了分享外,我希望版主不要删除此帖,因为将来万一在互联网搜索不到自己的源代码,这里还可以作为备份。(我自己不想收藏)

谢谢各位。
回复

使用道具 举报

发表于 5-3-2011 12:43 AM | 显示全部楼层
发去sourceforge不行么?
回复

使用道具 举报

发表于 5-3-2011 01:09 AM | 显示全部楼层
发去sourceforge不行么?
chrizyuen2 发表于 5-3-2011 12:43 AM


     可以么?不是Linux那些才发去那边的吗?(难道DOS也可以?)
回复

使用道具 举报

发表于 5-3-2011 01:17 AM | 显示全部楼层
可以么?不是Linux那些才发去那边的吗?(难道DOS也可以?)
FlierMate_ 发表于 5-3-2011 01:09 AM


当然可以
回复

使用道具 举报

发表于 5-3-2011 01:19 AM | 显示全部楼层
回复 15# chrizyuen2


    哗!太好了。谢谢!
回复

使用道具 举报


ADVERTISEMENT

发表于 5-3-2011 02:02 AM | 显示全部楼层
当然可以
chrizyuen2 发表于 5-3-2011 01:17 AM



    还是不要了,主要原因是我不要再提供源代码上的支持了。
回复

使用道具 举报

发表于 11-3-2011 03:13 PM | 显示全部楼层
PASCAL.......想当年......
(下删50000字)
...
回复

使用道具 举报

发表于 13-3-2011 08:49 AM | 显示全部楼层
PASCAL.......想当年......
(下删50000字)
...
aquamax 发表于 11-3-2011 03:13 PM



    如果你不知道,另外有人写了FreePascal, Virtual Pascal都很不错。
回复

使用道具 举报

发表于 14-3-2011 04:22 PM | 显示全部楼层
COBOL有做过吗?
现在的MARKET都是.NET/JAVA的了....
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

 

ADVERTISEMENT



ADVERTISEMENT



ADVERTISEMENT

ADVERTISEMENT


版权所有 © 1996-2023 Cari Internet Sdn Bhd (483575-W)|IPSERVERONE 提供云主机|广告刊登|关于我们|私隐权|免控|投诉|联络|脸书|佳礼资讯网

GMT+8, 14-11-2025 12:42 PM , Processed in 0.152259 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表