Appendix 2.3: Indexed Listing of program 'MultiGrab'

	INDEX:

   280 DEFPROCinitialise
   540 DEFPROCoptions
  1020 DEFPROCuser_pause
  1150 DEFPROCgrab_images
  1260 DEFPROCreach_for_the_popcorn
  1610 DEFPROCmulti_save
  1920 DEFPROCsave_and_step
  2210 DEFFNtimestamp(a$)
  2390 DEFPROCassemble_trigger
  2630 DEFPROCassemble_header_pause
  3000 DEFPROCassemble_grab

	LISTING:

   10 REM  > <MultiGrab$Dir>.!RunImage
   20 REM
   30 REM  Program : MULTIGRAB1
   40 REM
   50 REM  Purpose : Allows capture of multiple images from video
   60 REM
   70 REM  Notes   : Evolved from "IO_Test4", 10th December 1990
   80 REM
   81 REM            See Rockwell data sheet 29000D47 for VIA6522 spec's
   90 
  100 PROCinitialise
  110 PROCoptions
  120 
  130 PROCassemble_trigger
  140 PROCassemble_header_pause
  150 PROCassemble_grab
  160 
  170 PROCuser_pause
  180 PROCgrab_images
  190 PROCreach_for_the_popcorn
  200 
  210 END
  220 
  230 REM---------------------------------------------------------------------
  240 REM
  250 REM   Procedure INITIALISE
  260 REM
  270 
  280 DEFPROCinitialise
  290 
  300   DIM trigger%       &200
  310   DIM header_pause%  &400
  320   DIM grab%          &800
  330 
  340   first%   = 0
  350 
  360   osbyte%  = 6                 :REM --- SYS 6 is equivalent to OSbyte
  370   read%    = 150               :REM --- OSbyte no. for read-from-SHEILA
  380   write%   = 151               :REM --- OSbyte no. for write-to-SHEILA
  390   IORB     = &60 + 00          :REM --- Input/Output Register B
  400   DDRB     = &60 + 02          :REM --- Data Direction Register B
  410   T2C_L    = &60 + 08          :REM --- Timer/Counter 2    LOW
  420   T2C_H    = &60 + 09          :REM --- Timer/Counter 2    HIGH
  430   ACR      = &60 + 11          :REM --- Auxiliary Control Register
  440   iFR      = &60 + 13          :REM --- Interrupt Flag Register
  450   iER      = &60 + 14          :REM --- Interrupt Enable Register
  460 
  470 ENDPROC
  480 
  490 REM---------------------------------------------------------------------
  500 REM
  510 REM   Procedure OPTIONS
  520 REM
  530 
  540 DEFPROCoptions
  550 
  560   MODE 15
  570   PRINT '"Multiple image grabber 'MULTIGRAB' : special '92 version"
  580   PRINT  "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
  590   PRINT '"Last edited ";FNtimestamp("<MultiGrab$Dir>.!RunImage")
  600 
  610   INPUT '"Destination directory   [ 92/6nac2 ] ? "dir$
  620   IF dir$="" THEN dir$="92/6nac2"
  630   dir$ = "<HyperVel$Dir>.Images."+dir$
  640  
  650   room% = INT((HIMEM-END-&800)/(1024*128))
  660   PRINT '"There is room for ";room%;" fields of video."
  661   IF room%>19 THEN default%=20 ELSE default%=room%
  670   PRINT '"Digitise how many            [";STR$(default%);
  680   INPUT  "] ? "a$
  690   IF a$="" THEN total%=default% ELSE total%=VAL(a$)
  700 
  710   DIM buffer% (&100+total%*&20000)
  720   buffer%+=&80
  730 
  740   INPUT  "Header count (NAC frames)    [50] ? "a$
  750   IF a$="" THEN header%=50 ELSE header%=VAL(a$)
  760   header% = header%*2
  770 
  780   header_hi_byte%=INT(header%/256)
  790   header_lo_byte%=(header% AND %11111111)
  800 
  810   INPUT  "NAC frame spacing             [2] ? "a$
  820   IF a$="" THEN spacing%=2 ELSE spacing%=VAL(a$)
  830   spacing% = spacing%*2
  840 
  850   spacing% = spacing%-1
  860   spacing_hi_byte%=INT(spacing%/256)
  870   spacing_lo_byte%=(spacing% AND %11111111)
  880 
  890   INPUT '"Image file code to use   [6_2_] ? "code$
  900   IF code$="" THEN code$="6_2_"
  910 
  920 ENDPROC
  930 
  940 REM---------------------------------------------------------------------
  950 REM
  960 REM   Procedure USER_PAUSE
  970 REM
  980 REM   Purpose : Allows one to start the video tape before looking for
  990 REM             the triggering pulse.
 1000 REM
 1010 
 1020 DEFPROCuser_pause
 1030   PRINT '"Hit any key to start AUDIO MONITOR"
 1040   WHILE INKEY$(0)="":ENDWHILE
 1050   PRINT CHR$(11)+STRING$(40," ")+CHR$(11)
 1060 ENDPROC
 1070 
 1080 REM---------------------------------------------------------------------
 1090 REM
 1100 REM   Procedure GRAB_IMAGES
 1110 REM
 1120 REM   Purpose : CALLs the machine-code-thingies and grabs images.
 1130 REM
 1140 
 1150 DEFPROCgrab_images
 1160   PRINT "Waiting for trigger..."   +CHR$(7) : CALL trigger%
 1170   PRINT "Counting header fields..."+CHR$(7) : CALL header_pause%
 1180   PRINT "Grabbing images..."       +CHR$(7) : CALL grab%
 1190 ENDPROC
 1200 
 1210 REM---------------------------------------------------------------------
 1220 REM
 1230 REM   Procedure REACH_FOR_THE_POPCORN
 1240 REM
 1250 
 1260 DEFPROCreach_for_the_popcorn
 1270   PRINT'"Hit any key to display images"
 1280   WHILE INKEY$(0)="":ENDWHILE
 1290   COLOUR 0 TINT 0
 1300   COLOUR 63 TINT 128
 1310   image%=0
 1320   REPEAT
 1330     SYS "Vdig_WriteLine",(buffer%+(image%*&20000)),1,256
 1340     *SHOWPIC
 1350     VDU 28,56,10,76,1,12
 1360     PRINT'" Image No.";STR$(image%)
 1370     PRINT'"  S  - Save & step"
 1380     PRINT " ^S  - Multiple save"
 1390     PRINT " <>  - View fields"
 1400     PRINT "  Q  - quit"
 1410     key$=""
 1420     WHILE key$=""
 1430       key$=INKEY$(0)
 1440     ENDWHILE
 1450     CASE key$ OF
 1460       WHEN ","     : image%=image%-1:IF image%<0 THEN image%=total%-1
 1470       WHEN "."     : image%=image%+1:IF image%=total% THEN image%=0
 1480       WHEN "S","s" : PROCsave_and_step
 1490       WHEN CHR$(19): PROCmulti_save
 1500     ENDCASE
 1510   UNTIL key$="Q" OR key$="q"
 1520 ENDPROC
 1530 
 1540 REM--------------------------------------------------------------------
 1550 REM
 1560 REM   Procedure MULTI_SAVE
 1570 REM
 1580 REM   Purpose : Saves all images sequentially, using ref. numbers.
 1590 REM
 1600 
 1610 DEFPROCmulti_save
 1630   n$=""
 1640   WHILE n$="":CLS
 1650     PRINT'" First (XXX) ? ";:INPUT ""n$
 1660   ENDWHILE
 1670   first%=VAL(n$)
 1690   FOR image%=0 TO (total%-1)
 1710     SYS "Vdig_WriteLine",(buffer%+(image%*&20000)),1,256
 1720     *SHOWPIC
 1740     ref%=first%+image%*(INT(spacing%/2)+1)
 1750     m$=RIGHT$(STR$(10000+ref%),3)
 1760     f$=RIGHT$(STR$(10000+50*INT(ref%/50)),3)+"."+code$+m$
 1761     PRINT TAB(1,1);f$
 1770     OSCLI("*PICSAVE "+dir$+"."+f$)
 1780     OSCLI("*SETTYPE "+dir$+"."+f$+" 009")
 1800   NEXT image%
 1801   image%=0
 1830 ENDPROC
 1840 
 1850 REM---------------------------------------------------------------------
 1860 REM
 1870 REM  Procedure SAVE_AND_STEP
 1880 REM
 1890 REM  Purpose : Saves the grabbed images to disc.
 1900 REM
 1910 
 1920 DEFPROCsave_and_step
 1930   IF image%=0 THEN
 1940     n$="":WHILE n$="":CLS
 1950     PRINT'" Image (XXX) ? ";:INPUT ""n$:ENDWHILE
 1960     first%=VAL(n$)
 1970   ELSE
 1980     default%=first%+image%*(INT(spacing%/2)+1)
 1990     m$=RIGHT$(STR$(10000+default%),3)
 2000     CLS:PRINT'" Image [";m$;"] ? ";:INPUT ""n$
 2010     IF n$="" THEN n$=m$
 2020   ENDIF
 2030 
 2040   f$=code$+n$
 2050   PRINT'" Default:"''"  ";f$
 2060   INPUT'" Save [Y] ? "a$
 2070   IF (a$<>"N" AND a$<>"n") THEN
 2080     OSCLI("*PICSAVE "+dir$+"."+f$)
 2090     OSCLI("*SETTYPE "+dir$+"."+f$+" 009")
 2100     image%=image%+1:IF image%=total% THEN image%=0
 2110   ENDIF
 2120 ENDPROC
 2130 
 2140 REM----------------------------------------------------------------------
 2150 REM
 2160 REM   Function TIMESTAMP            { Library PROCs.FN_TmStamp }
 2170 REM
 2180 REM   Purpose : Returns the filesystem timestamp string of a file.
 2190 REM
 2200 
 2210 DEFFNtimestamp(a$)
 2220   DIM fivebyte 8
 2230   DIM string   32
 2240   DIM filename 64
 2250   $fivebyte     = STRING$(8,CHR$(0))
 2260   $string       = STRING$(32,CHR$(0))
 2270   $filename     = a$
 2280   SYS"OS_File",5,filename TO R0,R1,R2,R3,R4,R5
 2290   !(fivebyte+0) = R3
 2300   !(fivebyte+4) = R2
 2310   SYS"OS_ConvertStandardDateAndTime",fivebyte,string,32 TO R0
 2320 =$R0
 2330 
 2340 REM---------------------------------------------------------------------
 2350 REM
 2360 REM   Procedure ASSEMBLE_TRIGGER
 2370 REM
 2380 
 2390 DEFPROCassemble_trigger
 2400   FOR pass%=0 TO 2 STEP 2
 2410     P% = trigger%
 2420     [ OPT pass%
 2430     MOV    R0,#write%                    ; Clear the IFR
 2440     MOV    R1,#iFR                       ;
 2450     MOV    R2,#&FF                       ;
 2460     SWI    osbyte%                       ;
 2470     .trigger_loop
 2480        MOV    R0,#read%                  ; Poll the IFR
 2490        MOV    R1,#iFR                    ;
 2500        SWI    osbyte%                    ;
 2510        MOVS   R2,R2                      ; Test returned value
 2520        BEQ    trigger_loop               ;  ..zero means "no blip yet"
 2530     MOV    PC,R14                        ; Quit to BASIC
 2540     ]
 2550   NEXT pass%
 2560 ENDPROC
 2570 
 2580 REM---------------------------------------------------------------------
 2590 REM
 2600 REM   Procedure ASSEMBLE_HEADER_PAUSE
 2610 REM
 2620 
 2630 DEFPROCassemble_header_pause
 2640   FOR pass%=0 TO 2 STEP 2
 2650     P% = header_pause%
 2660     [ OPT pass%
 2670 
 2680     MOV    R0,#write%                    ; Set mode to COUNT-ON-PB6
 2690     MOV    R1,#ACR                       ;
 2700     MOV    R2,#%00100000                 ;
 2710     SWI    osbyte%                       ;
 2720 
 2730     MOV    R0,#write%                    ; Load low byte of counter
 2740     MOV    R1,#T2C_L                     ;
 2750     MOV    R2,#header_lo_byte%           ;  (will not start counting)
 2760     SWI    osbyte%                       ;
 2770 
 2780     MOV    R0,#write%                    ; Load high byte of counter
 2790     MOV    R1,#T2C_H                     ;
 2800     MOV    R2,#header_hi_byte%           ;  (This triggers the counting)
 2810     SWI    osbyte%                       ;
 2820 
 2830     .header_loop
 2840        MOV    R0,#read%                  ; Poll the IFR
 2850        MOV    R1,#iFR                    ;
 2860        SWI    osbyte%                    ;
 2870        TST    R2,#%100000                ; Test returned value
 2880        BEQ    header_loop                ; ..zero means "still counting"
 2890 
 2900     MOV    PC,R14
 2910     ]
 2920   NEXT pass%
 2930 ENDPROC
 2940 
 2950 REM---------------------------------------------------------------------
 2960 REM
 2970 REM   Procedure ASSEMBLE_GRAB
 2980 REM
 2990 
 3000 DEFPROCassemble_grab
 3010   FOR pass%=0 TO 2 STEP 2
 3020     P%    = grab%
 3030     ram   = 5
 3040     pic   = 6
 3050     temp  = 7
 3060     [ OPT pass%
 3070     LDR    ram,buff
 3080     MOV    pic,#total%
 3090 
 3100     .field_loop
 3110        MOV    R0,#write%                 ; Load low byte of counter
 3120        MOV    R1,#T2C_L                  ;
 3130        MOV    R2,#spacing_lo_byte%       ;  (will not start counting)
 3140        SWI    osbyte%                    ;
 3150 
 3160        MOV    R0,#write%                 ; Load high byte of counter
 3170        MOV    R1,#T2C_H                  ;
 3180        MOV    R2,#spacing_hi_byte%       ;  (This triggers the counting
 3190        SWI    osbyte%                    ;           and clears the IFR)
 3200 
 3210        MOV    R0,#00                     ; Grab image
 3220        SWI    "Vdig_Grab"                ;
 3230 
 3240        MOV    R0,ram                     ; Copy image to Arc RAM
 3250        MOV    R1,#00                     ;
 3260        MOV    R2,#255                    ;
 3270        SWI    "Vdig_ReadLine"            ;
 3280 
 3290        ADD    ram,ram,#&20000            ; Move the storage pointer
 3300        SUBS   pic,pic,#01                ; Have we grabbed enough?
 3310        BEQ    quit                       ; If YES, scram.
 3320 
 3330        .wait_loop
 3340           MOV    R0,#read%               ; Poll the IFR
 3350           MOV    R1,#iFR                 ;
 3360           SWI    osbyte%                 ;
 3370           TST    R2,#%100000             ; Test returned value
 3380           BEQ    wait_loop               ; ..zero means "still counting"
 3390        BAL     field_loop
 3400 
 3410     .quit
 3420     MOV    R15,R14
 3430 
 3440     .buff     EQUD     buffer%
 3450 
 3460      ]
 3470   NEXT pass%
 3480 ENDPROC