Home » Archimedes archive » Acorn User » AU 1995-03.adf » !StarInfo_StarInfo » Turnbull/FracLand
Turnbull/FracLand
This website contains an archive of files for the Acorn Electron, BBC Micro, Acorn Archimedes, Commodore 16 and Commodore 64 computers, which Dominic Ford has rescued from his private collection of floppy disks and cassettes.
Some of these files were originally commercial releases in the 1980s and 1990s, but they are now widely available online. I assume that copyright over them is no longer being asserted. If you own the copyright and would like files to be removed, please contact me.
Tape/disk: | Home » Archimedes archive » Acorn User » AU 1995-03.adf » !StarInfo_StarInfo |
Filename: | Turnbull/FracLand |
Read OK: | ✔ |
File size: | 89ED bytes |
Load address: | 0000 |
Exec address: | 0000 |
File contents
10MODE13 20PROCconstants 30DIMspace%spacelen%:P%=space% 40code%=P%:P%+=codelen% 50pos%=P%:P%+=32*levels% 60base%=P%:P%+=32*bsize%*bsize% 70dist%=P%:P%+=depth%*16 80col%=P%:P%+=8*32*64 90shape%=P%:P%+=shapelen% 100points%=P%:P%+=8*nopoints% 110map%=P%:P%+=32*msize%*msize%*levels% 120land%=P%:P%+=8*lsize%*lsize%*vis% 130hor%=P%:P%+=winc%*width% 140IFP%>space%+spacelen%THENERROR255,"Space isn't big enough" 150PRINTP%-space%;" bytes used" 160PROCassemble 170PROCsetupshape 180PROCsetupcol 190PROCsetupdist 200FORT%=0TOwidth%-1:hor%!(T%*winc%)=height%:NEXT 210PROCsetupbase:!refresh%=TRUE 220REPEAT 230PROCmap 240PROCfly 250UNTIL0 260END 270: 280: 290DEFPROCconstants 300spacelen%=&200000 310codelen%=&8000 320AC%=12:VC%=9:SC%=8:DC%=12 330ML%=2:loff%=1<<ML%-1 340MS%=5:msize%=1<<MS% 350LS%=MS%+ML%:lsize%=1<<LS% 360BS%=5:bsize%=1<<BS% 370BC%=AC%+9:LC%=AC%-2:MC%=LC%+ML%:EC%=32-LS% 380levels%=BC%-MC%+1:vis%=(AC%+14)-LS%-LC%+1 390WW%=6:width%=20<<WW%-4 400HH%=7:height%=16<<HH%-4 410dsteps%=10:winc%=256*8 420depth%=2*dsteps%+vis%*dsteps% 430IFdepth%*8+4>winc%THENERROR255,"winc% is not big enough" 440shapelen%=&4000 450nopoints%=64 460SCW%=8:scwidth%=20<<SCW%-4:sclinc%=scwidth% 470SCH%=8:scheight%=16<<SCH%-4 480SKW%=SCW%-2:skwidth%=20<<SKW%-4 490SKH%=SCH%-2:skheight%=16<<SKH%-4 500ENDPROC 510: 520DEFPROCsetupcol 530RESTORE+0 540U%=col% 550READA$:WHILEA$<>"*":L%=LEN(A$)/2-1 560FORT%=0TO31:B%=8*L%*T%/32 570!U%=EVAL("&"+MID$(A$,1+2*(B%+5>>3),2)+MID$(A$,1+2*(B%+1>>3),2)+MID$(A$,1+2*(B%+4>>3),2)+MID$(A$,1+2*(B%+0>>3),2)) 580U%!4=EVAL("&"+MID$(A$,1+2*(B%+3>>3),2)+MID$(A$,1+2*(B%+7>>3),2)+MID$(A$,1+2*(B%+2>>3),2)+MID$(A$,1+2*(B%+6>>3),2)) 590U%+=8:NEXT 600READA$:ENDWHILE 610ENDPROC 620: 630DATA"2BA2A3CCCD" 640DATA"FBFAF9F8CF","CFCECDCCA3","A3A2A1A00B","0B0A090800" 650DATA"2122234C4D","4D4E4FF0F1" 660DATA"2020212223","234C4D4E4F" 670DATA"2425262758","58595A5BF4" 680DATA"2223444546","464778797A" 690DATA"032C2D2E2F","2FD0D1D2D3" 700DATA"2FD0D1D2D3","D3FCFDFEFF" 710DATA"02032C2D2E","2E2FD0D1D2" 720DATA"060738393A","3A3BD4D5D6" 730DATA"*" 740: 750DEFPROCsetupdist 760maxdist%=(lsize%/2-8)/SQR(1^2+(5/8)^2) 770V%=dist%:FORT%=1TOdsteps%*2 780!V%=0:V%!4=T%/dsteps%/2*maxdist%/2*(1<<SC%) 790V%!8=(1<<20)/V%!4:V%!12=V%!4<<LC%-SC% 800V%+=16:NEXT 810FORU%=0TOvis%-1:FORT%=1TOdsteps% 820!V%=U%:V%!4=maxdist%*2^(T%/dsteps%-1)*(1<<SC%) 830V%!8=(1<<20)/V%!4:V%!12=V%!4<<(LC%+U%)-SC% 840V%+=16:NEXT, 850ENDPROC 860: 870DEFPROCsetupbase 880U%=base%:FORY%=0TObsize%-1:FORX%=0TObsize%-1 890!U%=0 900U%!4=0 910U%!8=(112/((X%-15)*(X%-16)+(Y%-15)*(Y%-16)+64)-0.5)*(1<<SC%)+RND(1<<SC%-1)-(1<<SC%-2) 920U%!12=RND(1<<SC%-2) 930U%!16=0:U%!20=0:U%!24=0:U%!28=0 940U%+=32:NEXT, 950ENDPROC 960: 970DEFPROCsetupshape 980DIMP$(nopoints%) 990P%=shape% 1000PROCnewshape:REM Brick 1010PROCpoint("SWD",-15,-20,-10) 1020PROCpoint("SED",15,-20,-10) 1030PROCpoint("NWD",-15,20,-10) 1040PROCpoint("NED",15,20,-10) 1050PROCpoint("SWU",-15,-20,10) 1060PROCpoint("SEU",15,-20,10) 1070PROCpoint("NWU",-15,20,10) 1080PROCpoint("NEU",15,20,10) 1090PROCface("SWD","SWU","SED",19):PROCface("SED","SWU","SEU",19) 1100PROCface("SED","SEU","NED",19):PROCface("NED","SEU","NEU",19) 1110PROCface("NED","NEU","NWD",19):PROCface("NWD","NEU","NWU",19) 1120PROCface("NWD","NWU","SWD",19):PROCface("SWD","NWU","SWU",19) 1130PROCface("SWU","NWU","SEU",19):PROCface("SEU","NWU","NEU",19) 1140PROCface("NWD","SWD","NED",19):PROCface("NED","SWD","SED",19) 1150PROCendshape 1160IFP%>shape%+shapelen%THENERROR255,"Shape isn't big enough" 1170ENDPROC 1180: 1190DEFPROCnewshape 1200pflag%=FALSE 1210nopoints%=0:nofaces%=0 1220pstart%=P%:P%+=4 1230ENDPROC 1240: 1250DEFPROCpoint(N$,X,Y,Z) 1260IFpflag%THENERROR255,"Points must come before faces" 1270!P%=X*(1<<AC%):P%!4=Y*(1<<AC%):P%!8=Z*(1<<AC%):P%+=12 1280P$(nopoints%)=N$:nopoints%+=1 1290ENDPROC 1300: 1310DEFPROCface(P1$,P2$,P3$,C%) 1320IFNOTpflag%THENpflag%=TRUE:fstart%=P%:P%+=4 1330P1%=FNpointno(P1$):P2%=FNpointno(P2$):P3%=FNpointno(P3$) 1340A1%=pstart%+4+P1%*12:A2%=pstart%+4+P2%*12:A3%=pstart%+4+P3%*12 1350NX=(A3%!4-A1%!4)*(A2%!8-A1%!8)-(A3%!8-A1%!8)*(A2%!4-A1%!4) 1360NY=(A3%!8-A1%!8)*(!A2%-!A1%)-(!A3%-!A1%)*(A2%!8-A1%!8) 1370NZ=(!A3%-!A1%)*(A2%!4-A1%!4)-(A3%!4-A1%!4)*(!A2%-!A1%) 1380F=(1<<VC%)/SQR(NX*NX+NY*NY+NZ*NZ)/SQR(3) 1390!P%=P1%:P%!4=P2%:P%!8=P3% 1400P%!12=NX*F:P%!16=NY*F:P%!20=NZ*F 1410P%!24=C%:P%+=28 1420nofaces%+=1 1430ENDPROC 1440: 1450DEFFNpointno(N$) 1460IFnopoints%=0THEN=-1 1470H%=-1:FORT%=0TOnopoints%-1 1480IFP$(T%)=N$THENH%=T%:T%=nopoints%-1 1490NEXT:=H% 1500: 1510DEFPROCendshape 1520!pstart%=nopoints%:!fstart%=nofaces% 1530ENDPROC 1540: 1550DEFPROCmap 1560CLS 1570view%!12=0:view%!16=0:view%!20=0:view%!24=0 1580!display%=vis%-1:MOUSETO640,512 1590REPEAT:MOUSEX%,Y%,Z%:MOUSETO640,512 1600PP%=pos%+32*!display% 1610!view%+=(X%-640)*(1<<PP%!24-4):view%!4+=(Y%-512)*(1<<PP%!24-4) 1620IFINKEY(-104)AND!display%<vis%-1THEN!display%+=1:REPEAT:UNTILNOTINKEY(-104) 1630IFINKEY(-103)AND!display%>0THEN!display%-=1:REPEAT:UNTILNOTINKEY(-103) 1640IFINKEY(-74)THEN!refresh%=TRUE 1650CALLlandgen% 1660CALLtestland% 1670UNTILINKEY(-99) 1680REPEAT:UNTILNOTINKEY(-99) 1690LX%=(!view%>>LC%)ANDlsize%-1:LY%=(view%!4>>LC%)ANDlsize%-1 1700view%!8=(land%!(8*(LX%+lsize%*LY%))<<LC%-SC%)+(1<<AC%+4) 1710ENDPROC 1720: 1730DEFPROCfly 1740B%=0 1750A%=0:V%=0:NT%=TIME 1760REPEAT:MOUSEX%,Y%,Z% 1770FT%=TIME-NT%:NT%+=FT%:IFFT%>100THENFT%=100 1780B%=B%+FT%*10AND&FFFF:A=2*PI*B%/&10000 1790testpos%!0=COS(A)*(1<<VC%):testpos%!4=SIN(A)*(1<<VC%) 1800testpos%!12=-testpos%!4:testpos%!16=testpos%!0 1810IFZ%=4THEN 1820view%!0+=view%!12<<AC%+5-VC% 1830view%!4+=view%!16<<AC%+5-VC% 1840view%!8+=view%!20<<AC%+5-VC% 1850ENDIF 1860A%=A%+(FT%*(640-X%)>>9-7)AND&FFFF:A=2*PI*A%/&10000 1870view%!12=COS(A)*(1<<VC%):view%!16=SIN(A)*(1<<VC%) 1880view%!20=(512-Y%)>>9-(VC%-1):view%!24=(640-X%)>>9-(VC%-1) 1890IFZ%=4THEN 1891V%=0 1900view%!0-=view%!12<<AC%+5-VC% 1910view%!4-=view%!16<<AC%+5-VC% 1920view%!8-=view%!20<<AC%+5-VC% 1930ENDIF 1940IFZ%=2THENV%-=(1<<AC%-10)*FT%:IFV%<0THENV%=0 1950IFZ%=1THENV%+=(1<<AC%-10)*FT%:IFV%>(1<<AC%)THENV%=(1<<AC%) 1960view%!0+=V%*FT%*view%!12>>VC% 1970view%!4+=V%*FT%*view%!16>>VC% 1980view%!8+=V%*FT%*view%!20>>VC% 1990CALLlandgen% 2000CALLdrawframe% 2010UNTILINKEY(-99) 2020REPEAT:UNTILNOTINKEY(-99) 2030ENDPROC 2040: 2050DEFPROCtestcol 2060SYS"OS_ReadVduVariables",vduvars%,scraddr% 2070V%=col%:FORT%=0TO31:S%=!scraddr%+(T%<<3):FORU%=0TO63 2080!S%=!V%:S%!4=!V% 2090S%!sclinc%=V%!4:S%!(sclinc%+4)=V%!4 2100S%!(sclinc%*2)=!V%:S%!(sclinc%*2+4)=!V% 2110S%!(sclinc%*3)=V%!4:S%!(sclinc%*3+4)=V%!4 2120S%+=sclinc%*4:V%+=8:NEXT, 2130ENDPROC 2140: 2150DEFPROCtesthor 2160FORT%=0TOwidth%-1:X%=T%*16:V%=hor%+T%*winc% 2170FORU%=0TOdepth% 2180Y%=959-2*!V%:LINEX%,Y%,X%+15,Y% 2190V%+=8:NEXT, 2200ENDPROC 2210: 2220DEFPROCtestpoints 2230U%=points%:FORT%=1TO8 2240POINT!U%>>(SCW%+DC%)-10,U%!4>>(SCH%+DC%)-10 2250U%+=8:NEXT 2260ENDPROC 2270: 2280DEFPROCtestmatrix 2290CALLdrawshape% 2300PROCplotblob(0,0,0,1<<AC%) 2310PROCplotblob(4<<AC%,0,0,1<<AC%-1) 2320PROCplotblob(0,4<<AC%,0,1<<AC%-1) 2330PROCplotblob(0,0,4<<AC%,1<<AC%-1) 2340ENDPROC 2350: 2360DEFPROCplotblob(X%,Y%,Z%,R%) 2370PY%=(X%*matrix%!4+Y%*matrix%!16+Z%*matrix%!28>>VC%)+matrix%!40 2380IFPY%<=0THENENDPROC 2390PX%=(X%*matrix%!0+Y%*matrix%!12+Z%*matrix%!24>>VC%)+matrix%!36 2400PZ%=(X%*matrix%!8+Y%*matrix%!20+Z%*matrix%!32>>VC%)+matrix%!44 2410F=1024/PY%:CIRCLEFILL640+F*PX%,512+F*PZ%,F*R% 2420ENDPROC 2430: 2440DEFFNadr(R%,A%,I%) 2450IF(P%AND3)<>0THENPRINT"Code isn't word aligned!":END 2460IF(T%AND2)=0THENP%+=I%<<2:=T% 2470LOCALN%,O%,H%,U%:H%=A%-(P%+8):N%=0:O%=15 2480FORU%=1TOI%:IFH%=0THEN 2490[OPT T%:MOV R%,O%:] 2500ELSEWHILE(H%AND3)=0:H%=H%>>2:N%+=2:ENDWHILE 2510IF(H%AND256)=0THEN 2520[OPT T%:ADD R%,O%,#(H%AND255)<<N%:]:H%-=H%AND255 2530ELSE[OPT T%:SUB R%,O%,#(256-H%AND255)<<N%:]:H%+=256-H%AND255 2540ENDIF 2550ENDIF:O%=R%:NEXT 2560IFH%<>0THENPRINT"Could not ADR to ";A%;" in ";I%;" instructions (R%=";R%;")":END 2570=T% 2580: 2590DEFFNregisterj(J%,N%) 2600J%!(N%<<2)=P%-J% 2610=T% 2620: 2630DEFPROCassemble 2640FORT%=0TO2STEP2:P%=code% 2650[OPT T% 2660: 2670.test% 2680EQUD -1:EQUD -1:EQUD -1:EQUD -1 2690EQUD -1:EQUD -1:EQUD -1:EQUD -1 2700EQUD -1:EQUD -1:EQUD -1:EQUD -1 2710EQUD -1:EQUD -1:EQUD -1:EQUD -1 2720: 2730.bank%:EQUD 1 2740: 2750.view% 2760EQUD 1<<BC%-1:EQUD 1<<BC%+BS%-1:EQUD 1<<AC%:; Position 2770EQUD 0:EQUD 1<<VC%:; Heading 2780EQUD 0:EQUD 0:; Pitch, Roll 2790: 2800.refresh%:EQUD -1 2810: 2820.landgen% 2830STMFD R13!,{R14} 2840BL calcpos% 2850BL copybase% 2860BL splitmap% 2870BL makeland% 2880LDMFD R13!,{PC} 2890: 2900.drawframe% 2910STMFD R13!,{R14} 2920BL calchor% 2930LDR R1,bank% 2940CMP R1,#1 2950MOVEQ R1,#2 2960MOVNE R1,#1 2970STR R1,bank% 2980MOV R0,#112 2990SWI "OS_Byte" 3000MOV R0,#19 3010SWI "OS_Byte" 3020OPT FNadr(0,vduvars%,2) 3030OPT FNadr(1,scraddr%,2) 3040SWI "OS_ReadVduVariables" 3050BL drawsky% 3060MOV R12,#depth% 3070SUB R12,R12,#1 3080.dloop% 3090OPT FNadr(1,dist%+12,2) 3100LDR R1,[R1,R12,ASL#4]:; Distance of strip in AC% 3110; Draw everything further away than R1 3120; *** Not done yet *** 3130BL drawstrip% 3140SUBS R12,R12,#1 3150BGE dloop% 3160BL drawshape% 3170MOV R0,#113 3180LDR R1,bank% 3190SWI "OS_Byte" 3200LDMFD R13!,{PC} 3210: 3220.calcpos% 3230STMFD R13!,{R14} 3240ADR R0,view% 3250LDMIA R0,{R6-R7,R8,R10-R11}:; Position,,Heading 3260OPT FNadr(12,pos%,2) 3270LDR R9,refresh% 3280MOV R8,#0 3290STR R8,refresh% 3300MOV R8,#MC% 3310.levloop% 3320LDMIA R12,{R2-R3} 3330MOV R0,R6,ASR R8 3340MOV R1,R7,ASR R8 3350SUB R0,R0,#msize%/2-1:; SW corner 3360SUB R1,R1,#msize%/2-1 3370BIC R0,R0,#1:; Make sure its even 3380BIC R1,R1,#1 3390MOV R4,R0,ASL R8 3400MOV R5,R1,ASL R8 3410CMP R9,#0 3420ADDNE R2,R0,#1<<30 3430STMIA R12,{R0-R1,R2-R3,R4-R5,R8} 3440ADD R12,R12,#32 3450ADD R8,R8,#1 3460CMP R8,#MC%+levels% 3470BLT levloop% 3480LDMFD R13!,{PC} 3490: 3500.copybase% 3510STMFD R13!,{R14} 3520OPT FNadr(12,base%,2) 3530OPT FNadr(11,map%+32*msize%*msize%*(levels%-1),3) 3540OPT FNadr(0,pos%+32*(levels%-1),2) 3550LDMIA R0,{R0-R1} 3560MOV R2,#32*bsize% 3570MLA R12,R1,R2,R12 3580MOV R10,#msize% 3590.nloop% 3600SUB R10,R10,#msize%<<16 3610.eloop% 3620CMP R0,#0 3630CMPGE R1,#0 3640BLT cbmakesea% 3650CMP R0,#bsize% 3660CMPLT R1,#bsize% 3670BGE cbmakesea% 3680ADD R2,R12,R0,ASL#5 3690LDMIA R2,{R2-R9} 3700STMIA R11!,{R2-R9} 3710B cbreturn% 3720: 3730.cbmakesea% 3740MOV R2,#0 3750MOV R3,#0 3760MVN R4,#1<<SC%-2:; Sea bed is -1/4 base square deep 3770MOV R5,#0 3780STMIA R11,{R2-R5} 3790ADD R11,R11,#32 3800.cbreturn% 3810ADD R0,R0,#1 3820ADDS R10,R10,#1<<16 3830BLE eloop% 3840SUB R0,R0,#msize% 3850ADD R1,R1,#1 3860ADD R12,R12,#32*bsize% 3870SUBS R10,R10,#1 3880BGT nloop% 3890LDMFD R13!,{PC} 3900: 3910.display%:EQUD levels%-1 3920: 3930.testmap% 3940STMFD R13!,{R14} 3950OPT FNadr(0,vduvars%,2) 3960ADD R1,R0,#scraddr%-vduvars% 3970SWI "OS_ReadVduVariables" 3980LDR R14,scraddr% 3990ADD R14,R14,#scheight%*sclinc% 4000ADD R14,R14,#sclinc%-4*msize% 4010OPT FNadr(12,map%,2) 4020LDR R0,display% 4030ADD R12,R12,R0,ASL#5+MS%+MS% 4040MOV R11,#msize% 4050.nloop% 4060SUB R14,R14,#sclinc%*4 4070SUB R11,R11,#msize%<<16 4080.eloop% 4090LDR R0,[R12,#8] 4100ADD R12,R12,#32 4110MOV R0,R0,LSR#SC%-2 4120AND R0,R0,#255 4130ORR R0,R0,R0,LSL#8 4140ORR R0,R0,R0,LSL#16 4150STR R0,[R14,#sclinc%*3] 4160STR R0,[R14,#sclinc%*2] 4170STR R0,[R14,#sclinc%] 4180STR R0,[R14],#4 4190ADDS R11,R11,#1<<16 4200BLE eloop% 4210SUB R14,R14,#4*msize% 4220SUBS R11,R11,#1 4230BGT nloop% 4240LDMFD R13!,{PC} 4250: 4260.splitmap% 4270STMFD R13!,{R14} 4280MOV R9,#levels%-1 4290.levloop% 4300; R9 is parent level 4310OPT FNadr(0,pos%,2) 4320ADD R0,R0,R9,ASL#5 4330LDMIA R0,{R4-R5}:; Parents origin 4340SUB R0,R0,#32 4350LDMIA R0,{R0-R1,R2-R3}:; New origin, Old origin 4360MOV R6,R0:; Current position 4370MOV R7,R1 4380MOV R8,#1:; Bottom to top 4390CMP R1,R3 4400CMPEQ R0,R2 4410BEQ smskiplev% 4420ADDLT R6,R6,#msize%-2 4430ADDLT R7,R7,#msize%-2 4440RSBLT R8,R8,#0:; Top to bottom 4450OPT FNadr(12,map%,3) 4460ADD R12,R12,R9,ASL#5+MS%+MS%:; Parent map 4470SUB R11,R12,#32*msize%*msize%:; New map 4480RSB R4,R4,R6,ASR#1:; Pos seen on parent 4490RSB R5,R5,R7,ASR#1 4500ADD R5,R4,R5,ASL#MS% 4510ADD R12,R12,R5,ASL#5 4520SUB R4,R6,R0:; Pos seen on new 4530SUB R5,R7,R1 4540ADD R5,R4,R5,ASL#MS% 4550ADD R11,R11,R5,ASL#5 4560SUB R6,R6,R2:; Pos seen on old 4570SUB R7,R7,R3 4580SUB R4,R0,R2:; New origin seen on old 4590SUB R5,R1,R3 4600ADD R5,R4,R5,ASL#MS% 4610MOV R10,#msize% 4620; At this point, the registers are used as: 4630; R12 is addr of pos on parent 4640; R11 is addr of pos on new 4650; R10 is msize% 4660; R9 is loop counter (less than 8 bits) 4670; R8 is direction 4680; R6-R7 are pos on old 4690; R5<<5 is offset from R11 to addr of pos on old 4700SUB R9,R9,#msize%<<8 4710.nsloop% 4720ADD R9,R9,#msize%<<20 4730.ewloop% 4740; If the square is not on old, then calculate it 4750ADR R14,smreturn% 4760CMP R6,#0 4770CMPGE R7,#0 4780BLT calcsq% 4790CMP R6,#msize% 4800CMPLT R7,#msize% 4810BGE calcsq% 4820; Copy it from its old position to its new position 4830STMFD R13!,{R5-R8} 4840ADD R8,R11,R5,ASL#5 4850LDMIA R8!,{R0-R7} 4860STMIA R11!,{R0-R7} 4870LDMIA R8!,{R0-R7} 4880STMIA R11!,{R0-R7} 4890ADD R8,R8,#32*msize% 4900ADD R11,R11,#32*msize% 4910LDMDB R8!,{R0-R7} 4920STMDB R11!,{R0-R7} 4930LDMDB R8!,{R0-R7} 4940STMDB R11!,{R0-R7} 4950SUB R11,R11,#32*msize% 4960LDMFD R13!,{R5-R8} 4970.smreturn% 4980ADD R6,R6,R8,ASL#1 4990ADD R11,R11,R8,ASL#5+1 5000ADD R12,R12,R8,ASL#5 5010SUBS R9,R9,#2<<20 5020BGT ewloop% 5030SUB R6,R6,R8,ASL#MS% 5040SUB R11,R11,R8,ASL#MS%+5 5050SUB R12,R12,R8,ASL#(MS%-1)+5 5060ADD R7,R7,R8,ASL#1 5070ADD R11,R11,R8,ASL#MS%+5+1 5080ADD R12,R12,R8,ASL#MS%+5 5090ADDS R9,R9,#2<<8 5100BLE nsloop% 5110.smskiplev% 5120SUBS R9,R9,#1 5130BGT levloop% 5140LDMFD R13!,{PC} 5150: 5160; Subdivides a map square to make 2x2 map squares 5170; R12 is old square 5180; R11 is new square 5190; R10 is msize 5200: 5210.calcsq% 5220STMFD R13!,{R0-R12,R14} 5230LDMIA R12,{R0,R1,R2,R5}:; Old Type, Water level, Height, Random 5240; Concoct a random seed 5250ADD R8,R2,R2,ROR#17 5260ADD R8,R8,R8,ROR#10 5270ADD R8,R8,R8,ROR#6 5280ADD R12,R12,#8 5290SUB R3,R12,#32 5300LDMIA R3,{R3,R6}:; W Height, Random 5310SUB R4,R12,R10,ASL#5 5320LDMIA R4,{R4,R7}:; S Height, Random 5330ADD R4,R4,R2,ASL#1 5340ADD R7,R7,R5,ASL#1 5350ADD R3,R3,R4 5360ADD R6,R6,R7 5370MOV R3,R3,ASR#2-1 5380MOV R6,R6,ASR#2 5390ADD R8,R8,R8,ROR#4 5400MOV R9,R8,LSR#32-6 5410MUL R9,R5,R9 5420SUB R9,R9,R5,ASL#5 5430ADD R3,R3,R9,ASR#5-1 5440ADD R8,R8,R8,ROR#4 5450ADDS R6,R6,R8,ASR#31-(SC%-5) 5460MOVLT R6,#0 5470STMIA R11,{R0,R1,R3,R6}:; New SW Type etc.. 5480ADD R11,R11,#32 5490ADD R3,R12,#32 5500LDMIA R3,{R3,R6}:; E Height, Random 5510ADD R4,R3,R4 5520ADD R7,R6,R7 5530MOV R4,R4,ASR#2-1 5540MOV R7,R7,ASR#2 5550ADD R8,R8,R8,ROR#4 5560MOV R9,R8,LSR#32-6 5570MUL R9,R5,R9 5580SUB R9,R9,R5,ASL#5 5590ADD R4,R4,R9,ASR#5-1 5600ADD R8,R8,R8,ROR#4 5610ADDS R7,R7,R8,ASR#31-(SC%-5) 5620MOVLT R7,#0 5630STMIA R11,{R0,R1,R4,R7}:; New SE Type etc.. 5640ADD R11,R11,R10,ASL#5 5650ADD R4,R12,R10,ASL#5 5660LDMIA R4,{R4,R7}:; N Height, Random 5670ADD R4,R4,R2,ASL#1 5680ADD R7,R7,R5,ASL#1 5690ADD R3,R3,R4 5700ADD R6,R6,R7 5710MOV R3,R3,ASR#2-1 5720MOV R6,R6,ASR#2 5730ADD R8,R8,R8,ROR#4 5740MOV R9,R8,LSR#32-6 5750MUL R9,R5,R9 5760SUB R9,R9,R5,ASL#5 5770ADD R3,R3,R9,ASR#5-1 5780ADD R8,R8,R8,ROR#4 5790ADDS R6,R6,R8,ASR#31-(SC%-5) 5800MOVLT R6,#0 5810STMIA R11,{R0,R1,R3,R6}:; New NE Type etc.. 5820SUB R11,R11,#32 5830SUB R3,R12,#32 5840LDMIA R3,{R3,R6}:; W Height, Random again 5850ADD R4,R3,R4 5860ADD R7,R6,R7 5870MOV R4,R4,ASR#2-1 5880MOV R7,R7,ASR#2 5890ADD R8,R8,R8,ROR#4 5900MOV R9,R8,LSR#32-6 5910MUL R9,R5,R9 5920SUB R9,R9,R5,ASL#5 5930ADD R4,R4,R9,ASR#5-1 5940ADD R8,R8,R8,ROR#4 5950ADDS R7,R7,R8,ASR#31-(SC%-5) 5960MOVLT R7,#0 5970STMIA R11,{R0,R1,R4,R7}:; New NW Type etc.. 5980SUB R11,R11,R10,ASL#5 5990LDMFD R13!,{R0-R12,PC} 6000: 6010.testland% 6020STMFD R13!,{R14} 6030OPT FNadr(0,vduvars%,2) 6040ADD R1,R0,#scraddr%-vduvars% 6050SWI "OS_ReadVduVariables" 6060LDR R14,scraddr% 6070ADD R14,R14,#scheight%*sclinc% 6080OPT FNadr(12,land%+4,3) 6090LDR R0,display% 6100ADD R12,R12,R0,ASL#3+LS%+LS% 6110OPT FNadr(1,pos%+24,2) 6120LDR R1,[R1,R0,ASL#5] 6130OPT FNadr(2,view%,2) 6140LDMIA R2,{R2-R3} 6150MOV R2,R2,ASR R1 6160MOV R3,R3,ASR R1 6170SUB R2,R2,#msize%/2-1:; SW corner of visible area 6180SUB R3,R3,#msize%/2-1 6190MOV R2,R2,ASL#ML% 6200MOV R3,R3,ASL#ML% 6210OPT FNadr(10,col%,2) 6220MOV R11,#lsize%-8 6230.nloop% 6240SUB R14,R14,#sclinc%*2 6250SUB R11,R11,#lsize%-8<<16 6260.eloop% 6270AND R0,R2,#lsize%-1 6280AND R1,R3,#lsize%-1 6290ADD R0,R0,R1,ASL#LS% 6300LDR R0,[R12,R0,ASL#3] 6310ADD R0,R10,R0,ASL#3 6320LDMIA R0,{R0-R1}:; Dither pattern 6330MOV R4,R0,LSL#16 6340MOV R5,R1,LSL#16 6350ADD R2,R2,#1 6360AND R0,R2,#lsize%-1 6370AND R1,R3,#lsize%-1 6380ADD R0,R0,R1,ASL#LS% 6390LDR R0,[R12,R0,ASL#3] 6400ADD R0,R10,R0,ASL#3 6410LDMIA R0,{R0-R1}:; Dither pattern 6420ORR R4,R4,R0,LSR#16 6430ORR R5,R5,R1,LSR#16 6440MOV R4,R4,ROR#16 6450MOV R5,R5,ROR#16 6460STR R4,[R14,#sclinc%] 6470STR R5,[R14],#4 6480ADD R2,R2,#1 6490ADDS R11,R11,#2<<16 6500BLE eloop% 6510SUB R2,R2,#lsize%-8 6520SUB R14,R14,#2*(lsize%-8) 6530ADD R3,R3,#1 6540SUB R14,R14,#sclinc%*2 6550SUB R11,R11,#lsize%-8<<16 6560.eloop% 6570AND R0,R2,#lsize%-1 6580AND R1,R3,#lsize%-1 6590ADD R0,R0,R1,ASL#LS% 6600LDR R0,[R12,R0,ASL#3] 6610ADD R0,R10,R0,ASL#3 6620LDMIA R0,{R0-R1}:; Dither pattern 6630MOV R4,R0,LSR#16 6640MOV R5,R1,LSR#16 6650ADD R2,R2,#1 6660AND R0,R2,#lsize%-1 6670AND R1,R3,#lsize%-1 6680ADD R0,R0,R1,ASL#LS% 6690LDR R0,[R12,R0,ASL#3] 6700ADD R0,R10,R0,ASL#3 6710LDMIA R0,{R0-R1}:; Dither pattern 6720ORR R4,R4,R0,LSL#16 6730ORR R5,R5,R1,LSL#16 6740STR R4,[R14,#sclinc%] 6750STR R5,[R14],#4 6760ADD R2,R2,#1 6770ADDS R11,R11,#2<<16 6780BLE eloop% 6790SUB R2,R2,#lsize%-8 6800SUB R14,R14,#2*(lsize%-8) 6810ADD R3,R3,#1 6820SUBS R11,R11,#2 6830BGT nloop% 6840LDMFD R13!,{PC} 6850: 6860.makeland% 6870STMFD R13!,{R14} 6880MOV R7,#vis%-1 6890.levloop% 6900OPT FNadr(0,pos%,2) 6910ADD R0,R0,R7,ASL#5 6920LDMIA R0,{R0-R1,R2-R3,R4-R5,R9}:; New origin, Old origin,, Scale 6930CMP R0,R2 6940CMPEQ R1,R3 6950BEQ mlendlev% 6960OPT FNadr(12,map%,3) 6970ADD R12,R12,R7,ASL#5+MS%+MS% 6980OPT FNadr(8,land%,3) 6990ADD R8,R8,R7,ASL#3+LS%+LS% 7000MOV R10,#msize% 7010SUB R7,R7,#msize%-1<<8 7020.nloop% 7030ADD R7,R7,#msize%-1<<20 7040.eloop% 7050AND R4,R0,#(1<<MS%)-1 7060AND R5,R1,#(1<<MS%)-1 7070ADD R11,R8,R4,ASL#ML%+3 7080ADD R11,R11,R5,ASL#ML%+3+LS% 7090ADR R14,mlreturn% 7100SUBS R4,R0,R2 7110SUBGES R5,R1,R3 7120BLT calclsq% 7130CMP R4,#msize%-1 7140CMPLT R5,#msize%-1 7150BGE calclsq% 7160.mlreturn% 7170ADD R0,R0,#1 7180ADD R12,R12,#32 7190SUBS R7,R7,#1<<20 7200BGE eloop% 7210SUB R0,R0,#msize%-1 7220SUB R12,R12,#32*(msize%-1) 7230ADD R1,R1,#1 7240ADD R12,R12,#32*msize% 7250ADDS R7,R7,#1<<8 7260BLT nloop% 7270.mlendlev% 7280SUBS R7,R7,#1 7290BGE levloop% 7300LDMFD R13!,{PC} 7310: 7320; Subdivides a map square to make 4x4 land squares (ML%=2) 7330; R12 is old square 7340; R11 is new square 7350; R10 is msize 7360; R9 is scale (log2 size of map square in world coords) 7370: 7380.calclsq% 7390STMFD R13!,{R0-R12,R14} 7400SUB R9,R9,#SC%:; Log2 square coord in world coords 7410; Get the heights 7420LDMIB R12,{R0,R2,R8}:; Water level, SW height (in square coords), rnd 7430ADD R12,R12,#8 7440ADD R3,R12,#32 7450LDMIA R3,{R3,R7}:; SE height, rnd 7460ADD R8,R8,R7 7470ADD R12,R12,R10,ASL#5 7480LDMIA R12,{R4,R7}:; NW height, rnd 7490ADD R8,R8,R7 7500ADD R5,R12,#32 7510LDMIA R5,{R5,R7}:; NE height, rnd 7520ADD R8,R8,R7 7530; Calculate average height 7540ADD R1,R2,R3 7550ADD R1,R1,R4 7560ADD R1,R1,R5 7570MOV R1,R1,ASR#2 7580; Calculate land base colour 7590MOV R7,R1,ASL R9:; Height in AC% 7600ADD R7,R7,R8,ASL#(AC%+9)-(SC%+1):; Bumpy ground seems high 7610MOV R8,#5<<5:; Grass 7620CMP R7,#128<<AC% 7630MOVGE R8,#7<<5:; Bracken 7640CMP R7,#256<<AC% 7650MOVGE R8,#9<<5:; Heather 7660CMP R7,#384<<AC% 7670MOVGE R8,#11<<5:; Rough grass 7680CMP R7,#512<<AC% 7690MOVGE R8,#13<<5:; Rocks 7700CMP R7,#640<<AC% 7710MOVGE R8,#15<<5:; Snow 7720SUB R7,R5,R2:; SW facing slope<<3 7730MOV R7,R7,ASR#SC%-4:; Approx range +-32 7740ADDS R7,R7,#24 7750MOVLT R7,#0 7760CMP R7,#60 7770MOVGT R7,#60 7780ADD R8,R8,R7 7790; Calculate water colour 7800SUBS R7,R0,R1 7810MOVLT R7,#0 7820MOV R7,R7,ASL R9 7830MOV R7,R7,ASR#AC%-1:; Depth in half metres 7840MOV R1,#0<<6:; Sea blue 7850CMP R7,#64 7860MOVGE R7,R7,ASR#4 7870ADDGE R1,R1,#16 7880CMP R7,#16 7890MOVGE R7,R7,ASR#2 7900ADDGE R1,R1,#8 7910CMP R7,#8 7920MOVGE R7,R7,ASR#1 7930ADDGE R1,R1,#4 7940ADD R1,R1,R7 7950CMP R1,#31 7960MOVGT R1,#31 7970; Generate a random seed 7980EOR R14,R2,R5,ROR#17 7990EOR R14,R14,R3,ROR#13 8000EOR R14,R14,R4,ROR#10 8010ADD R14,R14,R14,ROR#6 8020; Calculate gradients 8030SUB R4,R4,R2 8040SUB R5,R5,R3 8050ADD R2,R4,R2,ASL#3 8060ADD R3,R5,R3,ASL#3 8070SUB R3,R3,R2:; dH/dE<<3 8080SUB R5,R5,R4:; d2H/dNdE 8090ADD R2,R3,R2,ASL#3:; Height<<6 8100ADD R4,R5,R4,ASL#3:; dH/dN<<3 8110; At this point, registers are used as 8120; R0,R1 are water level, water colour 8130; R2-R5 are gradients 8140; R8 is land colour 8150; R9-R12 as on entry 8160; R14 is rnd seed 8170MOV R9,#4 8180.nloop% 8190]:FORU%=0TO3:[OPT T% 8200MOV R6,R2,ASR#6-2 8210ADD R14,R14,R14,ROR#2 8220ADD R7,R8,R14,LSR#32-2 8230CMP R6,R0,ASL#2 8240MOVLT R6,R0,ASL#2 8250MOVLT R7,R1 8260STMIA R11!,{R6,R7} 8270ADD R2,R2,R3,ASL#1 8280]:NEXT:[OPT T% 8290SUB R11,R11,#8*4 8300SUB R2,R2,R3,ASL#1+2 8310ADD R11,R11,R10,ASL#3+ML% 8320ADD R2,R2,R4,ASL#1 8330ADD R3,R3,R5,ASL#1 8340SUBS R9,R9,#1 8350BGT nloop% 8360LDMFD R13!,{R0-R12,PC} 8370: 8380.calchor% 8390STMFD R13!,{R14} 8400MOV R12,#0 8410.dloop% 8420OPT FNadr(0,dist%,2) 8430ADD R0,R0,R12,ASL#4 8440LDMIA R0,{R0,R8,R9}:; Level, distance in SC%, (1<<21)/R1 8450OPT FNadr(10,land%,3) 8460ADD R10,R10,R0,ASL#3+LS%+LS% 8470OPT FNadr(7,pos%+24,2) 8480LDR R7,[R7,R0,ASL#5] 8490SUB R7,R7,#ML%:; Log2 size of a square in AC% 8500OPT FNadr(0,view%,2) 8510LDMIA R0,{R0-R1,R2,R3-R4,R5,R6}:; Position, height, heading, pitch, roll 8520MUL R3,R8,R3:; Heading in SC%+VC% 8530MUL R4,R8,R4 8540MUL R5,R8,R5:; Pitch, Roll in SC%+VC% 8550MUL R6,R8,R6 8560RSB R11,R7,#EC% 8570MOV R0,R0,ASL R11:; Position in EC% 8580MOV R1,R1,ASL R11 8590SUB R11,R7,#SC% 8600MOV R2,R2,ASR R11:; Height in SC% 8610ADD R0,R0,R3,ASL#EC%-(SC%+VC%):; Move forwards 8620ADD R1,R1,R4,ASL#EC%-(SC%+VC%) 8630ADD R2,R2,R5,ASR#VC% 8640MOV R3,R3,ASR#WW% 8650MOV R4,R4,ASR#WW% 8660MOV R5,R3,ASL#EC%-(SC%+VC%):; Right vector (in EC%, SC%) 8670RSB R5,R5,#0 8680MOV R4,R4,ASL#EC%-(SC%+VC%) 8690MOV R6,R6,ASR#WW%+VC% 8700SUB R0,R0,R4,ASL#WW%-1:; Move left 1/2 screen except 1/2 pixel 8710SUB R1,R1,R5,ASL#WW%-1 8720SUB R2,R2,R6,ASL#WW%-1 8730SUB R0,R0,R4,ASL#WW%-3 8740SUB R1,R1,R5,ASL#WW%-3 8750SUB R2,R2,R6,ASL#WW%-3 8760ADD R0,R0,R4,ASR#1 8770ADD R1,R1,R5,ASR#1 8780ADD R2,R2,R6,ASR#1 8790ADD R2,R2,R8,ASR#1:; Up 1/2 screen 8810ADD R2,R2,R8,ASR#HH%+1:; Rounding 8820OPT FNadr(11,hor%,3) 8830ADD R11,R11,R12,ASL#3 8840; At this point, the registers are used as follows: 8850; R0-R1,R2 are top left of screen, with position in EC% and height in SC% 8860; R4-R5,R6 is right vector, also in EC% and SC% 8870; R9 is (1<<21) / (distance in SC%) 8880; R10 is base address of land for this level 8890; R11 is hor for this distance 8900; R12 is depth 8910SUB R0,R0,#loff%<<EC%:; Land is offset 8920SUB R1,R1,#loff%<<EC% 8930SUB R12,R12,#width%<<16 8940.wloop% 8950MOV R7,R0,LSR#EC% 8960MOV R8,R1,LSR#EC% 8970ADD R7,R7,R8,ASL#LS% 8980ADD R7,R10,R7,ASL#3 8990LDMIA R7,{R3,R7}:; Land height (SC%), colour number 9000RSBS R3,R3,R2:; Height below top of screen 9010MOVLT R3,#0 9020MUL R3,R9,R3 9030MOV R8,R3,LSR#20-HH% 9040LDR R3,[R11] 9050CMP R8,R3 9060MOVGT R8,R3 9070STMIA R11,{R3,R7,R8}:; Bottom, colour number, top in pixels 9080ADD R11,R11,#winc% 9090ADD R0,R0,R4 9100ADD R1,R1,R5 9110ADD R2,R2,R6 9120ADDS R12,R12,#1<<16 9130BLT wloop% 9140ADD R12,R12,#1 9150CMP R12,#depth% 9160BLT dloop% 9170LDMFD R13!,{PC} 9180: 9190.vduvars%:EQUD 148:EQUD -1 9200.scraddr%:EQUD -1 9210: 9220; R12 is depth of strip to draw 9230; R0-R11 corrupted 9240: 9250.drawstrip% 9260STMFD R13!,{R12,R14} 9270LDR R14,scraddr% 9280OPT FNadr(11,hor%,3) 9290ADD R11,R11,R12,ASL#3 9300OPT FNadr(10,col%,2) 9310SUB R12,R12,#width%<<16 9320.wloop% 9330LDMIA R11,{R0,R1,R2}:; Bottom, colour, top 9340SUBS R0,R0,R2:; Number of pixels to draw 9350BLE dsendw% 9360ADD R9,R14,R2,ASL#SCW%+1 9370ADD R9,R9,R2,ASL#SCW%-2+1 9380ADD R1,R10,R1,ASL#3 9390LDMIA R1,{R6,R7} 9400TST R2,#1 9410MOVNE R6,R6,ROR#16 9420MOVNE R7,R7,ROR#16 9430.yloop% 9440]:CASESCW%-WW%OF 9450WHEN3: 9460[OPT T% 9470MOV R8,R6 9480STMIA R9,{R6,R8} 9490ADD R9,R9,#sclinc% 9500MOV R8,R7 9510STMIA R9,{R7,R8} 9520ADD R9,R9,#sclinc% 9530MOV R6,R6,ROR#16 9540MOV R7,R7,ROR#16 9550] 9560WHEN2: 9570[OPT T% 9580STR R6,[R9],#sclinc% 9590STR R7,[R9],#sclinc% 9600MOV R6,R6,ROR#16 9610MOV R7,R7,ROR#16 9620] 9630OTHERWISE:ERROR255,"Only WW%=6 is supported" 9640ENDCASE:[OPT T% 9650SUBS R0,R0,#1 9660BGT yloop% 9670.dsendodd% 9680.dsendw% 9690ADD R11,R11,#winc% 9700ADD R14,R14,#1<<SCW%-WW% 9710ADDS R12,R12,#1<<16 9720BLT wloop% 9730LDMFD R13!,{R12,PC} 9740: 9750.drawsky% 9760STMFD R13!,{R14} 9770LDR R14,scraddr% 9780OPT FNadr(12,col%+8*(1<<5),2) 9790OPT FNadr(0,view%+20,2) 9800LDMIA R0,{R0,R1}:; Pitch, Roll 9810MOV R0,R0,ASL#24-VC% 9820MOV R1,R1,ASL#24-SKW%-VC% 9830SUB R0,R0,R1,ASL#SKW%-1:; Left 1/2 screen except 1/2 pixel 9840SUB R0,R0,R1,ASL#SKW%-3 9850ADD R0,R0,R1,ASR#1 9860ADD R0,R0,#1<<24-1:; Up 1/2 screen except 1/2 pixel 9870SUB R0,R0,#1<<24-SKH%-1 9880ADD R0,R0,R0,ASL#1 9890ADD R1,R1,R1,ASL#1 9900MOV R11,#skwidth% 9910.wloop% 9920SUB R11,R11,#skheight%<<16 9930.hloop% 9940ADD R4,R0,R1 9950ADD R6,R4,R1 9960ADD R8,R6,R1 9970MOV R2,R0,ASR#26-7 9980MOV R4,R4,ASR#26-7 9990MOV R6,R6,ASR#26-7 10000MOV R8,R8,ASR#26-7 10010]:FORU%=2TO8STEP2:[OPT T% 10020ADDS U%,U%,#32 10030MOVLT U%,#0 10040CMP U%,#127 10050MOVGT U%,#127 10060ADD U%,R12,U%,ASL#3 10070LDMIA U%,{U%-(U%+1)} 10080]:NEXT:[OPT T% 10090STMIA R14,{R2,R4,R6,R8} 10100ADD R14,R14,#sclinc% 10110STMIA R14,{R3,R5,R7,R9} 10120ADD R14,R14,#sclinc% 10130]:FORU%=2TO9:[OPT T% 10140MOV U%,U%,ROR#16 10150]:NEXT:[OPT T% 10160STMIA R14,{R2,R4,R6,R8} 10170ADD R14,R14,#sclinc% 10180STMIA R14,{R3,R5,R7,R9} 10190ADD R14,R14,#sclinc% 10200SUB R0,R0,#3<<24-SKH%:; Down 1 pixel 10210ADDS R11,R11,#1<<16 10220BLE hloop% 10230ADD R0,R0,#3<<24:; Up 1 screen 10240SUB R14,R14,#scheight%*sclinc% 10250ADD R0,R0,R1,ASL#2:; Right 2 pixels 10260ADD R14,R14,#4<<SCW%-SKW% 10270SUBS R11,R11,#4 10280BGT wloop% 10290LDMFD R13!,{PC} 10300: 10310; Draws any triangle 10320; R0-R1, R2-R3, R4-R5 are corners 10330; Everything preserved 10340: 10350.plottri% 10360STMFD R13!,{R0-R12,R14} 10370; Sort them into ascending order 10380CMP R3,R1 10390BGT pt13% 10400.pt31% 10410CMP R5,R1 10420BGT pt315% 10430CMP R5,R3 10440BGT pt351% 10450.pt531% 10460MOV R6,R0 10470MOV R0,R4 10480MOV R4,R6 10490MOV R6,R1 10500MOV R1,R5 10510MOV R5,R6 10520B pt135% 10530: 10540.pt351% 10550MOV R6,R0 10560MOV R0,R2 10570MOV R2,R4 10580MOV R4,R6 10590MOV R6,R1 10600MOV R1,R3 10610MOV R3,R5 10620MOV R5,R6 10630B pt135% 10640: 10650.pt315% 10660MOV R6,R0 10670MOV R0,R2 10680MOV R2,R6 10690MOV R6,R1 10700MOV R1,R3 10710MOV R3,R6 10720B pt135% 10730: 10740.pt13% 10750CMP R5,R3 10760BGT pt135% 10770CMP R5,R1 10780BGT pt153% 10790.pt513% 10800MOV R6,R0 10810MOV R0,R4 10820MOV R4,R2 10830MOV R2,R6 10840MOV R6,R1 10850MOV R1,R5 10860MOV R5,R3 10870MOV R3,R6 10880B pt135% 10890: 10900.pt153% 10910MOV R6,R2 10920MOV R2,R4 10930MOV R4,R6 10940MOV R6,R3 10950MOV R3,R5 10960MOV R5,R6 10970.pt135% 10980; Calculate long gradient 10990MOV R8,#1 11000SUB R7,R5,R1 11010SUBS R6,R4,R0 11020RSBLT R8,R8,#0 11030RSBLT R6,R6,#0 11040MOV R9,#0 11050]:FORU%=9TO1STEP-1:[OPT T% 11060CMP R7,R6,ASR#U% 11070SUBLE R6,R6,R7,ASL#U% 11080ADDLE R9,R9,R8,ASL#U%+DC% 11090]:NEXT:[OPT T% 11100CMP R6,R7 11110SUBGE R6,R6,R7 11120ADDGE R9,R9,R8,ASL#DC% 11130]:FORU%=DC%-1TO1STEP-1:[OPT T% 11140RSBS R6,R7,R6,ASL#1 11150ADDLT R6,R6,R7 11160ADDGE R9,R9,R8,ASL#U% 11170]:NEXT:[OPT T% 11180RSBS R6,R7,R6,ASL#1 11190ADDGE R9,R9,R8 11200; Calculate bottom short gradient 11210MOV R8,#1 11220SUB R7,R3,R1 11230SUBS R6,R2,R0 11240RSBLT R8,R8,#0 11250RSBLT R6,R6,#0 11260MOV R10,#0 11270]:FORU%=9TO1STEP-1:[OPT T% 11280CMP R7,R6,ASR#U% 11290SUBLE R6,R6,R7,ASL#U% 11300ADDLE R10,R10,R8,ASL#U%+DC% 11310]:NEXT:[OPT T% 11320CMP R6,R7 11330SUBGE R6,R6,R7 11340ADDGE R10,R10,R8,ASL#DC% 11350]:FORU%=DC%-1TO1STEP-1:[OPT T% 11360RSBS R6,R7,R6,ASL#1 11370ADDLT R6,R6,R7 11380ADDGE R10,R10,R8,ASL#U% 11390]:NEXT:[OPT T% 11400RSBS R6,R7,R6,ASL#1 11410ADDGE R10,R10,R8 11420; Calculate top short gradient 11430MOV R8,#1 11440SUB R7,R5,R3 11450SUBS R6,R4,R2 11460RSBLT R8,R8,#0 11470RSBLT R6,R6,#0 11480MOV R4,#0 11490]:FORU%=9TO1STEP-1:[OPT T% 11500CMP R7,R6,ASR#U% 11510SUBLE R6,R6,R7,ASL#U% 11520ADDLE R4,R4,R8,ASL#U%+DC% 11530]:NEXT:[OPT T% 11540CMP R6,R7 11550SUBGE R6,R6,R7 11560ADDGE R4,R4,R8,ASL#DC% 11570]:FORU%=DC%-1TO1STEP-1:[OPT T% 11580RSBS R6,R7,R6,ASL#1 11590ADDLT R6,R6,R7 11600ADDGE R4,R4,R8,ASL#U% 11610]:NEXT:[OPT T% 11620RSBS R6,R7,R6,ASL#1 11630ADDGE R4,R4,R8 11640; Calculate bottom, middle, top in pixels 11650; Also corrects x to nearest vertical pixel 11660ADD R6,R5,#1<<DC%-1 11670MOV R6,R6,ASR#DC% 11680ADD R5,R3,#1<<DC%-1 11690MOV R5,R5,ASR#DC% 11700RSB R3,R3,R5,ASL#DC% 11710ADD R3,R3,#1<<DC%-1 11720MOV R3,R3,ASR#DC%-6 11730MUL R7,R3,R4 11740ADD R2,R2,R7,ASR#6 11750STMFD R13!,{R2,R4,R6}:; top short x,dx, top in pixels 11760ADD R4,R1,#1<<DC%-1 11770MOV R4,R4,ASR#DC% 11780RSB R2,R1,R4,ASL#DC% 11790ADD R2,R2,#1<<DC%-1 11800MOV R2,R2,ASR#DC%-6 11810MUL R3,R2,R10 11820ADD R1,R0,R3,ASR#6 11830MUL R3,R2,R9 11840ADD R0,R0,R3,ASR#6 11850MOV R2,R9 11860MOV R3,R10 11870; At this point registers are used as... 11880; R0,R2 are long x,dx 11890; R1,R3 are bottom short x,dx 11900; R4,R5 are bottom, middle in pixels 11910; top short x,dx and top in pixels are on stack 11920RSBS R8,R4,#0 11930MLAGT R0,R8,R2,R0 11940MLAGT R1,R8,R3,R1 11950ADDGT R4,R4,R8 11960OPT FNadr(7,col%,2) 11970ADD R7,R7,R11,ASL#3 11980LDMIA R7,{R7,R11} 11990TST R4,#2 12000MOVNE R7,R7,ROR#16 12010MOVNE R11,R11,ROR#16 12020TST R4,#1 12030MOVNE R8,R11 12040MOVNE R11,R7 12050MOVNE R7,R8,ROR#16 12060LDR R12,scraddr% 12070RSB R8,R4,#scheight% 12080ADD R12,R12,R8,ASL#SCW% 12090ADD R12,R12,R8,ASL#SCW%-2 12100MOV R6,R5 12110CMP R6,#scheight% 12120MOVGT R6,#scheight% 12130SUBS R4,R6,R4 12140SUBLE R6,R6,R4:; R6 = old R4 12150BLE ptnobottom% 12160.yloop% 12170SUB R12,R12,#sclinc% 12180BL drawline% 12190ADD R0,R0,R2 12200ADD R1,R1,R3 12210MOV R8,R11 12220MOV R11,R7 12230MOV R7,R8,ROR#16 12240SUBS R4,R4,#1 12250BGT yloop% 12260.ptnobottom% 12270LDMFD R13!,{R1,R3,R4}:; short top x,dx, top in pixels 12280CMP R6,#0 12290SWILT &141 12300SUBS R8,R6,R5 12310MLAGT R1,R8,R3,R1 12320CMP R4,#scheight% 12330MOVGT R4,#scheight% 12340SUBS R4,R4,R6 12350BLE ptnotop% 12360.yloop% 12370SUB R12,R12,#sclinc% 12380BL drawline% 12390ADD R0,R0,R2 12400ADD R1,R1,R3 12410MOV R8,R11 12420MOV R11,R7 12430MOV R7,R8,ROR#16 12440SUBS R4,R4,#1 12450BGT yloop% 12460.ptnotop% 12470LDMFD R13!,{R0-R12,PC} 12480: 12490; Draws a horizontal line 12500; R0 is left end, R1 is right end, both in DC% 12510; R12 is screen line address 12520; R11 is colour 12530; Corrupts R0-R2,R8-R12 12540: 12550.drawline% 12560STMFD R13!,{R0-R2,R8-R12,R14} 12570CMP R0,R1 12580MOVGT R2,R0 12590MOVGT R0,R1 12600MOVGT R1,R2 12610CMP R0,#0<<DC% 12620MOVLT R0,#0<<DC% 12630CMP R1,#scwidth%<<DC% 12640MOVGT R1,#scwidth%<<DC% 12650MOV R0,R0,ASR#DC% 12660MOV R1,R1,ASR#DC% 12670CMP R0,R1 12680LDMGEFD R13!,{R0-R2,R8-R12,PC} 12690MOV R2,R0,ASR#2 12700ADD R12,R12,R2,ASL#2 12710CMP R2,R1,ASR#2 12720BEQ dhsmall% 12730MOV R8,R11 12740MOV R9,R11 12750MOV R10,R11 12760SUB R1,R1,R0 12770AND R0,R0,#3 12780ADR R2,dhleftj% 12790LDR R0,[R2,R0,ASL#2] 12800ADD PC,R2,R0 12810: 12820.dhleftj% 12830]:FORU%=0TO3:[OPT T% 12840EQUD dhend%-dhleftj% 12850]:NEXT:[OPT T% 12860: 12870OPT FNregisterj(dhleftj%,0) 12880.dhmiddle% 12890MOV R2,R1,ASR#4 12900AND R1,R1,#15 12910ADR R0,dhrightj% 12920LDR R1,[R0,R1,ASL#2] 12930CMP R2,#0 12940ADDLE PC,R0,R1 12950.xloop% 12960STMIA R12!,{R8-R11} 12970SUBS R2,R2,#1 12980BGT xloop% 12990ADD PC,R0,R1 13000: 13010]:FORU%=1TO3:[OPT T% 13020OPT FNregisterj(dhleftj%,U%) 13030LDR R2,[R12] 13040MOV R2,R2,LSL#4-U%<<3 13050ORR R2,R2,R11,LSR#U%<<3 13060MOV R2,R2,ROR#4-U%<<3 13070STR R2,[R12],#4 13080SUB R1,R1,#4-U% 13090B dhmiddle% 13100]:NEXT:[OPT T% 13110: 13120.dhrightj% 13130]:FORU%=0TO15:[OPT T% 13140EQUD dhend%-dhrightj% 13150]:NEXT:[OPT T% 13160: 13170]:FORU%=4TO15STEP4:W%=8+(U%>>2):[OPT T% 13180OPT FNregisterj(dhrightj%,U%) 13190STMIA R12,{R8-(W%-1)} 13200LDMFD R13!,{R0-R2,R8-R12,PC} 13210]:NEXT:[OPT T% 13220: 13230]:FORU%=0TO15STEP4:FORV%=1TO3:S%=U%+V%:W%=8+(U%>>2):[OPT T% 13240OPT FNregisterj(dhrightj%,S%) 13250LDR R0,[R12,#U%] 13260MOV R0,R0,LSR#V%<<3 13270ORR R0,R0,W%,LSL#4-V%<<3 13280MOV W%,R0,ROR#4-V%<<3 13290STMIA R12,{R8-W%} 13300LDMFD R13!,{R0-R2,R8-R12,PC} 13310]:NEXT,:[OPT T% 13320: 13330.dhsmall% 13340AND R0,R0,#3 13350AND R1,R1,#3 13360ADD R1,R0,R1,ASL#2 13370ADR R0,dhsmallj% 13380LDR R1,[R0,R1,ASL#2] 13390ADD PC,R0,R1 13400: 13410.dhsmallj% 13420]:FORV%=0TO3:FORU%=0TO3:[OPT T% 13430EQUD dhend%-dhsmallj% 13440]:NEXT,:[OPT T% 13450: 13460]:FORU%=0TO2:FORV%=U%+1TO3:[OPT T% 13470OPT FNregisterj(dhsmallj%,U%+(V%<<2)) 13480LDR R0,[R12] 13490]:IFU%>0THEN 13500[OPT T% 13510MOV R0,R0,ROR#U%<<3 13520MOV R11,R11,ROR#U%<<3 13530] 13540ENDIF:[OPT T% 13550MOV R0,R0,LSR#V%-U%<<3 13560ORR R0,R0,R11,LSL#4-(V%-U%)<<3 13570MOV R0,R0,ROR#4-V%<<3 13580STR R0,[R12] 13590LDMFD R13!,{R0-R2,R8-R12,PC} 13600]:NEXT,:[OPT T% 13610: 13620.dhend% 13630LDMFD R13!,{R0-R2,R8-R12,PC} 13640: 13650.testpos% 13660EQUD 1<<VC%:EQUD 0:EQUD 0:; E-vector 13670EQUD 0:EQUD 1<<VC%:EQUD 0:; N-vector 13680EQUD 0:EQUD 0:EQUD 1<<VC%:; U-vector 13690EQUD 0:EQUD 0:EQUD 10<<AC%:; Position 13700: 13710.matrix% 13720EQUD 1<<VC%:EQUD 0:EQUD 0:; E-vector 13730EQUD 0:EQUD 1<<VC%:EQUD 0:; N-vector 13740EQUD 0:EQUD 0:EQUD 1<<VC%:; U-vector 13750EQUD 0:EQUD 0:EQUD 10<<AC%:; Relative position 13760EQUD 0:EQUD 0:EQUD 1<<VC%:; Light vector 13770: 13780; Draws a vector graphics shape 13790; Uses testpos at the moment 13800; Uses shape data from shape% at the moment 13810; Eventually, it will expect matrix% to be set up 13820; and R12 to be shape data 13830: 13840.drawshape% 13850STMFD R13!,{R14} 13860ADR R12,testpos% 13870BL makematrix% 13880; Fill points% 13890OPT FNadr(12,shape%,2) 13900OPT FNadr(11,points%,2) 13910LDR R10,[R12],#4 13920.ploop% 13930LDMIA R12!,{R0-R2} 13940ADR R9,matrix% 13950LDMIA R9!,{R3-R5} 13960MUL R6,R0,R3 13970MUL R7,R0,R4 13980MUL R8,R0,R5 13990LDMIA R9!,{R3-R5} 14000MLA R6,R1,R3,R6 14010MLA R7,R1,R4,R7 14020MLA R8,R1,R5,R8 14030LDMIA R9!,{R3-R5} 14040MLA R6,R2,R3,R6 14050MLA R7,R2,R4,R7 14060MLA R8,R2,R5,R8 14070LDMIA R9!,{R3-R5} 14080ADD R6,R3,R6,ASR#VC%:; Apparent E 14090ADD R7,R4,R7,ASR#VC%:; Apparent N 14100ADD R8,R5,R8,ASR#VC%:; Apparent U 14110CMP R7,#1<<10 14120MOVLT R0,#1<<31 14130BLT dsbehind% 14140CMP R7,#1<<18 14150MOVGE R6,R6,ASR#8 14160MOVGE R7,R7,ASR#8 14170MOVGE R8,R8,ASR#8 14180CMP R7,#1<<14 14190MOVGE R6,R6,ASR#4 14200MOVGE R7,R7,ASR#4 14210MOVGE R8,R8,ASR#4 14220CMP R7,#1<<12 14230MOVGE R6,R6,ASR#2 14240MOVGE R7,R7,ASR#2 14250MOVGE R8,R8,ASR#2 14260MOV R0,#1<<22 14270MOV R9,#0 14280]:FORU%=22TO1STEP-1:[OPT T% 14290CMP R7,R0,ASR#U% 14300SUBLE R0,R0,R7,ASL#U% 14310ADDLE R9,R9,#1<<U% 14320]:NEXT:[OPT T% 14330CMP R7,R0 14340ADDLE R9,R9,#1 14350MUL R0,R6,R9 14360MUL R1,R8,R9 14370MOV R0,R0,ASR#22-(SCW%+DC%) 14380MOV R1,R1,ASR#22-(SCH%+DC%) 14390ADD R0,R0,#scwidth%<<DC%-1 14400ADD R1,R1,#scheight%<<DC%-1 14410.dsbehind% 14420STMIA R11!,{R0-R1} 14430SUBS R10,R10,#1 14440BGT ploop% 14450; Plot the triangles 14460LDR R10,[R12],#4 14470.tloop% 14480LDMIA R12!,{R0,R2,R4,R6-R8,R11} 14490ADR R1,matrix%+48 14500LDMIA R1,{R1,R3,R5} 14510MUL R1,R6,R1 14520MLA R1,R7,R3,R1 14530MLA R1,R8,R5,R1 14540MOV R1,R1,ASR#VC%+VC%-6 14550CMP R1,#0 14560MOVLT R1,#0 14570CMP R1,#63 14580MOVGT R1,#63 14590ADD R11,R1,R11,ASL#5 14600OPT FNadr(5,points%,2) 14610ADD R0,R5,R0,ASL#3 14620LDMIA R0,{R0-R1} 14630ADD R2,R5,R2,ASL#3 14640LDMIA R2,{R2-R3} 14650ADD R4,R5,R4,ASL#3 14660LDMIA R4,{R4-R5} 14670CMP R0,#1<<31 14680CMPNE R2,#1<<31 14690CMPNE R4,#1<<31 14700BEQ dsdontplot% 14710SUB R6,R2,R0 14720SUB R7,R5,R1 14730MOV R6,R6,ASR#DC%-4 14740MOV R7,R7,ASR#DC%-4 14750MUL R8,R6,R7 14760SUB R6,R4,R0 14770RSB R7,R3,R1 14780MOV R6,R6,ASR#DC%-4 14790MOV R7,R7,ASR#DC%-4 14800MLA R8,R6,R7,R8 14810CMP R8,#0 14820BLLT plottri% 14830.dsdontplot% 14840SUBS R10,R10,#1 14850BGT tloop% 14860LDMFD R13!,{PC} 14870: 14880; Calculates apparent pos of an object 14890; World pos is in R12 14900: 14910.makematrix% 14920STMFD R13!,{R14} 14930OPT FNadr(10,matrix%,2) 14940OPT FNadr(11,view%+12,2) 14950LDMIA R11,{R0-R1,R2,R3}:; Viewer's heading, pitch, roll 14960LDMIA R12!,{R7-R9}:; E vector 14970SUB R6,R9,R8 14980SUB R6,R6,R7 14990STR R6,matrix%+48:; Light E 15000MUL R4,R1,R7 15010MUL R6,R0,R8 15020SUB R4,R4,R6 15030MUL R5,R0,R7 15040MLA R5,R1,R8,R5 15050MOV R4,R4,ASR#VC% 15060MOV R5,R5,ASR#VC% 15070MUL R6,R5,R2 15080MLA R6,R4,R3,R6 15090SUB R6,R9,R6,ASR#VC% 15100STMIA R10!,{R4-R6} 15110LDMIA R12!,{R7-R9}:; N vector 15120SUB R6,R9,R8 15130SUB R6,R6,R7 15140STR R6,matrix%+52:; Light N 15150MUL R4,R1,R7 15160MUL R6,R0,R8 15170SUB R4,R4,R6 15180MUL R5,R0,R7 15190MLA R5,R1,R8,R5 15200MOV R4,R4,ASR#VC% 15210MOV R5,R5,ASR#VC% 15220MUL R6,R5,R2 15230MLA R6,R4,R3,R6 15240SUB R6,R9,R6,ASR#VC% 15250STMIA R10!,{R4-R6} 15260LDMIA R12!,{R7-R9}:; U vector 15270SUB R6,R9,R8 15280SUB R6,R6,R7 15290STR R6,matrix%+56:; Light U 15300MUL R4,R1,R7 15310MUL R6,R0,R8 15320SUB R4,R4,R6 15330MUL R5,R0,R7 15340MLA R5,R1,R8,R5 15350MOV R4,R4,ASR#VC% 15360MOV R5,R5,ASR#VC% 15370MUL R6,R5,R2 15380MLA R6,R4,R3,R6 15390SUB R6,R9,R6,ASR#VC% 15400STMIA R10!,{R4-R6} 15410LDMIA R12!,{R7-R9}:; Position 15420LDMDB R11,{R4-R6}:; Viewer's position 15430SUB R7,R7,R4 15440SUB R8,R8,R5 15450SUB R9,R9,R6 15460MOV R7,R7,ASR#AC%-9 15470MOV R8,R8,ASR#AC%-9 15480MUL R4,R1,R7 15490MUL R6,R0,R8 15500SUB R4,R4,R6 15510MUL R5,R0,R7 15520MLA R5,R1,R8,R5 15530MOV R7,R4,ASR#VC% 15540MOV R8,R5,ASR#VC% 15550MOV R4,R4,ASR#(VC%+9)-AC% 15560MOV R5,R5,ASR#(VC%+9)-AC% 15570MUL R6,R8,R2 15580MLA R6,R7,R3,R6 15590SUB R6,R9,R6,ASR#(VC%+9)-AC% 15600STMIA R10!,{R4-R6} 15610LDMFD R13!,{PC} 15620: 15630]:IFP%>code%+codelen%THENERROR255,"Code isn't big enough" 15640NEXT 15650SYS"OS_ReadVduVariables",vduvars%,scraddr% 15660ENDPROC
�13 �constants �space%spacelen%:P%=space% (code%=P%:P%+=codelen% 2pos%=P%:P%+=32*levels% <!base%=P%:P%+=32*bsize%*bsize% Fdist%=P%:P%+=depth%*16 Pcol%=P%:P%+=8*32*64 Zshape%=P%:P%+=shapelen% dpoints%=P%:P%+=8*nopoints% n(map%=P%:P%+=32*msize%*msize%*levels% x%land%=P%:P%+=8*lsize%*lsize%*vis% �hor%=P%:P%+=winc%*width% �6�P%>space%+spacelen%��255,"Space isn't big enough" ��P%-space%;" bytes used" � �assemble ��setupshape � �setupcol ��setupdist �,�T%=0�width%-1:hor%!(T%*winc%)=height%:� ��setupbase:!refresh%=� �� ��map ��fly ��0 � : : "��constants ,spacelen%=&200000 6codelen%=&8000 @AC%=12:VC%=9:SC%=8:DC%=12 JML%=2:loff%=1<<ML%-1 TMS%=5:msize%=1<<MS% ^LS%=MS%+ML%:lsize%=1<<LS% hBS%=5:bsize%=1<<BS% r.BC%=AC%+9:LC%=AC%-2:MC%=LC%+ML%:EC%=32-LS% |-levels%=BC%-MC%+1:vis%=(AC%+14)-LS%-LC%+1 �WW%=6:width%=20<<WW%-4 �HH%=7:height%=16<<HH%-4 �dsteps%=10:winc%=256*8 �!depth%=2*dsteps%+vis%*dsteps% �4�depth%*8+4>winc%��255,"winc% is not big enough" �shapelen%=&4000 �nopoints%=64 �/SCW%=8:scwidth%=20<<SCW%-4:sclinc%=scwidth% �SCH%=8:scheight%=16<<SCH%-4 �#SKW%=SCW%-2:skwidth%=20<<SKW%-4 �$SKH%=SCH%-2:skheight%=16<<SKH%-4 �� �: ��setupcol �+0 U%=col% &�A$:ȕA$<>"*":L%=�(A$)/2-1 0�T%=0�31:B%=8*L%*T%/32 :b!U%=�("&"+�A$,1+2*(B%+5>>3),2)+�A$,1+2*(B%+1>>3),2)+�A$,1+2*(B%+4>>3),2)+�A$,1+2*(B%+0>>3),2)) DcU%!4=�("&"+�A$,1+2*(B%+3>>3),2)+�A$,1+2*(B%+7>>3),2)+�A$,1+2*(B%+2>>3),2)+�A$,1+2*(B%+6>>3),2)) NU%+=8:� X �A$:� b� l: v�"2BA2A3CCCD" �8�"FBFAF9F8CF","CFCECDCCA3","A3A2A1A00B","0B0A090800" ��"2122234C4D","4D4E4FF0F1" ��"2020212223","234C4D4E4F" ��"2425262758","58595A5BF4" ��"2223444546","464778797A" ��"032C2D2E2F","2FD0D1D2D3" ��"2FD0D1D2D3","D3FCFDFEFF" ��"02032C2D2E","2E2FD0D1D2" ��"060738393A","3A3BD4D5D6" ��"*" �: ���setupdist �(maxdist%=(lsize%/2-8)/�(1^2+(5/8)^2) V%=dist%:�T%=1�dsteps%*2 /!V%=0:V%!4=T%/dsteps%/2*maxdist%/2*(1<<SC%) )V%!8=(1<<20)/V%!4:V%!12=V%!4<<LC%-SC% V%+=16:� *�U%=0�vis%-1:�T%=1�dsteps% 42!V%=U%:V%!4=maxdist%*2^(T%/dsteps%-1)*(1<<SC%) >.V%!8=(1<<20)/V%!4:V%!12=V%!4<<(LC%+U%)-SC% H V%+=16:�, R� \: f��setupbase p*U%=base%:�Y%=0�bsize%-1:�X%=0�bsize%-1 z !U%=0 � U%!4=0 �WU%!8=(112/((X%-15)*(X%-16)+(Y%-15)*(Y%-16)+64)-0.5)*(1<<SC%)+�(1<<SC%-1)-(1<<SC%-2) �U%!12=�(1<<SC%-2) �#U%!16=0:U%!20=0:U%!24=0:U%!28=0 � U%+=32:�, �� �: ���setupshape ��P$(nopoints%) � P%=shape% ��newshape:� Brick ��point("SWD",-15,-20,-10) ��point("SED",15,-20,-10) �point("NWD",-15,20,-10) �point("NED",15,20,-10) �point("SWU",-15,-20,10) $�point("SEU",15,-20,10) .�point("NWU",-15,20,10) 8�point("NEU",15,20,10) B;�face("SWD","SWU","SED",19):�face("SED","SWU","SEU",19) L;�face("SED","SEU","NED",19):�face("NED","SEU","NEU",19) V;�face("NED","NEU","NWD",19):�face("NWD","NEU","NWU",19) `;�face("NWD","NWU","SWD",19):�face("SWD","NWU","SWU",19) j;�face("SWU","NWU","SEU",19):�face("SEU","NWU","NEU",19) t;�face("NWD","SWD","NED",19):�face("NED","SWD","SED",19) ~ �endshape �6�P%>shape%+shapelen%��255,"Shape isn't big enough" �� �: ���newshape �pflag%=� �nopoints%=0:nofaces%=0 �pstart%=P%:P%+=4 �� �: ���point(N$,X,Y,Z) �0�pflag%��255,"Points must come before faces" �9!P%=X*(1<<AC%):P%!4=Y*(1<<AC%):P%!8=Z*(1<<AC%):P%+=12 !P$(nopoints%)=N$:nopoints%+=1 � : ��face(P1$,P2$,P3$,C%) (&�pflag%�pflag%=�:fstart%=P%:P%+=4 29P1%=�pointno(P1$):P2%=�pointno(P2$):P3%=�pointno(P3$) <BA1%=pstart%+4+P1%*12:A2%=pstart%+4+P2%*12:A3%=pstart%+4+P3%*12 F>NX=(A3%!4-A1%!4)*(A2%!8-A1%!8)-(A3%!8-A1%!8)*(A2%!4-A1%!4) P:NY=(A3%!8-A1%!8)*(!A2%-!A1%)-(!A3%-!A1%)*(A2%!8-A1%!8) Z:NZ=(!A3%-!A1%)*(A2%!4-A1%!4)-(A3%!4-A1%!4)*(!A2%-!A1%) d(F=(1<<VC%)/�(NX*NX+NY*NY+NZ*NZ)/�(3) n!P%=P1%:P%!4=P2%:P%!8=P3% x$P%!12=NX*F:P%!16=NY*F:P%!20=NZ*F �P%!24=C%:P%+=28 �nofaces%+=1 �� �: �ݤpointno(N$) ��nopoints%=0�=-1 �H%=-1:�T%=0�nopoints%-1 �#�P$(T%)=N$�H%=T%:T%=nopoints%-1 � �:=H% �: ���endshape �(!pstart%=nopoints%:!fstart%=nofaces% �� : ��map � "/view%!12=0:view%!16=0:view%!20=0:view%!24=0 ,!display%=vis%-1:ȗ�640,512 6�:ȗX%,Y%,Z%:ȗ�640,512 @PP%=pos%+32*!display% JB!view%+=(X%-640)*(1<<PP%!24-4):view%!4+=(Y%-512)*(1<<PP%!24-4) T6�(-104)�!display%<vis%-1�!display%+=1:�:���(-104) ^1�(-103)�!display%>0�!display%-=1:�:���(-103) h�(-74)�!refresh%=� r �landgen% |�testland% ���(-99) ��:���(-99) �:LX%=(!view%>>LC%)�lsize%-1:LY%=(view%!4>>LC%)�lsize%-1 �<view%!8=(land%!(8*(LX%+lsize%*LY%))<<LC%-SC%)+(1<<AC%+4) �� �: � ��fly �B%=0 �A%=0:V%=0:NT%=� ��:ȗX%,Y%,Z% �'FT%=�-NT%:NT%+=FT%:�FT%>100�FT%=100 �&B%=B%+FT%*10�&FFFF:A=2*�*B%/&10000 �5testpos%!0=�(A)*(1<<VC%):testpos%!4=�(A)*(1<<VC%) 2testpos%!12=-testpos%!4:testpos%!16=testpos%!0 �Z%=4� view%!0+=view%!12<<AC%+5-VC% & view%!4+=view%!16<<AC%+5-VC% 0 view%!8+=view%!20<<AC%+5-VC% :� D3A%=A%+(FT%*(640-X%)>>9-7)�&FFFF:A=2*�*A%/&10000 N1view%!12=�(A)*(1<<VC%):view%!16=�(A)*(1<<VC%) X=view%!20=(512-Y%)>>9-(VC%-1):view%!24=(640-X%)>>9-(VC%-1) b �Z%=4� cV%=0 l view%!0-=view%!12<<AC%+5-VC% v view%!4-=view%!16<<AC%+5-VC% � view%!8-=view%!20<<AC%+5-VC% �� �(�Z%=2�V%-=(1<<AC%-10)*FT%:�V%<0�V%=0 �6�Z%=1�V%+=(1<<AC%-10)*FT%:�V%>(1<<AC%)�V%=(1<<AC%) �!view%!0+=V%*FT%*view%!12>>VC% �!view%!4+=V%*FT%*view%!16>>VC% �!view%!8+=V%*FT%*view%!20>>VC% � �landgen% ��drawframe% ���(-99) ��:���(-99) �� �: ��testcol -ș"OS_ReadVduVariables",vduvars%,scraddr% 2V%=col%:�T%=0�31:S%=!scraddr%+(T%<<3):�U%=0�63 !S%=!V%:S%!4=!V% *'S%!sclinc%=V%!4:S%!(sclinc%+4)=V%!4 4+S%!(sclinc%*2)=!V%:S%!(sclinc%*2+4)=!V% >-S%!(sclinc%*3)=V%!4:S%!(sclinc%*3+4)=V%!4 HS%+=sclinc%*4:V%+=8:�, R� \: f ��testhor p,�T%=0�width%-1:X%=T%*16:V%=hor%+T%*winc% z�U%=0�depth% � Y%=959-2*!V%:�X%,Y%,X%+15,Y% �V%+=8:�, �� �: ���testpoints �U%=points%:�T%=1�8 �,Ȓ!U%>>(SCW%+DC%)-10,U%!4>>(SCH%+DC%)-10 �U%+=8:� �� �: ���testmatrix ��drawshape% ��plotblob(0,0,0,1<<AC%) "�plotblob(4<<AC%,0,0,1<<AC%-1) "�plotblob(0,4<<AC%,0,1<<AC%-1) "�plotblob(0,0,4<<AC%,1<<AC%-1) $� .: 8��plotblob(X%,Y%,Z%,R%) BBPY%=(X%*matrix%!4+Y%*matrix%!16+Z%*matrix%!28>>VC%)+matrix%!40 L �PY%<=0�� VBPX%=(X%*matrix%!0+Y%*matrix%!12+Z%*matrix%!24>>VC%)+matrix%!36 `BPZ%=(X%*matrix%!8+Y%*matrix%!20+Z%*matrix%!32>>VC%)+matrix%!44 j+F=1024/PY%:ȏȐ640+F*PX%,512+F*PZ%,F*R% t� ~: �ݤadr(R%,A%,I%) �,�(P%�3)<>0��"Code isn't word aligned!":� ��(T%�2)=0�P%+=I%<<2:=T% �(�N%,O%,H%,U%:H%=A%-(P%+8):N%=0:O%=15 ��U%=1�I%:�H%=0� �[OPT T%:MOV R%,O%:] � �ȕ(H%�3)=0:H%=H%>>2:N%+=2:� ��(H%�256)=0� �0[OPT T%:ADD R%,O%,#(H%�255)<<N%:]:H%-=H%�255 �9�[OPT T%:SUB R%,O%,#(256-H%�255)<<N%:]:H%+=256-H%�255 �� � �:O%=R%:� J�H%<>0��"Could not ADR to ";A%;" in ";I%;" instructions (R%=";R%;")":� =T% : ݤregisterj(J%,N%) (J%!(N%<<2)=P%-J% 2=T% <: F��assemble P�T%=0�2�2:P%=code% Z[OPT T% d: n .test% x#EQUD -1:EQUD -1:EQUD -1:EQUD -1 �#EQUD -1:EQUD -1:EQUD -1:EQUD -1 �#EQUD -1:EQUD -1:EQUD -1:EQUD -1 �#EQUD -1:EQUD -1:EQUD -1:EQUD -1 �: �.bank%:EQUD 1 �: � .view% �:EQUD 1<<BC%-1:EQUD 1<<BC%+BS%-1:EQUD 1<<AC%:; Position � EQUD 0:EQUD 1<<VC%:; Heading �EQUD 0:EQUD 0:; Pitch, Roll �: �.refresh%:EQUD -1 �: .landgen% STMFD R13!,{R14} BL calcpos% "BL copybase% ,BL splitmap% 6BL makeland% @LDMFD R13!,{PC} J: T.drawframe% ^STMFD R13!,{R14} hBL calchor% rLDR R1,bank% | CMP R1,#1 ��Q R1,#2 �MOVNE R1,#1 �STR R1,bank% �MOV R0,#112 �SWI "OS_Byte" �MOV R0,#19 �SWI "OS_Byte" �OPT �adr(0,vduvars%,2) �OPT �adr(1,scraddr%,2) �SWI "OS_ReadVduVariables" �BL drawsky% �MOV R12,#depth% �SUB R12,R12,#1 .dloop% OPT �adr(1,dist%+12,2) 4LDR R1,[R1,R12,ASL#4]:; Distance of strip in AC% &*; Draw everything further away than R1 0; *** Not done yet *** :BL drawstrip% DSUBS R12,R12,#1 NBGE dloop% XBL drawshape% bMOV R0,#113 lLDR R1,bank% vSWI "OS_Byte" �LDMFD R13!,{PC} �: � .calcpos% �STMFD R13!,{R14} �ADR R0,view% �3LDMIA R0,{R6-R7,R8,R10-R11}:; Position,,Heading �OPT �adr(12,pos%,2) �LDR R9,refresh% � MOV R8,#0 �STR R8,refresh% �MOV R8,#MC% � .levloop% �LDMIA R12,{R2-R3} MOV R0,R6,ASR R8 MOV R1,R7,ASR R8 %SUB R0,R0,#msize%/2-1:; SW corner SUB R1,R1,#msize%/2-1 *%BIC R0,R0,#1:; Make sure its even 4BIC R1,R1,#1 >MOV R4,R0,ASL R8 HMOV R5,R1,ASL R8 R CMP R9,#0 \ADDNE R2,R0,#1<<30 f$STMIA R12,{R0-R1,R2-R3,R4-R5,R8} pADD R12,R12,#32 zADD R8,R8,#1 �CMP R8,#MC%+levels% �BLT levloop% �LDMFD R13!,{PC} �: �.copybase% �STMFD R13!,{R14} �OPT �adr(12,base%,2) �4OPT �adr(11,map%+32*msize%*msize%*(levels%-1),3) �%OPT �adr(0,pos%+32*(levels%-1),2) �LDMIA R0,{R0-R1} �MOV R2,#32*bsize% �MLA R12,R1,R2,R12 �MOV R10,#msize% .nloop% SUB R10,R10,#msize%<<16 .eloop% $ CMP R0,#0 .CMPGE R1,#0 8BLT cbmakesea% BCMP R0,#bsize% LCMPLT R1,#bsize% VBGE cbmakesea% `ADD R2,R12,R0,ASL#5 jLDMIA R2,{R2-R9} tSTMIA R11!,{R2-R9} ~B cbreturn% �: �.cbmakesea% � MOV R2,#0 � MOV R3,#0 �7MVN R4,#1<<SC%-2:; Sea bed is -1/4 base square deep � MOV R5,#0 �STMIA R11,{R2-R5} �ADD R11,R11,#32 �.cbreturn% �ADD R0,R0,#1 �ADDS R10,R10,#1<<16 �BLE eloop% SUB R0,R0,#msize% ADD R1,R1,#1 ADD R12,R12,#32*bsize% SUBS R10,R10,#1 (BGT nloop% 2LDMFD R13!,{PC} <: F.display%:EQUD levels%-1 P: Z .testmap% dSTMFD R13!,{R14} nOPT �adr(0,vduvars%,2) x ADD R1,R0,#scraddr%-vduvars% �SWI "OS_ReadVduVariables" �LDR R14,scraddr% �"ADD R14,R14,#scheight%*sclinc% �!ADD R14,R14,#sclinc%-4*msize% �OPT �adr(12,map%,2) �LDR R0,display% � ADD R12,R12,R0,ASL#5+MS%+MS% �MOV R11,#msize% �.nloop% �SUB R14,R14,#sclinc%*4 �SUB R11,R11,#msize%<<16 �.eloop% �LDR R0,[R12,#8] ADD R12,R12,#32 MOV R0,R0,LSR#SC%-2 � R0,R0,#255 "�R R0,R0,R0,LSL#8 ,�R R0,R0,R0,LSL#16 6STR R0,[R14,#sclinc%*3] @STR R0,[R14,#sclinc%*2] JSTR R0,[R14,#sclinc%] TSTR R0,[R14],#4 ^ADDS R11,R11,#1<<16 hBLE eloop% rSUB R14,R14,#4*msize% |SUBS R11,R11,#1 �BGT nloop% �LDMFD R13!,{PC} �: �.splitmap% �STMFD R13!,{R14} �MOV R9,#levels%-1 � .levloop% �; R9 is parent level �OPT �adr(0,pos%,2) �ADD R0,R0,R9,ASL#5 �%LDMIA R0,{R4-R5}:; Parents origin �SUB R0,R0,#32 �3LDMIA R0,{R0-R1,R2-R3}:; New origin, Old origin MOV R6,R0:; Current position MOV R7,R1 MOV R8,#1:; Bottom to top & CMP R1,R3 0CMPEQ R0,R2 :BEQ smskiplev% DADDLT R6,R6,#msize%-2 NADDLT R7,R7,#msize%-2 X"RSBLT R8,R8,#0:; Top to bottom bOPT �adr(12,map%,3) l-ADD R12,R12,R9,ASL#5+MS%+MS%:; Parent map v+SUB R11,R12,#32*msize%*msize%:; New map �+RSB R4,R4,R6,ASR#1:; Pos seen on parent �RSB R5,R5,R7,ASR#1 �ADD R5,R4,R5,ASL#MS% �ADD R12,R12,R5,ASL#5 �"SUB R4,R6,R0:; Pos seen on new �SUB R5,R7,R1 �ADD R5,R4,R5,ASL#MS% �ADD R11,R11,R5,ASL#5 �"SUB R6,R6,R2:; Pos seen on old �SUB R7,R7,R3 �)SUB R4,R0,R2:; New origin seen on old �SUB R5,R1,R3 �ADD R5,R4,R5,ASL#MS% MOV R10,#msize% /; At this point, the registers are used as: "; R12 is addr of pos on parent ; R11 is addr of pos on new *; R10 is msize% 4+; R9 is loop counter (less than 8 bits) >; R8 is direction H; R6-R7 are pos on old R4; R5<<5 is offset from R11 to addr of pos on old \SUB R9,R9,#msize%<<8 f.nsloop% pADD R9,R9,#msize%<<20 z.ewloop% �4; If the square is not on old, then calculate it �ADR R14,smreturn% � CMP R6,#0 �CMPGE R7,#0 �BLT calcsq% �CMP R6,#msize% �CMPLT R7,#msize% �BGE calcsq% �7; Copy it from its old position to its new position �STMFD R13!,{R5-R8} �ADD R8,R11,R5,ASL#5 �LDMIA R8!,{R0-R7} �STMIA R11!,{R0-R7} LDMIA R8!,{R0-R7} STMIA R11!,{R0-R7} ADD R8,R8,#32*msize% $ADD R11,R11,#32*msize% .LDMDB R8!,{R0-R7} 8STMDB R11!,{R0-R7} BLDMDB R8!,{R0-R7} LSTMDB R11!,{R0-R7} VSUB R11,R11,#32*msize% `LDMFD R13!,{R5-R8} j.smreturn% tADD R6,R6,R8,ASL#1 ~ADD R11,R11,R8,ASL#5+1 �ADD R12,R12,R8,ASL#5 �SUBS R9,R9,#2<<20 �BGT ewloop% �SUB R6,R6,R8,ASL#MS% �SUB R11,R11,R8,ASL#MS%+5 � SUB R12,R12,R8,ASL#(MS%-1)+5 �ADD R7,R7,R8,ASL#1 �ADD R11,R11,R8,ASL#MS%+5+1 �ADD R12,R12,R8,ASL#MS%+5 �ADDS R9,R9,#2<<8 �BLE nsloop% �.smskiplev% SUBS R9,R9,#1 BGT levloop% LDMFD R13!,{PC} : (5; Subdivides a map square to make 2x2 map squares 2; R12 is old square <; R11 is new square F; R10 is msize P: Z.calcsq% dSTMFD R13!,{R0-R12,R14} nCLDMIA R12,{R0,R1,R2,R5}:; Old Type, Water level, Height, Random x; Concoct a random seed �ADD R8,R2,R2,ROR#17 �ADD R8,R8,R8,ROR#10 �ADD R8,R8,R8,ROR#6 �ADD R12,R12,#8 �SUB R3,R12,#32 �'LDMIA R3,{R3,R6}:; W Height, Random �SUB R4,R12,R10,ASL#5 �'LDMIA R4,{R4,R7}:; S Height, Random �ADD R4,R4,R2,ASL#1 �ADD R7,R7,R5,ASL#1 �ADD R3,R3,R4 �ADD R6,R6,R7 �MOV R3,R3,ASR#2-1 MOV R6,R6,ASR#2 ADD R8,R8,R8,ROR#4 MOV R9,R8,LSR#32-6 "MUL R9,R5,R9 ,SUB R9,R9,R5,ASL#5 6ADD R3,R3,R9,ASR#5-1 @ADD R8,R8,R8,ROR#4 J ADDS R6,R6,R8,ASR#31-(SC%-5) TMOVLT R6,#0 ^/STMIA R11,{R0,R1,R3,R6}:; New SW Type etc.. hADD R11,R11,#32 rADD R3,R12,#32 |'LDMIA R3,{R3,R6}:; E Height, Random �ADD R4,R3,R4 �ADD R7,R6,R7 �MOV R4,R4,ASR#2-1 �MOV R7,R7,ASR#2 �ADD R8,R8,R8,ROR#4 �MOV R9,R8,LSR#32-6 �MUL R9,R5,R9 �SUB R9,R9,R5,ASL#5 �ADD R4,R4,R9,ASR#5-1 �ADD R8,R8,R8,ROR#4 � ADDS R7,R7,R8,ASR#31-(SC%-5) �MOVLT R7,#0 �/STMIA R11,{R0,R1,R4,R7}:; New SE Type etc.. ADD R11,R11,R10,ASL#5 ADD R4,R12,R10,ASL#5 'LDMIA R4,{R4,R7}:; N Height, Random &ADD R4,R4,R2,ASL#1 0ADD R7,R7,R5,ASL#1 :ADD R3,R3,R4 DADD R6,R6,R7 NMOV R3,R3,ASR#2-1 XMOV R6,R6,ASR#2 bADD R8,R8,R8,ROR#4 lMOV R9,R8,LSR#32-6 vMUL R9,R5,R9 �SUB R9,R9,R5,ASL#5 �ADD R3,R3,R9,ASR#5-1 �ADD R8,R8,R8,ROR#4 � ADDS R6,R6,R8,ASR#31-(SC%-5) �MOVLT R6,#0 �/STMIA R11,{R0,R1,R3,R6}:; New NE Type etc.. �SUB R11,R11,#32 �SUB R3,R12,#32 �-LDMIA R3,{R3,R6}:; W Height, Random again �ADD R4,R3,R4 �ADD R7,R6,R7 �MOV R4,R4,ASR#2-1 �MOV R7,R7,ASR#2 ADD R8,R8,R8,ROR#4 MOV R9,R8,LSR#32-6 MUL R9,R5,R9 SUB R9,R9,R5,ASL#5 *ADD R4,R4,R9,ASR#5-1 4ADD R8,R8,R8,ROR#4 > ADDS R7,R7,R8,ASR#31-(SC%-5) HMOVLT R7,#0 R/STMIA R11,{R0,R1,R4,R7}:; New NW Type etc.. \SUB R11,R11,R10,ASL#5 fLDMFD R13!,{R0-R12,PC} p: z.testland% �STMFD R13!,{R14} �OPT �adr(0,vduvars%,2) � ADD R1,R0,#scraddr%-vduvars% �SWI "OS_ReadVduVariables" �LDR R14,scraddr% �"ADD R14,R14,#scheight%*sclinc% �OPT �adr(12,land%+4,3) �LDR R0,display% � ADD R12,R12,R0,ASL#3+LS%+LS% �OPT �adr(1,pos%+24,2) �LDR R1,[R1,R0,ASL#5] �OPT �adr(2,view%,2) �LDMIA R2,{R2-R3} MOV R2,R2,ASR R1 MOV R3,R3,ASR R1 5SUB R2,R2,#msize%/2-1:; SW corner of visible area $SUB R3,R3,#msize%/2-1 .MOV R2,R2,ASL#ML% 8MOV R3,R3,ASL#ML% BOPT �adr(10,col%,2) LMOV R11,#lsize%-8 V.nloop% `SUB R14,R14,#sclinc%*2 jSUB R11,R11,#lsize%-8<<16 t.eloop% ~� R0,R2,#lsize%-1 �� R1,R3,#lsize%-1 �ADD R0,R0,R1,ASL#LS% �LDR R0,[R12,R0,ASL#3] �ADD R0,R10,R0,ASL#3 �%LDMIA R0,{R0-R1}:; Dither pattern �MOV R4,R0,LSL#16 �MOV R5,R1,LSL#16 �ADD R2,R2,#1 �� R0,R2,#lsize%-1 �� R1,R3,#lsize%-1 �ADD R0,R0,R1,ASL#LS% �LDR R0,[R12,R0,ASL#3] ADD R0,R10,R0,ASL#3 %LDMIA R0,{R0-R1}:; Dither pattern �R R4,R4,R0,LSR#16 �R R5,R5,R1,LSR#16 (MOV R4,R4,ROR#16 2MOV R5,R5,ROR#16 <STR R4,[R14,#sclinc%] FSTR R5,[R14],#4 PADD R2,R2,#1 ZADDS R11,R11,#2<<16 dBLE eloop% nSUB R2,R2,#lsize%-8 xSUB R14,R14,#2*(lsize%-8) �ADD R3,R3,#1 �SUB R14,R14,#sclinc%*2 �SUB R11,R11,#lsize%-8<<16 �.eloop% �� R0,R2,#lsize%-1 �� R1,R3,#lsize%-1 �ADD R0,R0,R1,ASL#LS% �LDR R0,[R12,R0,ASL#3] �ADD R0,R10,R0,ASL#3 �%LDMIA R0,{R0-R1}:; Dither pattern �MOV R4,R0,LSR#16 �MOV R5,R1,LSR#16 �ADD R2,R2,#1 � R0,R2,#lsize%-1 � R1,R3,#lsize%-1 ADD R0,R0,R1,ASL#LS% "LDR R0,[R12,R0,ASL#3] ,ADD R0,R10,R0,ASL#3 6%LDMIA R0,{R0-R1}:; Dither pattern @�R R4,R4,R0,LSL#16 J�R R5,R5,R1,LSL#16 TSTR R4,[R14,#sclinc%] ^STR R5,[R14],#4 hADD R2,R2,#1 rADDS R11,R11,#2<<16 |BLE eloop% �SUB R2,R2,#lsize%-8 �SUB R14,R14,#2*(lsize%-8) �ADD R3,R3,#1 �SUBS R11,R11,#2 �BGT nloop% �LDMFD R13!,{PC} �: �.makeland% �STMFD R13!,{R14} �MOV R7,#vis%-1 � .levloop% �OPT �adr(0,pos%,2) �ADD R0,R0,R7,ASL#5 DLDMIA R0,{R0-R1,R2-R3,R4-R5,R9}:; New origin, Old origin,, Scale CMP R0,R2 CMPEQ R1,R3 &BEQ mlendlev% 0OPT �adr(12,map%,3) : ADD R12,R12,R7,ASL#5+MS%+MS% DOPT �adr(8,land%,3) NADD R8,R8,R7,ASL#3+LS%+LS% XMOV R10,#msize% bSUB R7,R7,#msize%-1<<8 l.nloop% vADD R7,R7,#msize%-1<<20 �.eloop% �� R4,R0,#(1<<MS%)-1 �� R5,R1,#(1<<MS%)-1 �ADD R11,R8,R4,ASL#ML%+3 � ADD R11,R11,R5,ASL#ML%+3+LS% �ADR R14,mlreturn% �SUBS R4,R0,R2 �SUBGES R5,R1,R3 �BLT calclsq% �CMP R4,#msize%-1 �CMPLT R5,#msize%-1 �BGE calclsq% �.mlreturn% ADD R0,R0,#1 ADD R12,R12,#32 SUBS R7,R7,#1<<20 BGE eloop% *SUB R0,R0,#msize%-1 4SUB R12,R12,#32*(msize%-1) >ADD R1,R1,#1 HADD R12,R12,#32*msize% RADDS R7,R7,#1<<8 \BLT nloop% f.mlendlev% pSUBS R7,R7,#1 zBGE levloop% �LDMFD R13!,{PC} �: �>; Subdivides a map square to make 4x4 land squares (ML%=2) �; R12 is old square �; R11 is new square �; R10 is msize �;; R9 is scale (log2 size of map square in world coords) �: � .calclsq% �STMFD R13!,{R0-R12,R14} �6SUB R9,R9,#SC%:; Log2 square coord in world coords �; Get the heights �ILDMIB R12,{R0,R2,R8}:; Water level, SW height (in square coords), rnd ADD R12,R12,#8 ADD R3,R12,#32 %LDMIA R3,{R3,R7}:; SE height, rnd $ADD R8,R8,R7 .ADD R12,R12,R10,ASL#5 8&LDMIA R12,{R4,R7}:; NW height, rnd BADD R8,R8,R7 LADD R5,R12,#32 V%LDMIA R5,{R5,R7}:; NE height, rnd `ADD R8,R8,R7 j; Calculate average height tADD R1,R2,R3 ~ADD R1,R1,R4 �ADD R1,R1,R5 �MOV R1,R1,ASR#2 � ; Calculate land base colour �$MOV R7,R1,ASL R9:; Height in AC% �>ADD R7,R7,R8,ASL#(AC%+9)-(SC%+1):; Bumpy ground seems high �MOV R8,#5<<5:; Grass �CMP R7,#128<<AC% �MOVGE R8,#7<<5:; Bracken �CMP R7,#256<<AC% �MOVGE R8,#9<<5:; Heather �CMP R7,#384<<AC% �!MOVGE R8,#11<<5:; Rough grass CMP R7,#512<<AC% MOVGE R8,#13<<5:; Rocks CMP R7,#640<<AC% MOVGE R8,#15<<5:; Snow (%SUB R7,R5,R2:; SW facing slope<<3 2+MOV R7,R7,ASR#SC%-4:; Approx range +-32 <ADDS R7,R7,#24 FMOVLT R7,#0 PCMP R7,#60 ZMOVGT R7,#60 dADD R8,R8,R7 n; Calculate water colour xSUBS R7,R0,R1 �MOVLT R7,#0 �MOV R7,R7,ASL R9 �.MOV R7,R7,ASR#AC%-1:; Depth in half metres �MOV R1,#0<<6:; Sea blue �CMP R7,#64 �MOVGE R7,R7,ASR#4 �ADDGE R1,R1,#16 �CMP R7,#16 �MOVGE R7,R7,ASR#2 �ADDGE R1,R1,#8 � CMP R7,#8 �MOVGE R7,R7,ASR#1 �ADDGE R1,R1,#4 ADD R1,R1,R7 CMP R1,#31 MOVGT R1,#31 "; Generate a random seed ,� R14,R2,R5,ROR#17 6� R14,R14,R3,ROR#13 @� R14,R14,R4,ROR#10 JADD R14,R14,R14,ROR#6 T; Calculate gradients ^SUB R4,R4,R2 hSUB R5,R5,R3 rADD R2,R4,R2,ASL#3 |ADD R3,R5,R3,ASL#3 �SUB R3,R3,R2:; dH/dE<<3 �SUB R5,R5,R4:; d2H/dNdE �"ADD R2,R3,R2,ASL#3:; Height<<6 �!ADD R4,R5,R4,ASL#3:; dH/dN<<3 �*; At this point, registers are used as �); R0,R1 are water level, water colour �; R2-R5 are gradients �; R8 is land colour �; R9-R12 as on entry �; R14 is rnd seed � MOV R9,#4 �.nloop% �]:�U%=0�3:[OPT T% MOV R6,R2,ASR#6-2 ADD R14,R14,R14,ROR#2 ADD R7,R8,R14,LSR#32-2 &CMP R6,R0,ASL#2 0MOVLT R6,R0,ASL#2 :MOVLT R7,R1 DSTMIA R11!,{R6,R7} NADD R2,R2,R3,ASL#1 X]:�:[OPT T% bSUB R11,R11,#8*4 lSUB R2,R2,R3,ASL#1+2 vADD R11,R11,R10,ASL#3+ML% �ADD R2,R2,R4,ASL#1 �ADD R3,R3,R5,ASL#1 �SUBS R9,R9,#1 �BGT nloop% �LDMFD R13!,{R0-R12,PC} �: � .calchor% �STMFD R13!,{R14} �MOV R12,#0 �.dloop% �OPT �adr(0,dist%,2) �ADD R0,R0,R12,ASL#4 �<LDMIA R0,{R0,R8,R9}:; Level, distance in SC%, (1<<21)/R1 !OPT �adr(10,land%,3) ! ADD R10,R10,R0,ASL#3+LS%+LS% !OPT �adr(7,pos%+24,2) ! LDR R7,[R7,R0,ASL#5] !*1SUB R7,R7,#ML%:; Log2 size of a square in AC% !4OPT �adr(0,view%,2) !>LLDMIA R0,{R0-R1,R2,R3-R4,R5,R6}:; Position, height, heading, pitch, roll !H%MUL R3,R8,R3:; Heading in SC%+VC% !RMUL R4,R8,R4 !\)MUL R5,R8,R5:; Pitch, Roll in SC%+VC% !fMUL R6,R8,R6 !pRSB R11,R7,#EC% !z'MOV R0,R0,ASL R11:; Position in EC% !�MOV R1,R1,ASL R11 !�SUB R11,R7,#SC% !�%MOV R2,R2,ASR R11:; Height in SC% !�2ADD R0,R0,R3,ASL#EC%-(SC%+VC%):; Move forwards !�"ADD R1,R1,R4,ASL#EC%-(SC%+VC%) !�ADD R2,R2,R5,ASR#VC% !�MOV R3,R3,ASR#WW% !�MOV R4,R4,ASR#WW% !�<MOV R5,R3,ASL#EC%-(SC%+VC%):; Right vector (in EC%, SC%) !�RSB R5,R5,#0 !�MOV R4,R4,ASL#EC%-(SC%+VC%) !�MOV R6,R6,ASR#WW%+VC% !�BSUB R0,R0,R4,ASL#WW%-1:; Move left 1/2 screen except 1/2 pixel "SUB R1,R1,R5,ASL#WW%-1 "SUB R2,R2,R6,ASL#WW%-1 "SUB R0,R0,R4,ASL#WW%-3 "$SUB R1,R1,R5,ASL#WW%-3 ".SUB R2,R2,R6,ASL#WW%-3 "8ADD R0,R0,R4,ASR#1 "BADD R1,R1,R5,ASR#1 "LADD R2,R2,R6,ASR#1 "V&ADD R2,R2,R8,ASR#1:; Up 1/2 screen "j%ADD R2,R2,R8,ASR#HH%+1:; Rounding "tOPT �adr(11,hor%,3) "~ADD R11,R11,R12,ASL#3 "�7; At this point, the registers are used as follows: "�M; R0-R1,R2 are top left of screen, with position in EC% and height in SC% "�3; R4-R5,R6 is right vector, also in EC% and SC% "�'; R9 is (1<<21) / (distance in SC%) "�0; R10 is base address of land for this level "�"; R11 is hor for this distance "�; R12 is depth "�*SUB R0,R0,#loff%<<EC%:; Land is offset "�SUB R1,R1,#loff%<<EC% "�SUB R12,R12,#width%<<16 "�.wloop% "�MOV R7,R0,LSR#EC% # MOV R8,R1,LSR#EC% # ADD R7,R7,R8,ASL#LS% #ADD R7,R10,R7,ASL#3 #7LDMIA R7,{R3,R7}:; Land height (SC%), colour number #(.RSBS R3,R3,R2:; Height below top of screen #2MOVLT R3,#0 #<MUL R3,R9,R3 #FMOV R8,R3,LSR#20-HH% #PLDR R3,[R11] #Z CMP R8,R3 #dMOVGT R8,R3 #n?STMIA R11,{R3,R7,R8}:; Bottom, colour number, top in pixels #xADD R11,R11,#winc% #�ADD R0,R0,R4 #�ADD R1,R1,R5 #�ADD R2,R2,R6 #�ADDS R12,R12,#1<<16 #�BLT wloop% #�ADD R12,R12,#1 #�CMP R12,#depth% #�BLT dloop% #�LDMFD R13!,{PC} #�: #�.vduvars%:EQUD 148:EQUD -1 #�.scraddr%:EQUD -1 #�: $#; R12 is depth of strip to draw $; R0-R11 corrupted $: $".drawstrip% $,STMFD R13!,{R12,R14} $6LDR R14,scraddr% $@OPT �adr(11,hor%,3) $JADD R11,R11,R12,ASL#3 $TOPT �adr(10,col%,2) $^SUB R12,R12,#width%<<16 $h.wloop% $r.LDMIA R11,{R0,R1,R2}:; Bottom, colour, top $|,SUBS R0,R0,R2:; Number of pixels to draw $�BLE dsendw% $�ADD R9,R14,R2,ASL#SCW%+1 $�ADD R9,R9,R2,ASL#SCW%-2+1 $�ADD R1,R10,R1,ASL#3 $�LDMIA R1,{R6,R7} $� TST R2,#1 $�MOVNE R6,R6,ROR#16 $�MOVNE R7,R7,ROR#16 $�.yloop% $�]:ȎSCW%-WW%� $��3: $�[OPT T% $� MOV R8,R6 %STMIA R9,{R6,R8} %ADD R9,R9,#sclinc% % MOV R8,R7 %&STMIA R9,{R7,R8} %0ADD R9,R9,#sclinc% %:MOV R6,R6,ROR#16 %DMOV R7,R7,ROR#16 %N] %X�2: %b[OPT T% %lSTR R6,[R9],#sclinc% %vSTR R7,[R9],#sclinc% %�MOV R6,R6,ROR#16 %�MOV R7,R7,ROR#16 %�] %�$:�255,"Only WW%=6 is supported" %� �:[OPT T% %�SUBS R0,R0,#1 %�BGT yloop% %�.dsendodd% %�.dsendw% %�ADD R11,R11,#winc% %�ADD R14,R14,#1<<SCW%-WW% %�ADDS R12,R12,#1<<16 %�BLT wloop% &LDMFD R13!,{R12,PC} &: & .drawsky% & STMFD R13!,{R14} &*LDR R14,scraddr% &4 OPT �adr(12,col%+8*(1<<5),2) &>OPT �adr(0,view%+20,2) &H"LDMIA R0,{R0,R1}:; Pitch, Roll &RMOV R0,R0,ASL#24-VC% &\MOV R1,R1,ASL#24-SKW%-VC% &f>SUB R0,R0,R1,ASL#SKW%-1:; Left 1/2 screen except 1/2 pixel &pSUB R0,R0,R1,ASL#SKW%-3 &zADD R0,R0,R1,ASR#1 &�7ADD R0,R0,#1<<24-1:; Up 1/2 screen except 1/2 pixel &�SUB R0,R0,#1<<24-SKH%-1 &�ADD R0,R0,R0,ASL#1 &�ADD R1,R1,R1,ASL#1 &�MOV R11,#skwidth% &�.wloop% &�SUB R11,R11,#skheight%<<16 &�.hloop% &�ADD R4,R0,R1 &�ADD R6,R4,R1 &�ADD R8,R6,R1 &�MOV R2,R0,ASR#26-7 &�MOV R4,R4,ASR#26-7 'MOV R6,R6,ASR#26-7 'MOV R8,R8,ASR#26-7 ']:�U%=2�8�2:[OPT T% '$ADDS U%,U%,#32 '.MOVLT U%,#0 '8CMP U%,#127 'BMOVGT U%,#127 'LADD U%,R12,U%,ASL#3 'VLDMIA U%,{U%-(U%+1)} '`]:�:[OPT T% 'jSTMIA R14,{R2,R4,R6,R8} 'tADD R14,R14,#sclinc% '~STMIA R14,{R3,R5,R7,R9} '�ADD R14,R14,#sclinc% '�]:�U%=2�9:[OPT T% '�MOV U%,U%,ROR#16 '�]:�:[OPT T% '�STMIA R14,{R2,R4,R6,R8} '�ADD R14,R14,#sclinc% '�STMIA R14,{R3,R5,R7,R9} '�ADD R14,R14,#sclinc% '�(SUB R0,R0,#3<<24-SKH%:; Down 1 pixel '�ADDS R11,R11,#1<<16 '�BLE hloop% '�"ADD R0,R0,#3<<24:; Up 1 screen ( "SUB R14,R14,#scheight%*sclinc% ( 'ADD R0,R0,R1,ASL#2:; Right 2 pixels (ADD R14,R14,#4<<SCW%-SKW% (SUBS R11,R11,#4 ((BGT wloop% (2LDMFD R13!,{PC} (<: (F; Draws any triangle (P%; R0-R1, R2-R3, R4-R5 are corners (Z; Everything preserved (d: (n .plottri% (xSTMFD R13!,{R0-R12,R14} (�$; Sort them into ascending order (� CMP R3,R1 (� BGT pt13% (� .pt31% (� CMP R5,R1 (�BGT pt315% (� CMP R5,R3 (�BGT pt351% (�.pt531% (� MOV R6,R0 (� MOV R0,R4 (� MOV R4,R6 (� MOV R6,R1 ) MOV R1,R5 ) MOV R5,R6 )B pt135% )": ),.pt351% )6 MOV R6,R0 )@ MOV R0,R2 )J MOV R2,R4 )T MOV R4,R6 )^ MOV R6,R1 )h MOV R1,R3 )r MOV R3,R5 )| MOV R5,R6 )�B pt135% )�: )�.pt315% )� MOV R6,R0 )� MOV R0,R2 )� MOV R2,R6 )� MOV R6,R1 )� MOV R1,R3 )� MOV R3,R6 )�B pt135% )�: )� .pt13% )� CMP R5,R3 *BGT pt135% * CMP R5,R1 *BGT pt153% *&.pt513% *0 MOV R6,R0 *: MOV R0,R4 *D MOV R4,R2 *N MOV R2,R6 *X MOV R6,R1 *b MOV R1,R5 *l MOV R5,R3 *v MOV R3,R6 *�B pt135% *�: *�.pt153% *� MOV R6,R2 *� MOV R2,R4 *� MOV R4,R6 *� MOV R6,R3 *� MOV R3,R5 *� MOV R5,R6 *�.pt135% *�; Calculate long gradient *� MOV R8,#1 *�SUB R7,R5,R1 +SUBS R6,R4,R0 +RSBLT R8,R8,#0 +RSBLT R6,R6,#0 + MOV R9,#0 +*]:�U%=9�1�-1:[OPT T% +4CMP R7,R6,ASR#U% +>SUBLE R6,R6,R7,ASL#U% +HADDLE R9,R9,R8,ASL#U%+DC% +R]:�:[OPT T% +\ CMP R6,R7 +fSUBGE R6,R6,R7 +pADDGE R9,R9,R8,ASL#DC% +z]:�U%=DC%-1�1�-1:[OPT T% +�RSBS R6,R7,R6,ASL#1 +�ADDLT R6,R6,R7 +�ADDGE R9,R9,R8,ASL#U% +�]:�:[OPT T% +�RSBS R6,R7,R6,ASL#1 +�ADDGE R9,R9,R8 +�%; Calculate bottom short gradient +� MOV R8,#1 +�SUB R7,R3,R1 +�SUBS R6,R2,R0 +�RSBLT R8,R8,#0 +�RSBLT R6,R6,#0 +�MOV R10,#0 ,]:�U%=9�1�-1:[OPT T% ,CMP R7,R6,ASR#U% ,SUBLE R6,R6,R7,ASL#U% ,$ADDLE R10,R10,R8,ASL#U%+DC% ,.]:�:[OPT T% ,8 CMP R6,R7 ,BSUBGE R6,R6,R7 ,LADDGE R10,R10,R8,ASL#DC% ,V]:�U%=DC%-1�1�-1:[OPT T% ,`RSBS R6,R7,R6,ASL#1 ,jADDLT R6,R6,R7 ,tADDGE R10,R10,R8,ASL#U% ,~]:�:[OPT T% ,�RSBS R6,R7,R6,ASL#1 ,�ADDGE R10,R10,R8 ,�"; Calculate top short gradient ,� MOV R8,#1 ,�SUB R7,R5,R3 ,�SUBS R6,R4,R2 ,�RSBLT R8,R8,#0 ,�RSBLT R6,R6,#0 ,� MOV R4,#0 ,�]:�U%=9�1�-1:[OPT T% ,�CMP R7,R6,ASR#U% ,�SUBLE R6,R6,R7,ASL#U% - ADDLE R4,R4,R8,ASL#U%+DC% - ]:�:[OPT T% - CMP R6,R7 -SUBGE R6,R6,R7 -(ADDGE R4,R4,R8,ASL#DC% -2]:�U%=DC%-1�1�-1:[OPT T% -<RSBS R6,R7,R6,ASL#1 -FADDLT R6,R6,R7 -PADDGE R4,R4,R8,ASL#U% -Z]:�:[OPT T% -dRSBS R6,R7,R6,ASL#1 -nADDGE R4,R4,R8 -x-; Calculate bottom, middle, top in pixels -�/; Also corrects x to nearest vertical pixel -�ADD R6,R5,#1<<DC%-1 -�MOV R6,R6,ASR#DC% -�ADD R5,R3,#1<<DC%-1 -�MOV R5,R5,ASR#DC% -�RSB R3,R3,R5,ASL#DC% -�ADD R3,R3,#1<<DC%-1 -�MOV R3,R3,ASR#DC%-6 -�MUL R7,R3,R4 -�ADD R2,R2,R7,ASR#6 -�9STMFD R13!,{R2,R4,R6}:; top short x,dx, top in pixels -�ADD R4,R1,#1<<DC%-1 -�MOV R4,R4,ASR#DC% .RSB R2,R1,R4,ASL#DC% .ADD R2,R2,#1<<DC%-1 .MOV R2,R2,ASR#DC%-6 ."MUL R3,R2,R10 .,ADD R1,R0,R3,ASR#6 .6MUL R3,R2,R9 .@ADD R0,R0,R3,ASR#6 .J MOV R2,R9 .TMOV R3,R10 .^,; At this point registers are used as... .h; R0,R2 are long x,dx .r!; R1,R3 are bottom short x,dx .|(; R4,R5 are bottom, middle in pixels .�3; top short x,dx and top in pixels are on stack .�RSBS R8,R4,#0 .�MLAGT R0,R8,R2,R0 .�MLAGT R1,R8,R3,R1 .�ADDGT R4,R4,R8 .�OPT �adr(7,col%,2) .�ADD R7,R7,R11,ASL#3 .�LDMIA R7,{R7,R11} .� TST R4,#2 .�MOVNE R7,R7,ROR#16 .�MOVNE R11,R11,ROR#16 .� TST R4,#1 .�MOVNE R8,R11 /MOVNE R11,R7 /MOVNE R7,R8,ROR#16 /LDR R12,scraddr% /&RSB R8,R4,#scheight% /0ADD R12,R12,R8,ASL#SCW% /:ADD R12,R12,R8,ASL#SCW%-2 /D MOV R6,R5 /NCMP R6,#scheight% /XMOVGT R6,#scheight% /bSUBS R4,R6,R4 /l SUBLE R6,R6,R4:; R6 = old R4 /vBLE ptnobottom% /�.yloop% /�SUB R12,R12,#sclinc% /�BL drawline% /�ADD R0,R0,R2 /�ADD R1,R1,R3 /�MOV R8,R11 /�MOV R11,R7 /�MOV R7,R8,ROR#16 /�SUBS R4,R4,#1 /�BGT yloop% /�.ptnobottom% /�9LDMFD R13!,{R1,R3,R4}:; short top x,dx, top in pixels /� CMP R6,#0 0SWILT &141 0SUBS R8,R6,R5 0MLAGT R1,R8,R3,R1 0 CMP R4,#scheight% 0*MOVGT R4,#scheight% 04SUBS R4,R4,R6 0>BLE ptnotop% 0H.yloop% 0RSUB R12,R12,#sclinc% 0\BL drawline% 0fADD R0,R0,R2 0pADD R1,R1,R3 0zMOV R8,R11 0�MOV R11,R7 0�MOV R7,R8,ROR#16 0�SUBS R4,R4,#1 0�BGT yloop% 0� .ptnotop% 0�LDMFD R13!,{R0-R12,PC} 0�: 0�; Draws a horizontal line 0�2; R0 is left end, R1 is right end, both in DC% 0� ; R12 is screen line address 0�; R11 is colour 0�; Corrupts R0-R2,R8-R12 0�: 1.drawline% 1!STMFD R13!,{R0-R2,R8-R12,R14} 1 CMP R0,R1 1$MOVGT R2,R0 1.MOVGT R0,R1 18MOVGT R1,R2 1BCMP R0,#0<<DC% 1LMOVLT R0,#0<<DC% 1VCMP R1,#scwidth%<<DC% 1`MOVGT R1,#scwidth%<<DC% 1jMOV R0,R0,ASR#DC% 1tMOV R1,R1,ASR#DC% 1~ CMP R0,R1 1�"LDMGEFD R13!,{R0-R2,R8-R12,PC} 1�MOV R2,R0,ASR#2 1�ADD R12,R12,R2,ASL#2 1�CMP R2,R1,ASR#2 1�BEQ dhsmall% 1�MOV R8,R11 1�MOV R9,R11 1�MOV R10,R11 1�SUB R1,R1,R0 1�� R0,R0,#3 1�ADR R2,dhleftj% 1�LDR R0,[R2,R0,ASL#2] 2 ADD PC,R2,R0 2 : 2 .dhleftj% 2]:�U%=0�3:[OPT T% 2(EQUD dhend%-dhleftj% 22]:�:[OPT T% 2<: 2FOPT �registerj(dhleftj%,0) 2P.dhmiddle% 2ZMOV R2,R1,ASR#4 2d� R1,R1,#15 2nADR R0,dhrightj% 2xLDR R1,[R0,R1,ASL#2] 2� CMP R2,#0 2�ADDLE PC,R0,R1 2�.xloop% 2�STMIA R12!,{R8-R11} 2�SUBS R2,R2,#1 2�BGT xloop% 2�ADD PC,R0,R1 2�: 2�]:�U%=1�3:[OPT T% 2�OPT �registerj(dhleftj%,U%) 2�LDR R2,[R12] 2�MOV R2,R2,LSL#4-U%<<3 2��R R2,R2,R11,LSR#U%<<3 3MOV R2,R2,ROR#4-U%<<3 3STR R2,[R12],#4 3SUB R1,R1,#4-U% 3"B dhmiddle% 3,]:�:[OPT T% 36: 3@.dhrightj% 3J]:�U%=0�15:[OPT T% 3TEQUD dhend%-dhrightj% 3^]:�:[OPT T% 3h: 3r%]:�U%=4�15�4:W%=8+(U%>>2):[OPT T% 3| OPT �registerj(dhrightj%,U%) 3�STMIA R12,{R8-(W%-1)} 3� LDMFD R13!,{R0-R2,R8-R12,PC} 3�]:�:[OPT T% 3�: 3�6]:�U%=0�15�4:�V%=1�3:S%=U%+V%:W%=8+(U%>>2):[OPT T% 3� OPT �registerj(dhrightj%,S%) 3�LDR R0,[R12,#U%] 3�MOV R0,R0,LSR#V%<<3 3��R R0,R0,W%,LSL#4-V%<<3 3�MOV W%,R0,ROR#4-V%<<3 3�STMIA R12,{R8-W%} 3� LDMFD R13!,{R0-R2,R8-R12,PC} 3�]:�,:[OPT T% 4: 4 .dhsmall% 4� R0,R0,#3 4&� R1,R1,#3 40ADD R1,R0,R1,ASL#2 4:ADR R0,dhsmallj% 4DLDR R1,[R0,R1,ASL#2] 4NADD PC,R0,R1 4X: 4b.dhsmallj% 4l]:�V%=0�3:�U%=0�3:[OPT T% 4vEQUD dhend%-dhsmallj% 4�]:�,:[OPT T% 4�: 4� ]:�U%=0�2:�V%=U%+1�3:[OPT T% 4�(OPT �registerj(dhsmallj%,U%+(V%<<2)) 4�LDR R0,[R12] 4�]:�U%>0� 4�[OPT T% 4�MOV R0,R0,ROR#U%<<3 4�MOV R11,R11,ROR#U%<<3 4�] 4� �:[OPT T% 4�MOV R0,R0,LSR#V%-U%<<3 4�!�R R0,R0,R11,LSL#4-(V%-U%)<<3 5MOV R0,R0,ROR#4-V%<<3 5STR R0,[R12] 5 LDMFD R13!,{R0-R2,R8-R12,PC} 5 ]:�,:[OPT T% 5*: 54.dhend% 5> LDMFD R13!,{R0-R2,R8-R12,PC} 5H: 5R .testpos% 5\(EQUD 1<<VC%:EQUD 0:EQUD 0:; E-vector 5f(EQUD 0:EQUD 1<<VC%:EQUD 0:; N-vector 5p(EQUD 0:EQUD 0:EQUD 1<<VC%:; U-vector 5z)EQUD 0:EQUD 0:EQUD 10<<AC%:; Position 5�: 5�.matrix% 5�(EQUD 1<<VC%:EQUD 0:EQUD 0:; E-vector 5�(EQUD 0:EQUD 1<<VC%:EQUD 0:; N-vector 5�(EQUD 0:EQUD 0:EQUD 1<<VC%:; U-vector 5�2EQUD 0:EQUD 0:EQUD 10<<AC%:; Relative position 5�,EQUD 0:EQUD 0:EQUD 1<<VC%:; Light vector 5�: 5�#; Draws a vector graphics shape 5� ; Uses testpos at the moment 5�/; Uses shape data from shape% at the moment 5�5; Eventually, it will expect matrix% to be set up 5�); and R12 to be shape data 6: 6.drawshape% 6STMFD R13!,{R14} 6$ADR R12,testpos% 6.BL makematrix% 68; Fill points% 6BOPT �adr(12,shape%,2) 6LOPT �adr(11,points%,2) 6VLDR R10,[R12],#4 6`.ploop% 6jLDMIA R12!,{R0-R2} 6tADR R9,matrix% 6~LDMIA R9!,{R3-R5} 6�MUL R6,R0,R3 6�MUL R7,R0,R4 6�MUL R8,R0,R5 6�LDMIA R9!,{R3-R5} 6�MLA R6,R1,R3,R6 6�MLA R7,R1,R4,R7 6�MLA R8,R1,R5,R8 6�LDMIA R9!,{R3-R5} 6�MLA R6,R2,R3,R6 6�MLA R7,R2,R4,R7 6�MLA R8,R2,R5,R8 6�LDMIA R9!,{R3-R5} 7 %ADD R6,R3,R6,ASR#VC%:; Apparent E 7 %ADD R7,R4,R7,ASR#VC%:; Apparent N 7%ADD R8,R5,R8,ASR#VC%:; Apparent U 7CMP R7,#1<<10 7(MOVLT R0,#1<<31 72BLT dsbehind% 7<CMP R7,#1<<18 7FMOVGE R6,R6,ASR#8 7PMOVGE R7,R7,ASR#8 7ZMOVGE R8,R8,ASR#8 7dCMP R7,#1<<14 7nMOVGE R6,R6,ASR#4 7xMOVGE R7,R7,ASR#4 7�MOVGE R8,R8,ASR#4 7�CMP R7,#1<<12 7�MOVGE R6,R6,ASR#2 7�MOVGE R7,R7,ASR#2 7�MOVGE R8,R8,ASR#2 7�MOV R0,#1<<22 7� MOV R9,#0 7�]:�U%=22�1�-1:[OPT T% 7�CMP R7,R0,ASR#U% 7�SUBLE R0,R0,R7,ASL#U% 7�ADDLE R9,R9,#1<<U% 7�]:�:[OPT T% 7� CMP R7,R0 8ADDLE R9,R9,#1 8MUL R0,R6,R9 8MUL R1,R8,R9 8"MOV R0,R0,ASR#22-(SCW%+DC%) 8,MOV R1,R1,ASR#22-(SCH%+DC%) 86ADD R0,R0,#scwidth%<<DC%-1 8@ADD R1,R1,#scheight%<<DC%-1 8J.dsbehind% 8TSTMIA R11!,{R0-R1} 8^SUBS R10,R10,#1 8hBGT ploop% 8r; Plot the triangles 8|LDR R10,[R12],#4 8�.tloop% 8�#LDMIA R12!,{R0,R2,R4,R6-R8,R11} 8�ADR R1,matrix%+48 8�LDMIA R1,{R1,R3,R5} 8�MUL R1,R6,R1 8�MLA R1,R7,R3,R1 8�MLA R1,R8,R5,R1 8�MOV R1,R1,ASR#VC%+VC%-6 8� CMP R1,#0 8�MOVLT R1,#0 8�CMP R1,#63 8�MOVGT R1,#63 8�ADD R11,R1,R11,ASL#5 9OPT �adr(5,points%,2) 9ADD R0,R5,R0,ASL#3 9LDMIA R0,{R0-R1} 9&ADD R2,R5,R2,ASL#3 90LDMIA R2,{R2-R3} 9:ADD R4,R5,R4,ASL#3 9DLDMIA R4,{R4-R5} 9NCMP R0,#1<<31 9XCMPNE R2,#1<<31 9bCMPNE R4,#1<<31 9lBEQ dsdontplot% 9vSUB R6,R2,R0 9�SUB R7,R5,R1 9�MOV R6,R6,ASR#DC%-4 9�MOV R7,R7,ASR#DC%-4 9�MUL R8,R6,R7 9�SUB R6,R4,R0 9�RSB R7,R3,R1 9�MOV R6,R6,ASR#DC%-4 9�MOV R7,R7,ASR#DC%-4 9�MLA R8,R6,R7,R8 9� CMP R8,#0 9�BLLT plottri% 9�.dsdontplot% 9�SUBS R10,R10,#1 :BGT tloop% :LDMFD R13!,{PC} :: : *; Calculates apparent pos of an object :*; World pos is in R12 :4: :>.makematrix% :HSTMFD R13!,{R14} :ROPT �adr(10,matrix%,2) :\OPT �adr(11,view%+12,2) :f;LDMIA R11,{R0-R1,R2,R3}:; Viewer's heading, pitch, roll :p!LDMIA R12!,{R7-R9}:; E vector :zSUB R6,R9,R8 :�SUB R6,R6,R7 :�STR R6,matrix%+48:; Light E :�MUL R4,R1,R7 :�MUL R6,R0,R8 :�SUB R4,R4,R6 :�MUL R5,R0,R7 :�MLA R5,R1,R8,R5 :�MOV R4,R4,ASR#VC% :�MOV R5,R5,ASR#VC% :�MUL R6,R5,R2 :�MLA R6,R4,R3,R6 :�SUB R6,R9,R6,ASR#VC% :�STMIA R10!,{R4-R6} ;!LDMIA R12!,{R7-R9}:; N vector ;SUB R6,R9,R8 ;SUB R6,R6,R7 ;$STR R6,matrix%+52:; Light N ;.MUL R4,R1,R7 ;8MUL R6,R0,R8 ;BSUB R4,R4,R6 ;LMUL R5,R0,R7 ;VMLA R5,R1,R8,R5 ;`MOV R4,R4,ASR#VC% ;jMOV R5,R5,ASR#VC% ;tMUL R6,R5,R2 ;~MLA R6,R4,R3,R6 ;�SUB R6,R9,R6,ASR#VC% ;�STMIA R10!,{R4-R6} ;�!LDMIA R12!,{R7-R9}:; U vector ;�SUB R6,R9,R8 ;�SUB R6,R6,R7 ;�STR R6,matrix%+56:; Light U ;�MUL R4,R1,R7 ;�MUL R6,R0,R8 ;�SUB R4,R4,R6 ;�MUL R5,R0,R7 ;�MLA R5,R1,R8,R5 ;�MOV R4,R4,ASR#VC% <