.........1.........2.........3.........4.........5.........6.........7.........8

LIGHT SCREEN DESIGNER
ZX Computing, December 1985/January 1986
Part 09 of 13

[The CPs at E486/E539/E54A were coded as FE10 in the listing,]
[but as they're supposed to be checking for >9, according to ]
[the comments, I changed them all to FE0A.               JimG]

[Part 10 changed the command at E45D to "JR   TEST_CPOS", to ]
[check that the cursor (left) position was valid, but I think]
[that JRs for the other three directions at E451/E470/E47F   ]
[should also be changed.                                 JimG]

-----------------------------------------------------------------------------
ADDR SUBROUTINE POINTED TO                  PURPOSE               HOW OBTAINED
---- ---------------------                  -------               ------------
E2E1 DDE4               DEFW E4DD,ITAL_OFF  Italics Off           SYM SHF/Q
E2E3 E2E4               DEFW E4E2,ITAL_HS   Half Slope Italics    SYM SHF/W
E2E5 E8E4               DEFW E4E8,ITAL_FS   Full Slope Italics    SYM SHF/E
E2E7 F2E4               DEFW E4F2,TEXT_EXIT Cancel Text Mode      CAP SHF/SPACE
E2E9 D0E4               DEFW E4D0,7_BIT     7 Bit Wide Toggle     TRUE VIDEO
E2EB D4E4               DEFW E4D4,BOLD      Bold Type Toggle      INVERSE VIDEO
E2ED 3AE3               DEFW E33A,CAPS_LOCK Caps Lock Toggle      CAPS LOCK
E2EF 5200               DEFW 0052,RET       Not Used              EDIT
E2F1 53E4               DEFW E453,TC_LEFT   Cursor Left           CURSOR LEFT
E2F3 45E4               DEFW E445,TC_RIGHT  Cursor Right          CURSOR RIGHT
E2F5 5FE4               DEFW E45F,TC_DOWN   Cursor Down           CURSOR DOWN
E2F7 72E4               DEFW E472,TC_UP     Cursor Up             CURSOR UP
E2F9 5200               DEFW 0052,RET       Not Used              DELETE
E2FB F2E4               DEFW E4F2,TEXT_EXIT Cancel Text Mode      ENTER
E2FD 01E5               DEFW E501,ALT_SIZE  Alter Chr Size        BOTH SHIFTS
E2FF 43E3               DEFW E343,GRAPHICS  Graphics Mode Toggle  GRAPHICS

E301 0100               DEFW 0001           HEIGHT of characters
E303 0100               DEFW 0001           WIDTH  of characters
E305 FF818181 TC_PIXEL
E309 818181FF                               PIXEL LAYOUT of text-cursor
-----------------------------------------------------------------------------

OK. Hands up all those people who spotted that if you used the ARC_RAD
routine in the last issue then HIDE and CURSOR_TYPE subsequently
didn't work! You didn't notice? Well it's lucky I'm observant then.
This bug was caused by a particularly daft oversight on my part,
whereby, the ARC_RAD routine corrupted the IX register - (actually
it's corrupted by the ROM, but that's neither here nor there). Since
the majority of the Light Screen Designer program relies upon IX
having a constant value of DB40 then I'm sure you will appreciate the
problems that such corruption may cause.

The solution is to re-assign IX within the main loop. If this is done
then it will not matter whether the daughter routines corrupt IX,
since the mother routine will always restore it. To correct the bug,
it is therefore necessary to type in the following BASIC program,
along with Light Screen Designer, RUN the BASIC, and re-SAVE the
machine code. The correction program is as follows:

10 FOR X=0 TO 61
20 POKE 56793+X,PEEK (56797+X)
30 NEXT X
40 POKE 56855,221
50 P0KE 56856,33
60 POKE 56857,64
70 P0KE 56858,219
80 P0KE 56915,23

Right - that's over and done with. Now onto this episode. This is a
particularly intricate piece of machine code engineering. This is the
TEXT option, available on the P key - easy to remember because PRINT
is on the same key, and if you've got an old style Spectrum "Minus"
with rubber keys then quotes (") are on the same key. Once you hit
text mode the familiar crosswire cursors disappear, and are replaced
by a small rectangle - this is the TEXT MODE CURSOR which you can
manipulate around the screen with the cursor keys (with CAPS SHIFT if
you have an ordinary Spectrum). But Text Mode allows you to do a whole
lot more than just move a different shaped cursor around the screen.
Allow me to elucidate.

First of all you could press a number or a letter. If you do this then
the required number or letter will appear on the screen where the
cursor was, and the cursor itself will move one square to the right.
With letters, of course, you can also use CAPS SHIFT to get a capital
letter. (Note: CAPS LOCK works as expected). You can also use SYMBOL
SHIFT to get a symbol - but this works slightly differently to normal.

If the normal use of SYMBOL SHIFT would be to produce a symbol then
this works exactly as it should. If however, it would normally produce
a token keyword (for instance SYMBOL SHIFT/Y which would normally
produce the keyword 'AND') then you get something different. In
general you get the E-Mode symbol on the same key (for instance SYMBOL
SHIFT/Y would give square left bracket) - this means that you never
have to enter E-Mode, but there are some exceptions. The COPYRIGHT
symbol for example. SYMBOL SHIFT/P will produce quotes, so I have
taken the liberty of moving COPYRIGHT onto a different key. SYMBOL
SHIFT/I will now generate the required COPYRIGHT symbol. This leaves
just three keys - Q, W and E - which don't have a symbol on them, and
these are used as control keys, which will be explained in a moment.

As well as covering letters, numbers, and symbols, you can also use
the graphics characters. Just press the GRAPHICS button to enter
graphic-mode as you would normally, and the same button again to get
back to normal. In this manner, the keys 1 to 8 will produce block
graphics, which may be inversed by the additional use of SHIFT. The
letter keys will produce the User Defined Graphics. In this program,
five extra UDGs are allowed - on keys V, W, X, Y and Z. To use them it
is necessary to allow an extra forty bytes in the UDG area of RAM, and
graphics V, W, X, Y and Z may be defined in this area.

To break with tradition, SPACE will print a space - it will not escape
from Text Mode. There are two ways to exit Text Mode. One is to press
SPACE with CAPS SHIFT, and the other is to press ENTER.


Characters

It's worth pointing out at this stage that the characters are not
necessarily printed on whole character squares. Depending upon the
position of the cursor a character may overlap two or more character
squares. You see when you hit TEXT MODE and you change from crosswire
cursor to text cursor, the text cursor is printed as an outline, whose
top left hand corner exactly coincides with the position of the
crosswire cursor - to the exact pixel!

You can print text with this facility in many different ways. We've
already seen the effect of CAPS LOCK and GRAPHICS, but what about the
rest of the control keys?

TRUE VIDEO will switch between 7-pixel wide, and 8-pixel wide
characters. 7-pixel wide characters are obtained by overprinting the
8th column of pixels, which leaves less space between two consecutive
characters. This will give you thirty six characters across the screen
instead of thirty two. I personally think that this makes text look
much better.

INVERSE VIDEO will switch between standard and bold typeface. Bold
type is produced by printing each INKEd pixel twice instead of once.
Bold type looks very nice, and of course there's nothing to stop you
using 7-pixel wide bold characters if you want to.

You can also print characters in italics. SYMBOL SHIFT/W will switch
to half-slope italics (sloping two pixels down for every one pixel
across); SYMBOL SHIFT/E will switch to full-slope italics (sloping at
forty-five degrees); and SYMBOL SHIFT/Q will switch to fully upright
characters (italics off).

Finally, you can change the size of characters. You are not restricted
to printing characters the size of a standard character square - you
can have double width, double-height, triple height, and so on. To
achieve this press both shifts together (or the Extended Mode key on
the Spectrum Plus). You can then alter the size of the cursor by
pressing the cursor keys: RIGHT to increase the width, and LEFT to
decrease the width; DOWN to increase the height, and UP to decrease
the height. Space will allow you to ESCAPE from Extended Mode and
return the cursor keys to their normal functions. Any other key will
be acted upon as normal, as well as escaping from E-Mode.

Overall then, it would seem that the text facilities of LSD are pretty
powerful. You can put text wherever you want it - to the exact pixel -
you can print it any size you want, and in a large variety of
typefaces (twelve in total!. You can escape from text mode by pressing
CAPS SHIFT/SPACE or ENTER. You can re-enter text mode by pressing key
P, or return to BASIC by pressing SPACE.

The Light Screen Designer series is now very nearly complete. The next
issue will contain the penultimate episode [Not quite; four more
chapters followed. JimG], which will be all about drawing ellipses.
The final part - part eleven - will do all the colouring in. I know a
lot of people have been waiting for that facility. After part eleven
there will be an Epilogue (I prefer to call it an Epilogue rather than
a Part Twelve because the program will be completed in Part Eleven).
This will be just to round everything off nicely. I'll leave you now
to feed in all this machine code. Bye bye till next time.

Toni Baker

-----------------------------------------------------------------------------
E30D FDCB016E T_CHR     BIT  5,(FLAGS)
E311 28FA               JR   Z,T_CHR       ;Wait until a key is pressed
E313 FDCB01AE           RES  5,(FLAGS)     ;Signal "Ready for a new key"
E317 FD46CE             LD   B,(LAST_K)    ;B= character code of key pressed
E31A CD541F             CALL BREAK_KEY     ;Test for CAPS SHIFT/SPACE
E31D 3802               JR   C,T_CHR_1     ;Jump unless CAPS SHIFT/SPACE pressed
E31F 0603               LD   B,#03         ;03 signals CAPS SHIFT/SPACE
E321 78       T_CHR_1   LD   A,B           ;A= character code
E322 FEAA               CP   #AA
E324 D8                 RET  C             ;Return if A contains a valid code
E325 216A02             LD   HL,SYMBOL_CODES ;Point HL to ROM table of
                                           ;"Symbol Shift Character Codes"
E328 EDB1               CPIR               ;Locate character in table
E32A 11DBFF             LD   DE,#FFDB
E32D 19                 ADD  HL,DE         ;Reposition HL so that it now points
                                           ;to "Extended Mode with SHIFT" table
E32E 7E                 LD   A,(HL)        ;A= E-mode symbol on same key
E32F FEBF               CP   "IN"
E331 2002               JR   NZ,T_CHR_2    ;Jump unless SYM SHIFT/I pressed
E333 3E7F               LD   A,")"         ;COPYRIGHT symbol now on SYM SHIFT/I
E335 A7       T_CHR_2   AND  A
E336 F0                 RET  P             ;Return with codes 00, 01 or 02
E337 D6B5               SUB  #B5           ;SYM SHF/Q, SYM SHF/W and SYM SHF/E
E339 C9                 RET                ;respectively

E33A 3A6A5C   CAPS_LOCK LD   A,(FLAGS2)
E33D EE08               XOR  #08
E33F 326A5C             LD   (FLAGS2),A    ;Complement CAPS LOCK flag
E342 C9                 RET
-----------------------------------------------------------------------------
E343 3A415C   GRAPHICS  LD   A,(MODE)
E346 EE02               XOR  #02
E348 32415C             LD   (MODE),A    ;Complement GRAPHICS flag
E34B C9                 RET

E34C C5       T_LOCATE  PUSH BC
E34D FE80               CP   #80
E34F 3006               JR   NC,T_LOC_1  ;Jump if A contains either a graphic
                                         ;symbol or a UDG
E351 ED4B365C           LD   BC,(CHARS)  ;Point BC to Pixel-Layout table in
                                         ;ROM, less 0100h
E355 1808               JR   T_LOC_2
E357 D690     T_LOC_1   SUB  #90
E359 380D               JR   C,T_LOC_3   ;Jump if A contains a graphic code
E35B ED4B7B5C           LD   BC,(UDG)    ;Point BC to Pixel-Layouts for UDGs
                                         ;(Note: Range of A is now 00h-19h)
E35F 6F       T_LOC_2   LD   L,A
E360 2600               LD   H,#00       ;HL= character code
E362 29                 ADD  HL,HL
E363 29                 ADD  HL,HL
E364 29                 ADD  HL,HL
E365 09                 ADD  HL,BC       ;HL points to pixel layout of
                                         ;required character
E366 C1                 POP  BC
E367 C9                 RET
E368 47       T_LOC_3   LD   B,A         ;Low nibble of B indicates which 
                                         ;graphic symbol is required
E369 CD380B             CALL PO_GR_1     ;Construct graphic symbol in MEMBOT
E36C 21925C             LD   HL,MEMBOT   ;Point HL to this newly created
                                         ;pixel layout
E36F C1                 POP  BC
E370 C9                 RET
-----------------------------------------------------------------------------
E371 F5       PR_NZ_DE  PUSH AF          ;Stack the zero flag
E372 3E20               LD   A,"space"
E374 D7                 RST  #10         ;Print a space
E375 F1                 POP  AF          ;Restore the zero flag
E376 2007               JR   NZ,PR_NZ_1
E378 3E20               LD   A,"space"
E37A D7                 RST  #10         ;Print a second space
E37B 3E20               LD   A,"space"
E37D D7                 RST  #10         ;Print a third space
E37E C9                 RET
E37F 7A       PR_NZ_1   LD   A,D
E380 D7                 RST  #10         ;Print CHR$(D);
E381 7B                 LD   A,E
E382 D7                 RST  #10         ;Print CHR$(E);
E383 C9                 RET

E384 C5       T_COLOUR  PUSH BC
E385 D5                 PUSH DE
E386 E5                 PUSH HL          ;Stack registers
E387 CDDB0B             CALL PO_ATTR     ;Colour appropriate attribute byte
E38A E1                 POP  HL
E38B D1                 POP  DE
E38C C1                 POP  BC          ;Restore registers
E38D 23                 INC  HL          ;HL points to next byte in screen
E38E 3E08               LD   A,#08       ;A= number of pixels in this byte
E390 C9                 RET
-----------------------------------------------------------------------------
E391 3E08     TX_PRINT  LD   A,#08
E393 08       TXLOOP_1  EX   AF,AF'      ;A'= number of rows in pixel layout
E394 3A01E3             LD   A,(HEIGHT)
E397 32675C             LD   (B_REG),A   ;(B_REG)= Number of times each row
                                         ;must be duplicated
E39A 3A40DB   TXLOOP_2  LD   A,(JFLAGS)
E39D EE10               XOR  #10
E39F 3240DB             LD   (JFLAGS),A  ;Complement ODD/EVEN ROW flag
E3A2 C5                 PUSH BC          ;Stack cursor coordinates
E3A3 D5                 PUSH DE          ;Stack pixel layout pointer
E3A4 E5                 PUSH HL          ;Stack address of screen-byte
                                         ;containing cursor
E3A5 79                 LD   A,C         ;A= column number of cursor (in pixels)
E3A6 E607               AND  #07
E3A8 4F                 LD   C,A         ;C= pos within screen-byte of cursor
E3A9 1A                 LD   A,(DE)
E3AA 57                 LD   D,A         ;D= current row from pixel layout
E3AB DDCB005E           BIT  3,(JFLAGS)
E3AF 2803               JR   Z,TXP_1     ;Jump unless using BOLD typeface
E3B1 87                 ADD  A,A         ;Shift left one bit; bit 0 reset
E3B2 B2                 OR   D           ;Use each bit twice, if set
E3B3 57                 LD   D,A         ;D now amended for BOLD type
E3B4 3A03E3   TXP_1     LD   A,(WIDTH)
E3B7 47                 LD   B,A         ;B= number of times each pixel
                                         ;must be duplicated
E3B8 3E08               LD   A,#08       ;A= number of pixels in screen-byte
E3BA 5F                 LD   E,A         ;E= number of bits in pixel layout row
E3BB 0C                 INC  C
E3BC 1803               JR   TXALIGN2
E3BE 3D       TXALIGN1  DEC  A           ;A= number of remaining pixels in (HL)
E3BF CB06               RLC  (HL)        ;Move next pixel from screen into bit 7
E3C1 0D       TXALIGN2  DEC  C
E3C2 20FA               JR   NZ,TXALIGN1 ;Pixel at cursor position now
                                         ;in bit 7 of (HL)
E3C4 C5       TXLOOP_3  PUSH BC          ;Stack character width (B)
E3C5 F5                 PUSH AF          ;Stack screen-byte pixel counter
E3C6 CB02               RLC  D           ;Move next pixel from pixel-layout
                                         ;into bit 0 of D
-----------------------------------------------------------------------------
E3C8 FD4E57   TXLOOP_4  LD   C,(P_FLAG)  ;Bit 0 of C= OVER status
E3CB 7E                 LD   A,(HL)
E3CC 07                 RLCA             ;Bit 0 of A= current pixel from screen
E3CD A1                 AND  C           ;Bit 0 of A= 0 if OVER 0; or current
                                         ;pixel from screen if OVER 1
E3CE CB19               RR   C
E3D0 CB19               RR   C           ;Bit 0 of C= INVERSE status
E3D2 A9                 XOR  C           ;If INVERSE 1, then complement
                                         ;bit 0 of A
E3D3 AA                 XOR  D           ;Bit 0 of A= current pixel from
                                         ;required pixel-layout, with OVER and
                                         ;INVERSE correctly implemented
E3D4 1F                 RRA              ;Carry= pixel to print
E3D5 CB16               RL   (HL)        ;Bit 0 of (HL) correctly stores pixel
E3D7 F1                 POP  AF          ;A= number of remaining pixels in
                                         ;(HL) to consider
E3D8 3D                 DEC  A
E3D9 CC84E3             CALL Z,T_COLOUR  ;If all 8 bits of (HL) have been dealt
                                         ;with, then colour the attribute byte
                                         ;and point HL to next byte from screen
E3DC F5                 PUSH AF          ;Stack screen-byte pixel counter
E3DD 10E9               DJNZ TXLOOP_4    ;Duplicate pixel as many times as
                                         ;is required
E3DF F1                 POP  AF          ;A= screen-byte pixel counter
E3E0 C1                 POP  BC          ;B= number of times each pixel must
                                         ;be duplicated
E3E1 1D                 DEC  E
E3E2 20E0               JR   NZ,TXLOOP_3 ;Repeat this procedure for all pixels
                                         ;within current pixel-layout row
E3E4 FE08               CP   #08
E3E6 2808               JR   Z,TXALIGN4  ;Jump if HL points to a new byte
E3E8 CB06     TXALIGN3  RLC  (HL)        ;This loop realigns (HL)
E3EA 3D                 DEC  A           ;so that all pixels are back in
E3EB 20FB               JR   NZ,TXALIGN3 ;the right place
E3ED CD84E3             CALL T_COLOUR    ;Colour in the last attribute
E3F0 E1       TXALIGN4  POP  HL          ;HL points to first screen byte
                                         ;affected in current row
E3F1 D1                 POP  DE          ;DE points to current row of
                                         ;pixel-layout
E3F2 C1                 POP  BC          ;B= current row number
                                         ;C= column number of first pixel
                                         ;affected in current row
E3F3 CD36DD             CALL DOWN_PIX    ;Point HL and B one pixel down
E3F6 DDCB0046           BIT  0,(JFLAGS)
E3FA 280D               JR   Z,TXP_3     ;Jump unless printing in italics
E3FC DDCB004E           BIT  1,(JFLAGS)
E400 2004               JR   NZ,TXP_2    ;Jump if using full slope
E402 DDCB0066           BIT  4,(JFLAGS)  ;Test ODD/EVEN ROW flag
E406 C413DD   TXP_2     CALL NZ,LEFT_PIX ;If reqd, point HL and C one pix left
E409 FD352D   TXP_3     DEC  (B_REG)
E40C 208C               JR   NZ,TXLOOP_2 ;Repeat current pixel-layout row
                                         ;as many times as is required 
E40E 13                 INC  DE          ;DE points to next pixel-layout row
E40F 08                 EX   AF,AF'
E410 3D                 DEC  A
E411 2080               JR   NZ,TXLOOP_1 ;Repeat procedure for all rows
                                         ;of pixel-layout
E413 C9                 RET
-----------------------------------------------------------------------------
E445 D5       TC_RIGHT  PUSH DE
E446 CD34E4             CALL GET_WIDTH
E449 5F                 LD   E,A         ;E= character width in pixels
E44A 87                 ADD  A,A         ;A= twice this width
E44B 81                 ADD  A,C
E44C 3802               JR   C,TCR_1     ;Jump if cursor right not possible
E44E 93                 SUB  E
E44F 4F                 LD   C,A         ;C= new column number of cursor
E450 D1       TCR_1     POP  DE
E451 182C               JR   J_PIXADDR
E453 D5       TC_LEFT   PUSH DE
E454 CD34E4             CALL GET_WIDTH
E457 5F                 LD   E,A         ;E= character width in pixels
E458 79                 LD   A,C         ;A= current cursor column number
E459 93                 SUB  E           ;A= new cursor column number
E45A D1                 POP  DE
E45B D8                 RET  C           ;Return if cursor left not possible
E45C 4F                 LD   C,A         ;C= new column number of cursor
E45D 1832               JR   TEST_CPOS
E45F D5       TC_DOWN   PUSH DE
E460 3A01E3             LD   A,(HEIGHT)  ;A= character height in squares
E463 87                 ADD  A,A
E464 87                 ADD  A,A
E465 87                 ADD  A,A
E466 5F                 LD   E,A         ;E= character height in pixels
E467 87                 ADD  A,A         ;A= twice this height
E468 80                 ADD  A,B
E469 FEB0               CP   #B0
E46B 3002               JR   NC,TCD_1    ;Jump if cursor down not possible
E46D 93                 SUB  E
E46E 47                 LD   B,A         ;B= new row number of cursor
E46F D1       TCD_1     POP  DE
E470 180D               JR   J_PIXADDR
E472 D5       TC_UP     PUSH DE
E473 3A01E3             LD   A,(HEIGHT)  ;A= character height in squares
E476 87                 ADD  A,A
E477 87                 ADD  A,A
E478 87                 ADD  A,A
E479 5F                 LD   E,A         ;E= character height in pixels
E47A 78                 LD   A,B         ;A= current row number of cursor
E47B 93                 SUB  E           ;A= new row number of cursor
E47C D1                 POP  DE
E47D D8                 RET  C           ;Return if cursor up not possible
E47E 47                 LD   B,A         ;B= new row number of cursor
E47F C341DD   J_PIXADDR JP   PIX_ADDR    ;Calculate HL= address of screen-byte
                                         ;containing cursor, and return
-----------------------------------------------------------------------------
E482 7E       TESTCSIZE LD   A,(HL)      ;A= character width (or height)
E483 A7                 AND  A
E484 2804               JR   Z,TCS_1     ;Jump if width (or height) zero
E486 FE0A               CP   #0A
E488 3802               JR   C,TCS_2     ;Jump if width (or height) valid
E48A 3601     TCS_1     LD   (HL),#01    ;Set width (or height) to 01
E48C 23       TCS_2     INC  HL
E48D 3600               LD   (HL),#00    ;Reset high byte
E48F 23                 INC  HL
E490 C9                 RET

E491 E5       TEST_CPOS PUSH HL
E492 2101E3             LD   HL,HEIGHT
E495 CD82E4             CALL TESTCSIZE   ;Ensure valid character height
E498 CD82E4             CALL TESTCSIZE   ;Ensure valid character width
E49B E1                 POP  HL
E49C AF                 XOR  A           ;A= 00
E49D DDCB0046           BIT  0,(JFLAGS)
E4A1 280C               JR   Z,TCP_1     ;Jump unless printing in italics
E4A3 3A03E3             LD   A,(WIDTH)   ;A= character width in squares
E4A6 87                 ADD  A,A
E4A7 87                 ADD  A,A
E4A8 DDCB004E           BIT  1,(JFLAGS)
E4AC 2801               JR   Z,TCP_1     ;Jump if using half-slope
E4AE 87                 ADD  A,A
E4AF B9       TCP_1     CP   C
E4B0 3801               JR   C,TCP_2     ;Jump unless current cursor position
                                         ;overhangs left-hand edge of screen
E4B2 4F                 LD   C,A         ;Cursor now as far left as possible
E4B3 CD34E4   TCP_2     CALL GET_WIDTH   ;A= character width in pixels
E4B6 81                 ADD  A,C
E4B7 3004               JR   NC,TCP_3    ;Jump unless current cursor position
                                         ;overhangs right-hand edge of screen
E4B9 91                 SUB  C
E4BA ED44               NEG
E4BC 4F                 LD   C,A         ;Cursor now as far right as possible
E4BD 3A01E3   TCP_3     LD   A,(HEIGHT)  ;A= character height in squares
E4C0 87                 ADD  A,A
E4C1 87                 ADD  A,A
E4C2 87                 ADD  A,A         ;A= character height in pixels
E4C3 80                 ADD  A,B
E4C4 FEB0               CP   #B0
E4C6 3806               JR   C,TCP_4     ;Jump unless current cursor position
                                         ;overhangs bottom of screen
E4C8 90                 SUB  B
E4C9 ED44               NEG
E4CB C6B0               ADD  A,#B0
E4CD 47                 LD   B,A         ;Cursor now as far down as possible
E4CE 18AF     TCP_4     JR   J_PIXADDR   ;Calculate HL= address of screen-byte
                                         ;containing cursor, and return
-----------------------------------------------------------------------------
E4D0 3E04     7_BIT     LD   A,#04       ;Bit 2 of A set
E4D2 1802               JR   BOLD_7
E4D4 3E08     BOLD      LD   A,#08       ;Bit 3 of A set
E4D6 DDAE00   BOLD_7    XOR  (JFLAGS)    ;Complement required bit
E4D9 3240DB             LD   (JFLAGS),A
E4DC C9                 RET
E4DD DDCB0086 ITAL_OFF  RES  0,(JFLAGS)  ;Signal "Not printing in italics"
E4E1 C9                 RET
E4E2 DDCB008E ITAL_HS   RES  1,(JFLAGS)  ;Signal "Not using full slope"
E4E6 1804               JR   ITAL_1
E4E8 DDCB00CE ITAL_FS   SET  1,(JFLAGS)  ;Signal "Using full slope"
E4EC DDCB00C6 ITAL_1    SET  0,(JFLAGS)  ;Signal "Printing in italics"
E4F0 189F               JR   TEST_CPOS   ;Adjust cursor position if necessary
E4F2 2214DB   TEXT_EXIT LD   (CURSOR),HL ;Set final position of cursor
E4F5 ED4316DB           LD   (CURSOR+2),BC ;Store final cursor coordinates
E4F9 CD6E0D             CALL CLS_LOWER   ;Clear lower part of screen
E4FC F1                 POP  AF          ;Drop return address TEXT_LOOP
E4FD C9                 RET              ;Return to LSD Main Loop
-----------------------------------------------------------------------------
E4FE CD91E4   ASZ_1     CALL TEST_CPOS   ;Ensure that cursor will fit on screen
E501 CD14E4   ALT_SIZE  CALL TX_CURSOR   ;Print cursor on screen
E504 FDCB01AE           RES  5,(FLAGS)   ;Signal "Ready for a new key"
E508 FDCB016E ASZ_2     BIT  5,(FLAGS)
E50C 28FA               JR   Z,ASZ_2     ;Wait until a key is pressed
                                         ;Note that bit 5 of FLAGS remains SET
                                         ;on exiting this loop
E50E C5                 PUSH BC          ;Stack cursor coordinates
E50F E5                 PUSH HL          ;Stack cursor address
E510 CD8E02             CALL KEY_SCAN    ;E= keyboard code for this key
E513 E1                 POP  HL          ;HL= cursor address
E514 C1                 POP  BC          ;BC= cursor coordinates
E515 7B                 LD   A,E         ;A= keyboard code of key pressed
E516 CD14E4             CALL TX_CURSOR   ;"Undraw" cursor from screen
E519 FE20               CP   #20
E51B 2005               JR   NZ,ASZ_3    ;Jump unless SPACE pressed
E51D FDCB01AE           RES  5,(FLAGS)   ;Signal "Ready for a new key"
E521 C9                 RET              ;Return to TEXT_LOOP
E522 FE04     ASZ_3     CP   #04
E524 200B               JR   NZ,ASZ_4    ;Jump unless 5 pressed with either
                                         ;shift (CURSOR LEFT)
E526 3A03E3             LD   A,(WIDTH)   ;A= width of character
E529 3D                 DEC  A
E52A 28D5               JR   Z,ALT_SIZE  ;Jump back if width=1
E52C 3203E3             LD   (WIDTH),A   ;Decrement width
E52F 18D0               JR   ALT_SIZE
E531 FE13     ASZ_4     CP   #13
E533 200D               JR   NZ,ASZ_5    ;Jump unless 8 pressed with either
                                         ;shift (CURSOR RIGHT)
E535 3A03E3             LD   A,(WIDTH)   ;A= width of character
E538 3C                 INC  A
E539 FE0A               CP   #0A
E53B 30C4               JR   NC,ALT_SIZE ;Jump if width greater than 9
E53D 3203E3             LD   (WIDTH),A   ;Increment width
E540 18BC               JR   ASZ_1       ;Jump back to check position on screen

E542 FE03     ASZ_5     CP   #03
E544 200D               JR   NZ,ASZ_6    ;Jump unless 6 pressed with either
                                         ;shift (CURSOR DOWN)
E546 3A01E3             LD   A,(HEIGHT)  ;A= height of characters
E549 3C                 INC  A
E54A FE0A               CP   #0A
E54C 30B3               JR   NC,ALT_SIZE ;Jump back if height greater than 9
E54E 3201E3             LD   (HEIGHT),A  ;Increment height
E551 18AB               JR   ASZ_1       ;Jump back to check position on screen
E553 FE0B     ASZ_6     CP   #0B
E555 C0                 RET  NZ          ;Return unless 7 pressed with either
                                         ;shift (CURSOR UP). Note that since
                                         ;bit 5 of FLAGS is set, the key
                                         ;pressed will be re-interpreted
                                         ;within the main TEXT_LOOP.
E556 3A01E3             LD   A,(HEIGHT)  ;A= height of characters
E559 3D                 DEC  A
E55A 28A5               JR   Z,ALT_SIZE  ;Jump back if height=1
E55C 3201E3             LD   (HEIGHT),A  ;Decrement height
E55F 18A0               JR   ALT_SIZE
-----------------------------------------------------------------------------
;This is the main entry point for TEXT MODE. When you press the TEXT key (key P)
;while running the Light Screen Designer, control commences from this point. On
;entry B contains the row number, and C the column number, of the main cursor.
;HL points to the byte from the screen which contains this cursor.
E561 CD91E4   TEXT_MODE CALL TEST_CPOS   ;Move cursor if necessary
E564 C5                 PUSH BC          ;Stack coordinates
E565 E5                 PUSH HL          ;Stack cursor position
E566 CDCCDC             CALL MESSAGE
E569 08                 DEFB #08         ;Print "Now in text mode"
E56A E1                 POP  HL
E56B C1                 POP  BC
E56C C5       TEXT_LOOP PUSH BC          ;Stack coordinates
E56D E5                 PUSH HL          ;Stack cursor position
E56E 3A3B5C             LD   A,(FLAGS)
E571 F5                 PUSH AF          ;Stack FLAGS (in particular bit 5)
E572 AF                 XOR  A           ;A= 00
E573 CD0116             CALL CHAN_OPEN   ;Select channel zero (lower screen)
E576 F1                 POP  AF
E577 323B5C             LD   (FLAGS),A   ;Restore bit 5 of FLAGS
E57A 011101             LD   BC,#0111
E57D CD9B0A             CALL AT_BC       ;PRINT AT 1,17d;
E580 3E4C               LD   A,"L"
E582 FDCB305E           BIT  3,(FLAGS2)
E586 2802               JR   Z,TEXT_1    ;Jump unless CAPS LOCK on
E588 3E43               LD   A,"C"
E58A FDCB074E TEXT_1    BIT  1,(MODE)
E58E 2802               JR   Z,TEXT_2    ;Jump unless in GRAPHICS mode
E590 3E47               LD   A,"G"
E592 D7       TEXT_2    RST  #10         ;Print cursor mode
E593 115348             LD   DE,#4853    ;D= "H", E= "S"
E596 DDCB004E           BIT  1,(JFLAGS)
E59A 2802               JR   Z,TEXT_3    ;Jump unless using full slope
E59C 1646               LD   D,"F"
E59E DDCB0046 TEXT_3    BIT  0,(JFLAGS)
E5A2 CD71E3             CALL PR_NZ_DE    ;Print italic status
E5A5 114D43             LD   DE,#434D    ;D= "C", E= "M"
E5A8 DDCB0056           BIT  2,(JFLAGS)
E5AC CD71E3             CALL PR_NZ_DE    ;Print compressed letter status
E5AF 114F42             LD   DE,#424F    ;D= "B", E= "O"
E5B2 DDCB005E           BIT  3,(JFLAGS)
E5B6 CD71E3             CALL PR_NZ_DE    ;Print bold status
E5B9 E1                 POP  HL
E5BA C1                 POP  BC
E5BB CD14E4             CALL TX_CURSOR   ;Draw the text cursor
E5BE C5                 PUSH BC
E5BF E5                 PUSH HL
E5C0 CD0DE3             CALL T_CHR       ;Wait for key pressed; A= chr code
E5C3 E1                 POP  HL
E5C4 C1                 POP  BC
E5C5 CD14E4             CALL TX_CURSOR   ;"Undraw" the text cursor
E5C8 116CE5             LD   DE,TEXT_LOOP
E5CB D5                 PUSH DE          ;Stack TEXT_LOOP as return address
E5CC F5                 PUSH AF          ;Stack key pressed
E5CD E5                 PUSH HL
E5CE C5                 PUSH BC
E5CF 3E02               LD   A,#02
E5D1 CD0116             CALL CHAN_OPEN   ;Select channel 2 (main screen)
E5D4 BF                 CP   A           ;Set the zero flag
E5D5 CD5E0D             CALL TEMPS_P     ;Reset OVER and INVERSE from
                                         ;permanent colours
E5D8 C1                 POP  BC
E5D9 E1                 POP  HL
E5DA F1                 POP  AF          ;A= key just pressed
E5DB FE20               CP   #20
E5DD 300F               JR   NC,TEXT_4   ;Jump unless A contains a control code
E5DF E5                 PUSH HL
E5E0 6F                 LD   L,A
E5E1 2600               LD   H,#00
E5E3 11E1E2             LD   DE,#E2E1
E5E6 29                 ADD  HL,HL
E5E7 19                 ADD  HL,DE       ;HL points to subroutine address
E5E8 5E                 LD   E,(HL)
E5E9 23                 INC  HL
E5EA 56                 LD   D,(HL)      ;DE= subroutine address
E5EB E1                 POP  HL          ;Restore HL value
E5EC D5                 PUSH DE
E5ED C9                 RET              ;Jump to required subroutine
-----------------------------------------------------------------------------
E5EE C5       TEXT_4    PUSH BC
E5EF E5                 PUSH HL
E5F0 CD4CE3             CALL T_LOCATE    ;HL= address of pixel layout
E5F3 EB                 EX   DE,HL       ;DE= address of pixel layout
E5F4 E1                 POP  HL
E5F5 C1                 POP  BC
E5F6 C5                 PUSH BC          ;Stack cursor coordinates
E5F7 CD91E3             CALL TX_PRINT    ;Print character on screen
E5FA C1                 POP  BC          ;Restore cursor coordinates
E5FB C345E4             JP   TC_RIGHT    ;Move cursor right, if possible,
                                         ;and return
-----------------------------------------------------------------------------
