Page 2 of 2
Re: Turbo C trouble with Interrupt Vector Table..
Posted: Mon Jun 15, 2009 5:47 pm
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:
:S
Re: Turbo C trouble with Interrupt Vector Table..
Posted: Mon Jun 15, 2009 6:00 pm
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
Re: Turbo C trouble with Interrupt Vector Table..
Posted: Mon Jun 15, 2009 6:02 pm
by Troy Martin
Do a disassembly like that of printf and show us. It's probably a bad segment.
Re: Turbo C trouble with Interrupt Vector Table..
Posted: Mon Jun 15, 2009 6:25 pm
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
Re: Turbo C trouble with Interrupt Vector Table..
Posted: Mon Jun 15, 2009 7:03 pm
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):
Well there goes my "bad segment register" theory...
offtopic: yay, I have 0x100 posts.
Re: Turbo C trouble with Interrupt Vector Table..
Posted: Tue Jun 16, 2009 3:02 am
by Risc
Well ru2aqare you were right, it's a bad segment. The data segment is initialized to 0 in the generated code
which is wrong. It should be 0x0050.
I temporarily fixed this with
However I would like to tell tlink that my data segment starts at 0x0050.. How would I do that?
Re: Turbo C trouble with Interrupt Vector Table..
Posted: Tue Jun 16, 2009 3:09 am
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?
Re: Turbo C trouble with Interrupt Vector Table..
Posted: Tue Jun 16, 2009 3:17 am
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..
Re: Turbo C trouble with Interrupt Vector Table..
Posted: Tue Jun 16, 2009 8:41 am
by Troy Martin
The DOS communication area isn't the kernel; it's for interacting between the kernel and the programs being run.
Re: Turbo C trouble with Interrupt Vector Table..
Posted: Tue Jun 16, 2009 11:27 am
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
Re: Turbo C trouble with Interrupt Vector Table..
Posted: Tue Jun 16, 2009 12:30 pm
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.

Re: Turbo C trouble with Interrupt Vector Table..
Posted: Tue Jun 16, 2009 1:24 pm
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.