News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_zhulien

interrupts questions

Started by zhulien, 09:52, 23 August 18

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

zhulien

Hi Guys,


I have an early version of my multitasking extension ROM for AMSDOS working which allows for multiple tasks to be spawned off.  The idea is to support drivers for BASIC/AMSDOS as well as programming extensions in a nice way.  I have tried 2 ways to play with interrupts.  First i tried to patch #38, but it isn't very reliable as I am wanting BASIC to co-exist, when the lower ROM is enabled, then of course my interrupt handler doesn't get called.  So, secondly I used KL_NEW_FAST_TICKER and this works nicely with firmware because it handles the lower ROM both enabled and disabled as well as optional interrupt handler in ROM or RAM. 


There are still some gremlins though in my code.  My interrupt handler currently is in the background ROM.  It caters for tasks spawned in expansion RAM (currently dkTronics compatible).  To keep it simple, I chose 1 task per bank, so a CPC6128 can have 4 concurrent tasks running in the background this way.  Now the trickey bit...  I would like to be able to use the firmware calls if possible from my interrupt handler and drivers.  What I noticed, currently I use TXT_OUT_CHAR and CAS_IN_DIRECT etc to both load new tasks from disc, but also for them to echo to the screen (yes, I know how to code my own text fast output routines, but... this is a quick and dirty task POC)... it seems that the firmware calls can randomly enable interrupts themselves... is that correct?  If that is in fact the case, although I can make text output and key scanning without using the firmware, I suspect if I was to bypass the firmware for file loading... I would lose compatibility with M4 and any other disc systems people might want to use.  What are my options?


Docent

What is your goal? Do you want to exclusively execute one loading task without running other interrupt driven tasks?

andycadley

I'd doubt the firmware routines randomly re-enable interrupts (although loading might I suppose). Are interrupts actually still disabled while the Ticker lists are processing? I can't remember but I have a sneaking suspicion the firmware may re-enable them before actually processing the lists so that higher priority task (such as flyback tasks) don't get starved by fast ticks.

Docent

Quote from: andycadley on 18:29, 23 August 18
I'd doubt the firmware routines randomly re-enable interrupts (although loading might I suppose). Are interrupts actually still disabled while the Ticker lists are processing? I can't remember but I have a sneaking suspicion the firmware may re-enable them before actually processing the lists so that higher priority task (such as flyback tasks) don't get starved by fast ticks.

Express asynchronous events are executed with interrupts disabled, but other events are handled with interrupts enabled. It is safe to assume that the firmware runs most of the time with interrupts enabled - both interrupt handler and most routines that play with rom or interrupts/events end with ei...

zhulien

Quote from: Docent on 13:52, 23 August 18
What is your goal? Do you want to exclusively execute one loading task without running other interrupt driven tasks?


Actually I don't mind if one loading task blocks the others, but... i am loading into memory that is paged in (the main memory paged out) at #4000, so it is essential that nothing unpredictable executes when I have disabled interrupts.  It is possible that non-firmware code that I have coded has a bug, but... it is very easy to reproduce when i try spawn two tasks from disc in rapid succession rather than wait.  This makes me suspicious that the CAS_IN_OPEN and CAS_IN_DIRECT and CAS_IN_CLOSE, one might be re-enabling interrupts before I have finished spawning one task... once the tasks are spawned mostly reliably except when i call TXT_CHAR_OUT, oddly reliable in mode 2, but not in mode 1.

AMSDOS

Sorry it may have nothing to do with what's being discussed here.
The other week when I was using tin(<filename>,<address>) to load some MODE 0 screens for my 128kb example in Hisoft Pascal, I noticed PEN 14 was flashing even during the loading block cycle.
Unfortunately I don't know the inner workings of tin(); and tout(); The files aren't standard and the loading is slower than the standard loading/saving in BASIC, the commands exist in the earlier Spectrum version of Hisoft Pascal though, but don't know if both version are using something which is custom made or if they depend on some sort of Firmware.

I just thought it was interesting that Palette Switching was occurring while files were being loaded. Was going to work on an example, though I'm not very imaginative!  :-[
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

Docent

Quote from: AMSDOS on 11:04, 24 August 18
Sorry it may have nothing to do with what's being discussed here.
The other week when I was using tin(<filename>,<address>) to load some MODE 0 screens for my 128kb example in Hisoft Pascal, I noticed PEN 14 was flashing even during the loading block cycle.
Unfortunately I don't know the inner workings of tin(); and tout(); The files aren't standard and the loading is slower than the standard loading/saving in BASIC, the commands exist in the earlier Spectrum version of Hisoft Pascal though, but don't know if both version are using something which is custom made or if they depend on some sort of Firmware.

I just thought it was interesting that Palette Switching was occurring while files were being loaded. Was going to work on an example, though I'm not very imaginative!  :-[

That's because inks are changed by an event handled by the interrupt. The interrupt is disabled only for actual data loading from tape/disk because it requires certain timings. After that, interrupts are enabled and inks blink until another data load occurs. I bet that the loading in Pascal goes through cas in char and, as this function loads data in 2kb blocks, you should notice at least 7 periods without blinking inks during loading :)


Docent

Quote from: zhulien on 01:20, 24 August 18

Actually I don't mind if one loading task blocks the others, but... i am loading into memory that is paged in (the main memory paged out) at #4000, so it is essential that nothing unpredictable executes when I have disabled interrupts.  It is possible that non-firmware code that I have coded has a bug, but... it is very easy to reproduce when i try spawn two tasks from disc in rapid succession rather than wait.  This makes me suspicious that the CAS_IN_OPEN and CAS_IN_DIRECT and CAS_IN_CLOSE, one might be re-enabling interrupts before I have finished spawning one task... once the tasks are spawned mostly reliably except when i call TXT_CHAR_OUT, oddly reliable in mode 2, but not in mode 1.

They enable interrupts, especially cas in close - because at the end of loading an event is set up to stop the disk motor. In order to fire this event interrupts must be enabled.
But I don't think that it is the source of your problem as on 6128 you can page in other memory banks and you can still use basic etc. so there is nothing in the firmware that forces certain memory bank configuration. Assuming that you page 16kb blocks at $4000..
Btw: you mentioned that you do task switching - is this a sort of preemptive multitasking, are you switching registers and stack pointer between tasks?
Post the source code if you can - it will be easier to spot the problem.

GUNHED

Well switching off interrupts by "just" using DI can have the effect that some CPC-OS routines switch on interrupts. I won't put my hand in the fire for that - just my experience.  :)
http://futureos.de --> Get the revolutionary FutureOS (Update: 2023.11.30)
http://futureos.cpc-live.com/files/LambdaSpeak_RSX_by_TFM.zip --> Get the RSX-ROM for LambdaSpeak :-) (Updated: 2021.12.26)

AMSDOS

Quote from: Docent on 16:44, 24 August 18
That's because inks are changed by an event handled by the interrupt. The interrupt is disabled only for actual data loading from tape/disk because it requires certain timings. After that, interrupts are enabled and inks blink until another data load occurs. I bet that the loading in Pascal goes through cas in char and, as this function loads data in 2kb blocks, you should notice at least 7 periods without blinking inks during loading

Well the example I had for loading 4 screens into the 2nd 64k made it seem like INK animations (PEN 15 of my editors cursor) were occurring while data was being loaded in. I don't know if it has got anything to do with the default Palette being used.
I could just make out brief pauses after creating another example (with my own set of colours), though it was only after I made a Tape Version could I confirm that. The Disk version makes it seem like 2 things are happening at once, though after checking out the Tape version, I noticed very brief pauses.
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

zhulien

#10
I think I fixed it, and it is likely 99% to do with TXT_OUT_CHAR and not the CAS_IN calls, which is good.


I can now run dozens of tasks in the POC environment without crashes.


I guess to write some 'real' drivers and decide on the context switching scheme.


scheme options: 


A - Round robin next task each 300th of a second cooperative all sharing the 1 stack (interupts disabled while a call is in progress), BASIC is the main task
B - BASIC get's x/300th of the processing time (x is configurable), all other tasks are preemptive with their own stacks


A is what is coded and working at the moment, with POC handlers.  It is really like machine code versions of what you might code using the 'EVERY' BASIC keyword.  Quite easy to code small handlers, but not the easiest to code complex handlers for.


B I am wondering if there is much benefit - if a full new OS then it's a given, but since I am wanting to enhance BASIC / AMSDOS, not really so much run complete 'other' applications in the background, would it really benefit much?


Driver examples:
- MultiPlay mouse driver
- simple M4 internet driver (just a bit more on top of the current M4 ROM) for background page and data fetching
- 8BML rendering tasks among some others...


A couple of features I have implemented related being able to optionally resume processing upon reset.  This is working pretty well.  Also the ability to recover processing tasks upon reset.  What I am hoping is that these will ease development.  Trying to think of how to use 512kb RAM on a CPC, or even 4MB if using the 4MB RAM expansion in a way that is useful beyond a RAMDisc and SYMBOS.


Just some ideas...


4096 (a 4MB expansion) gives 256 x 16KB Blocks, each which can be one of the following: 
- a driver (eg: mouse or if someone else wants to code it, TCP/IP stack)
- a background task (eg: music player)
- an allocated memory block (to be used by a background task or driver)
- a reserved memory block (reserved for use outside of this system, eg: RAMDisc)


Any suggestions? 


Code online for scrutiny...

https://drive.google.com/drive/folders/1Xvirgaep8dHFQUSaQxa5aQRV_SIbAfbR


To use it:


The easiest for now in WinAPE, use the given disc image for the tasks to be spawned or write a couple of your own using protext / maxam.  but assemble the mcp.asm directly from WinAPE into the ROM memory.



|mcphelp - Displays online help.
|mcpversion - Displays the current MCP version.
|mcpstatus - Displays system statistics.


|mcpautorestore - Automatically restore the computer state and resume tasks on reset.
|mcpautostart - Automatically start tasks upon reset.
|mcpstart - Manually start tasks.
|mcpshutdown - Manually shut down all tasks.
|mcpstop - Manually pause all tasks.  They may be resumed.
|mcpresume - Manually resume all paused tasks.
|mcpreboot - Reboot the computer preserving the running or shutdown status of tasks.
NOT YET IMPLEMENTED |mcpsnapshot - Manually save the computer state.
NOT YET IMPLEMENTED |mcprestore - Manually restore the computer state and resume tasks.
|mcprecover - Attempts to resume a system that was not stopped.


|mcptasks - Lists current tasks.
NOT YET IMPLEMENTED |mcpgo,<taskid> - Brings the specified task to the foreground.
|mcpspawn,"<filename>" - Loads and runs a new task.
|mcpkill,<taskid> - Kills the specified task and frees up resources.




GUNHED

The power of multitasking is always within the applications. If they don't need any time / cpu any longer, then just give control to the next task.  :)
http://futureos.de --> Get the revolutionary FutureOS (Update: 2023.11.30)
http://futureos.cpc-live.com/files/LambdaSpeak_RSX_by_TFM.zip --> Get the RSX-ROM for LambdaSpeak :-) (Updated: 2021.12.26)

Powered by SMFPacks Menu Editor Mod