ok, here's the idea I have for the call table in V2_OS. The problem was to be able to retrieve the pointers to the services in order to call them later. We wanted it to be fast, without a main redirector routine to always switch us around. A way to do exactly what we want is to make our program call and request all addresses to services that will be used later. When the program execute, it only have to look in the tabled he did fill at startup and jump. Here's an example. --------------8<---------------snip!!:start here-------------- ; sample program for call table in V2_OS ; by eks (futur@mad.scientist.com) ; ; developed under the GNU Public License mov edi, Table_external_services call far [gs:GetS16IB(CallTableFiller)] ;Our table is now filled with all the pointers to the services. mov edi, program_title call far [write_to_screen] ;Return to V2_OS retf Table_external_services: ;------------------------------------------ ; This table is filled at runtime when we call CallTableFiller ;----------------------------------------------------------------------- service1: dd 76548212 ; <- code for 'write to screen' sys32/sr04.inc write_to_screen: dw 0 ;\ dd 0 ;-- These two values are filled in by the ; CallTableFiller service end_of_table: dd 0 ; <- code to specify end of table so that ; CallTableFiller know when to stop filling program_title: db ;------------8<----------------snip:end here!----------------- So as we see, this program would call the table filler at startup, it would fill the internal table with the necessary code segment and offset needed to call each services. The call table stored inside the program could follow the following format: offset size description ------------------------------------- 0 4 service code 4 2 segment of desired service (filled-in by TableFiller) 6 4 offset to service routine (filled-in by TableFiller) ... This structure is reapeated as many time as we have services that we want to be able to call later. To indicate the end of the table, we simply write a 0 code as service number. So a program could use a bit more complex table like this: Table_external_services: ;----------------------- service1: dd 76548212 ; <- code for 'write to screen' sys32/sr04 write_to_screen:dw 0 dd 0 service2: dd 76548214 ; <- code for 'write hex to screen' sys32/sr05 write_hex: dw 0 dd 0 service3: dd 76548216 ; <- code for 'set interrupt vector' sys32/sr01 set_int_vector: dw 0 dd 0 end_of_table: dd 0 The CallTableFiller would require a pointer to the table be passed in 'edi'. It will then look into the table, see the service code, return the value, look at the next service code, return the value and so on. I think it would be the fastest way to retrieve all the services addresses. Only one call to make to the CallTableFiller, one internal table, and after that it's a simple matter of calling the rigth service inside our internal table. In order for all that to work, there must be a way to know if the CallTableFiller have correctly retrieve all the needed services. so a return error code should be returned in eax. CallTableFiller: ;----------------- ; parameters: ds:edi -> pointer to service table ; returned value: eax -> number of services translated ;----------------- .... some code The eax register would contain the number of services that have been correctly filled with seg:offset values. So when the program ask for the CallTableFiller to fill the table at startup, it can check if the correct number of services is filled at startup. If not, it can simply return to v2os or display a message. I think that should work, anyway, give me back your comments :) btw, if you need help to develop the CallTableFiller or whatever we call it, tell me. EKS-Dave Poirier futur@mad.scientist.com