Your Spectrum
Issue 4, June 1984 - Dumps of Distinction
Home Contents KwikPik


See also these letters in the Forum sections:
Issue 7"Modification Madness" & "Disappointed Dumper"
Issue 8"Dilated Dumps"
Issue 10"Dumps on a Shoestring"
Issue 12"Cure for Insomniacs"
Issue 14"North of Watford?" & "Dumping the Gemini"
Issue 16"One Dump Ahead"


D U M P S   O F   D I S T I N C T I O N

 
Frustrated at producing tiny screen dumps on your full-sized printer? So was Andrew Pennell - until he developed this clever little machine code utility, that is!
If you're fortunate (ie. rich) enough to have an Epson RX8O or FX8O connected to your Spectrum, then this is the screen dump program for you.
Most printer interfaces are supplied with a high resolution dump routine, which produces a ZX Printer-sized copy of the screen. However, the copies lack the different colours of the original, and the colour system on the Spectrum can produce weird results when copied because only the screen bitmap is examined, and the colour information is ignored.
Nothing's ignored in this colour screen dump. However, not having the wherewithal for a full seven-colour printer, I decided to write a screen dump routine for my Epson that printed a large picture with different shades simulating different
Atic Atac loading screen
Lunar Jetman loading screen these interfaces, you'll just have to modify the machine code yourself - details to follow. And equally important, if your printer requires Line Feeds after Carriage Returns, add the line:

230 POKE 32478, 205: POKE 32479,20: POKE 32480,127

Once you've entered and RUN the loader, save the routine to tape with SAVE "col copy" CODE 32350,250 - and the Basic loader after it, in case of a crash. Then load a SCREEN$, and type RANDOMIZE USR 32350. If your printer starts printing, you've probably got the code right. If it doesn't, or if the system crashes, then there must be a mistake and you should re-load the Basic and check it against the listings.
I think the best screen dumps are
pixel colours; the following program is the result, producing an 11-by 6-inch copy.
The program works on either the 16K or 48K Spectrum, as it moves RAMTOP down to address 32349; 48K owners cannot use their extra 32K of memory. For those with the inclination, the routine can be modified to run from address 65118, by changing all '205,20,127' sequences to '205,20,255', and by changing '33,244,126' to '33,244,254'.
Listing 1 shows the Basic loader for those with the Hilderbay interface; note that you must load the 'mini- software' first. For those with a Kempston interface, add the lines in Listing 2 and, for those with a Kempston E interface, add the lines in Listing 3. If you've got none of
Pssst loading screen


This program is available on "ZIPi'T'ape".

DUMPS OF DISTINCTION
 
those from the Ultimate programs, and some of these adorn this article. Unfortunately, they all contain a lot of black, so you'll need a new(ish) ribbon for best results. If you're using fan-fold paper 11-inches in length, position the perforations just above the print head before the dump - otherwise the next perforation
Listing 4
This listing is taken from the Hisoft GENS assembler and uses # to denote hex numbers and % for binary numbers. It also supports conditional assembly.


 
                100 ; EPSON COLOUR COPY
                110 ; for RX/FX80s
                120 ; (C) A.PENNELL 1984
                130 ; define interface types
0001            140 HILDER EQU  %1
0002            150 KEMPN  EQU  %10
0004            160 KEMPE  EQU  %100
0001            170 TYPE   EQU  HILDER ;change to suit interface
7E5E            180 START  EQU  32350
7E5E            190        ORG  START
                200 ;Hilderbay set-up routine
0001            210        IF   TYPE&HILDER
7E5E CD005B     220        CALL 23296 ;setup routine
7E61 180F       230        JR   BEGIN
7E63            240        END  ;Hilderbay setup
                250 ;Kemp normal setup
0000            260        IF   TYPE&KEMPN
7E63            270        LD   BC,#E3BF
7E63            280        LD   A,129
7E63            290        OUT  (C),A
7E63            300        LD   A,15
7E63            310        OUT  (C),A
7E63            320        JR   BEGIN
7E63            330        END
                340 ;KEMPSTON E setup
0000            350        IF   TYPE&KEMPE
7E63            360        LD   A,3
7E63            370        CALL #1601 ;open "P"
7E63            380        JR   BEGIN
7E63            390        END
001B            400 ESC    EQU  27
                410 ;
                420 ;the routine itself
7E72            430        ORG  START+20
7E72 3E1B       440 BEGIN  LD   A,ESC
7E74 CD147F     450        CALL OUTCH
7E77 3E41       460        LD   A,"A"
7E79 CD147F     470        CALL OUTCH
7E7C 3E03       480        LD   A,3
7E7E CD147F     490        CALL OUTCH ;set up small line feeds
7E81 0E00       500        LD   C,0 ;zero X counter
7E83 3E1B       510 NLINE  LD   A,ESC
7E85 CD147F     520        CALL OUTCH
7E88 3E2A       530        LD   A,"*"
7E8A CD147F     540        CALL OUTCH
7E8D 3E04       550        LD   A,4 ;put in mode 4
7E8F CD147F     560        CALL OUTCH
7E92 3E10       570        LD   A,16
7E94 CD147F     580        CALL OUTCH
7E97 3E02       590        LD   A,2
7E99 CD147F     600        CALL OUTCH ;set up for 3*176 bits of data
7E9C 0600       610        LD   B,0 ;zero Y counter
7E9E C5         620 NXY    PUSH BC
7E9F CDAA22     630        CALL #22AA ;HL=screen memory
7EA2 47         640        LD   B,A
7EA3 04         650        INC  B
7EA4 3E01       660        LD   A,1
7EA6 0F         670 L1     RRCA
7EA7 10FD       680        DJNZ L1
7EA9 A6         690        AND  (HL) ;Z if ink, NZ if paper
7EAA 08         700        EX   AF,AF'
7EAB 7C         710        LD   A,H
7EAC 0F         720        RRCA
7EAD 0F         730        RRCA
7EAE 0F         740        RRCA
7EAF E603       750        AND  3
7EB1 F658       760        OR   #58
7EB3 67         770        LD   H,A ;HL=attribute byte
7EB4 46         780        LD   B,(HL) ;B=ATTR
7EB5 08         790        EX   AF,AF'
7EB6 78         800        LD   A,B ;A=ATTR
7EB7 2003       810        JR   NZ,INK
7EB9 0F         820        RRCA ;if PAPER then /8
7EBA 0F         830        RRCA
7EBB 0F         840        RRCA
7EBC E607       850 INK    AND  7 ;mask other bits
7EBE 21F47E     860        LD   HL,TABLE
7EC1 87         870        ADD  A,A
7EC2 87         880        ADD  A,A
7EC3 5F         890        LD   E,A
7EC4 1600       900        LD   D,0
7EC6 19         910        ADD  HL,DE ;HL=data specified colour
7EC7 0603       920        LD   B,3 ;=no of bytes per pixel
7EC9 7E         930 OUTLP  LD   A,(HL) ;read byte
7ECA CD147F     940        CALL OUTCH ;send it
Listing 1
 100 CLEAR 32349
 110 RESTORE 1000
 119 REM POKE the setup routine
 120 FOR i=32350 TO 32369
 130 READ a: IF a=-1 THEN GO TO 
150
 140 POKE i,a: NEXT i
 149 REM POKE the routine itself
 150 LET c=0
 155 FOR i=32370 TO 32531
 160 READ a: POKE i,a
 170 LET c=c+a
 180 NEXT i
 185 IF c<>13071 THEN PRINT "DAT
A ERROR": STOP
 190 FOR i=32532 TO 32599
 200 READ a: IF a=-1 THEN GO TO 
220
 210 POKE i,a: NEXT i
 220 PRINT "FINISHED."
1000 DATA 205,0,91,24,15,-1
1100 DATA 62,27,205,20,127,62,65
,205,20
1110 DATA 127,62,3,205,20,127,14
,0,62
1120 DATA 27,205,20,127,62,42,20
5,20,127
1130 DATA 62,4,205,20,127,62,16,
205,20
1140 DATA 127,62,2,205,20,127,6,
0,197
1150 DATA 205,170,34,71,4,62,1,1
5,16
1160 DATA 253,166,8,124,15,15,15
,230,3
1170 DATA 246,88,103,70,8,120,32
,3,15
1180 DATA 15,15,230,7,33,244,126
,135,135
1190 DATA 95,22,0,25,6,3,126,205
,20
1200 DATA 127,35,16,249,193,4,12
0,254,176
1210 DATA 56,199,62,13,205,20,12
7,62,10
1220 DATA 0,0,0,12,32,159,62,27,
205
1230 DATA 20,127,62,65,205,20,12
7,62,12
1240 DATA 205,20,127,201,224,224
,224,0,192
1250 DATA 96,192,0,160,64,160,0,
32,64
1260 DATA 128,0,96,0,96,0,64,0,6
4
1270 DATA 0,0,64,0,0,0,0,0,0
1300 DATA 197,229,205,254,91,225
,193,201,-1
The Basic loader for the Hilderbay interface.
1000 DATA 1,191,227,62,129,237,1
21,62,15
1015 DATA 237,121,24,7,-1
1300 DATA 243,197,1,191,226,30,1
4,237,80
1310 DATA 203,66,32,250,6,224,23
7,121,6
1320 DATA 227,237,89,28,237,89,2
51,205,84
1330 DATA 31,210,0,13,193,201,-1
Add these lines to the loader to use with a Kempston interface.
1000 DATA 62,3,205,1,22,24,13,-1
1300 DATA 245,62,27,215,241,215,
201,-1
Add these lines to the loader to use with a Kempston E interface.

DUMPS OF DISTINCTION
 
will appear in the middle of the dump. if you break in the middle of it, you may find that your printer acts strangely, because it's in bit mode; the best way to clear it is by switching the printer off, then on again.


MODUS OPERANDI
 
The screen is copied sideways, and consists of a 176 x 256 grid of pixels. If each screen pixel is represented by a three- by- three grid on the printer, then this points to a printer resolution of 528 x 768. The former figure rules out the old Epsons (MX-type and assorted look-alikes) with their resolution of only 480 dots per line. The new Epsons have a resolution of 640 dots per line in bit image mode 4, and that's why we're using them here. As well as this, the vertical Line Feed distance has to be changed to three dots, which is 3/72 of an inch, and is changed with the ESC "A" command.


CRACKING THE CODE
 
The full assembler listing is shown in Listing 4, printed from the Hisoft GENS assembler, which uses '#' to denote hex numbers, and '%' for binary numbers. It also supports conditional assembly, which I have used to determine the setup and output routines for different interfaces. If your assembler does not support conditional assembly,just leave out all mnemonics that refer to interfaces other than your own. If you have a different interface, substitute your own set-up routine at START, and your own output routine at OUTCH. Note that OUTCH must preserve the values of HL and BC.
The copy routine proper starts at BEGIN, which firstly resets the Line Feed distance to 3/72 of an inch and zeros C - which is used as a counter for the X co-ordinate. Next the printer is put into graphics mode 4, and the B reg (which is the Y counter) is set to zero. The ROM routine at 22AA is called, which calculates screen location HL and bit position B from the screen co-ordinates in B and C, and the pixel colour calculated from the attribute file. The relevant data is read from TABLE and printed out, and this is repeated for all 176 Y positions. After this, a Newline is sent (and optionally a Line Feed), and all 256 X positions are done. Finally, the Line Feed distance is reset to 12/72 of an inch. The data at TABLE contains the bit patterns for each colour. They were originally chosen quite arbitrarily, but I left them as they seem to produce good results. If you don't like the shades produced, feel free to change the data, though note that the fourth byte for each colour should be zero. Also, beware, Listing 4 was made with the Hilderbay interface selected, so no object code was generated for either of the Kempston interfaces.
7ECD 23         950        INC  HL
7ECE 10F9       960        DJNZ OUTLP ;do 3 bytes
7ED0 C1         970        POP  BC ;restore X & Y
7ED1 04         980        INC  B
7ED2 78         990        LD   A,B
7ED3 FEB0      1000        CP   176
7ED5 38C7      1010        JR   C,NXY ;do all 176
7ED7 3E0D      1020        LD   A,13 ;end of line so do a CR
7ED9 CD147F    1030        CALL OUTCH
7EDC 3E0A      1040        LD   A,10 ;LF code
7EDE 00        1050        NOP  ;room for CALL OUTCH
7EDF 00        1060        NOP
7EE0 00        1070        NOP
7EE1 0C        1080        INC  C
7EE2 209F      1090        JR   NZ,NLINE ;do all 256 X pixels
7EE4 3E1B      1100        LD   A,ESC ;reset line feed distance
7EE6 CD147F    1110        CALL OUTCH
7EE9 3E41      1120        LD   A,"A"
7EEB CD147F    1130        CALL OUTCH
7EEE 3E0C      1140        LD   A,12
7EF0 CD147F    1150        CALL OUTCH
7EF3 C9        1160        RET  ;finish
               1170 ;data table for colour patterns
7EF4 E0        1180 TABLE  DEFB %11100000 ;black
7EF5 E0        1190        DEFB %11100000
7EF6 E0        1200        DEFB %11100000
7EF7 00        1210        DEFB 0
7EF8 C0        1220        DEFB %11000000 ;blue
7EF9 60        1230        DEFB %01100000
7EFA C0        1240        DEFB %11000000
7EFB 00        1250        DEFB 0
7EFC A0        1260        DEFB %10100000 ;red
7EFD 40        1270        DEFB %01000000
7EFE A0        1280        DEFB %10100000
7EFF 00        1290        DEFB 0
7F00 20        1300        DEFB %00100000 ;magenta
7F01 40        1310        DEFB %01000000
7F02 80        1320        DEFB %10000000
7F03 00        1330        DEFB 0
7F04 60        1340        DEFB %01100000 ;green
7F05 00        1350        DEFB %00000000
7F06 60        1360        DEFB %01100000
7F07 00        1370        DEFB 0
7F08 40        1380        DEFB %01000000 ;cyan
7F09 00        1390        DEFB %00000000
7F0A 40        1400        DEFB %01000000
7F0B 00        1410        DEFB 0
7F0C 00        1420        DEFB %00000000 ;yellow
7F0D 40        1430        DEFB %01000000
7F0E 00        1440        DEFB %00000000
7F0F 00        1450        DEFB 0
7F10 00        1460        DEFB %00000000 ;white
7F11 00        1470        DEFB %00000000
7F12 00        1480        DEFB %00000000
7F13 00        1490        DEFB 0
7F14           1500        END
               1510 ; OUTCH - the send character to printer routine
7F14           1520 OUTCH  EQU  $
               1530 ; Hilderbay O/P routine
0001           1540        IF   TYPE&HILDER
7F14 C5        1550        PUSH BC
7F15 E5        1560        PUSH HL ;save regs
7F16 CDFE5B    1570        CALL 23550 ;call the routine
7F19 E1        1580        POP  HL
7F1A C1        1590        POP  BC ;restore regs
7F1B C9        1600        RET
7F1C           1610        END
               1620 ; KEMPSTON normal output
0000           1630        IF   TYPE&KEMPN
7F1C           1640        DI
7F1C           1650        PUSH BC
7F1C           1660        LD   BC,#E2BF
7F1C           1670        LD   E,14
7F1C           1680 KBUSY  IN   D,(C)
7F1C           1690        BIT  0,D
7F1C           1700        JR   NZ,KBUSY
7F1C           1710        LD   B,224
7F1C           1720        OUT  (C),A
7F1C           1730        LD   B,227
7F1C           1740        OUT  (C),E
7F1C           1750        INC  E
7F1C           1760        OUT  (C),E
7F1C           1770        EI
7F1C           1780        CALL #1F54 ;test break
7F1C           1790        JP   NC,#0D00 ;error if pressed
7F1C           1800        POP  BC
7F1C           1810        RET
7F1C           1820        END
               1830 ; KEMPSTON E output
0000           1840        IF   TYPE&KEMPE
7F1C           1850        PUSH AF
7F1C           1860        LD   A,ESC
7F1C           1870        RST  #10
7F1C           1880        POP  AF
7F1C           1890        RST  #10
7F1C           1900        RET
7F1C           1910        END
Home Contents KwikPik