Printed Amstrad Addict magazine announced, check it out here!

Main Menu

MASK Patterns on a CPC464

Started by AMSDOS, 10:20, 16 May 18

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.


I've written some very specific routines before just to produce a pattern which would of being easily produced using the MASK command in BASIC 1.1.

I don't recall anybody tackle the MASK command before (in terms of writing a routine), though since MASK is patterns based, I was able to recreate something more generic using BASIC 1.0.

100 MODE 0:BORDER 11:INK 0,11:INK 1,18:INK 14,9:INK 15,15
110 DEFINT a-z
120 y=398
130 a$="10011001":x=0:d=640:c=INT(RND*15):GOSUB 1000
140 FOR a=0 TO 1
150 a$="10111101":x=0:d=640:y=y-2:c=INT(RND*15):GOSUB 1000
160 NEXT a
170 y=y-2
180 a$="10011001":x=0:d=640:c=INT(RND*15):GOSUB 1000
190 y=y-4
200 IF y>0 THEN GOTO 130
210 CALL &BB18
220 END
1000 WHILE l<d\32
1010   FOR p=1 TO LEN(a$)
1020     IF MID$(a$,p,1)="1" THEN PLOT x,y,VAL(MID$(a$,p,1))+c
1030     x=x+4
1040   NEXT p
1050   l=l+1
1060 WEND:l=0

I've polished the code up a little bit from what I originally had, and it produces the correct result when I compared to the BASIC 1.1 version I made below, though it also helps as a template for coding in assembly.

org &8000

;; CALL &8000,xpos,dest,ypos,grapen,mask

ld l,(ix+00)
ld h,(ix+01)
ld a,(hl)
ld (length),a
inc hl
ld e,(hl)
inc hl
ld d,(hl)
ex hl,de
ld (adrstring),hl
ld (savstring),hl

ld l,(ix+04)
ld h,(ix+05)
ld (ypos),hl

ld a,(ix+06)
ld (dest),a

ld l,(ix+08)
ld h,(ix+09)
ld (xpos),hl

ld a,(ix+02)
ld (grapen),a

xor a
ld (count),a

ld a,(grapen)
call &bbde

.main ld a,(length)
ld b,a
ld hl,(adrstring)
ld a,(hl)
sub #30
or a
jr z,skip_plot

push bc

ld hl,(xpos)
ex hl,de
ld hl,(ypos)
call &bbea

pop bc

ld a,(adrstring)
inc a
ld (adrstring),a

ld hl,(xpos)
ld de,&0004 ;; byte set for mode 0, change to 2 for mode 1 or 1 for mode 2
add hl,de
ld (xpos),hl

djnz mask

ld hl,(savstring)
ld (adrstring),hl

ld a,(count)
inc a
ld (count),a
ld b,a

ld a,(dest)
cp b
jr nz,main


.xpos defw 0
.dest defb 0
.ypos defw 0
.count defb 0
.grapen defb 0
defb 0
defw 0
defw 0

With the Assembly version I've added a whole stack of parameters, the most confusing being the "dest" parameter. The BASIC version takes a Graphical coordinate and divides by 32 which returns a number between 1 and 20, which is all to do with the program producing patterns in MODE 0 and the length of the MASK. The length of the MASK being a series of 0s & 1s 8 characters in length, so for each pixel along in MODE 0 being 4 pixels across, 8x4 = 32 if that makes sense. The best way to describe the "dest" parameter is to picture the text cursor. In MODE 0 of a x position of 20 puts the cursor on the Right Side of the Screen. Of course if the MASK pattern was 4 characters, that would give a "dest" range of 1 to 40 across the screen. The only other limiting thing about this assembly routine is it's only MODE 0. I've commented on the line where the value needs to change if this was being used in MODE 1 or 2.

I also made a BASIC version with the included M/C to show the process. Performance wise it's comparable to the BASIC 1.1 version.

100 ' Test Mask
110 MODE 0:INK 0,11:BORDER 11:INK 1,26:INK 14,9:INK 15,15:DEFINT a-z
120 GOSUB 2000
130 FOR y=398 TO 0 STEP -4
140 a$="10011001":x=0:l=20:c=INT(RND*15)+1:GOSUB 1000
150 FOR a=0 TO 2 STEP 2
160 a$="10111101":x=0:l=20:c=INT(RND*15)+1:y=y-2:GOSUB 1000
170 NEXT a
180 a$="10011001":x=0:l=20:c=INT(RND*15)+1:y=y-2:GOSUB 1000
190 NEXT y
200 CALL &BB18
210 END         
1000 CALL &8000,x,l,y,c,@a$
2010 RESTORE 2100:ad=&8000
2020 FOR l=1 TO 9
2030   READ a$
2040   FOR p=1 TO 31 STEP 2
2050     POKE ad,VAL("&"+MID$(a$,p,2))
2060     ad=ad+1
2070   NEXT p
2080 NEXT l
2100 DATA DD6E00DD66017E328580235E2356EB22
2110 DATA 8680228880DD6E04DD6605228180DD7E
2120 DATA 06328080DD6E08DD6609227E80DD7E02
2130 DATA 328480AF3283803A8480CDDEBB3A8580
2140 DATA 472A86807ED630B7280CC52A7E80EB2A
2150 DATA 8180CDEABBC13A86803C3286802A7E80
2160 DATA 11040019227E8010D82A88802286803A
2170 DATA 83803C328380473A8080B820C0C90000
2180 DATA 00000000000000000000000000000000

And this was the BASIC 1.1 version I knocked up:

100 MODE 0:BORDER 11:INK 0,11:INK 1,18:INK 14,9:INK 15,15
110 DEFINT a-z
120 y=398
130 MASK &X10011001
140 c=INT(RND*15)
150 GOSUB 1000
160 FOR a=0 TO 1
170 MASK &X10111101
180 y=y-2
190 c=INT(RND*15)
200 GOSUB 1000
210 NEXT a
220 y=y-2
230 MASK &X10011001
240 c=INT(RND*15)
250 GOSUB 1000
260 y=y-4
270 IF y>0 THEN GOTO 130
280 CALL &BB18
290 END
1000 MOVE 0,y:DRAW 640,y,c

I was able to make some nice patterns out of it.  :D

The only thing I'm not sure about is what happens if the Pattern DATA pushes back to where my BASIC program is, or does BASIC simply not let this happen?
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

Powered by SMFPacks Menu Editor Mod