Previous Next Contents Index
The snapshot routines

THE 'SNAPSHOT-FILE' UFIA
The following bytes are the last 20 bytes of a snapshot file UFIA.

0052 SNAP_UFIA  DEFB 0                   Directory description.
0053            DEFM "Snap      "        File name.
005D            DEFB 3                   File type.
005E            DEFW #0000               File length.
0060            DEFW #0000               File address.
0062            DEFW #0000               Not used with Snap's.
0064            DEFW #FFFF               Not used with Snap's.

THE 'NON-MASKABLE INTERRUPT' ROUTINE
This is the third point, from address #0000, at which the DISCiPLE system is
paged in. It is reached  either by pressing the 'snapshot' button or when
returning from a CALBAS.

0066 NMI_RAM    PUSH AF                  Save A register.
0067            LD   A,(#1DE5)
006A            CP   #47                 Check if returning from a CALBAS.
006C            JR   NZ,#0074,SNAPSHOT   Jump if not returning from a CALBAS.
006E            XOR  A
006F            LD   (#1DE5),A           Clear CALBAS executing.
0072            POP  AF                  Restore A register and return to the
0073            RET                      calling routine.

THE 'SNAPSHOT' ROUTINE
When the 'snapshot' button is pressed this routine is executed. By pressing the
keys 1 to 5 a choice between the following options can be made: dump the screen
to the printer small or grey-scale, save the screen to disk, or to save the
complete RAM contents to disk both for the 48K and 128K Spectrums.

0074 SNAPSHOT   LD   A,R
0076            PUSH AF                  Save R register and interrupt status.
0077            LD   (#1FFE),SP          Use 'internal' stack.
007B            LD   SP,#1FFE
007E            LD   A,I
0080            PUSH AF                  Save all registers, starting with I.
0081            PUSH HL
0082            PUSH BC
0083            PUSH DE
0084            EXX                      Save alternative registerset.
0085            PUSH AF                  Note, AF is PUSHed again!
0086            PUSH HL                  So in effect AF' is completely
0087            PUSH BC                  forgotten.
0088            PUSH DE
0089            PUSH IX                  Save the index registers.
008B            PUSH IY
008D            DI                       This is not necessary, interrupts are
                                         disabled already.
008E            LD   HL,#01EE,SNAP_EXIT
0091            PUSH HL                  RETurn address from snapshot.
0092            LD   (#0296),SP          Store current stackpointer at D_ERR_SP
                                         so an error will activate SNAP_EXIT.
0096            LD   BC,#FEFE            Keyboard port and CAPS-V I/O address.
0099            IN   A,(C)
009B            BIT  0,A
009D            RET  NZ                  Test for CAPS, RETurn if not pressed.
009E            LD   B,#F7               Key 1-5 I/O address.
00A0 SNAP_KEYS  IN   E,(C)
00A2            BIT  0,E                 CASE key OF
00A4            JP   Z,#164C,COPS         1: jump to the smallcopy routine.
00A7            BIT  1,E
00A9            JP   Z,#16B2,COPS2        2: jump to the greyscale routine.
00AC            LD   HL,16384                 start of RAM (also start of SCR$).
00AF            BIT  2,E
00B1            JR   NZ,#00BA,NO_SCREEN   3: Save SCREEN$.
00B3            LD   A,7                      type=SCR$.
00B5            LD   DE,6912                  length of SCR$.
00B8            JR   #00D8,SNAP_SAVE

00BA NO_SCREEN  BIT  3,E
00BC            JR   NZ,#00C5,NO_SNAP_48  4: 48K Snapshot.
00BE            LD   A,5                      type=48K Snap.
00C0            LD   DE,49152                 length of 48K RAM.
00C3            JR   #00D8,SNAP_SAVE

00C5 NO_SNAP_48 BIT  4,E
00C7            JR   Z,#00D0,SNAP_128     5: 128K Snapshot.
00C9            INC  A                   END.
00CA            AND  #07
00CC            OUT  (C),A               Nice stripes in border.
00CE            JR   #00A0,SNAP_KEYS     Wrong key pressed, try again.

00D0 SNAP_128   LD   A,9                 Type=128K Snap.
00D2            LD   DE,16384            Length of a RAM-page.
00D5            LD   HL,49152            Start of a RAM-page.
00D8 SNAP_SAVE  LD   (#0052),A           Store type in snapshot UFIA.
00DB            LD   (#005E),DE          Store length in UFIA.
00DF            LD   (#0060),HL          And the start-address.
00E2            LD   B,#FE               Key CAPS-V I/O address.
00E4            IN   A,(C)
00E6            BIT  0,A
00E8            JR   NZ,#00F2,NO_DRV_CHG If CAPS is pressed the Snap goes to
00EA            LD   A,(#1ACE)           the other drive.
00ED            XOR  #01
00EF            LD   (#1ACE),A
00F2 NO_DRV_CHG LD   A,#40
00F4            CALL #2993,JSCAN_CAT     Search first free catalogue entry.
00F7            RET  NZ                  Exit if catalogue full.
00F8            LD   A,D                 Track to A.
00F9            AND  #07                 Jump if CAT-entry will be located
00FB            JR   Z,#0102,SNAP_NAME1  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 ' '.

00FD            ADD  A,48                ASCII offset for '0'.
00FF            LD   (#0057),A           Store a 1, 2 or 3 in name-part of UFIA.
0102 SNAP_NAME1 LD   L,E                 Store sector in L.
0103            LD   A,(#1DDA)           Fetch current control port state.
0106            AND  #04
0108            JR   NZ,#010D,SNAP_NAME2 Jump if Single Density.
010A            SLA  L                   Two entries per sector.
010C            DEC  L
010D SNAP_NAME2 LD   A,(IX+14)           Is it the first or second entry in the
0110            ADD  A,L                 CAT-sector.
0111            ADD  A,64                Add ASCII 'A' offset.
0113            LD   (#0058),A           Store 'A' to 'T' in name-part of UFIA.
0116            LD   HL,#0052            Copy UFIA to DFCA.
0119            LD   DE,#1E05
011C            LD   BC,20
011F            LDIR
0121            CALL #29A8,JOFSM_2       Open the file.
0124            LD   HL,#1FEA            Copy snap registers to catalogue entry.
0127            LD   DE,#1BB2
012A            LD   BC,22
012D            LDIR
012F            LD   A,(#0052)           Get directory description.
0132            CP   9
0134            JP   NZ,#01DC,NO_SNAP128 Jump if not a 128K Snapshot.
0137            LD   HL,49152            Now the 5 first bytes of the current
013A            LD   DE,#1BD6            RAM-page are saved in the DISCiPLE RAM
013D            LD   BC,5                and replaced by the "BRUCE" message.
0140            LDIR                     This is done to determine the currently
0142            LD   HL,#01D7,BRUCE      paged in RAM-page.
0145            LD   DE,49152
0148            LD   BC,5
014B            LDIR
014D            XOR  A                   Signal '128K ROM bank active'.
014E            LD   (#1E19),A
0151            CALL #0258,?_ROMBANK     Determine current 'main' ROM bank.
0154            JR   NZ,#015B,SNAP128_1  Jump if 128K ROM bank.
0156            LD   A,#10               Signal '48K ROM bank active'.
0158            LD   (#1E19),A
015B SNAP128_1  CALL #027B,REST_PBUF     Restore printer buffer contents.
015E            LD   A,(#1E19)
0161            JR   #016B,SNAP128_2
0163            DEFB #00,#00             Unused locations.

THE 'EXIT TO STATEMENT RETURN' ROUTINE
This routine returns to the 'main' ROM statement loop. The ROM error routine uses
it if error messages are to be surpressed.

0165 EXIT_STAT  LD   HL,#1B7D,STMT_R_1   Return to 'STMT_R_1' in 'main' ROM.
0168            JP   #004F,UNPAGE_HL

THE 'SNAPSHOT ROUTINE' CONTINUED

016B SNAP128_2  CALL #003D,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.

016E SNAP128_3  LD   BC,#DFFE            Keyboard port and I/O address for Y-P.
0171            IN   E,(C)
0173            BIT  4,E
0175            JR   Z,#0186,CHANGED_$   Jump if 'Y' was pressed, screen changed.
0177            LD   B,#7F               I/O address for B-SPACE.
0179            IN   E,(C)
017B            BIT  3,E
017D            JR   Z,#0191,SAME_$      Jump if 'N' was pressed, same screen.
017F            INC  A
0180            AND  #07
0182            OUT  (C),A               Make nice stripes in border again.
0184            JR   #016E,SNAP128_3     Only 'Y' or 'N' is accepted.

0186 CHANGED_$  LD   A,(#1E19)
0189            OR   #08                 Signal 'screen 1'.
018B ?_RAMBANK  LD   (#1E19),A
018E            CALL #003D,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.

0191 SAME_$     LD   DE,49152            Here the message has been placed.
0194            LD   HL,#01D7,BRUCE      Message to be found.
0197            LD   B,5                 There are five bytes in the message.
0199 BRUCE?_1   LD   A,(DE)
019A            CP   (HL)
019B            JR   Z,#01A3,BRUCE?_2    Jump if characters match.
019D            LD   A,(#1E19)           Otherwise it has to be one of the other
01A0            INC  A                   banks.
01A1            JR   #018B,?_RAMBANK

01A3 BRUCE?_2   INC  DE
01A4            INC  HL
01A5            DJNZ #0199,BRUCE?_1      All five characters have to match.
01A7            LD   HL,#1BD6            The active RAM bank has been found,
01AA            LD   DE,49152            restore the original five bytes.
01AD            LD   BC,5
01B0            LDIR
01B2            LD   A,(#1E19)
01B5            PUSH AF                  Save the page-configuration byte in the
01B6            CALL #29C3,JSBYT         snapshot file.
01B9            AND  #F8                 Mask RAM bank, start with 0.
01BB            LD   B,#08               There are eight RAM banks
01BD SAVE_BANK  PUSH AF
01BE            PUSH BC
01BF            CALL #003D,RAMPAGE_A     Page in RAM bank.
01C2            LD   HL,(#0060)
01C5            LD   DE,(#005E)
01C9            CALL #29C9,JHSVBK_2      Save DE bytes starting at address HL.
01CC            POP  BC
01CD            POP  AF
01CE            INC  A                   Next RAM bank.
01CF            DJNZ #01BD,SAVE_BANK     Loop for all eight 16K RAM banks.
01D1            POP  AF
01D2            CALL #003D,RAMPAGE_A     Page in original RAM bank.
01D5            JR   #01EB,CLOSE_SNAP

01D7 BRUCE      DEFM "BRUCE"

01DC NO_SNAP128 CP   7                   Copy the 9 header bytes to the file if
01DE            CALL Z,#0D2F,SAVE_HEAD1  it is a SCREEN$.
01E1            LD   HL,(#0060)
01E4            LD   DE,(#005E)
01E8            CALL #29C9,JHSVBK_2      Save DE bytes starting at address HL.
01EB CLOSE_SNAP JP   #2981,JCFSM         Close the file.

THE 'SNAP_EXIT' ROUTINE
This routine is used to return to the snapshotted program, whether it has been loaded,
a snapshot was saved or an error occurred.

01EE SNAP_EXIT  LD   HL,#0000            Clear D_ERR_SP.
01F1            LD   (#0296),HL
01F4            DI
01F5            NOP
01F6            NOP
01F7            LD   SP,#1FEA
01FA            POP  IY                  Restore the index registers.
01FC            POP  IX
01FE            POP  DE                  Restore the alternate registerset.
01FF            POP  BC
0200            POP  HL
0201            POP  AF
0202            EXX
0203            CALL #0258,?_ROMBANK     Determine current 'main' ROM bank.
0206            JR   NZ,#0230,SNAP_EX_3  Jump if 128K ROM bank.
0208            CALL #027B,REST_PBUF
020B            POP  DE                  Restore the registerset.
020C            POP  BC
020D            POP  HL
020E            POP  AF
020F            LD   I,A
0211            CP   #00
0213            JR   Z,#021B,SNAP_EX_1
0215            CP   #3F                 When the I register doesn't contain #00
0217            JR   Z,#021B,SNAP_EX_1   or #3F, it is most likely that the
0219            IM   2                   interrupt mode is 2.
021B SNAP_EX_1  LD   SP,(#1FFE)          Restore stack pointer.
021F            POP  AF
0220            LD   R,A                 Jump if the interupts were disabled
0222            JP   PO,#022C,SNAP_EX_2  when 'SNAPSHOT' was entered.
0225            PUSH HL
0226            LD   HL,#004F            Otherwise return to snapshotted program
0229            JP   #004F,UNPAGE_HL     via 'main' ROM "POP  HL", "POP  AF" and
                                         "EI".
022C SNAP_EX_2  POP  AF                  Return to the instruction before which
022D            JP   #0050,UNPAGE_1      the snapshot occurred.

This piece of code does almost the same as the above. The only difference is that it
returns to the 128 'main' ROM at a somewhat different address.

0230 SNAP_EX_3  CALL #027B,REST_PBUF
0233            POP  DE
0234            POP  BC
0235            POP  HL
0236            POP  AF
0237            LD   I,A
0239            CP   #00
023B            JR   Z,#0243,SNAP_EX_4
023D            CP   #3F
023F            JR   Z,#0243,SNAP_EX_4
0241            IM   2
0243 SNAP_EX_4  LD   SP,(#1FFE)
0247            POP  AF
0248            LD   R,A
024A            JP   PO,#0254,SNAP_EX_5
024D            PUSH BC
024E            LD   BC,#007B
0251            JP   #0046,UNPAGE_BC

0254 SNAP_EX_5  POP  AF
0255            JP   #0047,UNPAGE_0

THE 'DETERMINE 128K ROM BANK' SUBROUTINE
This routine determines, by examining the byte at address #0001, which bank of the
128K ROM is selected. Because the DISCiPLE system is currently paged in the 'main'
ROM can't be accessed directly. So a routine, which pages out the DISCiPLE, is
copied to the printer buffer. But first the first 10 bytes of the printer buffer
are saved.

0258 ?_ROMBANK  LD   HL,23296            Save the 10 bytes needed by the
025B            LD   DE,#1BE6            subroutine in DISCiPLE RAM.
025E            LD   BC,10
0261            LDIR
0263            LD   HL,#0271,DET_ROM    Copy the subroutine to the freed bytes.
0266            LD   DE,23296,DET_ROM'
0269            LD   BC,10
026C            LDIR
026E            JP   23296,DET_ROM'      Exit via DET_ROM.

This small routine is copied to 23296, it returns with the Zero flag set if address
#0001 in the 'main' ROM contains 175, that is when the 48K ROM bank is paged in.

0271 DET_ROM    OUT  (187),A             Page DISCiPLE out.
0273            LD   A,(#0001)
0276            CP   175
0278            IN   A,(187)             Page DISCiPLE in.
027A            RET

THE 'RESTORE PRINTER BUFFER' SUBROUTINE
This subroutine restores the printer buffers 10 bytes which were destroyed by the
'?_ROMBANK' subroutine.

027B REST_PBUF  LD   HL,#1BE6
027E            LD   DE,23296
0281            LD   BC,10
0284            LDIR
0286            RET

Previous Next Contents Index