[Resolu] Interruption mode reel depuis mode protegé avec DPMI

Interruption mode reel depuis mode protegé avec DPMI [Resolu] - ASM - Programmation

Marsh Posté le 19-11-2015 à 16:04:43    

Bonjour,
 
J'ai un programme en Borland Pascal 7 qui doit etre compilé en mode protégé. Dans ce programme, j'ai un appel a un interruption du mode réel. Donc j'ai besoin d'utiliser l'assembleur et les fonctions du DPMI.
Or mes connaissances en assembleur, DPMI et mémoire DOS sont proches du 0  :D
 
J'ai trouvé dans les spécifications du DMPI, le "Simulate Real Mode Interrupt" 0300H. http://www.ctyme.com/intr/rb-5831.htm
 
J'ai même trouvé des exemples :

Code :
  1. function  Intr386(const int_number:byte; const stack_words:word;
  2.                   var regs:DPMIRegisters) : word; assembler;
  3. (* Make Real Mode interrupt while in Protected Mode.         *)
  4. asm
  5.    xor bx,bx                                       { clear bx }
  6.    mov bl,int_number                  { load interrupt number }
  7.    mov cx,stack_words                       { get stack words }
  8.    les di,regs               { load effective address of regs }
  9.    mov ax,0300h                        { function number 300h }
  10.    int 31h                                   { call interrupt }
  11.    jc @pexit              { if error jump to end of procedure }
  12.    xor ax,ax                           { clear ax; successful }
  13. @pexit:                                    { end of procedure }
  14. end;


 

Code :
  1. type DPMIRegisters = record    { registers for DPMI int calls }
  2.       case byte of
  3.            1 : (EDI,ESI,EBP,EReserved,
  4.                 EBX,EDX,ECX,EAX:longint;
  5.                 Flags,ES,DS,FS,GS,
  6.                 IP,CS,SP,SS:word);
  7.            2 : (DI,XDI,SI,XSI,BP,XBP,Reserved,
  8.                 XReserved,BX,XBX,DX,XDX,CX,XCX,
  9.                 AX,XAX:word);
  10.            3 : (DIL,DIH,XDIL,XDIH,
  11.                 SIL,SIH,XSIL,XSIH,
  12.                 BPL,BPH,XBPL,XBPH,
  13.                 ReservedL,ReservedH,
  14.                 XReservedL,XReservedH,
  15.                 BL,BH,XBL,XBH,
  16.                 DL,DH,XDL,XDH,
  17.                 CL,CH,XCL,XCH,
  18.                 AL,AH,XAL,XAH,
  19.                 FlagsL,FlagsH,
  20.                 ESL,ESH,DSL,DSH,FSL,FSH,
  21.                 GSL,GSH,IPL,IPH,CSL,CSH,
  22.                 SPL,SPH,SSL,SSH:byte);
  23.         end;


 
Mais voilà, le hic c'est que je dois faire passer lors de mon appel à mon interruption $65, la structure suivante, qui de plus contient des buffers !!

Code :
  1. Type
  2. urbtype = Record
  3. transaction_token: byte (* control (2Dh), in (69h), out (E1h) as hex code *);
  4. chain_end_flag   : byte {another urb follow this urb in memory? zero=no,one=yes};
  5. dev_add          : byte;
  6. end_point        : byte;
  7. error_code       : byte;
  8. status           : byte (* returned by dosuhci *);
  9. transaction_flags: word (* reserved *);
  10. buffer_off       : word (* for in/out *);
  11. buffer_seg       : word (* for in/out *);
  12. buffer_length    : word (* for in/out *);
  13. actual_length    : word (* for in/out *);
  14. setup_buffer_off : word (* for control *);
  15. setup_buffer_seg : word (* for control *);
  16. start_frame      : word (* reserved *);
  17. nr_of_packets    : word (* iso *);
  18. int_interval     : byte (* reserved *);
  19. error_count      : byte (* reserved *);
  20. timeout          : word (* reserved *);
  21. next_urb_off     : word (* reserved *);
  22. next_urb_seg     : word (* reserved *);
  23. end (* 32 byte long *);


 

Code :
  1. Procedure do_out;  (* To PIC *)
  2. Var
  3. Reg: Registers;
  4. Begin
  5. (* set up out request *)
  6. urb.transaction_token := $E1;(* $E1= Sortie*)
  7. urb.chain_end_flag := 0;
  8. urb.dev_add := the_dev_add; 
  9. urb.end_point := out_endpoint;
  10. urb.error_code := 0;
  11. urb.status := 0;
  12. urb.transaction_flags := 0;
  13. urb.buffer_off := ofs(buffer_o);
  14. urb.buffer_seg := seg(buffer_o);
  15. urb.buffer_length := packetlen;
  16. urb.actual_length := 64;
  17. urb.setup_buffer_off := 0;
  18. urb.setup_buffer_seg := 0;
  19. urb.start_frame := 0;
  20. urb.nr_of_packets := 0;
  21. urb.int_interval := 0;
  22. urb.error_count := 0;
  23. urb.timeout := 0;
  24. urb.next_urb_off := 0;
  25. urb.next_urb_seg := 0;
  26. (* now call DosUHCI *)
  27. Reg.DS := seg(urb);
  28. Reg.DX := ofs(urb);
  29. Intr($65, Reg); (*NE FONCTIONNE PAS EN MODE PROTEGE*)
  30. Inc(ReqNr);
  31. End (* do_out *);


 
Bref ça fait 2 semaines que je suis dessus et que je mouline. N'hesitez pas a me poser des questions. J'ai toujours des difficultés pour arriver à etre clair.
 
Merci


Message édité par rocky77 le 25-11-2015 à 00:15:50
Reply

Marsh Posté le 19-11-2015 à 16:04:43   

Reply

Marsh Posté le 19-11-2015 à 17:07:06    

Alors je regarderais ce que j'ai dans mes archives.
Comme je disais en MP, ça fait 15 ans que j'ai pas fait ça :D

Reply

Marsh Posté le 19-11-2015 à 17:17:22    

Une doc un peu plus claire:
http://www.delorie.com/djgpp/doc/dpmi/api/310300.html


Message édité par bjone le 20-11-2015 à 14:59:29
Reply

Marsh Posté le 20-11-2015 à 14:18:15    

J'avais deja reperé cette doc.

 

Je vais tenter par faire un truc simple.

 
Code :
  1. asm
  2.    mov ah, 2Ch   //Fonction 2Ch Gettime
  3.    int 21h           //Dos Int.
  4.    mov hour, CH
  5.    mov minut, CL
  6. end;
  7. writeln('Heure',hour,':',minut);
 

Ce code fonctionne car dmpi converti automatiquement l'interruption en mode reel.(automatic mirroring of interrupts into real mode by DMPI). Donc je vais essayer de refaire ce code comme si DMPI ne prenait pas en charge cette conversion, et du coup essayer d'utiliser le 300h (simulation interruption mode reel)...Toute aide est le bienvenue  :)


Message édité par rocky77 le 20-11-2015 à 14:19:01
Reply

Marsh Posté le 20-11-2015 à 15:01:23    

Désolé, j'ai pas pris le temps de regarder dans mes archives.
 
Par contre du cas tu en es où ?
Tu fait ton appel dpmi et ça crashe ?

Reply

Marsh Posté le 20-11-2015 à 15:07:43    

J'en suis a essayer de comprendre comment faire pour allouer ma structure et mes buffer dans le bloc memoire dos.
Donc dans un premier temps, j'essaie avec l'exemple de la fonction gettime ou il n'a que la fonction 2Ch à passer.
Puis j’essaierais avec la fonction 09h (afficher du texte) qui necessite en plus de transferrer du texte.
 
Et si ca marche je continue avec ma structure et mes buffers.
 

Code :
  1. Program heure;
  2. USES CRT,dos, winapi;
  3. type
  4. DPMIRegisters = Record  {Registers for DPMI int callst}
  5.     DPMI_EDI, DPMI_ESI, DPMI_EBP, EReserved,
  6.     DPMI_EBX, DPMI_EDX, DPMI_ECX, DPMI_EAX : longint;
  7.     DPMI_Flags, DPMI_ES, DPMI_DS, DPMI_FS, DPMI_GS,
  8.     DPMI_IP, DPMI_CS, DPMI_SP, DPMI_SS : word;
  9. end;
  10. var
  11.   hour, minute : shortint;
  12.   dcs : DPMIRegisters;
  13.   transfer_Buf_Seg: word;
  14.   transfer_Buf : word;
  15. function Intr386(const int_number:byte; const stack_words:word;
  16.                        var regs:DPMIRegisters): word; assembler;
  17. asm
  18.    xor bx, bx
  19.    mov bl, int_number
  20.    mov cx, stack_words
  21.   ; mov dx, ds
  22.   ; mov es, dx
  23.    les di,regs
  24.    mov ax, 0300h
  25.    int 31h
  26. end;
  27. BEGIN
  28. asm
  29.    mov ax, 0100h
  30.    mov bx, 8
  31.    int 31h
  32.    mov [transfer_Buf], dx
  33.    mov [transfer_Buf_Seg], ax
  34.    mov word[dcs.DPMI_EAX], 2Ch
  35.    mov word[dcs.DPMI_EDX], 0
  36.    mov ax, [transfer_Buf_Seg]
  37.    mov word[dcs.DPMI_DS], ax
  38.   end;
  39.    writeln('debut appel');
  40.    intr386($21,0,dcs);
  41.   writeln('hour ',hour,':',minute);
  42. END.


 
Je me retrouve avec une erreur d'allocation memoire :(


Message édité par rocky77 le 20-11-2015 à 16:00:14
Reply

Marsh Posté le 20-11-2015 à 16:44:18    

Si tu est bien en adressage flat 32bits, ça devrait être:
 
les edi, regs
 
mais lds sous-entends que "var regs:DPMIRegisters" devrait faire que "regs" résoudra vers une pointeur far de "dcs" en mode protégé (sélecteur 16bits:offset 32bits).
 
Si "regs" résous vers l'offset même de la structure "dcs" (sous-entendu par rapport à ds), alors il faut utiliser "lea edi,[dcs]".
(dans cas copier ds dans es, comme tu avais mis en commentaire)
 
 

Reply

Marsh Posté le 20-11-2015 à 17:59:08    

Première étape, la plus simple, enfin bonne. J'ai tout revu, je m’étais planté dans le placement de mon 2C.  
J'arrive a récupérer l'heure système a partir d'une simulation d'interruption (300h)
 

Code :
  1. Program tmem;
  2. USES CRT,dos, winapi;
  3. type
  4. DPMIRegisters = Record  {Registers for DPMI int callst}
  5.     DPMI_EDI, DPMI_ESI, DPMI_EBP, EReserved,
  6.     DPMI_EBX, DPMI_EDX, DPMI_ECX, DPMI_EAX : longint;
  7.     DPMI_Flags, DPMI_ES, DPMI_DS, DPMI_FS, DPMI_GS,
  8.     DPMI_IP, DPMI_CS, DPMI_SP, DPMI_SS : word;
  9. end;
  10. var
  11.   hour, minute : shortint;
  12.   dcs : DPMIRegisters;
  13.   transfer_Buf_Seg: word;
  14.   transfer_Buf : word;
  15.   selector, segment : word;
  16.   selseg :longint;
  17. function Intr386(const int_number:byte; const stack_words:word;
  18.                        var regs:DPMIRegisters): word; assembler;
  19. asm
  20.    push es
  21.    push di
  22.    xor bx, bx
  23.    mov bl, int_number
  24.    mov cx, stack_words
  25.    les di,regs
  26.    mov ax, 0300h
  27.    int 31h
  28.    pop di
  29.    pop es
  30. end;
  31. BEGIN
  32.    dcs.DPMI_EAX := $00002C00;  {fonction 2C de int $21}
  33.    dcs.DPMI_EDI := 0;
  34.    writeln('debut appel');
  35.    intr386($21,0,dcs);
  36.    hour:=word(dcs.DPMI_ECX SHR 8);
  37.    minute:=word(dcs.DPMI_ECX AND $00FF);
  38.    writeln('dcs = ',word(dcs.DPMI_ECX));
  39.    writeln('hour ',hour,':',minute);
  40.   repeat until keypressed;
  41. END.


 
 Prochaine étape. Essayer d'envoyer la structure suivante sur l'interruption $65. Ca attendra lundi :)
 

Code :
  1. urb.transaction_token := $E1;(* $E1= Sortie*)
  2. urb.chain_end_flag := 0;
  3. urb.dev_add := the_dev_add;  (* Adresse Microchip =1 si c'est le seul usb connecte à la carte mere*)
  4. urb.end_point := out_endpoint;    (* =1 *)
  5. urb.error_code := 0;
  6. urb.status := 0;
  7. urb.transaction_flags := 0;
  8. urb.buffer_off := ofs(buffer_o);
  9. urb.buffer_seg := seg(buffer_o);
  10. urb.buffer_length := packetlen;
  11. urb.actual_length := 64;
  12. urb.setup_buffer_off := 0;
  13. urb.setup_buffer_seg := 0;
  14. urb.start_frame := 0;
  15. urb.nr_of_packets := 0;
  16. urb.int_interval := 0;
  17. urb.error_count := 0;
  18. urb.timeout := 0;
  19. urb.next_urb_off := 0;
  20. urb.next_urb_seg := 0;


Reply

Marsh Posté le 23-11-2015 à 14:43:27    

J'ai vu sous Borland pascal une fonction qui me semble intéressante  
GlobalDosAlloc qui me permet d'allouer un zone mémoire sous les 640k
 

Code :
  1. var
  2. selseg : longint;
  3. segment, selector :word
  4. .....
  5. selseg   := globaldosalloc (64) {64 bytes taille de l'espace memoire sous less 640k.}
  6. selector := word(selseg and $FFFF); {conversion en word - le poids faible determine le selecteur pour utilisation mode protegé}
  7. segment := word(selseg and SHR 16); {conversion en word - le poids fort determine le segment pour utilisation mode reel}

 
 
 
Mais là je ne sais pas trop comment m''y prendre. J'ai ma structure urb qui est actuellement en mémoire protegé. Il faudrait que je puisse la copier en mémoire réel ainsi que son contenu. Mais comment ?


Message édité par rocky77 le 23-11-2015 à 14:44:01
Reply

Marsh Posté le 23-11-2015 à 15:53:58    

GlobalDosAlloc ça permet effectivement de communiquer avec des services nécessitant des grosses structures en mémoire conventionnelle.
 
Après il y a un truc que je comprends pas : vu winapi et des registres -que- 16bits dans ton source, tu fais quoi avec BC7 ? un projet win16 ?
 
Ou alors ton projet est bien setupé pour du mode protégé (opérandes implicitement 32bits pour les même opcodes 16bits du mode réel), et tu utilises sciemment ce trick pour contourner les limites de BP7 ?
 
Normalement on faisait plutôt du DPMI pour un jeu/une démo sous à Dos à l'époque.
 
Si c'est pour attaquer un PIC en USB, normalement en Win32/64, tu as WinUSB & co...


Message édité par bjone le 23-11-2015 à 16:03:59
Reply

Marsh Posté le 23-11-2015 à 15:53:58   

Reply

Marsh Posté le 23-11-2015 à 16:10:05    

Oui c'est un projet qui doit tourner uniquement sous dos et qui doit obligatoirement être compilé en protected mode. Borland Pascal 7 sait gerer le DMPI.
 
Mon but est de pouvoir à partir de mon programme faire appel a un programme résident (un driver USB - DOSUSB.COM) via l'interruption 65 en envoyant la structure URB qui contient le segment et l'offset d'un buffer.
 
Tu me dis si je ne suis pas clair :pt1cable:  
 
Je viens de trouver ça aussi, je vais voir si je peux m'en servir
ProtectedAddr := Ptr(L and $FFFF, 0);  
Move( FontData, ProtectedAddr^, Size);
 
Edit : Ah qu'est ce que j'aurais voulu utliser WinUSB, ca m'aurait bien facilité la tache. Malheuresement, on m'impose BP7 (mon boss), Compilation en mode protected et bien sur que ca tourne sous dos, le vrai MS DOS

Message cité 1 fois
Message édité par rocky77 le 23-11-2015 à 16:13:22
Reply

Marsh Posté le 23-11-2015 à 17:52:53    

Je pense que je progresse, mais aussi que je me melange les pinceaux. J'ai toujours du mal avec les notions de segments, selector, offset ....malgré la lecture de documentation
 

Code :
  1. Uses DOS, CRT, WINAPI;
  2. Const
  3. the_dev_add = 1;    (*Adresse peripherique usb*)
  4. in_endpoint = 1;
  5. out_endpoint = 1;    (* 2 avant *)
  6. (* myFN = 'dosuhci.txt';*)
  7. ATTENTE : INTEGER = 800  ;
  8. type
  9. DPMIRegisters = Record  {Registers for DPMI int callst}
  10.     DPMI_EDI, DPMI_ESI, DPMI_EBP, EReserved,
  11.     DPMI_EBX, DPMI_EDX, DPMI_ECX, DPMI_EAX : longint;
  12.     DPMI_Flags, DPMI_ES, DPMI_DS, DPMI_FS, DPMI_GS,
  13.     DPMI_IP, DPMI_CS, DPMI_SP, DPMI_SS : word;
  14. end;
  15. (* define structure of URB *)
  16. Type
  17. urbtype = Record
  18. transaction_token: byte (* control (2Dh), in (69h), out (E1h) as hex code *);
  19. chain_end_flag   : byte {another urb follow this urb in memory? zero=no,one=yes};
  20. dev_add          : byte;
  21. end_point        : byte;
  22. error_code       : byte;
  23. status           : byte (* returned by dosuhci *);
  24. transaction_flags: word (* reserved *);
  25. buffer_off       : word (* for in/out *);
  26. buffer_seg       : word (* for in/out *);
  27. buffer_length    : word (* for in/out *);
  28. actual_length    : word (* for in/out *);
  29. setup_buffer_off : word (* for control *);
  30. setup_buffer_seg : word (* for control *);
  31. start_frame      : word (* reserved *);
  32. nr_of_packets    : word (* iso *);
  33. int_interval     : byte (* reserved *);
  34. error_count      : byte (* reserved *);
  35. timeout          : word (* reserved *);
  36. next_urb_off     : word (* reserved *);
  37. next_urb_seg     : word (* reserved *);
  38. end (* 32 byte long *);
  39. type
  40. buffer = Array[0..255] Of Byte;
  41. p_buffer = ^buffer;
  42. Var
  43. urb: urbtype;
  44. buffer_o: Array[0..(*1024-1*)255] Of Byte;
  45. buffer_i: Array[0..(*1024-1*)255] Of Byte;
  46. packetlen: Word;
  47. bStr: String;
  48. f: File;
  49. ReqNr: Word;
  50. tab_out: Array[0..16] Of Byte;   {To PIC}
  51. tab_in: Array[0..32] Of Byte;   {From PIC}
  52. i,j,choix,val,quit_proc,quit_ok: integer;
  53. SNOOPY, TEST_SNOOPY : BOOLEAN ;
  54. selseg, selseg_buff :longint;
  55. selector, selector_buff, segment, segment_buff : word;
  56. P_PM : p_buffer;
  57. P_PM_buff : p_buffer;
  58. function Intr386(const int_number:byte; const stack_words:word;
  59.                        var regs:DPMIRegisters): word; assembler;
  60. asm
  61.    push es
  62.    push di
  63.    xor bx, bx
  64.    mov bl, int_number
  65.    mov cx, stack_words
  66.    les di,regs
  67.    mov ax, 0300h
  68.    int 31h
  69.    pop di
  70.    pop es
  71. end;
  72. {//////////////////////////// DO_OUT //////////////////////////////////}
  73. Procedure do_out;  { To PIC }
  74. Var
  75.   DCS : DPMIRegisters;
  76. Begin
  77. selseg := globaldosalloc(40 );
  78. selector := word(selseg and $FFFF);
  79. segment := word(selseg SHR 16);
  80. P_PM:=ptr(selector,0);  {pointeur pour remplir ma structure dans la memoire <640k}
  81. writeln('1 ');
  82. selseg_buff := globaldosalloc(257);
  83. selector_buff := word(selseg_buff and $FFFF);
  84. segment_buff := word(selseg_buff SHR 16);
  85. P_PM_buff:=ptr(selector_buff,0);  {pointeur pour remplir mon buffer dans la memoire <640k}
  86. writeln('2 - size de buffer_o = ',sizeof(buffer_o));
  87. move(buffer_o,P_PM_Buff^,sizeof(buffer_o)); {copie des données du buffer dans la memoire <640k}
  88. writeln('3 ',P_PM_Buff^[0],' ',P_PM_Buff^[1],' ',P_PM_Buff^[2]);
  89. (* set up out request *)
  90. urb.transaction_token := $E1;(* $E1= Sortie*)
  91. urb.chain_end_flag := 0;
  92. urb.dev_add := the_dev_add;  (* Adresse Microchip =1 si c'est le seul usb connecte à la carte mere*)
  93. urb.end_point := out_endpoint;    (* =1 *)
  94. urb.error_code := 0;
  95. urb.status := 0;
  96. urb.transaction_flags := 0;
  97. urb.buffer_off := 0;(*ofs(P_PM_Buff^);*) {quoi mettre ??? ofs(P_PM_Buff^) ? 0? autre?}
  98. urb.buffer_seg := selector_buff;(*(seg(P_PM_Buff^);*) {quoi mettre ??? seg(P_PM_Buff^) ? autre ?
  99. urb.buffer_length := packetlen;
  100. urb.actual_length := 64;
  101. urb.setup_buffer_off := 0;
  102. urb.setup_buffer_seg := 0;
  103. urb.start_frame := 0;
  104. urb.nr_of_packets := 0;
  105. urb.int_interval := 0;
  106. urb.error_count := 0;
  107. urb.timeout := 0;
  108. urb.next_urb_off := 0;
  109. urb.next_urb_seg := 0;
  110. (* now call DosUHCI *)
  111. fillchar(dcs, sizeof(dcs), 0);
  112. move(urb,P_PM^,sizeof(urb));  {copie des données de la struct. URB dans la memoire <640k}
  113. writeln('4');
  114. DCS.DPMI_ES := segment;{Est ce vraiment ca qu'il faut mettre}
  115. DCS.DPMI_DS := seg(P_PM^); {Est ce vraiment ca qu'il faut mettre}
  116. DCS.DPMI_EDX :=ofs(P_PM^);{Est ce vraiment ca qu'il faut mettre}
  117. writeln('5');
  118. intr386($65, 0, dcs);
  119. GlobalDosFree(selector);
  120. GlobalDosFree(selector_buff);
  121. (* Reg.DS := seg(urb); {Ce que je cherche a remplacer depuis le debut !!!! Arghh}
  122. Reg.DX := ofs(urb); {Ce que je cherche a remplacer depuis le debut !!!! Arghh}
  123. Intr($65,Reg);*) {Ce que je cherche a remplacer depuis le debut !!!! Arghh}
  124. Inc(ReqNr);
  125. End (* do_out *);
  126. (*//////////////////////////// MAIN ////////////////////////////////////*)
  127. Begin
  128.   ReqNr:=0;
  129.   for i:=0 to 16 do tab_out[i]:=0;
  130.   tab_out[2] := 64;
  131.   packetlen:=17;
  132.   for i:=0 to 16 do buffer_o[i]:=tab_out[i];
  133.   do_out;
  134.   repeat until keypressed;
  135. end. (* AXUSB.PAS *)


Message édité par rocky77 le 24-11-2015 à 10:55:53
Reply

Marsh Posté le 23-11-2015 à 18:22:21    

[:drapal]

Reply

Marsh Posté le 25-11-2015 à 00:11:33    

Probleme résolu !
 
Merci à tous, je posterais la soluce demain, tranquillement.

Reply

Marsh Posté le 25-11-2015 à 10:01:47    

rocky77 a écrit :


Edit : Ah qu'est ce que j'aurais voulu utliser WinUSB, ca m'aurait bien facilité la tache. Malheuresement, on m'impose BP7 (mon boss), Compilation en mode protected et bien sur que ca tourne sous dos, le vrai MS DOS


 
Dans un contexte professionnel, si c'est pour maintenir du vieux software utilisé en production je veux bien (typique de l'info indus), mais autrement ce serait plus sain de rebooter l'appli avec un outil moderne et pérenne.

Reply

Marsh Posté le 25-11-2015 à 10:38:42    

J'ai deja tenté de dire à mon boss qu'il serait temps de mettre à niveau le programme (qui doit bien avoir 50000 lignes de code). Mais il aime bien les vieux trucs et surtout veut pas se lancer dans cette mise à niveau.
Du coup, on se fait ch.., enfin je me fais ch... pour la maintenance de son programme indigeste :pt1cable: :fou:

Reply

Marsh Posté le 25-11-2015 à 10:49:44    

Le prob c'est que pour une réécriture d'un soft, il faut de la force de frappe.
 
Maintenant le premier truc à voir c'est le ratio code "fonctionnel" (ce qui est réellement utilie, ce qui traite vraiment de la donnée)/ code "inutile" (ce qui est imposé par les frameworks : ie par exemple les MFC sont responsables d'un gros tas de merde dans beaucoup de projets qui datent de la fin des années 90).
 
En réutilisant un framework moderne, tu élagues les lignes de caca en dégageant un gros volume de code useless. (ie Winforms vs MFC, etc...)
 
Bon là avec BP7, si vous voulez rester en Pascal pour pas perdre vos habitues, rebooter l'appli en Delphi (embarcadero) peut être une étape rentable : ça permettrait d'élaguer beaucoup de mochetés.
 

Spoiler :

Si vous êtes dans une PME, vous êtes typiquement verrouillés dans le soft écrit il y a 10 ans, que vous avez pas le budget pour le refacto, et que vous ferez une murale lorsqu'un concurrent refera un soft équivalent mais moderne, qui lui aussi repartira dans le cycle de 10~15ans avant de faire sprotch à son tour :D


Message édité par bjone le 25-11-2015 à 10:58:09
Reply

Marsh Posté le 25-11-2015 à 11:17:05    

Pour la forme, voici ma solution
 

Code :
  1. function Intr386(const int_number:byte; const stack_words:word;
  2.                        var regs:DPMIRegisters): word; assembler;
  3. asm
  4.    push es
  5.    push di
  6.    xor bx, bx
  7.    mov bl, int_number
  8.    mov cx, stack_words
  9.    les di,regs
  10.    mov ax, 0300h
  11.    int 31h
  12.    pop di
  13.    pop es
  14. end;
  15. (*//////////////////////////// DO_OUT //////////////////////////////////*)
  16. Procedure do_out;  (* To PIC *)
  17. Var
  18.   DCS : DPMIRegisters;
  19.   selseg, selseg_buff :longint;
  20.   selector, selector_buff, segment, segment_buff : word;
  21.   P_PM : p_buffer;
  22.   P_PM_buff : p_buffer;
  23. Begin
  24. selseg := globaldosalloc(40);
  25. selector := word(selseg and $FFFF);
  26. segment := word(selseg SHR 16);
  27. P_PM:=ptr(selector,0);
  28. selseg_buff := globaldosalloc(257);
  29. selector_buff := word(selseg_buff and $FFFF);
  30. segment_buff := word(selseg_buff SHR 16);
  31. P_PM_buff:=ptr(selector_buff,0);
  32. move(buffer_o,P_PM_Buff^,sizeof(buffer_o)); (*REMPLISSAGE AVEC POINTEUR PROTECTED VERS MEMOIRE AVEC DONNEES MODE REEL *)
  33. (* set up out request *)
  34. urb.transaction_token := $E1;(* $E1= Sortie*)
  35. urb.chain_end_flag := 0;
  36. urb.dev_add := the_dev_add;  (* Adresse Microchip =1 si c'est le seul usb connecte à la carte mere*)
  37. urb.end_point := out_endpoint;    (* =1 *)
  38. urb.error_code := 0;
  39. urb.status := 0;
  40. urb.transaction_flags := 0;
  41. urb.buffer_off :=0; (* METTRE OFFSET A 0 *)
  42. urb.buffer_seg := segment_buff; (* SEGMENT ADRESSE EN MODE REEL *)
  43. urb.buffer_length := packetlen;
  44. urb.actual_length := 64;
  45. urb.setup_buffer_off := 0;
  46. urb.setup_buffer_seg := 0;
  47. urb.start_frame := 0;
  48. urb.nr_of_packets := 0;
  49. urb.int_interval := 0;
  50. urb.error_count := 0;
  51. urb.timeout := 0;
  52. urb.next_urb_off := 0;
  53. urb.next_urb_seg := 0;
  54. (* now call DosUHCI *)
  55. fillchar(dcs, sizeof(dcs), 0);
  56. move(urb,P_PM^,sizeof(urb)); (*REMPLISSAGE AVEC POINTEUR PROTECTED VERS MEMOIRE AVEC DONNEES MODE REEL *)
  57. DCS.DPMI_ES := 0;(*segment;*)
  58. DCS.DPMI_DS := segment;(*ADRESSE SEGMENT MODE REEL DE MA STRUCTURE URB*)
  59. DCS.DPMI_EDX := 0;
  60. intr386($65, 0, dcs);
  61. GlobalDosFree(selector);
  62. GlobalDosFree(selector_buff);
  63. (* Reg.DS := seg(urb);
  64. Reg.DX := ofs(urb);
  65. Intr($65,Reg);*)
  66. Inc(ReqNr);
  67. End (* do_out *);

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed