The periodic routines &
The DISCiPLE system variables and tables
THE 'KEY-SCAN' ROUTINE
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
THE 'SYSTEM VARIABLES'
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
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
02A8 EVERY_INT DEFW #03B0 @16 Address of routine called at every
THE 'PRINTER CODES' TABLE
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
THE 'GRAPHIC REPRESENTATION' TABLE
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
THE 'GREYSCALE' PRINTER CONTROL CODE
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
THE 'GREYSCALE' TABLE
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
THE 'KSCAN_RAM' ROUTINE CONTINUED
02FB KSCAN_RAM1 NOP The following call was removed for
02FC NOP Sys 3d: CALL #03B1,TEST_MOUSE
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
THE 'NETWORK SERVER' ROUTINE
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.
THE 'DEFAULT EVERY_INT' ROUTINE
THE 'MOUSE' ROUTINE
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.
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.
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.
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.
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.
03F3 SIGN_MOUSE OUT (C),D Give original signal to mouse.
03F6 DEFB #00,#00,#00,#00 Unused locations.