|
||
|
||
In addition to character arguments, each line has its own argument word. Line arguments are located in the 25-word table LINE_ARG. High byte of each word has the same structure as the character arguments and, if its content is >0, all character arguments for that line are overridden by LINE_ARG. That is the fast way to change the ink/paper colour and blinking arguments for the whole line in only one step. Low byte of the line argument contains bits which define the character
width and height for that line. In double-width mode, only 30 characters
are displayed in one line, and in double-height mode that line takes the
place of two lines on the screen. Combination of those two modes is also
possible. As not all of video memory locations are used in
those modes, the rest of line is skipped during the video signal
generation. The drawing describes how the video memory is
sliced for those modes. Gray
areas are ignored for double-width and double-height modes, only the red
areas are used. Each line can be preset for double-width and/or double-height mode independently. The only limitation is that the last row cannot be preset for double-height mode, as there is no sense in displaying only the upper portion of the row. There is also the word SCREEN_ARG which overrides all line and character arguments. I has the same structure as the line arguments and it affects the paper/ink colour, blinking bits, width and height for the whole screen. The only exception is the row 25 again, which will be forced to single-height mode. If some cursor is located at some non-visible area, covered by the previous double-height row or pushed outside the screen by the double-width characters, it remains hidden, but still active. If variables LINE_ARG or SCREEN_ARG are set, the lower priority argument bytes are not modified, but only ignored by the video routine. When LINE_ARG is SCREEN_ARG are reset back to 0, the lower priority arguments will be unchanged and active again. There is no global background setting. By default, background is black, but it is possible to simulate any global background by presetting it in the background field (xBGRxxxx) at each location in the video memory (or for all rows, or for the screen, but then you can not manipulate the arguments for the single location). In that case, the only unfilled area will be a small margin around the area covered by characters, but you can paint this area by writing the desired colour in variable MARGIN. In this variable, only the bits 0, 1 and 2 are valid (R, G and B respectively). For instance, if you want to set the yellow background for the whole screen, you can write x011xxxx at all character argument bytes (or at all line arguments, or the screen argument) and write xxxxx011 at the variable MARGIN. Note that writing to MARGIN does not paint the whole screen area, but only the small visible area (11 pixels left, 8 pixels right, 3 scan lines at the top and one scan line at the bottom) which is not covered by the active character area, but is visible on the screen. Each text row is 24 scan lines high. As one character pixel takes 2x2 screen pixels, this makes 12 character scan lines. The 3 upper lines are for pseudographics box characters, and the rest is for characters. Most characters are 7 pixels high (14 screen pixels), and the remaining two bottom pixels are just used by characters g, j, p, q, y and some special characters. The upper 4 scan lines in the first text row are missing, so the first text row is only 20 scan lines high. That gives 24x24+20=596 scan lines, and the remaining 4 lines are added as the at the top (3) and the bottom margin (1) of the visible area. There are two extra pixels, which are added unconditionally by the routine. One is at the top left (pixel 0,0), and the other one at the bottom right (799,599). They are used by the intelligent monitor, for auto adjustment of x, y positions. Those pixels are blue, so they are hardly visible by the user. If the foreground blinking bit (xxxx1xxx) is set, the character blinks so that it changes its colour between the foreground (xxxxBGR) and the background (xBGRxxxx) colour, but if the background blinking bit is set (1xxxxxxx), then the background blinks between background colour (xBGRxxxx) and black (x000xxxx), leaving the foreground (character) unaffected. Setting both blinking bits (1xxx1xxx) results in synchronous blinking both foreground and background between their preset colours (xBGRxBGR) and black (x000x000). Character and background blinking rate may be preset at the variable PERIOD0. Interrupt routine saves all W registers and RCOUNT register used for repeat loop, so there are no restrictions for their use in the main program. If your project is based on dsPIC33 family, you can use DO instruction and its shadow registers in the main program, as the interrupt routine does not use it. In some cases, the main program requires synchronization with the video signal. For that purpose, interrupt routine sets bit FLAG,#2 unconditionally at the beginning of the vertical sync pulse. This bit is not used (neither reset) by interrupt routine, and the main program can test and reset it at any time. The normal synchronization process is to reset this bit and then to poll its state. When it detects that this bit is set (which will, at worst case, happen after 1/60 s), that means that the frame generation is over and that the vertical sync pulse has just started. Note: Any attempt to disable interrupts in the main program flow, or to use some higher priority interrupts, will result in picture disappearing from the monitor. After the signal stabilizing, it will take some time before the monitor "catches" sync signals and picture reappears. You can add as much program in the main flow as you wish, but you must count on that it will be interrupted frequently, so the use of time-dependent routines will be impossible. That is why the keyboard and UART services are carefully "embedded" in this routine, otherwise the interfacing to those peripherals would not be possible without a slave microcontroller. The worse will probably happen if you try to modify any part of the existing routine or to add some new features. The program is highly optimized for execution speed, but most timings are so "tight" that there is no extra time for additional tasks. But, nothing is impossible, so every enhancement of the project will be welcome. Even during vertical porch period and vertical sync, interrupt is generated at every 26.4 microseconds (1056 instruction cycles), which is necessary to maintain the proper keyboard and UART polling. |
||