6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Nov 23, 2024 4:14 am

All times are UTC




Post new topic Reply to topic  [ 40 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
 Post subject:
PostPosted: Mon Jan 06, 2003 3:49 pm 
Offline

Joined: Wed Sep 04, 2002 4:08 pm
Posts: 57
Location: Iowa
Garth,

Quote:
> In defense of myself I must say that normally one does check the flags from an
> actual status register to determine the source of an interrupt...

BRK does not respect the interrupt-disable flag.


All I meant was that I expected (wrongly) to examine the B flag (not the I flag) to determine whether BRK was the cause of interrupt.

Quote:
If I'm understanding you right, this sounds like really bad programming!


That was precisely my point! Somewhere (I forgot where) I saw NMI handler code that attempted to get around the "skipped BRK on NMI" bug in the 6502 by examining the opcode at the saved PC minus 2. I was hoping that someone reading this might not make that mistake if they didn't think about it.


Quote:
..PC and Windoze are very unsuitable for real-time applications because the interrupt latency is so nondeterminate...


Agreed. I think the main problem is the lengthy swap times to harddisk. Windows is always messing around with the harddisk, making any application execution indeterminant. Nonetheless, I read somewhere that DOS is the most popular embedded operating system by volume. Scary.

Quote:
there are only certain places where it offers the system the option of switching to another task


An operating system can of course include a number of features which either complicate it or simplify it. It depends on your needs. If you write your own OS, naturally you have the most flexibility.

Quote:
But BRK can be entered endlessly without exiting


I forgot about that. I was thinking that a timer event might signal a task switch in the middle of an OS call, thus possibly reentering the same OS call. However, BRK doesn't just happen anywhere, so already we have control of it causing reentrancy problems. Also, if you're not using preemption, it's not an issue anyway.

Quote:
I can think of plenty of situations where you would want to re-enable
interrupts during an ISR


Me too. On my little SBC project I have a "panic" button attached to NMI, whose handler basically drops into a monitor prompt, enabling interrupts to do I/O. Until the monitor returns to the interrupted program, the NMI-triggered monitor prompt can be thought of as one long ISR. Thanks for the correction. I was trying to illustrate that in a multitasking OS, you probably likewise want to disable (hardware) interrupts because they cause a context switch, when your OS may already be in the middle of switching tasks.

Quote:
I hope none of this is taken to be combative and argumentative.


Nope. Again an interesting discussion.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Jan 06, 2003 6:09 pm 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
GARTHWILSON wrote:
I guess I can see where you're coming from now. It's kind of a foreign idea to me because I have never had to work with someone else's OS on the 6502 since 1982 when we used the AIM-65's in school. I've always had full control of every speck of code, and my workbench computer quickly compiles applications on the fly every time I load them up to use them, so even the possibility of changing addresses in the kernel are no threat. I commented above about the problem of task-switching happening at the worst possible times.

Garth


Understood. :) As an avid Forth programmer myself, I fully desire having full control over everything. I'm currently hacking up a new native Forth implementation for my old, otherwise useless 486 laptop (not enough resources to run any OS of modern value, including Linux). I'm really enjoying the experience, but I fear that when it comes time to control the video, I won't have the degree of control that I desire. The chipset is Cirrus Logic, and that's all I know about it. It's really bizarre. I originally wanted to go into protected mode and utilize all available memory, but it's looking like I can't do that now, because going into protected mode eliminates any possibility of invoking BIOS services to set video mode. :( I'll just use "flat real mode" to fake a protected-mode environment in real-mode, I guess, and although program code will be limited to the first 640K (indeed, in my system, it'll probably be limited to a single 64K segment!), and set up extended RAM as a super-fast cache for block I/O. That should give me the next best thing in convenience and speed.

Just as a side project, I'm planning on building a wire-wrapped home computer around the 65816, probably running at 4MHz (since I have 7 CPUs of this type, I might as well do something with them). This is a long-term project for me, unfortunately, as I have many other things competing for my brain at the moment. It'll probably have 128K of RAM to start off with. And as much as I love preemptive multitasking, seeing as how the kernel will be Forth, I've decided to stick with cooperative multitasking instead. It's easier to implement in the kernel (indeed, for the Forth VM, it's utterly trivial), and as long as the applications are multitasking aware, it can be sufficiently responsive enough to rival preemptive systems. I have no real-time requirements, so preemption is a complexity not worth investing in. (Though I've done it in the past, and it's not that much harder to do once you've gotten cooperative multitasking implemented. So if I ever need it again, it would be rather easy to add.)

The nice thing about Forth is that switching from one application to another involves, literally, recompiling the source of the application from scratch. Suppose I have a calculator on-screen. I want to switch (back?) to a word processor. When I do that, the word processor invokes a word along the lines of "NEW" or something (it's usually Forth specific), which resets the Forth dictionary, and provides a clean slate for the WP code to load in. Since it's all source-based, fixups and OS entry points aren't a consideration. In fact, the coupling between the application and the Forth kernel is so tight that it's hard to tell where one starts and the other ends. :) Moreover, the persistence mechanism of Forth mimicks how a data cache operates; thus, even though your application is swapped out of memory, if your application's DATA space is kept purely in blocks, you still get excellent performance with the additional benefit of near-full persistence.

Another nice thing about Forth is that the language itself makes making multitasking-aware applications dead simple. In fact, they're as simple as non-multitasking-aware applications. Unless you're going to be doing heavy inner-loop calculations, you'll almost never call PAUSE yourself, which relinguishes the "time-slice" to another task, but otherwise appears as a NOP to the application. Forth's I/O words, including KEY(?), BLOCK/BUFFER, etc. all implicitly invoke PAUSE after initiating the I/O operation (hardware permitting), allowing some form of overlap to occur. It might sound primitive (and it is), but I've used systems like this, and considering the Forth kernel is kilobytes in size, the results are absolutely impressive. When developing code, I honestly thought it had preemptive multitasking at first.

But I'm digressing, and it's way off topic for this channel. :D I'll go back to my notebook and continue daydreaming about the '816 project.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Jan 07, 2003 6:13 am 
Offline
User avatar

Joined: Sun Dec 29, 2002 8:56 pm
Posts: 460
Location: Canada
Hey,

By reading this discussion, I've just uncovered a bug (well really a "feature") in my Verilog implementation of the 6502 processor. The "BC6502" actually does restore the previous state of the break flag from the stack. It seems that while reading docs on the 6502 I thought it must be a misprint where stated that the B flag is set to one by plp and rti, as this would mean the B flag is always set. :)

Regarding a multi-tasking OS, as far as interrupts go I've of the opinion that the only thing an ISR should do is send a message to the appropriate mailbox indicating that an ISR occurred and nothing else. This should be handled automatically within the scope of the operating system and not left up to device drivers. There is no real reason for device drivers to directly handle interrupts. Pre-emptive interrupts should only be used to avoid bogging the system down with polling loops and should only be used to send a simple "interrupt occurred" message. The only exception to this would be the OS time slicer that determines the time slice period (really a polling interval) at which point the OS can look at outstanding messages and prioritize what should be done next.

My two cents,
Rob


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Jan 07, 2003 9:56 am 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
Rob Finch wrote:
Regarding a multi-tasking OS, as far as interrupts go I've of the opinion that the only thing an ISR should do is send a message to the appropriate mailbox indicating that an ISR occurred and nothing else.


Of course. However, in a memory protected environment, it could become a performance bottleneck if you're not careful, which is why so many MMU-based OSes do not do this.

Quote:
The only exception to this would be the OS time slicer that determines the time slice period (really a polling interval) at which point the OS can look at outstanding messages and prioritize what should be done next.


The time slice interrupt should be treated NO differently than any other interrupt. Moreover, messages should be handled as soon as they're delivered, task priority permitting. That is, if you deliver a message to a task that is higher in priority than your currently running task, a task switch should occur immediately. Waiting for the task quantum to expire before all messages are processed effectively makes your preemptive multitasker no more efficient than a poorly written cooperative multitasker.

Moreover, task switches can occur at any moment in time, but never when running kernel code. Thus, it makes perfect sense to switch tasks at the completion of ANY interrupt handling, not just timer interrupts. This is especially true if the OS entry point is handled as a system call interrupt of some kind.

I highly encourage people to study how VMS and AmigaOS implement its multitasking. They both have done things "The Right Way," to be sure. Even today, my 7MHz Amiga multitasks more reliably and predictably than my 1GHz Athlon running Linux. My multitasking kernels for the x86, which I've written years ago, also are incredibly more "regular" than Linux. All of my kernels are based on AmigaOS, which I later found out, was itself inspired by VMS.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Jan 08, 2003 1:33 am 
Offline
User avatar

Joined: Sun Dec 29, 2002 8:56 pm
Posts: 460
Location: Canada
Oh my gosh, I must have been asleep when I posted last time. Having written most of the kernel for my own OS you would think I would know how it was written. Although it has been quite a while since I worked on it last. :oops:

Quote:
The time slice interrupt should be treated NO differently than any other interrupt.


You're right on here. I confused a process based on a message from the time slice interrupt with the time slice interrupt itself.

Quote:
Moreover, messages should be handled as soon as they're delivered, task priority permitting.


Also the way to go. I even have a big comment about this in my code!

Quote:
Even today, my 7MHz Amiga multitasks more reliably and predictably than my 1GHz Athlon running Linux.


I've never been impressed with any OS that runs on the PC; one of the reasons why I started working on my own OS. I suspect there are two basic reasons why people like Linux 1) it's free 2) there is source code available.

Why is it that in Win2000 HE whenever a program crashes task manager is unable to shut it down ? I have had program crashes many times and not once has task manager been able to shut the program down. I have to reboot.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Jan 08, 2003 10:03 pm 
Offline

Joined: Mon Dec 23, 2002 8:47 pm
Posts: 70
I would die to see a real good, SIMPLE OS. Either on the 80386, or on the 65816.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Jan 08, 2003 10:28 pm 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
usotsuki wrote:
I would die to see a real good, SIMPLE OS. Either on the 80386, or on the 65816.


Well, I had written an OS architecture called Dolphin years back that satisfied your requirements. The executive kernel was about 4K in size, and could perform about 1,000 task switches per second on a 386/33 without breaking a sweat. It was preemptively multitasking, with semaphores and message-passing as the sole IPC mechanisms. So, where were you back when I wrote this? :D

Though, it still needed a whole slew of device drivers and a shell implementation. But all other things combined, I still think the whole OS environment could easily have fit on a 360K floppy.

Now I'm planning an OS called Dolphin 0.5, which will probably never leave the ground due to my lack of time. But the kernel is memory protected, so it'll not switch tasks that fast. But it is still small and agile, and preserves the semaphore/message-passing IPC APIs from earlier Dolphin releases. Unlike previous Dolphin implementations, it's intended to be an exokernel, which would allow even more flexibility than a microkernel would. I was planning on implementing it in Forth.


Top
 Profile  
Reply with quote  
 Post subject: Great OS
PostPosted: Thu Jan 09, 2003 3:11 am 
Offline

Joined: Sat Aug 31, 2002 12:33 pm
Posts: 64
Location: USA
Hi Everyone,

Someone said that they were looking for a great simple OS for x86....
Give QNX a try. I wrote a device driver for it once and it
is really good. I believe that you can download a demo copy.
It also has a GUI (if you are into that sort of thing). And to top-
it-all-off... it's actually a realtime OS (real realtime).

http://www.qnx.org/

Cheers,

Paul


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Jan 22, 2003 11:54 pm 
Offline

Joined: Mon Dec 23, 2002 8:47 pm
Posts: 70
QNX?

(Of course, if I didn't have a problem with hard drive space, I'd try anything. Then again my OS is MS-DOS. I wonder how complex MSX-DOS 1 [=CP/M 2.2, roughly] is...)


Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 30, 2003 3:40 pm 
Offline

Joined: Tue Dec 30, 2003 10:35 am
Posts: 42
I recently ran some tests on the variant of the 6502 in the NES game console and came to the following conclusions regarding the $10 bit of the value:

IRQ, NMI: push status AND $EF

BRK: push status OR $10

PHP: push status OR $10

RTI, PLP: pop status

On this 6502 variant, there seems to be no way to get its value, since all push operations either set or clear this bit. What comes from this is that the existence of a B flag would be pointless, since its non-existence wouldn't affect operation in any way. In other words, there is no B flag; the value pushed on the stack during a status save has this bit set/cleared appropriately. Similar applies to the $20 bit position.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Jan 09, 2004 6:26 am 
Offline

Joined: Wed Sep 04, 2002 4:08 pm
Posts: 57
Location: Iowa
Yeah, you're probably right about the B flag not actually being implemented in the hardware status register alongside N, Z, C, etc. That is probably the hardware optimization I was talking about. The B "flag" that gets pushed on the stack would then simply be derived from the IRQ/NMI lines. Any status push onto the stack would consist of the NVDIZC flags from the status register (only 6 memory cells), and a control line for the B flag that is derived from the control unit.

This makes the discussion in 6502 documentation about a B flag in the status register even more obtuse in my opinion, if it doesn't exist. It leads to the confusion that I had--where I thought you would check the status register for the BRK condition instead of what was pushed on the stack. Looking back over some documentation, it is clear now that checking the status as pushed on the stack is the proper way to do it, but even now the WDC document for the 65816 claims that the B flag is available only through the processor register. Isn't that what one would expect to do--to check the status of a flag by reading the actual register? Apparently this isn't the case with the B flag. Oh well.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Jan 09, 2004 8:49 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8544
Location: Southern California
> Looking back over some documentation, it is clear now that checking
> the status as pushed on the stack is the proper way to do it, but even
> now the WDC document for the 65816 claims that the B flag is available
> only through the processor register.

Did you find that in the data sheet? Their programming manual says on page 253, "notice that it is the stacked status byte which must be checked, not the current status byte."

The '816 does not require testing this flag though, because it has a separate vector for BRK in native mode, at FFE6-FFE7.

To say the B flag doesn't exist is an interesting way to look at it. Since I've never used BRK except in my days in that college class in 1982 with the AIM-65, I never gave it much thought; but it makes sense.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Jan 10, 2004 7:04 am 
Offline

Joined: Wed Sep 04, 2002 4:08 pm
Posts: 57
Location: Iowa
Garth,

Page 9 of the Sept. 2003 WDC 65816 PDF states the following:

The Emulation (E) select and the Break (B) flags are accessible only through the Processor Status Register.
The Emulation mode select flag is selected by the Exchange Carry and Emulation Bits (XCE) instruction.
Table 8-1, W65C816S Compatibility Information, illustrates the features of the Native (E=0) and Emulation
(E=1) modes. The M and X flags are always equal to one in Emulation mode. When an interrupt occurs
during Emulation mode, the Break flag is written to stack memory as bit 4 of the Processor Status Register.

The latter half of that statement implies that you must check the B flag on the stack, but doesn't explicitly say to do so, and I think you'd only see it in that context if you read that part already knowing that that's the correct way to do it. However, the first part of the paragraph definitely gives the impression of checking the B flag "through the processor status register." If you don't already know which way to do it (like I didn't last year when I started this topic), then you'd naturally be inclined to think that you need to check the actual processor register.

Anyway, it sounds like I'm whining about the docs (and maybe I am a little), but my confusion was cleared up long ago when I was told explicitly by members of this forum that checking B in the processor register won't work, and that I need to check it on the stack.

Scott


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Jan 10, 2004 7:54 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8544
Location: Southern California
Oh, I see what you're saying. I can't find that on my paper copies I have my notes in; but without downloading a long .pdf on a slow modem, I think the idea is that there's no instruction like BBC (Branch on Break bit Clear). Yes, it's confusing.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Jan 14, 2004 8:00 pm 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
schidester wrote:
Quote:
The Emulation (E) select and the Break (B) flags are accessible only through the Processor Status Register.
The Emulation mode select flag is selected by the Exchange Carry and Emulation Bits (XCE) instruction.
Table 8-1, W65C816S Compatibility Information, illustrates the features of the Native (E=0) and Emulation
(E=1) modes. The M and X flags are always equal to one in Emulation mode. When an interrupt occurs
during Emulation mode, the Break flag is written to stack memory as bit 4 of the Processor Status Register.


The latter half of that statement implies that you must check the B flag on the stack


I interpret it distinctly as telling me to check the memory-stored copy of the flags. The words written to stack memory are the critical words. :)

Quote:
. . . but doesn't explicitly say to do so, and I think you'd only see it in that context if you read that part already knowing that that's the correct way to do it. However, the first part of the paragraph definitely gives the impression of checking the B flag "through the processor status register."


I agree that the beginning of the paragraph is ambiguous. Its verbiage should be changed or otherwise annotated with a footnote.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 40 posts ]  Go to page Previous  1, 2, 3  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 26 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: