Page 1 of 1

Systems Programming Project: Interrupt Questions (etc..)

Posted: Sat Feb 17, 2007 12:25 am
by tja1618
First of all, this looks like it has the potential to be a great resource!

Anyway, I am a third year computer science student and Rochester Institute of Technology. Currently I am taking a systems programming class along with a general operating systems class.

For the systems programming class my last project is quite challenging. We are required to write a simply program that prints a sentence to the screen, and tests the user for accuracy and speed based on 3 attempts at typing the sentence. Well, the hard part is the fact that we have to implement this on an x86 system WITHOUT AND O.S.! We are compiling the program onto bootable files (based on my professors standalone framework). For more details, the project page is here if you're interested:

http://www.cs.rit.edu/~wrc/courses/sp1/projects/3/

Now, on to my questions.

We are required to communicate with a serial device (connected to a simple terminal with screen and keyboard) using interrupt driven IO. We must implement this ourselves as there is no operating system running. For the most part I understand how this works, and basically have most of it already coded.

(assuming intel x86 based system)
1) What are the PROPER, required procedures when handling:
a. serial interrupts
b. keyboard interrupts
c. timer interrupts

2) With the timer interrupt, how does this work if I want to increment an integer once every second? I believe the timer interrupt ticks a defined number of times per second, in one of my professors included files is the definition:

Code: Select all

#define TIMER_TICKS_PER_SECOND 18
As an example of what I am doing, here is my in progress keyboard interrupt service routine. Even though I have done assembly (some assembly is in my project), this is my first time working with low level hardware in this manner.

Code: Select all

void keyboard_isr(int vector, int code) {
	char newch;
	int ctrl_m = 0xff;

	int k_code = inportb( KEYBOARD_DATA );	/* get code */

	k_code &= 0xff;
	switch( k_code ) {
	case 0x2a:	/* make shift */
	case 0x36:
		shift = 1;
		break;
	case 0xaa:	/* break shift */
	case 0xb6:
		shift = 0;
		break;
	case 0x1c:	/* enter key */
		if(!READY) READY = 1;
		break;
	case 0x1d:	/* handle ctrl mask */
		ctrl_m = 0x1f;
		break
	case 0x9d:
		ctrl_m = 0xff;
		break;
	default:
		if (k_code & 0x80) {
			/* ignore break code */
		} else {
			/* get char */
			newch = scan_code[ shift ][ (int)k_code ];
			if(newch != '\377') {
				/* TODO: process characters  */
			}
		}
		break;
	} /* switch */

	outportb(0x20,0x20);	/* acknowledge irq */
}

Thanks for reading the long post and contributing (anything) if possible,
Tom

P.S. Upon request I will supply some source code I am working with.[/url]

Re: Systems Programming Project: Interrupt Questions (etc..)

Posted: Sat Feb 17, 2007 9:16 am
by Brendan
Hi,

Before you do much more, I'd suggest reading the requirements for the project:

http://www.cs.rit.edu/~wrc/courses/sp1/projects/3/

Nowhere in here does it say you need to use the keyboard. The user's keyboard is connected to a dumb terminal or terminal emulator, and the terminal emulator is connected to a serial port. You need to get bytes from the serial port, and send bytes to the serial port.
tja1618 wrote:1) What are the PROPER, required procedures when handling:
a. serial interrupts
b. keyboard interrupts
c. timer interrupts
The "proper" procedures would probably involve an OS with a full device driver interface and IPC (e.g. IOCTL, pipes, stdin/stdout, etc).

My advice is: "make stuff up" (or more specifically, custom design software to suit it's intended purpose rather than recycling generic stuff designed for someone else's intended purpose, unless you find something somewhere that is close enough to what you need that will also save you development time and isn't restricted by patent and/or copyright limitations).

Your professor seems to agree with this - from the project description:
"Design functionality that is helpful in solving the problem. If you design read and write routines that behave exactly like those found in UNIX, this problem is a lot harder to solve."
tja1618 wrote:2) With the timer interrupt, how does this work if I want to increment an integer once every second? I believe the timer interrupt ticks a defined number of times per second, in one of my professors included files is the definition:

Code: Select all

#define TIMER_TICKS_PER_SECOND 18
How about something like this:

Code: Select all

timerIRQ:
   push ds
   push ax
   mov ax,yourDataSegment
   mov ds,ax

   add word [.fractions],0x0E39
   adc word [timerCountLow],0
   adc word [timerCountHigh],0

   mov al,0x20
   out 0x20,al
   pop ax
   pop ds
   iret

   section .data
   align 2
.fractions:  dw 0
   section .test
Of course your professor does say "Do as much as possible in C; as little as possible in assembly.". In this case you'll probably end up with code that is about 3 times slower because of C's inability to generate code suitable for an interrupt handler, not having explicit control of overflow conditions and the resulting branch mis-prediction penalties you'll get on modern 80x86 CPUs.

There's probably not much you can do about this - poorly written bloated messes are "fashionable", while using the right tool for the job isn't.... ;)


Cheers,

Brendan

Posted: Sat Feb 17, 2007 12:07 pm
by tja1618
I don't think speed is much of an issue with this project. This project introduces us to working low-level with hardware and interrupts.

EDIT: See below

Basically, what I mean is that should I interpret information coming off the serial port as user keypresses? Meaning I will get a string of characters, terminated by a carriage return (\r)?

I feel like we were just thrown into this project. At RIT the quarters are so short a lot of times I end up teaching myself much of what the professors never have time to.

Please excuse my ignorance in the area, I am only a beginner with this low-level of systems programming.

Thanks,
Tom

Posted: Sat Feb 17, 2007 3:46 pm
by tja1618
OK. After pouring over the VT100 documentation (terminal we must interface with) I think I found what was confusing me.

So, what I need to do, is simply perform serial IO with the serial port, because the VT100 terminal has a microprocessor itself that handles incoming characters. So when a user presses a key on the terminal, the internal processor translates it to an ASCII character an send it out on the serial line.[\b]

Originally, I assumed we somehow had to handle keyboard interrupts and translate characters ourselves. I think this simplifies my task quite a bit. ;)

But please, continue with feedback if your interested. All the ideas help!

Thanks again,
Tom