This program provides a set of procedures which are useful for creating special effects in any mode from 0 to 17 by reprogramming the Video Controller chip (VIDC). Although the VIDC is a complex device, the procedures listed here should make it easy to create two particular types of effect.
Firstly, you can move the outer edge of the border around the screen to any specified rectangle. If the border is moved to within the display area, it forms a movable window on the display. This is the first part of the demonstration supplied. Alternatively, you can "wrap up" the display area so that it appears in any specified rectangle on the screen, with border round about (this is the second part of the demonstration).
To use the facilities provided by this program in your own programs, you must include PROCassemble, PROCscrinit and PROCscr. You will probably also wish to include PROCscrto.
Before using PROCscr or PROCscrto, you must first call PROCassemble to assemble the machine code routine which writes to the VIDC, then PROCscrinit which reads information about the current mode and sets up parameters in the machine code. This procedure should therefore be called with the screen mode which you intend to use already selected. It also sets up the global variables scrc% and pixshift% which are used by PROCscr and PROCscrto. Therefore you should not use these names for variables you define in the rest of the program.
PROCscr forms the basis of all the other procedures and moves either the border or display to within a given rectangle. It can also put the new co-ordinates into the array scrc%, which is primarily for the use of PROCscrto. The parameters for PROCscr are:
PROCscr(left,bottom,right,top,select,set)
The first four give the co-ordinates in normal graphics units of the new rectangle. Left and top refer to a pixel just inside the top-left corner of the rectangle, right and bottom to a pixel just outside the bottom-right corner. Co-ordinates are measured, as usual, from the bottom-left corner of the normal display area.
In most modes, the horizontal co-ordinates will be numbered from 0 to 1279 for the default area, but in modes 16 and 17, as there are 1056 pixels horizontally, the numbering is from 0 to 1055 for the default area. With negative co-ordinates, or co-ordinates greater than the usual maximum, the 'screen' can be expanded.
One additional point is that the number of bits in a line of the display area (i.e. the number of pixels multiplied by the bits per pixel) must be a multiple of 16 to achieve a steady display.
The fifth parameter, select, should be zero if you wish to move the outer edge of the border, and one if you wish to move the display area. The final parameter, set, should be TRUE if you wish to store the new co-ordinates in scrc%, FALSE if you do not. This should normally be TRUE, so that PROCscrto can correctly calculate the steps it requires to take. PROCscrto itself sets this parameter to FALSE as it performs its own updating.
PROCscrto will smoothly move the current border or display rectangle to a new one, in a specified number of steps. For this it requires correct values in the array scrc%. It would therefore be usual to make a call to PROCscr, with set=TRUE before using PROCscrto. PROCscrto takes very similar parameters to PROCscr. They are:
PROCscrto(left,bottom,right,top,select,steps)
The first five parameters have the same function as in PROCscr. The last specifies the number of steps required to move from the old to the new rectangle. The steps are made once every frame (i.e. fifty per second) by use of the WAIT command.
Three procedures are included to demonstrate the use of PROCscr and PROCscrto. These are PROCswap, which contracts the screen to any point, then swaps to a different bank before expanding the screen, and PROCbounce and PROCstretch which provide two possible routines for swapping between screens.
The best way to understand how to create your own effects is to modify these procedures. If you should lose the screen display, escape from the program, then type a mode change command; if this fails, which is unlikely, pressing Reset will always work. Alternatively, the final procedure in the demonstration shows one method of resetting the screen to a reasonable condition.
With these procedures, a large number of effects are available: the only limit is your own imagination in their application.
10 REM >VidcProg11
20 REM Program VIDC Programmer
30 REM Version A 0.11
40 REM Author Graham Veitch
50 REM RISC User July/Aug 1989
60 REM Program Subject to Copyright
70 :
80 MODE 12:OFF
90 PROCassemble
100 PROCscrinit
110 ON ERROR PROCerror:END
120 PROCscreen
130 REPEAT
140 *Fx 112 1
150 *Fx 113 1
160 FOR bord%=0 TO 1
170 PROCscr(-96,-64,1376,1088,0,TRUE)
180 PROCscr(0,0,1280,1024,1,TRUE)
190 FOR vpos%=0 TO 1
200 FOR hpos%=0 TO 1
210 PROCswitch1(hpos%*1280,vpos%*1023,(vpos%+hpos%) MOD 2+1)
220 REPEAT UNTIL INKEY(150)
230 NEXT hpos%
240 IF vpos%=0 THEN PROCbounce(1) ELSE
PROCstretch(2)
250 REPEAT UNTIL INKEY(150)
260 NEXT vpos%
270 NEXT bord%
280 UNTIL FALSE
290 END
300 :
310 DEF PROCassemble
320 LOCAL code%,opt%
330 DIM code% &7F,scrc%(3,1)
340 FOR opt%=0 TO 3 STEP 3
350 P%=code%
360 [
370 OPT opt%
380 .screensizer
390 SWI 22
400 MOVNV R0,R0
410 MOV R7,#&03400000
420 TEQ R4,#0
430 LDREQ R5,hbstart
440 LDRNE R5,hsstart
450 LDR R6,vstart
460 ADD R0,R5,R0,ASR #1
470 ADD R2,R5,R2,ASR #1
480 ADD R1,R6,R1
490 ADD R3,R6,R3
500 ADD R0,R0,#&88000000
510 ADD R1,R1,#&B4000000
520 ADD R2,R2,#&94000000
530 ADD R3,R3,#&A8000000
540 ADD R0,R0,R4:SUB R1,R1,R4
550 SUB R2,R2,R4:ADD R3,R3,R4
560 STMIA R7,{R0-R3}
570 TEQP PC,#0:MOVNV R0,R0
580 MOVS PC,R14
590 .hbstart EQUD 0
600 .hsstart EQUD 0
610 .vstart EQUD &98000
620 ]
630 NEXT
640 ENDPROC
650 :
660 DEF PROCscrinit
670 LOCAL bytes%,pix%,pixbits%,hstart%,vstart%
680 SYS 53,MODE,6 TO ,,bytes%
690 SYS 53,MODE,9 TO ,,pixbits%
700 pix%=bytes%*8>>>pixbits%
710 CASE pix% OF
720 WHEN 1056:hstart%=&A6:pixshift%=0
730 WHEN 640:hstart%=&84:pixshift%=1
740 WHEN 320:hstart%=&42:pixshift%=2
750 WHEN 160:hstart%=&21:pixshift%=3
760 ENDCASE
770 !hbstart=hstart%<<14
780 CASE pixbits% OF
790 WHEN 0:!hsstart=hstart%-9<<14
800 WHEN 1:!hsstart=hstart%-5<<14
810 WHEN 2:!hsstart=hstart%-3<<14
820 WHEN 3:!hsstart=hstart%-2<<14
830 ENDCASE
840 ENDPROC
850 :
860 DEF PROCscreen
870 LOCAL loop%,char%,x%,y%
880 VDU 19,0,24,&F0,&80,&80
890 *Fx 112 1
900 *Fx 113 1
910 COLOUR 0,4
920 CLS
930 *Help
940 *Help FileCommands
950 *Fx 112 2
960 *Fx 113 2
970 CLS
980 MOVE RND(1280)-1,RND(1024)-1
990 FOR loop%=0 TO 31
1000 GCOL 3,RND(7)
1010 PLOT 85,RND(1280)-1,RND(1024)-1
1020 NEXT
1030 ENDPROC
1040 :
1050 DEF PROCbounce(scr%)
1060 PROCscr(0,0,1280,1024,bord%,TRUE)
1070 PROCscrto(0,992,32,1024,bord%,32)
1080 PROCscrto(1248,992,1280,1024,bord%,32)
1090 PROCscrto(0,0,32,32,bord%,32)
1100 PROCscrto(1248,0,1280,32,bord%,32)
1110 SYS 6,112,scr%
1120 SYS 6,113,scr%
1130 PROCscrto(0,0,1280,1024,bord%,32)
1140 ENDPROC
1150 :
1160 DEF PROCswitch1(x%,y%,scr%)
1170 PROCscr(0,0,1280,1024,bord%,TRUE)
1180 PROCscrto(x%,y%,x%+4,y%+4,bord%,32)
1190 SYS 6,112,scr%
1200 SYS 6,113,scr%
1210 PROCscrto(0,0,1280,1024,bord%,32)
1220 ENDPROC
1230 :
1240 DEF PROCstretch(scr%)
1250 PROCscr(0,0,1280,1024,bord%,TRUE)
1260 PROCscrto(0,1008,16,1024,bord%,32)
1270 PROCscrto(0,1008,320,1024,bord%,8)
1280 PROCscrto(960,1008,1280,1024,bord%,24)
1290 PROCscrto(1264,1008,1280,1024,bord%,8)
1300 PROCscrto(1264,768,1280,1024,bord%,8)
1310 PROCscrto(1264,0,1280,256,bord%,24)
1320 PROCscrto(1264,0,1280,16,bord%,8)
1330 SYS 6,112,scr%
1340 SYS 6,113,scr%
1350 PROCscrto(0,0,1280,1024,bord%,32)
1360 ENDPROC
1370 :
1380 DEF PROCscr(A%,B%,C%,D%,E%,set%)
1390 IF B%>=D% THEN D%=B%+4
1400 IF set% THEN
1410 scrc%(0,E%)=A%:scrc%(1,E%)=B%
1420 scrc%(2,E%)=C%:scrc%(3,E%)=D%
1430 ENDIF
1440 A%=A%<<14-pixshift%:B%=(1023-B%) DIV 4<<14
1450 C%=C%<<14-pixshift%:D%=(1023-D%) DIV 4<<14
1460 E%=E%<<26
1470 CALL screensizer
1480 ENDPROC
1490 :
1500 DEF PROCscrto(l%,b%,r%,t%,E%,step%)
1510 LOCAL ls,rs,ts,bs,loop%
1520 ls=(l%-scrc%(0,E%))/step%
1530 bs=(b%-scrc%(1,E%))/step%
1540 rs=(r%-scrc%(2,E%))/step%
1550 ts=(t%-scrc%(3,E%))/step%
1560 FOR loop%=1 TO step%
1570 l%=scrc%(0,E%)+loop%*ls
1580 b%=scrc%(1,E%)+loop%*bs
1590 r%=scrc%(2,E%)+loop%*rs
1600 t%=scrc%(3,E%)+loop%*ts
1610 PROCscr(l%,b%,r%,t%,E%,FALSE)
1620 WAIT
1630 NEXT
1640 scrc%(0,E%)=l%:scrc%(1,E%)=b%
1650 scrc%(2,E%)=r%:scrc%(3,E%)=t%
1660 ENDPROC
1670 :
1680 DEF PROCerror
1690 PROCscr(-96,-64,1376,1088,0,TRUE)
1700 PROCscr(0,0,1280,1024,1,TRUE)
1710 ON:REPORT
1720 PRINT " at line ";ERL
1730 ENDPROC