Turbo C trouble with Interrupt Vector Table..

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Risc
Posts: 11
Joined: Sun Jun 14, 2009 8:29 pm

Re: Turbo C trouble with Interrupt Vector Table..

Post by Risc »

Thanks for the tip! The video code as it is now is still rudimentary as I planned on defeating this problem first.
What annoys me is that printc works flawless and printf (which uses printc) doesn't..

EDIT: It seems to be some relocation problem (?) once inside the isr..

Code: Select all

void interrupt INT_0()
{
	printc('a');
	printc('b');
	printc('c');
	
	printf("Hello world!\0");
	
	printc('k');
	printc('l');
	printc('m');
	asm hlt
}
That code produces this output:

Code: Select all

abcklm
:S
Risc
Posts: 11
Joined: Sun Jun 14, 2009 8:29 pm

Re: Turbo C trouble with Interrupt Vector Table..

Post by Risc »

ru2aqare wrote:I don't know what assembly code does your TC generate, but you may have to reload (and upon exit from the interrupt function, restore) the segment registers.
This function

Code: Select all

void interrupt INT_0()
{
	printc('a');
	
	printf("Hello world!\0");
	
	printc('b');
	asm hlt
}
...is compiled and linked into this (from debug):

Code: Select all

13E0:022C 50            PUSH    AX
13E0:022D 53            PUSH    BX
13E0:022E 51            PUSH    CX
13E0:022F 52            PUSH    DX
13E0:0230 06            PUSH    ES
13E0:0231 1E            PUSH    DS
13E0:0232 56            PUSH    SI
13E0:0233 57            PUSH    DI
13E0:0234 55            PUSH    BP
13E0:0235 2E            CS:
13E0:0236 8E1E0000      MOV     DS,[0000]
13E0:023A 8BEC          MOV     BP,SP
13E0:023C B061          MOV     AL,61		
13E0:023E 50            PUSH    AX
13E0:023F E862FF        CALL    01A4		// printc('a');
13E0:0242 59            POP     CX
13E0:0243 B8C201        MOV     AX,01C2
13E0:0246 50            PUSH    AX
13E0:0247 E868FF        CALL    01B2		// printf("Hello world!\0");
13E0:024A 59            POP     CX
13E0:024B B062          MOV     AL,62
13E0:024D 50            PUSH    AX
13E0:024E E853FF        CALL    01A4		// printc('b');
13E0:0251 59            POP     CX
13E0:0252 F4            HLT					// asm hlt
13E0:0253 5D            POP     BP
13E0:0254 5F            POP     DI
13E0:0255 5E            POP     SI
13E0:0256 1F            POP     DS
13E0:0257 07            POP     ES
13E0:0258 5A            POP     DX
13E0:0259 59            POP     CX
13E0:025A 5B            POP     BX
13E0:025B 58            POP     AX
13E0:025C CF            IRET
User avatar
Troy Martin
Member
Member
Posts: 1686
Joined: Fri Apr 18, 2008 4:40 pm
Location: Langley, Vancouver, BC, Canada
Contact:

Re: Turbo C trouble with Interrupt Vector Table..

Post by Troy Martin »

Do a disassembly like that of printf and show us. It's probably a bad segment.
Image
Image
Solar wrote:It keeps stunning me how friendly we - as a community - are towards people who start programming "their first OS" who don't even have a solid understanding of pointers, their compiler, or how a OS is structured.
I wish I could add more tex
User avatar
mathematician
Member
Member
Posts: 437
Joined: Fri Dec 15, 2006 5:26 pm
Location: Church Stretton Uk

Re: Turbo C trouble with Interrupt Vector Table..

Post by mathematician »

Risc wrote:Thanks for the tip! The video code as it is now is still rudimentary as I planned on defeating this problem first.
What annoys me is that printc works flawless and printf (which uses printc) doesn't..
What would happen if the compiled code looked something like this when you are not zeroing bh inside printc? There is no guarantee that's the problem, but it might be:

Code: Select all

mov bx, [bp]
xor si,si

next:
mov al, [bx+si]
or al,al
jz finish

push ax
call _printc
add sp, 2
inc si
jmp next

finish:
ret
The continuous image of a connected set is connected.
ru2aqare
Member
Member
Posts: 342
Joined: Fri Jul 11, 2008 5:15 am
Location: Hungary

Re: Turbo C trouble with Interrupt Vector Table..

Post by ru2aqare »

Risc wrote:
This function

Code: Select all

void interrupt INT_0()
{
	printc('a');
	
	printf("Hello world!\0");
	
	printc('b');
	asm hlt
}
...is compiled and linked into this (from debug):

Code: Select all

snip
Well there goes my "bad segment register" theory...

offtopic: yay, I have 0x100 posts.
Risc
Posts: 11
Joined: Sun Jun 14, 2009 8:29 pm

Re: Turbo C trouble with Interrupt Vector Table..

Post by Risc »

Well ru2aqare you were right, it's a bad segment. The data segment is initialized to 0 in the generated code

Code: Select all

13E0:0236 8E1E0000      MOV     DS,[0000]
which is wrong. It should be 0x0050.

I temporarily fixed this with

Code: Select all

mov     ax, 0x0050
mov     ds, ax
However I would like to tell tlink that my data segment starts at 0x0050.. How would I do that?
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Re: Turbo C trouble with Interrupt Vector Table..

Post by pcmattman »

Most C compilers assume a flat memory model - ie, all segments are equal. Is there any specific reason why it *has* to be 0x50?
Risc
Posts: 11
Joined: Sun Jun 14, 2009 8:29 pm

Re: Turbo C trouble with Interrupt Vector Table..

Post by Risc »

pcmattman wrote:Most C compilers assume a flat memory model - ie, all segments are equal. Is there any specific reason why it *has* to be 0x50?
Not really, but I would like to mimic the DOS memory model to some extent though. Below is a map snatched from http://www.osdata.com/system/physical/memmap.htm:

Code: Select all

0000h	0000h	1024	interrupt vector table
0400h	172	BIOS communication area
04ACh	68	reserved by IBM
04F0h	16	user communication area
0500h	256	DOS communication area
EDIT: I'm no expert (as you may have understood by now :) ) but shouldn't I be able to init all segments to 0 and set the origin to 0x0500? I mean shouldn't 0x0050:0x0000 be the same as 0x0000:0x0500?

EDIT2: Stupid me, it's probably exe2bin that relocates the code..
User avatar
Troy Martin
Member
Member
Posts: 1686
Joined: Fri Apr 18, 2008 4:40 pm
Location: Langley, Vancouver, BC, Canada
Contact:

Re: Turbo C trouble with Interrupt Vector Table..

Post by Troy Martin »

The DOS communication area isn't the kernel; it's for interacting between the kernel and the programs being run.
Image
Image
Solar wrote:It keeps stunning me how friendly we - as a community - are towards people who start programming "their first OS" who don't even have a solid understanding of pointers, their compiler, or how a OS is structured.
I wish I could add more tex
User avatar
mathematician
Member
Member
Posts: 437
Joined: Fri Dec 15, 2006 5:26 pm
Location: Church Stretton Uk

Re: Turbo C trouble with Interrupt Vector Table..

Post by mathematician »

The segment registers will obviously have whatever you put into them prior to jumping to the kernel. To get a load address of 0x500 you would need to write an assembly language stub, which looked something like this:

Code: Select all

text    segment    para    'text'              ;may need modifying - it's a long time since I
                                                  ;programmed in turbo-c, so I can't
                                                  ;remember what the naming conventions are
   
org 500h

call _kmain
call _bsod                                           ;under normal circumstances, you shouldn't
                                                  ;return from kmain
jmp $

text    ends


/*******************************************
                  Kernel.c
********************************************/

void  _kmain()
{
     printf( "Hello World" );
}
C:\ tlink stub.obj kernel.obj
The continuous image of a connected set is connected.
Risc
Posts: 11
Joined: Sun Jun 14, 2009 8:29 pm

Re: Turbo C trouble with Interrupt Vector Table..

Post by Risc »

Look at kernel.c below (kernel.obj is the first object-file linked in). Shouldn't this qualify as a stub?

Code: Select all

/* Note to self: Only use stream commments,
   TURBOC cannot handle // comments */

#include "include\system.h"
asm .model tiny
asm ORG 0x0050

struct BIOS_EQUIPMENT bios_eq;
char zero = 0;

void main()
{
	/* Adjust segment registers and disable interrupts */
	asm cli
	asm mov     ax, 0x0050
	asm mov     ds, ax
	asm mov     es, ax
	
	/* Install interrupts and enable them */
	install_interrupts();
	
	get_bios_equipment_list(&bios_eq);

	printf("uKernel 0.1\r\nCopyright (C) E.Sandberg 2009\r\n\r\n");
	if(bios_eq.MOUSE_INSTALLED)
		printf("PS/2 Mouse installed\r\n");
	
	/* Never return! */
	for(;;);
}
I guess tcc may put some perverted stack initalization at the top of main...
Thanks for the replies! I will try adding a separate stub in assembler. :)
User avatar
mathematician
Member
Member
Posts: 437
Joined: Fri Dec 15, 2006 5:26 pm
Location: Church Stretton Uk

Re: Turbo C trouble with Interrupt Vector Table..

Post by mathematician »

Why have you got org 0x50? The org directive refers to the offset.

If you load the segment registers with 0x50 in the boot sector, the kernel will need an org 0. An assembly language stub is not a bad idea, because you will know exactly what you are getting.

Also, any sight of a function called main() could be an open invitation for the linker to try and link in the default stub used in applications development (which, amongst other things, creates the argc and argv[] arguments). Call it kmain, or whatever else takes your fancy.
The continuous image of a connected set is connected.
Post Reply