Changes

Jump to: navigation, search

Caruh

14,969 bytes added, 16:38, 1 November 2023
/* Examples */
==== Memory address &7FF8 (TCON8) ====
* Bits marked with a '=' 1, 3, 4 and 6 are set by the task and* Bits marked with a '-' 2 and 7 are set by Caruh* Bits marked with a '*' 0 and 5 are manipulated by both Caruh and the task itself. See separate sections.
Bit 7: = 1 -> The system asks the Task to prepare for its saving. It is then restarted again at address &4000. (Save bit)
 
==== Memory address &7FF9 (TCON9) ====
* Reserved for future expansions
 
 
= V. Programming a Task =
In order to program a task, certain conventions must be observed. Strict rules apply here, which must be observed in every case.
However, Caruh also provides the Tasks with helpful functions. See later
 
=== Task conventions: Requirements for Tasks ===
* Tasks must retain their expansion RAM (E-RAM) configuration. Each task can read its own RAM banking status from addresses &7FFA and &7FFB. E.g. by an LD BC,(TER16). If illegal banking is still to be carried out, the interrupts must be switched off.
 
* Tasks must maintain the ROM / RAM status (the upper ROM is always on). For example, if data has to be read from the screen memory, the interrupts must be temporarily switched off. Note the status of the lower ROM!
 
* A Task can be a maximum of 15.75 KB long, because the stack of the Task and the Task variables are located above (see above: 'Structure of a task')
 
* Tasks do not require a header, as they are always loaded at address &4000. Tasks that have a header, including the header, must not be larger than 16 KB
 
* Tasks / files larger than 16 KB are NOT loaded / started by Caruh!
 
* A Task is allowed to output on screen only if in Caruh's Variable CCON2. (at address &BE02) the bits 0 and 7 are both cleared to zero. Exception: A Task did set bit 0 by himself, so its the Foreground-Task now
 
* During the call of OS functions that use hardware directly, the interrupts must be switched OFF and then switched ON again. The same is true if a Task used direct I/O hardware access.
 
* During the call of OS functions that use the stack pointer SP, the interrupts must be switched OFF and then switched ON again. Example:
 
DI ;switch off interrupts
 
CALL CUR_CPY ;Call OS function that changes SP
 
EI ;then switch on interrupts
 
 
'''Corresponding OS functions are in ROM A:'''
 
CUR_CPY
 
B8DIN
 
B16DIN
 
and all TERM_2 (?) OS functions (because of the control characters!) -> See the following ...
 
 
* The text output uses the OS variable C_POS to define the Cursor POSition. If a Task wants to output text, this variable must first be saved, then it must be set for the current text output (then output the text). Then C_POS must be restored again. During this time the interrupts must be switched off. Here's an example:
 
C_POS EQU &B848
 
DI ;switch off interrupts
 
 
LD HL,(C_POS) ;Store old Cursor-POSition
 
LD (Buffer),HL
 
 
LD HL,&BFFF + (line * 80) + row ;Set new Cursor-POSition
 
LD (C_POS),HL
 
 
LD HL,Text ;Pointer to text
 
CALL TERM_2 ;Call OS function to print text on screen
 
LD HL,(Buffer) ;Restore old Cursor-POSition
 
LD (C_POS),HL
 
 
EI ;then switch on interrupts
 
 
* The OS ROM A must always be banked in / selected! If the ROM is changed or an OS function is called in the other OS ROMs B,C,D the interrupts must be switched OFF and then switched ON again. See example:
 
DI ;switch off interrupts
 
LD IX, LESC ;OS function is located in ROM C -> Load its name to IX
 
CALL ROM_A2C ;Call OS function in ROM C
 
EI ;then switch on interrupts again
 
 
* Cooperative Tasks can switch to the next task as long as they have nothing to do (e.g. waiting for an event, etc.) This is done through the commands:
 
DI ;disable interrupts
 
RST 7 ;call interrupt entry
 
 
The 'DI' command is required to counteract a simultaneous interrupt.
Without the 'DI' command the consequences could be fatal.
After processing the 'RST 7', the interrupts are switched on again.
The command sequence 'DI: RST 7' thus corresponds to a system interrupt.
 
* Each Task has to set some bits of the Action and Configuration bits itself. These are located in memory locations &7FF8 and &7FF9 (see above!).
 
* Tasks with full screen capability are able to use the entire screen. Such Tasks have set bit 1 (switch bit) of address &7FF8 in their E-RAM. All other tasks (e.g. without screen output) should delete this Switch bit. Every Foreground task should regularly check bit 0 (Foreground bit) ats &7FF8. Because if it's set, the entire screen is available to the Task. If the 'ESC' key is pressed, the Task should switch itself back to Background. This is done by deleting bit 0 at address &7FF8 in the E-RAM of the Task.
 
* If a Task wants to end itself and remove itself from the system, it sets the bit 3 (Kill bit). The system will delete the Task at times.
Specifically, this means that the task writes the value &08 to the address &7FF8 and can then call the task manager using 'DI: RST 7'. A jump to the previous 'DI' command should then follow. Example:
 
LOOP DI ;interrupts off, this is necessary before EVERY RST 7!
 
RST 7 ;Call Caruh (or next task) ...
 
JR LOOP ;waiting for the task to be terminated by Caruh
 
 
* Storable Tasks are Tasks that work together with the system to save a copy of themselves. To indicate to the system that it is a storable task, the Task independently sets bit 4 (Storable bit) at address &7FF8 in its own E-RAM.
Tasks that do not attach importance to being able to be saved should delete this bit 4 once when they are called the first time.
A storable Task should regularly check whether the system wants to save it now. This is the case when Caruh sets bit 0 (Save bit).
As soon as the Save bit has been set at address &7FF8, the task should take all necessary steps to prepare for saving.
If the task is ready to be saved, then it must set bit 6 (Hold bit) at the address &7FF8.
The Task is then saved, and Caruh takes care of this process.
As soon as the Task has been successfully saved by Caruh, Caruh sets bit 5 (Secured-Bit) at the Tasks E-RAM address &7FF8.
The Task now knows that it has been saved successfully. The Task now needs to reset the 'Secured Bit' and jump to address &4000.
Tasks saved by the Caruh system are loaded (like any other) to address &4000 and also started there.
 
= OS functions for Tasks =
The Tasker Caruh provides several additional OS functions for Tasks.
Furthermore, certain parameters can be queried from RAM variables.
Please refer to the chapter on Task variables above.
 
=== Caruh's GUI and OS functions ===
Both screen mode and screen format can be set by the user in Caruh.
This is done using options.
These settings can be read from the following RAM variables:
 
* Memory address &000E contains the screen mode (0-3) which was set by the user. Each task can read the desired screen mode from this byte if the Task is switched to the Foreground.
 
* Memory address &000F contains the screen format (0 for 80x25, 1 for 68x30 and 3 for 64x32 format) that was set by the user. Each Task can read the desired screen format from this byte if the Task is switched to the Foreground.
 
* MENU SYSTEM
The 'M_DISP2' menu system known from CBM can be called up with the 'RST 1' command. For parameter transfer see source code.
 
* DRAW WINDOW
The 'DR_WIN' window drawer known from CBM can be called with 'CALL &000B'. To call DR_WIN:
 
HL = Pointer to start of Parameter- and Text-Block
 
 
'''Such a data block looks like this:'''
 
DB LOCATE_YY ;Upmost line
 
DB LOCATE_XX ;Leftmost row
 
 
DB LINES ;Number of lines in Window-Frame
 
DB ROWS ;Number of rows / columns
 
 
DB "Sample text",&00 ;Text of first line, terminated by byte &00
 
 
Now the text of the following lines may follow here...
 
Every line must be terminated by an &00 byte
 
A text line can use control codes for screen MODE 2
 
As for example the locate control code (80x25 format):
 
DB &1F,YY,XX,"Text sample",&00
 
 
'''ATTENTION:''' DR_WIN at &000B will switch the Interrupts OFF. The calling Task must switch them on again by itself.
 
 
* REQUEST SQUARE ON COMMON SCREEN SOMEWHERE
Calling the 'SAOMS' function at address &0003 allows the user to reserve a piece of the general multi-screen (regular view).
This OS function must be called by a Task.
 
 
'''To call this function:'''
 
Task number in TTNS3 = &BE03 (A Task can read its number from address TNUME = &7FFD)
 
YL = Total number of rows of area to be reserved (width, MODE 2 chars)
 
YH = Total number of lines of the area to be reserved (height)
 
 
'''Return from function:''' First you need to take a look at the Z-Flag, then see for data in XL and XH.
 
Z-Flag set '1' -> User Break using ESC key! Do not use values in IX!
 
Z-Flag cleared -> All fine! -> See registers XL and XH: XL = Upmost line / Y position of frame (0-24). XH = Leftmost raw / X position of Frame (0-79)
 
 
* REQUEST DEFINED SQUARE ON COMMON SCREEN ON DEFINED POSITION
 
If the 'RFMSA' function is called using the 'CALL &0013' command at address &0013, a Task can use it to reserve a part of the shared screen. The parameters are required as follows:
 
XL = Upmost line / Y position of frame (0-24)
 
XH = Leftmost raw / X position of Frame (0-79)
 
YL = Total Rows of Frame (1-80)
 
YH = Total Lines of Frame (1-25)
 
Address (TTNS3 = &BE03) = Number of requesting the Task
 
 
'''Return from function:''' When returning, the zero flag provides information about the success:
 
Z-Flag cleared -> Areas overlapping! Area can NOT be used!
 
Z flag set '1' -> Requested area CAN be used!
 
 
* SET PRIORITY OF A TASK
If the function 'SEPRI' is called using the Z80 command 'RST 2' at address &0010, a Task can change its priority (new priority in A).
Each task is started with the highest priority '1' after loading.
Often, however, a Task does not have to be called up that often (e.g. display time or temperature, send data to the printer, etc.). In such a case, the priority can be reduced.
The new priority is transferred in the accumulator; values from 1 to 255 are permissible. Smaller values have higher priority.
 
 
* If a task currently has nothing to do, it can actively switch to the next Task. This is done using the commands:
 
DI ;Disable interrupts (command before each 'RST 7' necessary!)
 
RST 7 ;Call up the Task Manager or the next Task
 
 
* Testing the content of address &7FFB on &7x allows integrity tests. Since the E-RAM status (high byte) is read here, the upper nibble must be '7'. If it's not equal to '7', the task E-RAM has been corrupted!
 
 
= Examples =
 
== Set a regular Background Task as the Foreground Task ==
If any Background Task is made the only Foreground Task, then control of the
screen and keyboard scanning is passed to that new Foreground Task.
 
This is done either using the Task function 'Switch <t>o' of Caruh's menu or by clicking on one of the four Task names in the task bar (at the bottom of the screen).
 
This process cannot be initiated by the Task itself. However, if the user wants to switch a Task to the Foreground, this Task must also be able to react to it!
 
== Process log: A Background Task becomes a Foreground Task ==
* Caruh reads and evaluates byte at memory location &7FF8 (TCON8) of the task:
 
If bit 1 is cleared, the task cannot become a Foreground Task!
 
If bit 1 is set, however, the task can be switched as a Foreground Task
 
* Caruh now sets bit 0 of memory location &7FF8 (TCON8) in the E-RAM of the Task to '1'. This tells the Task that it has now become the Foreground Task. The Task must now take control of the screen and the keyboard scanning.
 
* To inform Caruh that the Task has taken over screen control, the Task must set bit 0 in memory location &BE02 (CCON2). As soon as this bit is set, Caruh will relinquish screen control.
 
* At this point Caruh is now waiting for bit 0 to be set to '1' at address &BE02 (CCON2)! If that does not happen, Caruh will take over control again after a while (90 * DI: RST 7), as the Task appears incapable of doing so.
 
* As soon as bit 0 at address &BE02 (CCON2) is set to '1', Caruh waits for it to be reset in order to take control back again. See next paragraph
 
* The screen and keyboard are now available to the newly baked Foreground Task. Now it makes sense to first clear the screen, set the screen MODE 0-2 and possibly the screen format.
 
* The foreground task takes its course ...
 
* It's essential to test for 'ESCape' being pressed and to give control back to Caruh when the user's using the 'ESCape' key.
 
How does it work?
Continue reading please ... ;-)
 
== How can a Foreground Task return control to Caruh? ==
When a Task has taken control of the screen and keyboard, it must also test whether the ESC key is pressed. If this is the case, control must be returned to Caruh.
The same applies if the Task simply wants to give back control.
 
* The Task deletes bit 0 at address &7FF8 (TCON8) in its own E-RAM. This turns the Task into a Background Task (regular state). But the Task also has to tell Caruh! This is how it happens ...
 
* The Foreground Task also deletes bit 0 at address &BE02 (CCON2)!
 
* As soon as bit 0 at address &BE02 (CCON2) is cleared, Caruh takes control of the screen and keyboard (as before). The former Foreground Task is now working in the Background again.
 
* Caruh is in the Foreground again :-)
 
 
'''Note:''' If the newly appointed Foreground Task is not able to set bit 0 of memory address &BE02 (CCON2) to 1, the Foreground status will be withdrawn after 192 cycles (192 times 'DI: RST 7')!
 
That means nothing else than that Caruh will take control again.
 
== Reserve parts of the common screen ==
It's possible for each task to use certain parts of the general screen.
The position and extent of the claimed area are transferred. This request can be approved or rejected, depending on whether the claimed area is available.
This way it's possible for each task to always reserve the same sections for itself, since it can remember the coordinates of the first-time selection.
Either by saving the Task, using nvRAM or a configuration file.
 
The screen is divided into 80 columns (0-79) and 25 lines (0-24).
The table begins with the leftmost character on the top line.
 
When the Caruh system is started, Caruh reserves the first four lines (0-3) and
the bottom line (24).
 
 
This is how a Task can reserve a part of the general screen:
 
Entry (from the Task) at address &0003
 
 
'''Parameter:'''
 
The number of the reserving Task is stored in TTNS3 = address &BE03
 
The number of MODE 2 columns is transferred in register YL
 
The number of lines is transferred in register YH
 
The command 'LD IY, &0309' would therefore display 3 rows and 9 columns
 
 
* The current table is now graphically displayed on the screen. Only every 'empty' position can be assigned. A box - consisting of lines - can now be moved using the cursor keys and pressing Copy reserves the corresponding area of the screen and enters the position in the multi-screen Table.
 
* If the frame can't be set at the current position, the BORDER is shown in orange color (15). Either a valid area is found or the process can be canceled using the 'ESC' key.
 
* The Task is finally informed whether the setting of the frame was successful.
 
Furthermore, X (0-79 in XL) and Y (4-23 in XH) coordinates are transferred. These correspond to the left (XL) and upper (XH) corner on the screen. Register IX contains these two values.
 
In addition, the corresponding screen address of the top left corner is transferred (in RAM variable C_POS).
2,002
edits