Previous Next Contents Index
The periodic routines &
   The DISCiPLE system variables and tables

This is another entry point to the DISCiPLE system; it is paged in when the Z80
reaches address #028E, that is, the Spectrum 'KEY-SCAN' routine. So whenever the
Spectrum tries to scan the keyboard by calling this routine the DISCiPLE is paged
in first. This routine tests for some sort of pointing device (the non-existent
MGT mouse?) and when the network is enabled a check is made for network activity.

028E KSCAN_RAM  LD   L,#2F
0290            JP   #02FB,KSCAN_RAM1
0293            NOP                      An unused location.

0294 KSCAN_RET  OUT  (187),A             Page out to continue in 'main' ROM

These variables hold various settings for drives etc. The variables starting at
address #0298 can be accessed from BASIC with POKE @p,n. Where p is 0 for RBCC
at #0298.

0296 D_ERR_SP   DEFW #0000

0298 RBCC       DEFB #00       @0        No flashing borders.
0299 TRAKS1     DEFB 80+128    @1        Drive 1 80 tracks double sided.
029A TRAKS2     DEFB 80+128    @2        Drive 2 80 tracks double sided.
029B STPRAT     DEFB 0         @3        "Steprate" 0 msec.
029C NSTAT      DEFB 0         @4        Network off.
029D WIDTH      DEFB 80        @5        Printer right margin.
029E PCODE      DEFB 0         @6        Expand tokens, etc. before printing.
029F LSPCE      DEFB 12        @7        Line spacing 12/72 inch.
02A0 LFEED      DEFB 1         @8        Number of line feeds after CR 1.
02A1 LMARG      DEFB 0         @9        Left margin at 0.
02A2 GRAPH      DEFB 1         @10       Give graphic representation of some chars.
02A3 ZXPNT      DEFB 1         @11       DISCiPLE printer port not used.
02A4 RESERVED   DEFW #0000     @12
02A6 ONERR      DEFW #0000     @14       Address of routine called after an error
                                         has occurred.
02A8 EVERY_INT  DEFW #03B0     @16       Address of routine called at every

Here the printer control codes are stored.

02AA INIT_PRT   DEFB 27,"@",#80,#80
02AE            DEFB #80,#80,#80,#80
02B2 CHAR_PITCH DEFB 27,"M",#80,#80
02B6            DEFB #80,#80,#80,#80
02BA N/72_LSPC  DEFB 27,"A",#80,#80
02BE            DEFB #80,#80,#80,#80
02C2 60_DPI     DEFB 27,"K",#80,#80
02C6            DEFB #80,#80,#80,#80
02CA INIT_PRT2  DEFB #80,#80,#80,#80
02CF            DEFB #80,#80,#80,#80

This table consists of the graphic representations of the £, # and (c) signs. The
'GRAPH' system variable (@10) determines whether the normal code or the graphic
representation is outputted to the printer.

02D2 £-SIGN     DEFB %00011000
02D3            DEFB %00100000
02D4            DEFB %00100000
02D5            DEFB %01111000
02D6            DEFB %00100000
02D7            DEFB %00100000
02D8            DEFB %01111100
02D9            DEFB %00000000

02DA #-SIGN     DEFB %00000000
02DB            DEFB %00100100
02DC            DEFB %01111110
02DD            DEFB %00100100
02DE            DEFB %00100100
02DF            DEFB %01111110
02E0            DEFB %00100100
02E1            DEFB %00000000

02E2 (c)-SIGN   DEFB %01111110
02E3            DEFB %10000001
02E4            DEFB %10111101
02E5            DEFB %10100001
02E6            DEFB %10100001
02E7            DEFB %10111101
02E8            DEFB %10000001
02E9            DEFB %01111110

This code is outputted to the printer if a 'SCREEN$ 2' screendump is wanted.

02EA GREY_BITIM DEFB 27,"*",5,#40
02EE            DEFB #02,#80,#80,#80

This table consists of three times three bytes of greyscale info. Each screen
pixel is converted into 3x3 printer dots during greyscale printing. The printer
dots are ordered as follows: The first dot row is produced from the first three
bytes by taking the bit, which number is corresponding with the colour number,
from each of the three bytes. E.g. for colour 2 (=red) bit 2 is used. In the
same way the second and third dot rows are produced from the second and third
three bytes respectively.
The following eight 3x3 matrices are produced:

 White  Yellow  Cyan  Green Magenta  Red    Blue  Black
  000    000    100    000    100    010    110    111
  000    010    010    101    111    111    111    111
  000    000    001    000    001    010    011    111

Note that some greytones aren't right. E.g. cyan is darker than green, which isn't
so on the screen. System 3d can't print a greyscale dump anymore (see #1751).


02F2            DEFB %00101011
02F3            DEFB %00011111           first row
02F4            DEFB %00000001

02F5            DEFB %00000111
02F6            DEFB %01101111           second row
02F7            DEFB %00000111

02F8            DEFB %00000001
02F9            DEFB %00011111           third row
02FA            DEFB %00101011


02FB KSCAN_RAM1 NOP                      The following call was removed for
02FC            NOP                      Sys 3d:  CALL #03B1,TEST_MOUSE
02FD            NOP
02FE            LD   A,(#1DE5)
0301            CP   #47                 If a CALBAS was under execution return
0303            JR   Z,#031A,KSCAN_EXIT  immediately to 'main' ROM 'KEY-SCAN'.
0305            LD   A,(#029C)
0308            CP   0                   Jump if network is on, that is when a
030A            JR   NZ,#0325,NET_SERVER station number is specified.
030C KSCAN_RAM2 LD   A,(#1DDA)           Make network inactive, select current
030F            OUT  (31),A              drive.
0311            CALL #0460,TAKE_PRTR     Refresh 'P'-channel if necessary.
0314            LD   HL,(#02A8)          Call routine which has to be called
0317            CALL #04F0,JP_HL         every 'interrupt'. (Normal #03B0)
031A KSCAN_EXIT LD   L,#2F               Restore registers for 'main' ROM
031C            LD   DE,#FFFF            'KEY-SCAN'
031F            LD   BC,#FEFE
0322            JP   #0294,KSCAN_RET

This routine checks if a "command block" is send over the network. In a master/
pupil network (Shared Access Network) a pupil has no drive or printer. When a pupil
gives a command like "CAT 1" the command is send over the network to the master or
an assistent station, which executes the command and sends the result back to the
pupil which gave the command. Before a command block can be received the network
has to be active for about 10400 T cycles and then has to go inactive in less than
52000 T states. Then a check is made if the command block is for this station, and
if so the command is executed.

0325 NET_SERVER LD   HL,200              This counter allows the network to be
                                         tested for 10395 T cycles.
0328 TST_N_ACT  IN   A,(31)              Read network port.
032A            BIT  7,A
032C            JR   NZ,#030C,KSCAN_RAM2 Exit if the network is inactive.
032E            DEC  HL                  Decrease the counter.
032F            LD   A,H
0330            OR   L
0331            JR   NZ,#0328,TST_N_ACT  Repeat test until finished.

Now the network has to go inactive within about 52000 T cycles otherwise this routine
will be left.

0333            LD   HL,1000
0336 TST_N_INA  DEC  HL                  Decrease the counter.
0337            LD   A,H
0338            OR   L                   Exit if network isn't inactive within
0339            JR   Z,#030C,KSCAN_RAM2  the right time.
033B            IN   A,(31)
033D            BIT  7,A

Now the command block is fetched from the network.

033F            JR   Z,#0336,TST_N_INA   Repeat until network is inactive.
0341            LD   HL,#031A,KSCAN_EXIT Return address.
0344            PUSH HL
0345            LD   HL,#1DFD            Point to the data buffer.
0348            LD   E,29
034A            CALL #2969,JINPAK        Read 29 bytes from the network.
034D            RET  NZ                  Return when no bytes received.
034E            LD   HL,#1DFD            Restore the pointer.
0351            XOR  A                   Clear checksum.
0352            LD   B,28                Calculate checksum for 28 bytes.
0354 TST_N_CHKS ADD  A,(HL)              Add this byte.
0355            INC  HL                  Next byte.
0356            DJNZ #0354,TST_N_CHKS    Repeat for all bytes.
0358            CP   (HL)                Compare with received checksum.
0359            RET  NZ                  Return if they don't match.
035A            LD   HL,#1DFD            Restore pointer.
035D            LD   A,(#029C)           Fetch own station number (NSTAT).
0360            CP   (HL)                Return if the message isn't for this
0361            RET  NZ                  Spectrum.
0362            CALL #2972,JSEND_RESP    Otherwise send response code.
0365            LD   HL,#1DFF            Point to the command.
0368            LD   A,(HL)              Fetch it.
0369            CP   210                 A pupil station cannot ERASE a file, so
036B            RET  Z                   return if the command was "ERASE".

Now follows an undocumented feature of the Shared Access Network. When a pupil
prints something to a "P"-channel (normally attached to #3), it is send directly
to the master station. Please note that printer output gets garbled when more users
try to use the printer at the same time.

036C            CP   245
036E            JR   NZ,#0375,SERVE_PUP  Jump if it wasn't "PRINT".
0370            INC  HL                  Otherwise send one byte to the printer.
0371            LD   A,(HL)
0372            JP   #1944,PNTP

0375 SERVE_PUP  CALL #09D3,SIGN_SERV     Signal 'serving pupil'.
0378            PUSH AF                  Store command.
0379            LD   HL,(23633)          Store CURCHL.
037C            LD   (#1E32),HL
037F            LD   HL,#1E34
0382            LD   A,(23611)           Store FLAGS.
0385            LD   (HL),A
0386            INC  HL
0387            LD   A,(23612)           Store TVFLAG.
038A            LD   (HL),A
038B            INC  HL
038C            LD   A,(23658)           Store FLAGS2.
038F            LD   (HL),A
0390            POP  AF
0391            CALL #0674,EXEC_COMM     Execute command.
0394            LD   HL,(#1E32)          Restore CURCHL.
0397            LD   (23633),HL
039A            LD   HL,#1E34            Restore FLAGS.
039D            LD   A,(HL)
039E            LD   (23611),A
03A1            INC  HL
03A2            LD   A,(HL)              Restore TVFLAG.
03A3            LD   (23612),A
03A6            INC  HL
03A7            LD   A,(HL)              Restore FLAGS2.
03A8            LD   (23658),A
03AB            XOR  A
03AC            LD   (#1ACF),A           Reset FLAGS3 and exit.
03AF            RET


03B0            RET

This routine tests a mouse-like device. Pointers which seem to keep track of screen
coordinates are updated when necessary.

03B1 TEST_MOUSE LD   BC,#03FF            The MGT mouse port?
03B4            IN   A,(C)
03B6            BIT  7,A
03B8            RET  NZ                  Return if no activity.
03B9            CPL
03BA            AND  #05                 Return if there was no horizontal or
03BC            RET  Z                   vertical movement.
03BD            LD   HL,#03F3,SIGN_MOUSE
03C0            PUSH HL
03C1            LD   HL,#03DD,MOVE_VERT
03C4            PUSH HL
03C5            IN   D,(C)               Read mouse bits again.
03C7            LD   HL,23681,X_POS_M    Mouses x-coordinate.
03CA            BIT  0,D
03CC            RET  NZ                  Return to vertical movement test.
03CD            BIT  1,D
03CF            JR   Z,#03D7,MOVE_RIGHT  Jump if mouse was moved right.
03D1            LD   A,0                 Left side of screen.
03D3            CP   (HL)
03D4            RET  Z                   Return if left movement isn't possible.
03D5            DEC  (HL)                Otherwise decrement x-coordinate.
03D6            RET

03D7 MOVE_RIGHT LD   A,255               Right side of screen.
03D9            CP   (HL)
03DA            RET  Z                   Return if right movement impossible.
03DB            INC  (HL)                Otherwise increment x.
03DC            RET

03DD MOVE_VERT  LD   HL,23729,Y_POS_M    Y-coordinate of mouse.
03E0            BIT  2,D
03E2            RET  NZ                  Return to signal mouse.
03E3            BIT  3,D
03E5            JR   NZ,#03ED,MOVE_UP    Jump if mouse was moved up.
03E7            LD   A,0                 Bottom side of screen.
03E9            CP   (HL)
03EA            RET  Z                   Return if bottom has been reached.
03EB            DEC  (HL)                Otherwise move towards it.
03EC            RET

03ED MOVE_UP    LD   A,175               Top side of screen.
03EF            CP   (HL)
03F0            RET  Z                   Return if top was reached.
03F1            INC  (HL)                Otherwise increment y-coordinate.
03F2            RET

03F3 SIGN_MOUSE OUT  (C),D               Give original signal to mouse.
03F5            RET
03F6            DEFB #00,#00,#00,#00     Unused locations.

Previous Next Contents Index