The +D system variables and tables
THE 'SYSTEM VARIABLES'
These variables hold various settings for drives etc. The variables starting at address
#2000 can be accessed from BASIC with POKE @p,n. Where p is 0 for RBCC at #2000.
2000 RBCC DEFB #07 Flashing borders.
2001 TRAKS1 DEFB 80+128 Drive 1 80 tracks double sided.
2002 TRAKS2 DEFB 80+128 Drive 2 80 tracks double sided.
2003 STPRAT DEFB 0 "Steprate" 0 msec.
2004 NSTAT DEFB 1 Network on?
2005 WIDTH DEFB 80 Printer right margin.
2006 PCODE DEFB 0 Expand tokens, etc. before printing.
2007 LSPCE DEFB 12 Line spacing 12/72 inch.
2008 LFEED DEFB 1 Number of line feeds after CR 1.
2009 LMARG DEFB 0 Left margin at 0.
200A GRAPH DEFB 0 Print special graphics off.
200B ZXPNT DEFB 0 +D printer port on.
200C RESERVED DEFW #0000
200E ONERR DEFW #0000 Address of routine called after an
error has occurred.
2010 EVERY_INT DEFW #208F Address of routine called at every
interrupt.
THE 'PRINTER CODES' TABLE
Here the printer control codes are stored.
2012 INIT_PRT DEFB 27,"@",#80,#80
2016 DEFB #80,#80,#80,#80
201A CHAR_PITCH DEFB #80,#80,#80,#80
201E DEFB #80,#80,#80,#80
2022 N/72_LSPC DEFB 27,"A",#80,#80
2026 DEFB #80,#80,#80,#80
202A GRAPH_DPI DEFB 27,"*",5,#80
202E DEFB #80,#80,#80,#80
2032 INIT_PRT2 DEFB #80,#80,#80,#80
2036 DEFB #80,#80,#80,#80
THE 'GRAPHIC REPRESENTATION' TABLE
This table consists of the graphic representations of the £, # and © signs. The 'GRAPH'
system variable (@10) determines whether the normal code or the graphic representation is
outputted to the printer.
203A £_SIGN DEFB %00011000
203B DEFB %00100000
203C DEFB %00100000
203D DEFB %01111000
203E DEFB %00100000
203F DEFB %00100000
2040 DEFB %01111100
2041 DEFB %00000000
2042 #_SIGN DEFB %00000000
2043 DEFB %00100100
2044 DEFB %01111110
2045 DEFB %00100100
2046 DEFB %00100100
2047 DEFB %01111110
2048 DEFB %00100100
2049 DEFB %00000000
204A ©-SIGN DEFB %01111110
204B DEFB %10000001
204C DEFB %10111101
204D DEFB %10100001
204E DEFB %10100001
204F DEFB %10111101
2050 DEFB %10000001
2051 DEFB %01111110
THE 'GREYSCALE' PRINTER CONTROL CODE
This code is outputted to the printer if a 'SCREEN$ 2' screendump is wanted.
2052 GREY_BITIM DEFB 27,"*",5,#40
2056 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.
colour
76543210
205A GREYSCALE DEFB %00101011
205B DEFB %00011111 first row
205C DEFB %00000001
205D DEFB %00000111
205E DEFB %01101111 second row
205F DEFB %00000111
2060 DEFB %00000001
2061 DEFB %00011111 third row
2062 DEFB %00101011
2063 DEFW #1429,P_ALL Address of 'output' routine for "P".
2065 DEFB #00 The 'ENTER' flag.
2066 DEFW #0000 D_ERR_SP
2067 DEFB #00
THE 'SNAPSHOT-FILE' UFIA
The following bytes are the last 20 bytes of a snapshot file UFIA.
2068 SNAP_UFIA DEFB 0 Directory description.
2069 DEFM "Snap " File name.
2073 DEFB 3 File type.
2074 DEFW #0000 File length.
2076 DEFW #0000 File address.
2078 DEFW #0000 Not used with Snap's.
207A DEFW #FFFF Not used with Snap's.
SOME 'LOST' ASSEMBLER TEXT
Miles-Gordon seem to have lost some of their assembler text.
207C DEFM "JP"
207E DEFB #07
207F DEFB "Z"
THE 'RAM JUMPS'
These 13 'jumps' are used from the ROM to call +D System routines present in RAM (after
the System file has been loaded).
2080 JCOPS NOP The small dump isn't patched.
2081 NOP
2082 RET
2083 JCOPS2 NOP Neither is the greyscale dump.
2084 NOP
2085 RET
2086 JPCHAN NOP Nor the PCHAN_OUT routine.
2087 NOP
2088 RET
2089 JPOKE NOP Nor the POKE routine.
208A NOP
208B RET
208C JPRTR NOP Even the TAKE_PRTR routine isn't
208D NOP patched.
208E RET
208F JJIFFY NOP Called EVERY_INT.
2090 NOP
2091 RET
2092 JLOAD JP #28EE,LD_VF_MR1 Load the file.
2095 JHXFER JP #2F8B,HXFER Transfer UFIA to DFCA.
2098 JKSCAN JP #2245,JIFFY Called every interrupt.
209B JMSG3 JP #3090,MSG_3 Give the copyright message.
209E JHOOK JP #228E,HOOK_CODE Execute the hook or command code.
20A1 JSNAP JP #2115,SNAP Continue with the Snapshot routine.
20A4 JCTRL JP #20A7,CTRL Continue with the control routine.
THE 'CONTROL ROUTINE' CONTINUED
The final part of the control routine determines which command failed the Spectrum
syntax. If it is a +D command then the apropriate routine is executed.
20A7 CTRL PUSH AF
20A8 LD HL,#3DF4
20AB LD BC,60
20AE RESET_VARS LD (HL),255 Reset +D work areas, including UFIA1
20B0 INC HL and UFIA2.
20B1 DEC BC 20B2 LD A,B
20B3 OR C
20B4 JR NZ,#20AE,RESET_VARS
20B6 LD (#3ACF),A Clear FLAGS3.
20B9 LD IX,#3AC3 Point to +D system variables.
20BD POP AF Fetch the command.
20BE LD (#3DFF),A Store it.
20C1 CP 207 Is the command 'CAT' ?
20C3 JP Z,#245B,CAT Jump to the CAT routine if so.
20C6 CP 208 Also for 'FORMAT',...
20C8 JP Z,#2AB9,FORMAT
20CB CP 209 ...'MOVE',...
20CD JP Z,#2B03,MOVE
20D0 CP 210 ...'ERASE',...
20D2 JP Z,#250C,ERASE
20D5 CP 211 ...'OPEN #',...
20D7 JP Z,#2C68,OPEN
20DA CP 212 ...'CLOSE #',...
20DC JP Z,#2E16,CLOSE
20DF CP 213 ...'MERGE',...
20E1 JP Z,#28E4,MERGE
20E4 CP 214 ...'VERIFY',...
20E6 JP Z,#28DF,VERIFY
20E9 CP 239 ...'LOAD',...
20EB JP Z,#28DA,LOAD
20EE CP 248 ...'SAVE',...
20F0 JP Z,#288B,SAVE
20F3 CP 251 ...'CLS',...
20F5 JP Z,#2EB9,CLS
20F8 CP 253 ...'CLEAR',...
20FA JP Z,#2E39,CLEAR
20FD CP 255 ...'COPY',...
20FF JP Z,#3020,COPY
2102 LD HL,(#200E) Fetch ONERR address.
2105 LD A,H
2106 OR L
2107 RET Z Return if no ON ERROR address.
2108 LD (#2110),HL Store it so it can be CALBASsed.
210B POP HL Drop return address.
210C LD A,(#3DFF) Fetch command which has to be examined
210F RST #10,CALBAS by user-routine (BASIC extensions).
2110 DEFW #0000 CALL the extend BASIC routine(s).
2112 JP #047C,END Test end of command and exit.
THE 'SNAPSHOT ROUTINE' CONTINUED
Here the snapshot routine continues with the disk related functions, keys 3-5.
2115 SNAP LD HL,16384 start of RAM (also start of SCR$).
2118 BIT 2,E
211A JR NZ,#2123,NO_SCR 3: Save SCREEN$.
211C LD A,7 type=SCR$.
211E LD DE,6912 length of SCR$.
2121 JR #2139,SNAP_SAVE
2123 NO_SCR BIT 3,E
2125 JR NZ,#212E,NO_SNP48 4: 48K Snapshot.
2127 LD A,5 type=48K Snap.
2129 LD DE,49152 length of 48K RAM.
212C JR #2139,SNAP_SAVE
212E NO_SNP48 BIT 4,E
2130 RET NZ Exit if not 5: 128K Snapshot.
2131 LD A,9 Type=128K Snap.
2133 LD DE,16384 Length of a RAM-page.
2136 LD HL,49152 Start of a RAM-page.
2139 SNAP_SAVE LD (#2068),A Store type in snapshot UFIA.
213C LD (#2074),DE Store length in UFIA.
2140 LD (#2076),HL And the start-address.
2143 POP AF Drop return addres.
2144 LD B,#FE Key CAPS-V I/O address.
2146 IN A,(C)
2148 BIT 0,A
214A JR NZ,#2154,SNAP_NAME If CAPS is pressed the Snap goes to
214C LD A,(#3ACE) the other drive.
214F XOR #03
2151 LD (#3ACE),A
2154 SNAP_NAME LD A,%01000000
2156 CALL #09A5,SCAN_CAT Search first free catalogue entry.
2159 RET NZ Exit if catalogue full.
215A LD A,D Track to A.
215B AND #07 Jump if CAT-entry will be located
215D JR Z,#2164,SNAP_N1 on track 0.
The name a snapshot-file is given, depends on the position it's going to occupy in the
directory. When the entry will be located on the first track the names range from 'Snap
A' to 'Snap T', if however the entry will be located on track 1 to 3 the character after
'Snap' will be the track number. I.e. 'Snap1A' to 'Snap1T' for track 1, etc. Notice that
the character after 'Snap' is never set to a ' '.
215F ADD A,48 ASCII offset for '0'.
2161 LD (#206D),A Store a 1, 2 or 3 in name-part of UFIA.
2164 SNAP_N1 LD L,E Store sector in L.
2165 SLA L Two entries per sector.
2167 DEC L
2168 LD A,(IX+14) Is it the first or second entry in the
216B ADD A,L CAT-sector.
216C ADD A,64 Add ASCII 'A' offset.
216E LD (#206E),A Store 'A' to 'T' in name-part of UFIA.
2171 LD HL,#2068,SNAP_UFIA Copy UFIA to DFCA.
2174 LD DE,#3E05
2177 LD BC,20
217A LDIR
217C CALL #0AD9,OFSM_2 Open the file.
217F LD HL,#3FEA Copy snap registers to catalogue entry.
2182 LD DE,#3BB2
2185 LD BC,22
2188 LDIR
218A LD A,(#2068) Get directory description.
218D CP 9
218F JP NZ,#222D,NO_SNP128 Jump if not a 128K Snapshot.
2192 LD HL,49152 Now the 5 first bytes of the current
2195 LD DE,#3BD6 RAM-page are saved in the +D RAM
2198 LD BC,5 and replaced by the "BRUCE" message.
219B LDIR This is done to determine the currently
219D LD HL,#2228,BRUCE paged in RAM-page.
21A0 LD DE,49152
21A3 LD BC,5
21A6 LDIR
21A8 XOR A Signal '128K ROM bank active'.
21A9 LD (#3E19),A
21AC CALL #011D,?_ROMBANK Determine current 'main' ROM bank.
21AF JR NZ,#21B6,SNP128_1 Jump if 128K ROM bank.
21B1 LD A,#10 Signal '48K ROM bank active'.
21B3 LD (#3E19),A
21B6 SNP128_1 CALL #0511,REST_PBUF Restore printer buffer contents.
21B9 LD A,(#3E19)
21BC CALL #223F,RAMPAGE_A Page in current ROM bank & RAM page 0.
The code now tests which screen is active. Because it isn't possible to detect which is
the active screen, the user is consulted. By making nice border stripes the user is
signalled that 'Y' (meaning: yes, screen changed) or 'N' (meaning: no, screen hasn't
changed) has to be pressed.
21BF SNP128_2 LD BC,#DFFE Keyboard port and I/O address for Y-P.
21C2 IN E,(C)
21C4 BIT 4,E
21C6 JR Z,#21D7,CHANGED_$ Jump if 'Y' was pressed, screen changed
21C8 LD B,#7F I/O address for B-SPACE.
21CA IN E,(C)
21CC BIT 3,E
21CE JR Z,#21E2,SAME_$ Jump if 'N' was pressed, same screen.
21D0 INC A
21D1 AND #07
21D3 OUT (C),A Make nice stripes in border again.
21D5 JR #21BF,SNP128_2 Only 'Y' or 'N' is accepted.
21D7 CHANGED_$ LD A,(#3E19)
21DA OR #08 Signal 'screen 1'.
21DC ?_RAMBANK LD (#3E19),A
21DF CALL #223F,RAMPAGE_A Page in active ROM bank and screen.
Now the 'which RAM bank' test is executed. The active RAM bank is determined by
searching which bank has been given the "BRUCE" message.
21E2 SAME_$ LD DE,49152 Here the message has been placed.
21E5 LD HL,#2228,BRUCE Message to be found.
21E8 LD B,5 There are five bytes in the message.
21EA BRUCE_1 LD A,(DE)
21EB CP (HL)
21EC JR Z,#21F4,BRUCE_2 Jump if characters match.
21EE LD A,(#3E19) Otherwise it has to be one of the other
21F1 INC A banks.
21F2 JR ?_RAMBANK
21F4 BRUCE_2 INC DE
21F5 INC HL
21F6 DJNZ #21EA,BRUCE_1 All five characters have to match.
21F8 LD HL,#3BD6 The active RAM bank has been found,
21FB LD DE,49152 restore the original five bytes.
21FE LD BC,5
2201 LDIR
2203 LD A,(#3E19)
2206 PUSH AF Save the page-configuration byte in the
2207 CALL #0761,SBYT snapshot file.
220A AND #F8 Mask RAM bank, start with 0.
220C LD B,8 There are eight RAM banks
220E SAVE_BANK PUSH AF
220F PUSH BC
2210 CALL #223F,RAMPAGE_A Page in RAM bank.
2213 LD HL,(#2076)
2216 LD DE,(#2074)
221A CALL #0850,HSVBK_2 Save DE bytes starting at address HL.
221D POP BC
221E POP AF
221F INC A Next RAM bank.
2220 DJNZ #220E,SAVE_BANK Loop for all eight 16K RAM banks.
2222 POP AF
2223 CALL #223F,RAMPAGE_A Page in original RAM bank.
2226 JR #223C,SNAP_CLOSE
2228 BRUCE DEFM "BRUCE"
222D NO_SNP128 CP 7 Copy the 9 header bytes to the file if
222F CALL Z,#2879,SAVE_HEAD1 it is a SCREEN$.
2232 LD HL,(#2076)
2235 LD DE,(#2074)
2239 CALL #0850,HSVBK_2 Save DE bytes starting at address HL.
223C SNAP_CLOSE JP #0B89,CFSM Close the file.
THE 'PAGE 128K RAM' ROUTINE
The 128K RAM-bank contained in the A register is paged-in.
223F RAMPAGE_A LD BC,#7FFD 128K bank-switch port address.
2242 OUT (C),A Select RAM bank.
2244 RET
THE 'JIFFY' CALL
This routine is executed whenever KEY-SCAN in the Spectrum ROM is reached at #028E. It
can be used to executed a routine with every interrupt.
2245 JIFFY LD HL,(#2010) Call routine which has to be called
2248 JP (HL) every 'interrupt'. (Normal #208F)
THE 'MOUSE' ROUTINE
This routine is also present in the DISCiPLE and tests a mouse-like device. Pointers
which seem to keep track of screen coordinates are updated when necessary.
2249 TEST_MOUSE LD BC,#03FF The MGT mouse port?
224C IN A,(C)
224E BIT 7,A
2250 RET NZ Return if no activity.
2251 CPL
2252 AND #05 Return if there was no horizontal or
2254 RET Z vertical movement.
2255 LD HL,#228B,SIGN_MOUSE
2258 PUSH HL
2259 LD HL,#2275,MOVE_VERT
225C PUSH HL
225D IN D,(C) Read mouse bits again.
225F LD HL,#3DF1 Mouses x-coordinate.
2262 BIT 0,D
2264 RET NZ Return to vertical movement test.
2265 BIT 1,D
2267 JR Z,#226F,MOVE_RIGHT Jump if mouse was moved right.
2269 LD A,0 Left side of screen.
226B CP (HL)
226C RET Z Return if left movement isn't possible.
226D DEC (HL) Otherwise decrement x-coordinate.
226E RET
226F MOVE_RIGHT LD A,255 Right side of screen.
2271 CP (HL)
2272 RET Z Return if right movement impossible.
2273 INC (HL) Otherwise increment x.
2274 RET
2275 MOVE_VERT LD HL,#3DF2 Y-coordinate of mouse.
2278 BIT 2,D
227A RET NZ Return to signal mouse.
227B BIT 3,D
227D JR NZ,#2285,MOVE_UP Jump if mouse was moved up.
227F LD A,0 Bottom side of screen.
2281 CP (HL)
2282 RET Z Return if bottom has been reached.
2283 DEC (HL) Otherwise move towards it.
2284 RET
2285 MOVE_UP LD A,175 Top side of screen.
2287 CP (HL)
2288 RET Z Return if top was reached.
2289 INC (HL) Otherwise increment y-coordinate.
228A RET
228B SIGN_MOUSE OUT (C),D Give original signal to mouse.
228D RET