GARTHWILSON wrote:
Hugh Aguilar wrote:
Then I got rid of the T flag. My thought was that only ISRs would access I/O ports, and they would send or receive the data to or from the tasks in circular buffers. It is okay for an interrupt to occur in the middle of a primitive even if the primitive is accessing a circular buffer and the ISR accesses the same circular buffer. So, no worries!
I would just encourage that non-queued things in the I/O still be accessible. Countless times in my applications (in fact it's the most common case), I need to read an input bit or set or clear an output bit in realtime, not waiting on a queue.
At one time I had this instruction:
Code:
EXA adr exchange A with an 8-bit variable (at an absolute address, not a direct-page address)
The purpose of this was to read and write a semaphore in a single instruction so it couldn't be interrupted in the middle (this works with an absolute address rather than a direct-page address because the direct-page is task-specific).
I may go back to EXA so I can have a primitive that reads and writes a semaphore and can't be interrupted. This would allow code such as you are describing (accessing an I/O port from a task and being sure that you don't get a task-switch in the middle of accessing the port) --- and this code could be written in Forth.
I still don't like the idea of a task-switch being only on NEXT because this slows down NEXT --- also, this means that accessing an I/O port has to be done inside of a primitive, which means that it has to be written in assembly-language --- it is much more convenient if this could be written in Forth using C@ C! etc., but this involves multiple primitives.
Thanks for the links to information on multi-tasking OS design, from you and the others --- I will read up on that.