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



STREAMS AND CHANNELS

by Toni Baker

part 3 of 5, ZX Computing February 1987



The concluding part of Toni Baker's Windows program.



[Note that the code in STREAMS.TAP "PART3"]

[includes the code from "PART2".      JimG]





Last month we began experimenting with windows. The listing continues

...



As a demonstration, the extra program WIND_DEMO which I've tagged on

at the end at address B544 will open a window twenty-four squares wide

by eight squares high, positioned AT 2,1 (relative to the whole

screen) with yellow paper and blue ink. Furthermore, the window will

be a SLOW window, so words won't ever be cut in half, and although the

standard character set is used, they are defined to be seven bits

wide, not eight, so you get more characters than you would normally.

Running the program once will open the window and attach it to stream

four. Thereafter PRINT #4 will print onto the window.





Follow through



For those of you who wish to follow the program through and understand

how it all works, I'll tell you that the program starts running from

location WINDOW (address B4F1) with the A register containing the

character to be printed, whenever RST 10 is used with this channel.



Oh - incidentally - while we're talking about the WINDOW routine, take

a look at the four instructions following the label WIND_CTRL. The

CALL instruction carries out the control code function, the POP

instruction restores the control character to the A register, and the

RET instruction terminates everything - the routine has finished -

control will then pass back to the RST 10 sub-routine itself, and then

back to the PRINT statement which caused the RST 10 to be used. But

... what's this AND A instruction doing just before the RET? The

comment beside the instruction reads "Reset the carry flag". Why? -

Surely everything's finished now. We shouldn't need to worry about

flags should we?



Unfortunately we do. You see when a control code such as PAPER 4 or

INVERSE 1 is used in a PRINT statement then the appropriate control

codes are sent to RST 10 to be carried out. The PRINT routine expects

the carry flag to be reset on return from such a routine, and will

produce the error message "C Nonsense in BASIC" if this is not the

case.



Next month I'll give you no less than two new channels: a modified

network channel for owners of the ZX Interface 1 which will

successfully communicate with a QL, and a channel which will allow

users of the Spectrum 128 to use the standard ZX Printer whilst in

128K mode, saving a lot of money in the process. See you then.



- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

The following subroutine prints a newline; ie. it moves the print position to

the left-hand edge of the next line down.



B2BB CDC3B2   ENTER     CALL ENTER_1       ;Print a single newline once

B2BE DDCB0B56           BIT  2,(IX+W_FLAGS)

B2C2 C8                 RET  Z             ;Return if using single height

B2C3 DD7E0E   ENTER_1   LD   A,(IX+W_YCOORD)  ;A= current y coordinate

B2C6 3C                 INC  A             ;A= new y coordinate

B2C7 DDBE0F             CP   (IX+W_HEIGHT)

B2CA C2B1B1             JP   NZ,LINE_A     ;Jump if in range to move print pos

B2CD DDCB0B6E           BIT  5,(IX+W_FLAGS)

B2D1 2812               JR   Z,SCROLL      ;Jump if scroll pause disabled

B2D3 DD3515             DEC  (IX+W_SCROLLS);Decrement scroll count

B2D6 200D               JR   NZ,SCROLL     ;Jump unless scroll pause required

B2D8 DD7E0F             LD   A,(IX+W_HEIGHT)

B2DB DD7715             LD   (IX+W_SCROLLS),A ;Re-initialise scroll count

B2DE 3E7F     SCR_PAUSE LD   A,#7F

B2E0 DBFE               IN   A,(#FE)       ;Scan part of the keyboard

B2E2 1F                 RRA

B2E3 38F9               JR   C,SCR_PAUSE   ;Pause until SPACE pressed

B2E5 CD541F   SCROLL    CALL BREAK_KEY

B2E8 D2000D             JP   NC,REPORT_D   ;Give error report if BREAK pressed

B2EB DD7E0E             LD   A,(IX+W_YCOORD)  ;A= y coordinate of bottom line

B2EE F5                 PUSH AF

B2EF CDB1B1             CALL LINE_A        ;Move print pos to start of bottom

                                           ;line of window

B2F2 C1                 POP  BC            ;B= number of lines to copy

B2F3 CD06B2             CALL GET_WIDTH     ;C= width of window in squares

B2F6 DD6E12             LD   L,(IX+W_HOME)lo

B2F9 DD6613             LD   H,(IX+W_HOME)hi  ;HL= address of top left corner

B2FC CD71B1             CALL PAGE_7        ;Use RAM page 7 in case scr 1 used

B2FF C5       SCR_LOOP1 PUSH BC            ;Stack loop counter

B300 0600               LD   B,#00         ;BC= width of line

B302 C5                 PUSH BC

B303 E5                 PUSH HL

B304 CDA5B1             CALL ATTR_ADDR     ;HL= addr of this attribute line

B307 112000             LD   DE,#0020

B30A EB                 EX   DE,HL         ;DE= addr of this attribute line

B30B 19                 ADD  HL,DE         ;HL= addr of next attribute line

B30C EDB0               LDIR               ;Copy one attribute line

B30E E1                 POP  HL

B30F C1                 POP  BC

B310 E5                 PUSH HL

B311 CD9BB1             CALL DOWN_8        ;HL= address of next line

B314 D1                 POP  DE            ;DE= address of this line

B315 E5                 PUSH HL

B316 3E08               LD   A,#08         ;A= number of rows per line

B318 C5       SCR_LOOP2 PUSH BC

B319 D5                 PUSH DE

B31A E5                 PUSH HL

B31B EDB0               LDIR               ;Copy one row from line

B31D E1                 POP  HL

B31E D1                 POP  DE

B31F C1                 POP  BC

B320 24                 INC  H             ;HL= addr of next row of next line

B321 14                 INC  D             ;DE= addr of next row of this line

B322 3D                 DEC  A

B323 20F3               JR   NZ,SCR_LOOP2  ;Copy whole line

B325 E1                 POP  HL

B326 C1                 POP  BC

B327 10D6               DJNZ SCR_LOOP1     ;Transfer all required lines

B329 0B                 DEC  BC            ;BC= length of line, less one

B32A DD7E14             LD   A,(IX+W_ATTR) ;A= attribute byte

B32D CDDEB1             CALL CLW_LINE      ;Clear bottom line

B330 C36CB1             JP   PAGE_0        ;Restore RAM page zero and return



The following subroutine deals with all control codes except for comma-control

and TAB (these are dealt with by CHR_TYPE2 at address B12F). On entry the A

register will contain the control code itself, while any parameters required

will be stored in B (middle parameter, if one exists) and C (last parameter).



B333 FE0D     CONTROLS  CP   "enter"

B335 2884               JR   Z,ENTER       ;Jump to deal with "enter"

B337 D610               SUB  #10

B339 D8                 RET  C             ;Return with codes 00 to 0F

B33A FE06               CP   #06

B33C 2827               JR   Z,CTRL_AT     ;Jump to deal with AT

B33E D0                 RET  NC            ;Return with codes 17 to 1F

B33F C65F               ADD  A,CTRL_INFO lo

B341 6F                 LD   L,A

B342 26B3               LD   H,CTRL_INFO hi;HL points to control info table

B344 46                 LD   B,(HL)        ;B= bit mask for this control

B345 111400             LD   DE,#0014      ;DE= IX displacement to W_ATTR

B348 FE63               CP   #63

B34A 3802               JR   C,CTRL_CONT   ;Jump unless ctrl is INVERSE/OVER

B34C 1E0B               LD   E,#0B         ;DE= IX displacement to W_FLAGS

B34E DDE5     CTRL_CONT PUSH IX

B350 E1                 POP  HL            ;HL points to channel info block

B351 19                 ADD  HL,DE         ;HL points to variable to alter

B352 79                 LD   A,C           ;A= control parameter

B353 48                 LD   C,B           ;C= bit mask

B354 0F                 RRCA

B355 07       CTRL_LOOP RLCA

B356 CB18               RR   B

B358 30FB               JR   NC,CTRL_LOOP  ;A= ctrl parameter in correct posn

B35A AE                 XOR  (HL)

B35B A1                 AND  C

B35C AE                 XOR  (HL)          ;Mix in reqd bits according to mask

B35D 77                 LD   (HL),A        ;Store variable

B35E C9                 RET



B35F 07       CTRL_INFO DEFB #07           ;Bit mask for INK

B360 38                 DEFB #38           ;Bit mask for PAPER

     80                 DEFB #80           ;Bit mask for FLASH

B362 40                 DEFB #40           ;Bit mask for BRIGHT

B363 08                 DEFB #08           ;Bit mask for INVERSE

B364 04                 DEFB #04           ;Bit mask for OVER



The next subroutine is the WINDOW version of the AT function. It performs the

function AT B,C for the current window.



B365 C5       CTRL_AT   PUSH BC

B366 78                 LD   A,B           ;A= proposed y coordinate

B367 CDB1B1             CALL LINE_A        ;Move print pos to start of this line

B36A C1                 POP  BC

B36B 79                 LD   A,C           ;A= proposed x coordinate

B36C A7                 AND  A

B36D C8                 RET  Z             ;Return if task already done

B36E DDBE0D             CP   (IX+W_WIDTH)

B371 D29F1E             JP   NC,REPORT_B   ;Give error report if out of range

B374 DD770C             LD   (IX+W_XCOORD),A  ;Store new x coordinate

B377 0600               LD   B,#00         ;BC= x coordinate

B379 DDCB0B66           BIT  4,(IX+W_FLAGS)

B37D 281A               JR   Z,AT_EXIT     ;Jump with "Fast" channels

B37F E5                 PUSH HL            ;Stack address of start of line

B380 DD4E17             LD   C,(IX+W_CH_WID)  ;BC= character width in pixels

B383 60                 LD   H,B

B384 68                 LD   L,B           ;HL= 0000

B385 09       AT_LOOP_1 ADD  HL,BC

B386 3D                 DEC  A

B387 20FC               JR   NZ,AT_LOOP_1  ;HL= no of pixels to start of char

B389 0603               LD   B,#03

B38B CB3C     AT_LOOP_2 SRL  H

B38D CB1D               RR   L

B38F 1F                 RRA

B390 10F9               DJNZ AT_LOOP_2     ;HL= no of squares to start of char

B392 07                 RLCA

B393 07                 RLCA

B394 07                 RLCA               ;A= pixel position within char square

B395 DD7716             LD   (IX+W_PIX),A  ;Store in variable

B398 C1                 POP  BC            ;BC= address of start of line

B399 09       AT_EXIT   ADD  HL,BC         ;HL= new print position address

B39A DD7510   STOREADDR LD   (IX+W_PRPOS)lo,L

B39D DD7411             LD   (IX+W_PRPOS)hi,H  ;Store new print position

B3A0 C9                 RET                ;Return



The following subroutine is very short and simple. It merely sets the attribute

byte corresponding to the screen address in HL.



B3A1 E5       SET_ATTR  PUSH HL

B3A2 CDA5B1             CALL ATTR_ADDR     ;HL= address of attribute byte

B3A5 DD7E14             LD   A,(IX+W_ATTR) ;A= current colours

B3A8 77                 LD   (HL),A        ;Store attribute byte

B3A9 E1                 POP  HL

B3AA C9                 RET                ;Return



This subroutine is intended for use with "Slow" windows only. It will plot one

row of a character onto the screen.



B3AB CDA1B3   PLOT_ROW  CALL SET_ATTR      ;Set attribute byte

B3AE 7E                 LD   A,(HL)        ;A= byte from screen

B3AF AA                 XOR  D

B3B0 A0                 AND  B

B3B1 AA                 XOR  D             ;Mix in bits from character

B3B2 77                 LD   (HL),A        ;Store in screen

B3B3 79                 LD   A,C           ;A= low byte of mask

B3B4 3C                 INC  A

B3B5 280A               JR   Z,PLRW_EXIT   ;Exit if all bits stored on screen

B3B7 23                 INC  HL            ;HL points to next screen byte

B3B8 CDA1B3             CALL SET_ATTR      ;Set this attribute byte as well

B3BB 7E                 LD   A,(HL)        ;A= byte from screen

B3BC AB                 XOR  E

B3BD A1                 AND  C

B3BE AB                 XOR  E             ;Mix in bits from character

B3BF 77                 LD   (HL),A        ;Store in screen

B3C0 2B                 DEC  HL            ;HL points to original screen byte

B3C1 C38CB1   PLRW_EXIT JP   DOWN_1        ;Point HL one pixel down, and return



This subroutine will calculate 8*A+DE, and will also collect the current print

position.



B3C4 6F       PREPARE   LD   L,A

B3C5 2600               LD   H,#00         ;HL= character code

B3C7 29                 ADD  HL,HL

B3C8 29                 ADD  HL,HL

B3C9 29                 ADD  HL,HL         ;HL= eight times character code

B3CA 19                 ADD  HL,DE

B3CB EB                 EX   DE,HL         ;DE= address of pixel expansion

B3CC DD6E10             LD   L,(IX+W_PRPOS)lo

B3CF DD6611             LD   H,(IX+W_PRPOS)hi  ;HL= address of print position

B3D2 C9                 RET                ;Return



This subroutine will collect one byte from the pixel expansion pointed to by DE

and will invert it if necessary.



B3D3 1A       GET_ROW   LD   A,(DE)        ;A= next row of pixel expansion

B3D4 13                 INC  DE            ;DE points to next row

B3D5 DDCB0B5E           BIT  3,(IX+W_FLAGS)

B3D9 C8                 RET  Z             ;Return unless INVERSE 1 in operation

B3DA 2F                 CPL                ;Otherwise invert the row

B3DB C9                 RET



This next and very important subroutine will actually print a character,

specified in the A register, onto the current window.



B3DC F5       PRINT_CHR PUSH AF            ;Stack character to print

B3DD F5                 PUSH AF            ;Stack character to print (again)

B3DE DD7E0C             LD   A,(IX+W_XCOORD)  ;A= current X coordinate

B3E1 DDBE0D             CP   (IX+W_WIDTH)

B3E4 CCBBB2             CALL Z,ENTER       ;Print newline if at end of line

B3E7 DDCB0B66           BIT  4,(IX+W_FLAGS)

B3EB 2034               JR   NZ,PCHRSLOW   ;Jump with "Slow" window

B3ED F1                 POP  AF            ;A= character to print

B3EE ED5B365C           LD   DE,(CHARS)    ;DE= addr of normal char set - 100h

B3F2 2012               JR   NZ,PCHR_OK_1  ;Jump with ASCII character

B3F4 300A               JR   NC,PCHR_UDG   ;Jump with user-defined graphics

B3F6 47                 LD   B,A

B3F7 CD380B             CALL PO_GR_1       ;Construct block graphic

B3FA 11925C             LD   DE,MEMBOT     ;DE points to pixel expansion

B3FD AF                 XOR  A

B3FE 1806               JR   PCHR_OK_1     ;Jump forward

B400 D690     PCHR_UDG  SUB  #90

B402 ED5B7B5C           LD   DE,(UDG)      ;DE points to user-defined graphics

B406 CDC4B3   PCHR_OK_1 CALL PREPARE       ;DE= address of pixel expansion

                                           ;HL= address of print position

B409 CDA1B3             CALL SET_ATTR      ;Set attribute for this square

B40C E5                 PUSH HL

B40D 0608               LD   B,#08         ;B= number of rows per line

B40F CDD3B3   PCHRLOOP1 CALL GET_ROW       ;A= next row from expansion

B412 CD71B1             CALL PAGE_7        ;Use RAM page 7 in case scrn 1 in use

B415 77                 LD   (HL),A        ;Store row in screen

B416 24                 INC  H             ;HL points to next row

B417 CD6CB1             CALL PAGE_0        ;Restore RAM page zero

B41A 10F3               DJNZ PCHRLOOP1     ;Print whole character

B41C E1                 POP  HL

B41D 23                 INC  HL            ;HL= new print position

B41E C3B2B4             JP   PCHR_EXIT     ;Jump to exit

B421 DDCB0B56 PCHRSLOW  BIT  2,(IX+W_FLAGS)

B425 281E               JR   Z,PCHRSLOW2   ;Jump unless using double height

B427 DD7E0F             LD   A,(IX+W_HEIGHT)  ;A= height of window

B42A 3D                 DEC  A             ;A= y coordinate of bottom line

B42B DDBE0E             CP   (IX+W_YCOORD)

B42E 2015               JR   NZ,PCHRSLOW2  ;Jump unless at bottom line

B430 DD4E0C             LD   C,(IX+W_XCOORD)  ;C= current x coordinate

B433 47                 LD   B,A           ;B= current y coordinate

B434 05                 DEC  B             ;B= y coordinate after scroll

B435 DD7E0B             LD   A,(IX+W_FLAGS)

B438 F5                 PUSH AF            ;Stack flags

B439 C5                 PUSH BC            ;Stack coordinates

B43A CDC3B2             CALL ENTER_1       ;Scroll the screen once

B43D C1                 POP  BC            ;BC= coordinates

B43E CD65B3             CALL CTRL_AT       ;Move print position back where it

                                           ;belongs

B441 F1                 POP  AF

B442 DD770B             LD   (IX+W_FLAGS),A  ;Restore the flags

B445 F1       PCHRSLOW2 POP  AF            ;A= character to print

B446 DD5E18             LD   E,(IX+W_CHARS)lo

B449 DD5619             LD   D,(IX+W_CHARS)hi;DE= addr of normal chr set - 100h

B44C 2008               JR   NZ,PCHR_OK_2  ;Jump with ASCII characters

B44E D680               SUB  #80

B450 DD5E1A             LD   E,(IX+W_UDG)lo

B453 DD561B             LD   D,(IX+W_UDG)hi;DE points to graphics chr set

B456 CDC4B3   PCHR_OK_2 CALL PREPARE       ;DE= address of pixel expansion

                                           ;HL= address of print position

B459 E5                 PUSH HL            ;Stack address of print position

B45A 01FFFF             LD   BC,#FFFF

B45D DD7E17             LD   A,(IX+W_CH_WID)  ;A= width of chr in pixels

B460 CB38     PCHRMASK1 SRL  B

B462 CB19               RR   C

B464 3D                 DEC  A

B465 20F9               JR   NZ,PCHRMASK1  ;BC= mask, not yet in position

B467 DD7E16             LD   A,(IX+W_PIX)  ;A= pixel posn within chr square

B46A A7                 AND  A

B46B 2808               JR   Z,PCHRMASK3   ;Jump if mask OK

B46D 37       PCHRMASK2 SCF

B46E CB18               RR   B

B470 CB19               RR   C

B472 3D                 DEC  A

B473 20F8               JR   NZ,PCHRMASK2  ;Otherwise rotate mask into place

B475 3E08     PCHRMASK3 LD   A,#08         ;A= number of rows per line

B477 F5       PCHRLOOP2 PUSH AF            ;Stack loop counter

B478 CDD3B3             CALL GET_ROW       ;A= next row from expansion

B47B D5                 PUSH DE            ;Stack pointer into expansion

B47C 57                 LD   D,A

B47D DD7E16             LD   A,(IX+W_PIX)  ;A= pixel posn within chr square

B480 A7                 AND  A

B481 2807               JR   Z,PCHR_ROW    ;Jump if pixels correctly aligned

B483 CB1A     PCHRSHIFT RR   D

B485 CB1B               RR   E

B487 3D                 DEC  A

B488 20F9               JR   NZ,PCHRSHIFT  ;Shift pixels into position

B48A CD71B1   PCHR_ROW  CALL PAGE_7        ;Set RAM page 7 in case scrn 1 in use

B48D CDABB3             CALL PLOT_ROW      ;Plot row onto screen

B490 DDCB0B56           BIT  2,(IX+W_FLAGS)

B494 C4ABB3             CALL NZ,PLOT_ROW   ;And again if using double height

B497 CD6CB1             CALL PAGE_0        ;Restore RAM page zero

B49A D1                 POP  DE            ;DE points to pixel expansion

B49B F1                 POP  AF            ;A= loop counter

B49C 3D                 DEC  A

B49D 20D8               JR   NZ,PCHRLOOP2  ;Print whole character

B49F E1                 POP  HL            ;HL= original print position

B4A0 DD7E16             LD   A,(IX+W_PIX)  ;A= original position within square

B4A3 DD8617             ADD  A,(IX+W__CH_WID)  ;Allow for width of character

B4A6 FE08     PCHR_POS  CP   #08

B4A8 3805               JR   C,PCHR_POS2   ;Jump if print position OK

B4AA D608               SUB  #08

B4AC 23                 INC  HL            ;Otherwise amend it

B4AD 18F7               JR   PCHR_POS      ;Loop back to try again

B4AF DD7716   PCHR_POS2 LD   (IX+W_PIX),A  ;Store new position within square

B4B2 CD9AB3   PCHR_EXIT CALL STOREADDR     ;Store new print position

B4B5 DD340C             INC  (IX+W_XCOORD) ;Increment x coordinate

B4B8 F1                 POP  AF            ;A= character just printed

B4B9 C9                 RET                ;Return



The following subroutine will empty the buffer ("Slow" windows only), printing

the former contents onto the window.



B4BA D4BBB2   EMPTY     CALL NC,ENTER      ;Print a newline if required

B4BD DDE5               PUSH IX

B4BF E1                 POP  HL            ;HL points to channel info block

B4C0 011D00             LD   BC,#001D

B4C3 09                 ADD  HL,BC         ;HL points to variable W_LEN

B4C4 7E                 LD   A,(HL)        ;A= number of characters in buffer

B4C5 A7                 AND  A

B4C6 C8       EMPTYLOOP RET  Z             ;Return if finished

B4C7 23                 INC  HL            ;HL points to next char in buffer

B4C8 7E                 LD   A,(HL)

B4C9 E5                 PUSH HL

B4CA CDF4B0             CALL CTYP_NTOK     ;Flags indicate type of character

B4CD CDDCB3             CALL PRINT_CHR     ;Print the character

B4D0 E1                 POP  HL

B4D1 DD351D             DEC  (IX+W_LEN)

B4D4 18F0               JR   EMPTYLOOP



The following subroutine will empty the buffer ("Slow") or do nothin ("Fast").

It will decide whether or not a newline is required, and print one if so.



B4D6 DDCB0B66 EMPTY_2   BIT  4,(IX+W_FLAGS)

B4DA C8                 RET  Z             ;Return with "Fast" windows

B4DB 57                 LD   D,A           ;D= next character to print

B4DC DD7E1D             LD   A,(IX+W_LEN)  ;A= length of word in buffer

B4DF DD860C             ADD  A,(IX+W_XCOORD)  ;A= potential x coordinate after

                                           ;the buffer has been emptied

B4E2 DDBE0D             CP   (IX+W_WIDTH)

B4E5 2002               JR   NZ,EMPTY_OUT  ;Jump unless word exactly fills line

B4E7 53                 LD   D,E           ;D= alternative char to print

B4E8 37                 SCF                ;Signal "Newline not needed"

B4E9 D5       EMPTY_OUT PUSH DE

B4EA C5                 PUSH BC

B4EB CDBAB4             CALL EMPTY         ;Empty buffer with newline if needed

B4EE C1                 POP  BC

B4EF F1                 POP  AF            ;A= next character to print

B4F0 C9                 RET                ;Return



And now at last we have the window output subroutine itself.



B4F1 DD2A515C WINDOW    LD   IX,(CURCHL)   ;IX points to channel info block

B4F5 CDB7B0             CALL CHR_TYPE      ;Deal with keywords, etc.

B4F8 F8                 RET  M             ;Return if tasks completed

B4F9 F5                 PUSH AF            ;Stack character to print

B4FA 2824               JR   Z,WIND_ABLE   ;Jump with graphics characters

B4FC 3013               JR   NC,WINDASCII  ;Jump with ASCII characters

B4FE A7                 AND  A

B4FF CC92B2             CALL Z,CLSWINDOW   ;Clear window for CHR$ 0

B502 F1                 POP  AF

B503 F5                 PUSH AF

B504 5F                 LD   E,A           ;Signal "Char not to be changed"

B505 CDD6B4             CALL EMPTY_2       ;Empty buffer

B508 CD32B1             CALL CHRTYPE2A     ;Deal with TAB and comma control

B50B CD33B3  WIND_CTRL  CALL CONTROLS      ;Deal with remaining ctrl characters

B50E F1                 POP  AF

B50F A7                 AND  A             ;Reset Carry flag

B510 C9                 RET                ;Return

B511 FE20     WINDASCII CP   "space"

B513 200B               JR   NZ,WIND_ABLE  ;Jump with all chars except "space"

B515 1E0D               LD   E,"enter"     ;Use "enter" as alternative char

B517 CDD6B4             CALL EMPTY_2       ;Empty buffer

B51A FE0D               CP   "enter"

B51C 28ED               JR   Z,WIND_CTRL   ;Jump if newline now required

B51E 1806               JR   WINDPRINT     ;Jump to print "space" on window

B520 DDCB0B66 WIND_ABLE BIT  4,(IX+W_FLAGS)

B524 2004               JR   NZ,#B52A      ;Jump with "Slow" windows

B526 F1       WINDPRINT POP  AF

B527 C3DCB3             JP   PRINT_CHR     ;Jump to print the character

B52A 2A515C   WIND_SLOW LD   HL,(CURCHL)   ;HL points to channel info block

B52D 011D00             LD   BC,#001D

B530 09                 ADD  HL,BC         ;HL points to variable W_LEN

B531 7E                 LD   A,(HL)        ;A= number of chars in buffer

B532 DDBE0D             CP   (IX+W_WIDTH)

B535 2005               JR   NZ,WINDSLOW2  ;Jump unless buffer full

B537 E5                 PUSH HL

B538 CDBAB4             CALL EMPTY         ;Empty buffer

B53B E1                 POP  HL

B53C F1       WINDSLOW2 POP  AF

B53D 34                 INC  (HL)          ;Increment length of buffer

B53E 4E                 LD   C,(HL)

B53F 0600               LD   B,#00         ;BC= new length of buffer

B541 09                 ADD  HL,BC

B542 77                 LD   (HL),A        ;Store char in buffer

B543 C9                 RET                ;Return



;[The next subroutine gets overwritten by the code in Part 4.  JimG]



And finally - just a quick demonstration program to open a window and attach it

to stream four. If you RUN this you'll be able to use PRINT #4; to print onto

the window.



B544 3E04     WIND_DEMO LD   A,#04

B546 08                 EX   AF,AF'        ;A'= stream number

B547 2A7B5C             LD   HL,(UDG)      ;HL= address of user-defined graphics

B54A 0180FF             LD   BC,#FF80

B54D 09                 ADD  HL,BC

B54E 44                 LD   B,H

B54F 4D                 LD   C,L           ;BC'= address of UDGs - 80h

B550 ED5B365C           LD   DE,(CHARS)    ;DE'= addr of normal char set - 100h

B554 2607               LD   H,#07         ;H'= width of characters

B556 D9                 EXX

B557 3E31               LD   A,#31         ;A= attribute byte for window

B559 010102             LD   BC,#0201      ;BC= position of window

B55C 111808             LD   DE,#0818      ;DE= size of window

B55F 21FFFF             LD   HL,#FFFF      ;HL signals "Slow window" and

                                           ;"Scroll pause enabled"

B562 CD12B2             CALL OPEN_WIND     ;Open the window channel

B565 215827             LD   HL,#2758

B568 D9                 EXX                ;HL'= value required by BASIC

B569 C9                 RET                ;Return

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

