diff --git a/bstc.exe b/bstc.exe new file mode 100644 index 0000000..febcbd0 Binary files /dev/null and b/bstc.exe differ diff --git a/bstl.exe b/bstl.exe new file mode 100644 index 0000000..dab87ec Binary files /dev/null and b/bstl.exe differ diff --git a/demo/3d_multicore/3d_multicore-bst-archive-100506-135649.zip b/demo/3d_multicore/3d_multicore-bst-archive-100506-135649.zip new file mode 100644 index 0000000..8e417a3 Binary files /dev/null and b/demo/3d_multicore/3d_multicore-bst-archive-100506-135649.zip differ diff --git a/demo/3d_multicore/3d_multicore.spin b/demo/3d_multicore/3d_multicore.spin new file mode 100644 index 0000000..48c4a37 --- /dev/null +++ b/demo/3d_multicore/3d_multicore.spin @@ -0,0 +1,228 @@ +{ + Multi core transform sample + + derived from "3D Graphics DEMO" by Beau Schwabe (Parallax) +} + +CON + ' enable multi core transform calculation + MultiCoreTranform = true + + ZX = 180 + ZY = 240 + + MaxPoints = 50 + + _CLKMODE = XTAL1 + PLL16X + _XINFREQ = 5_000_000 + _stack = ($3000 + $3000 + 100) >> 2 + + x_tiles = 16 + y_tiles = 12 + + paramcount = 14 + bitmap_base = $2000 + display_base = $5000 + + +VAR + long tv_status '0/1/2 = off/visible/invisible read-only + long tv_enable '0/? = off/on write-only + long tv_pins '%ppmmm = pins write-only + long tv_mode '%ccinp = chroma,interlace,ntsc/pal,swap write-only + long tv_screen 'pointer to screen (words) write-only + long tv_colors 'pointer to colors (longs) write-only + long tv_hc 'horizontal cells write-only + long tv_vc 'vertical cells write-only + long tv_hx 'horizontal cell expansion write-only + long tv_vx 'vertical cell expansion write-only + long tv_ho 'horizontal offset write-only + long tv_vo 'vertical offset write-only + long tv_broadcast 'broadcast frequency (Hz) write-only + long tv_auralcog 'aural fm cog write-only + + word screen[x_tiles * y_tiles] + long colors[64] + + long cogStack[40 * 5] + long pointData[MaxPoints * 5] + byte frame + + +OBJ + tv : "tv" 'located in default Library + gr : "PF_graphics" 'located in default Library + + +PUB start | i,dx,dy + 'start tv + longmove(@tv_status, @tvparams, paramcount) + tv_screen := @screen + tv_colors := @colors + tv.start(@tv_status) + + 'init colors + repeat i from 0 to 63 + colors[i] := $ad02ad06 + + 'init tile screen + i := 0 + repeat dy from 0 to tv_vc - 1 + repeat dx from 0 to tv_hc - 1 + screen[i++] := display_base >> 6 + dy + dx * tv_vc + (dy << 10) + + 'start and setup graphics + gr.start + gr.setup(tv_hc, tv_vc, tv_hc<<3, tv_vc<<3, bitmap_base) + + 'Start transform routines (per object) + if MultiCoreTranform + repeat i from 0 to 4 + cognew( Polyobj(@pointData[ MaxPoints * i ], @PostureData + i * 20), @cogStack[i * 40] ) + + MainLoop + + +PRI MainLoop | i, n, t + n := 0 + t := cnt & |<27 + repeat + gr.clear + gr.width(0) + + repeat i from 0 to n + if !MultiCoreTranform + TranslatePoints( @pointData[ MaxPoints * i ], @PostureData + i * 20, @PointSrc, constant((@PointSrc_End - @PointSrc)/3) ) + repeat until ( word[ @PostureData + i * 20 + 18] == frame ) + gr.lineseq( @pointData[MaxPoints * i], @SeqData) + + gr.copy(display_base) + frame++ + + if ( t <> cnt & |<27 ) + t := cnt & |<27 + n := (n + 1) <# 4 + + 'wait Vsync + repeat until ( tv_status == 1 ) + + +PRI PolyObj(destAddr, postureAddr) + repeat + repeat while word[ postureAddr + 18 ] == frame + TranslatePoints( destAddr, postureAddr, @PointSrc, constant((@PointSrc_End - @PointSrc)/3) ) + + +PRI TranslatePoints( destAddr, postureAddr, pointAddr, numPoints ) | i,dst,px,py,pz,tx,ty,tz,dx,dy,dz,S1,S2,S3,C1,C2,C3,x,y,z + tx := ( word[ postureAddr + 6 ] += word[ postureAddr + 12 ] ) + ty := ( word[ postureAddr + 8 ] += word[ postureAddr + 14 ] ) + tz := ( word[ postureAddr + 10 ] += word[ postureAddr + 16 ] ) + + S1 := Sin(tx) + S2 := Sin(ty) + S3 := Sin(tz) + + C1 := Cos(tx) + C2 := Cos(ty) + C3 := Cos(tz) + + x := ~word[ postureAddr + 0 ] + y := ~word[ postureAddr + 2 ] + z := word[ postureAddr + 4 ] + (C1 ~> 9) ' add C1~>9 for test + + repeat i from 0 to numPoints + px := ~byte[pointAddr++] + py := ~byte[pointAddr++] + pz := ~byte[pointAddr++] + + tx := ( px * C2 - pz * S2 ) ~> 16 + tz := ( px * S2 + pz * C2 ) ~> 16 + ty := ( tz * S1 + py * C1 ) ~> 16 + + dx := ( tx * C3 + ty * S3 ) ~> 16 + x + dy := ( ty * C3 - tx * S3 ) ~> 16 + y + dz := ( tz * C1 - py * S1 ) ~> 16 + z + + word[destAddr ] := dx * ZX / dz + word[destAddr+2] := dy * ZY / dz + destAddr += 4 + + word[ postureAddr + 18 ] := frame + + +pri cos(angle) : x + x := sin(angle + $800) + + +pri sin(angle) : y + '' Get sine of angle (0-8191) + y := angle << 1 & $FFE ' address + if angle & $800 + y := word[$F000 - y] + else + y := word[$E000 + y] + if angle & $1000 + -y + + +DAT +PostureData + ' trans rot rotspeed sync + word 0, 0, 400, 0, 0, 0, 0, 0, 200, 0 + word -120, -80, 400, 0, 0, 0, 50, 30, 40, 0 + word -120, 80, 400, 0, 0, 0, 40, 50, 30, 0 + word 120, -80, 400, 0, 0, 0, 30, 50, 40, 0 + word 120, 80, 400, 0, 0, 0, 50, 40, 30, 0 + +PointSrc + byte -20,-20,-20 + byte -20,-20, 20 + byte -20, 20, 20 + byte -20, 20,-20 + byte 20,-20,-20 + byte 20,-20, 20 + byte 20, 20, 20 + byte 20, 20,-20 + + byte -40,-40,-40 + byte -40,-40, 40 + byte -40, 40, 40 + byte -40, 40,-40 + byte 40,-40,-40 + byte 40,-40, 40 + byte 40, 40, 40 + byte 40, 40,-40 + + byte -70, 0, 0 + byte 70, 0, 0 +PointSrc_End + +SeqData + ' orange thing + byte 13, 1, 16, 0, 4, 17, 5, 1, 16, 2, 6, 17, 7, 3, 16 + byte 5, 1, 0, 1, 2, 3, 0 + byte 5, 1, 4, 5, 6, 7, 4 + ' black cube + byte 10, 2, 8, 9,10,11, 8,12,13,14,15,12 + byte 2, 2, 9,13 + byte 2, 2,10,14 + byte 2, 2,11,15 + byte 0 + + +tvparams long 0 'status + long 1 'enable + 'long %011_0000 'pins Old Board + long %010_0101 'pins New Board + long %0000 'mode + long 0 'screen + long 0 'colors + long x_tiles 'hc + long y_tiles 'vc + long 10 'hx + long 1 'vx + long 0 'ho + long 0 'vo + long 60_000_000 '_xinfreq<<4 'broadcast + long 0 'auralcog + diff --git a/demo/3d_multicore/PF_Graphics.spin b/demo/3d_multicore/PF_Graphics.spin new file mode 100644 index 0000000..1e1eeb4 Binary files /dev/null and b/demo/3d_multicore/PF_Graphics.spin differ diff --git a/demo/3d_multicore/TV.spin b/demo/3d_multicore/TV.spin new file mode 100644 index 0000000..b58adcf Binary files /dev/null and b/demo/3d_multicore/TV.spin differ diff --git a/demo/3d_multicore/_readme_.txt b/demo/3d_multicore/_readme_.txt new file mode 100644 index 0000000..8c014a2 --- /dev/null +++ b/demo/3d_multicore/_readme_.txt @@ -0,0 +1,17 @@ +BST Propeller Archive +Created by Brads Spin Tool Compiler v0.15.4-pre5 - Copyright 2008,2009,2010 All rights reserved +Compiled for i386 Win32 at 14:24:31 on 2010/03/10 + +Archive Created at 13:56:49 On 06/05/10 +Included Objects : +3d_multicore + | + +-----tv + | + +-----PF_graphics + +, + - 3d_multicore.spin + - TV.spin + - PF_Graphics.spin +, diff --git a/demo/3d_multicore/quelle.txt b/demo/3d_multicore/quelle.txt new file mode 100644 index 0000000..2abe423 --- /dev/null +++ b/demo/3d_multicore/quelle.txt @@ -0,0 +1 @@ +http://propfan.wordpress.com/page/2/ diff --git a/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/VGA_JB_001.spin b/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/VGA_JB_001.spin new file mode 100644 index 0000000..d63cf88 Binary files /dev/null and b/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/VGA_JB_001.spin differ diff --git a/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/VGA_JB_Demo.spin b/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/VGA_JB_Demo.spin new file mode 100644 index 0000000..18006e4 --- /dev/null +++ b/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/VGA_JB_Demo.spin @@ -0,0 +1,115 @@ +''*************************************** +''* VGA Tile + Sprite Driver Demo v1.0 * +''* (C) Jim Bagley * +''*************************************** + + _clkmode = xtal1 + pll16x ' enable external clock and pll times 16 + _xinfreq = 5_000_000 ' set frequency to 5 MHZ + +CON + +NUM_COGS = 3 'if not using sprites, you can set this to 1 :) +NUM_SPRITES = 32 '64 'buffer is 3 words ( X,Y,TILENUM), so use even numbers. + +OBJ + vga : "VGA_JB_001" + rend : "VGA_REND_JB_001" + +PUB start | i,c,x,y + vga.start(@vga_params) + rend.start(@rend_params) + + repeat y from 0 to 29 + repeat x from 0 to 63 + PutChar(x,y,word[@map][y*64+x]) + + print(0,0,string("Hallo Welt")) + + c:=$deadface + if NUM_SPRITES>0 + repeat i from 0 to rend_num_sprites-1 step 2 + x:=c? + y:=c? + SetSprite(i ,x ,y,0) + SetSprite(i+1,x+4,y,1) +' SetSprite(i,4+i*3,8+i*2,0) + + repeat + repeat while vga_params<>1 + repeat while vga_params==1 + if NUM_SPRITES>0 + wordmove(@sprite_list,@sprite_list2,3*rend_num_sprites) + repeat i from 0 to rend_num_sprites-1 + sprite_list2[i*3+0]++ + sprite_list2[i*3+1]++ + +PUB print(x,y,str) | c,a + repeat + c:=byte[str++] + if(c==0) + return + a:=-1 + if(c>"A"-1) and (c<"Z"+1) + a:=(c-"A")+10 + if(c>"a"-1) and (c<"z"+1) + a:=(c-"a")+10 + if(c>"0"-1) and (c<"9"+1) + a:=c-"0" + if(a==-1) + screen[y<<6+x++]:=0 + screen[y<<6+x++]:=0 + else + a:=(a<<6)+(@font-@chars) '*64 ( 2 4x8 chars per letter ) + offset from chars to font + screen[y<<6+x++]:=a + screen[y<<6+x++]:=a+32 + +PUB PutChar(x,y,charnum) + screen[y<<6+x]:=charnum<<5 + +PUB SetSprite(sprnum,x,y,tilenum) + sprite_list2[sprnum*3+0]:=x + sprite_list2[sprnum*3+1]:=y + sprite_list2[sprnum*3+2]:=tilenum<<5 + +DAT + +rend_params +rend_cognum long 0 +rend_image long 0 +rend_pixels long @pixelsdata+$10 'pointer to line buffers ( (256+8)*rendercogs ) +rend_screen long @screen+$10 'pointer to screen charmap buffer ( 64x30 ) +rend_chars long @chars+$10 'pointer to screen character image tiles ( 4x8 ) +rend_sprite_ptr long @sprite_list+$10 'pointer to sprite list ( X,Y,CHR ) +rend_sprchr_ptr long @sprchrs+$10 'pointer to sprite image tiles ( 4x8 ) +rend_num_sprites long NUM_SPRITES +'vga_params falls after rend_params +vga_params long 0 'sync +vga_pixels long @pixelsdata+$10 'pointer to line buffers +vga_nextlineptr long @next_line+$10 'pointer to nextline to be draw +vga_enable long 1 'enable display +vga_cogs long NUM_COGS 'number of display lines before looping to top of buffer + +sprite_list word 0[3*NUM_SPRITES] '4 words as it reads data in longs +sprite_list2 word 0[3*NUM_SPRITES] '4 words as it reads data in longs + +next_line long 0 + +pixelsdata byte 0[(256+8)*NUM_COGS] + +screen word 0*32[64*30] 'Character map layout, TILENUM*32, as you can use pixel offsets into chars if you want, or set the charset to 0, and use as pointer to area + +chars file "mario.chr" + +sprchrs +font file "font.chr" + + byte $0f,$0f,$0f,$0f + byte $0f,$03,$03,$0f + byte $0f,$ff,$ff,$0f + byte $0f,$ff,$ff,$0f + byte $0f,$ff,$ff,$0f + byte $0f,$ff,$ff,$0f + byte $0f,$03,$03,$0f + byte $0f,$0f,$0f,$0f + +map file "mario.map" diff --git a/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/VGA_Rend_JB_001.spin b/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/VGA_Rend_JB_001.spin new file mode 100644 index 0000000..f0908ca Binary files /dev/null and b/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/VGA_Rend_JB_001.spin differ diff --git a/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/_README_.txt b/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/_README_.txt new file mode 100644 index 0000000..a29c602 Binary files /dev/null and b/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/_README_.txt differ diff --git a/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/bmp8toLite.c b/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/bmp8toLite.c new file mode 100644 index 0000000..bcc5772 --- /dev/null +++ b/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/bmp8toLite.c @@ -0,0 +1,966 @@ +#include "stdio.h" + +unsigned short header[0x36]; +unsigned char palette[256*4]; +unsigned char proppal[256]; + +unsigned char charcell[8*8]; +unsigned char convchar[8*8]; +unsigned short currentattr; + +unsigned short currentblock; +unsigned short blockcell[4]; +unsigned short blockmap[10240*10240]; +unsigned short blocks[40960*64]; +unsigned short charmap[5120*5120]; +unsigned char chars[20480*64]; +unsigned int charnum; +unsigned int blocknum; +unsigned int blockmapsize=1; +unsigned int blocksize=1; +int yfirst=0; +int justcharmap=0; +int invx=0; +int nopalette=0; +int pal16=0; +int getting_2600=0; + +#define bitmap2 0 +#define bitmap4 1 +#define bitmap16 2 +#define bitmap256 3 +#define C64bitmap2 4 +#define C64bitmap4 5 +#define AMSbitmap4 6 +#define AMSbitmap16 7 +#define charmap2 8 +#define charmap4 9 +#define charmap16 10 +#define charmap256 11 +#define C64sprites 12 +#define VGAchars4x8 13 + +int charand=0x03; +int paland=0xfc; +int palshift=2; +int mode=charmap4; +int fat=0; + +int repeatable=0; +int flipable=0; + +char extjcs[]="JCS"; //c64 mode sprites +char extcb2[]="CB2"; //c64 mode bitmap2col +char extcb4[]="CB4"; //c64 mode bitmap4col +char extjcc[]="JCC"; //c64 mode characters + +char extab4[]="AB4"; //Ams mode 4colour bitmap +char exta16[]="A16"; //Ams mode 16colour fat bitmap +char extas4[]="AS4"; //Ams mode 4colour sprite +char extas6[]="AS6"; //Ams mode 16colour fat sprite + +char extjb2[]="JB2"; +char extjb4[]="JB4"; +char extj16[]="J16"; +char extj8b[]="J8B"; +char extbm2[]="BM2"; +char extbm4[]="BM4"; +char extb16[]="B16"; +char extb8b[]="B8B"; +char extvga[]="VGA"; +char *ext=extjb4; + +char fname[1024]; +unsigned char screen[4096*4096]; + +unsigned int scrwidth; +unsigned int scrheight; + +int doingvga; + +unsigned char PropRGBs[256*4]={ + 0x04,0x05,0x05,0x00, 0x02,0x04,0x04,0x00, 0x04,0x06,0x06,0x00, 0x31,0x34,0x33,0x00, 0x64,0x66,0x66,0x00, 0x97,0x9b,0x9b,0x00, 0xcf,0xd0,0xd0,0x00, 0xf0,0xf9,0xfa,0x00, 0x29,0x8c,0xa1,0x00, 0x44,0x0a,0x0e,0x00, 0x75,0x00,0x00,0x00, 0x9f,0x2c,0x26,0x00, 0xd4,0x63,0x5c,0x00, 0xfb,0x97,0x90,0x00, 0xf4,0xc5,0xbe,0x00, 0x23,0x5e,0x72,0x00, + 0x02,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x03,0x05,0x05,0x00, 0x30,0x33,0x33,0x00, 0x62,0x65,0x65,0x00, 0x96,0x99,0x99,0x00, 0xcd,0xce,0xcd,0x00, 0xef,0xf7,0xfb,0x00, 0x21,0x7b,0xd7,0x00, 0x3c,0x07,0x19,0x00, 0x6f,0x06,0x00,0x00, 0x97,0x33,0x11,0x00, 0xcc,0x69,0x43,0x00, 0xfe,0x9e,0x75,0x00, 0xf6,0xc9,0xa8,0x00, 0x1e,0x4c,0xa9,0x00, + 0x02,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x03,0x05,0x05,0x00, 0x30,0x33,0x33,0x00, 0x62,0x66,0x65,0x00, 0x96,0x9a,0x99,0x00, 0xcd,0xcf,0xcd,0x00, 0xf1,0xf6,0xfd,0x00, 0x25,0x66,0xf4,0x00, 0x21,0x04,0x21,0x00, 0x4b,0x0e,0x00,0x00, 0x77,0x3d,0x02,0x00, 0xac,0x73,0x2d,0x00, 0xe3,0xa9,0x5e,0x00, 0xf3,0xd1,0x95,0x00, 0x1f,0x36,0xdc,0x00, + 0x02,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x03,0x05,0x04,0x00, 0x30,0x33,0x33,0x00, 0x62,0x66,0x65,0x00, 0x95,0x99,0x99,0x00, 0xcc,0xcf,0xcd,0x00, 0xf4,0xf5,0xfd,0x00, 0x47,0x54,0xf7,0x00, 0x08,0x03,0x22,0x00, 0x1d,0x16,0x00,0x00, 0x4c,0x45,0x01,0x00, 0x80,0x7b,0x23,0x00, 0xb8,0xb1,0x51,0x00, 0xe0,0xd8,0x8a,0x00, 0x23,0x24,0xef,0x00, + 0x02,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x03,0x05,0x04,0x00, 0x30,0x33,0x33,0x00, 0x62,0x65,0x65,0x00, 0x96,0x99,0x99,0x00, 0xca,0xcf,0xcc,0x00, 0xf9,0xf4,0xfd,0x00, 0xad,0x47,0xf7,0x00, 0x14,0x05,0x23,0x00, 0x02,0x1c,0x00,0x00, 0x1e,0x4a,0x01,0x00, 0x52,0x80,0x22,0x00, 0x85,0xb7,0x50,0x00, 0xb8,0xdd,0x88,0x00, 0x7c,0x1d,0xf0,0x00, + 0x01,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x03,0x05,0x05,0x00, 0x30,0x33,0x33,0x00, 0x63,0x66,0x65,0x00, 0x96,0x9a,0x99,0x00, 0xc9,0xd0,0xcc,0x00, 0xfc,0xf3,0xfc,0x00, 0xf4,0x41,0xf7,0x00, 0x24,0x05,0x23,0x00, 0x00,0x1e,0x00,0x00, 0x02,0x4c,0x01,0x00, 0x28,0x82,0x2a,0x00, 0x55,0xb9,0x5a,0x00, 0x90,0xdd,0x90,0x00, 0xe6,0x1c,0xdf,0x00, + 0x01,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x03,0x05,0x05,0x00, 0x30,0x33,0x33,0x00, 0x63,0x66,0x65,0x00, 0x96,0x9a,0x99,0x00, 0xca,0xd0,0xcd,0x00, 0xfc,0xf3,0xfa,0x00, 0xfd,0x49,0xe3,0x00, 0x28,0x06,0x20,0x00, 0x00,0x1b,0x00,0x00, 0x00,0x4a,0x0c,0x00, 0x09,0x7f,0x3d,0x00, 0x31,0xb6,0x6f,0x00, 0x70,0xdb,0xa1,0x00, 0xf6,0x1c,0xb2,0x00, + 0x01,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x03,0x05,0x05,0x00, 0x30,0x33,0x33,0x00, 0x62,0x65,0x65,0x00, 0x96,0x99,0x99,0x00, 0xca,0xcf,0xce,0x00, 0xfc,0xf3,0xf6,0x00, 0xfb,0x5b,0xa8,0x00, 0x29,0x06,0x15,0x00, 0x00,0x15,0x00,0x00, 0x00,0x44,0x21,0x00, 0x00,0x79,0x57,0x00, 0x1d,0xb0,0x8a,0x00, 0x5e,0xd5,0xb6,0x00, 0xf2,0x28,0x72,0x00, + 0x02,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x03,0x05,0x05,0x00, 0x30,0x33,0x33,0x00, 0x62,0x65,0x65,0x00, 0x96,0x99,0x99,0x00, 0xc9,0xcf,0xcf,0x00, 0xfc,0xf4,0xf4,0x00, 0xfb,0x6f,0x63,0x00, 0x29,0x09,0x07,0x00, 0x00,0x0d,0x0e,0x00, 0x00,0x3c,0x3d,0x00, 0x00,0x72,0x73,0x00, 0x1b,0xa7,0xaa,0x00, 0x5d,0xce,0xd0,0x00, 0xf2,0x3c,0x2f,0x00, + 0x01,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x03,0x05,0x04,0x00, 0x30,0x33,0x33,0x00, 0x63,0x65,0x65,0x00, 0x96,0x99,0x99,0x00, 0xca,0xcf,0xd0,0x00, 0xfc,0xf6,0xf1,0x00, 0xfc,0x83,0x29,0x00, 0x28,0x0d,0x0a,0x00, 0x00,0x03,0x2a,0x00, 0x00,0x32,0x58,0x00, 0x06,0x68,0x8e,0x00, 0x2b,0x9d,0xc4,0x00, 0x6c,0xc6,0xe8,0x00, 0xf4,0x50,0x1c,0x00, + 0x02,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x02,0x05,0x04,0x00, 0x30,0x33,0x33,0x00, 0x62,0x65,0x65,0x00, 0x96,0x9a,0x99,0x00, 0xca,0xce,0xd0,0x00, 0xfc,0xf7,0xf0,0x00, 0xfa,0x98,0x20,0x00, 0x26,0x10,0x19,0x00, 0x00,0x00,0x41,0x00, 0x00,0x29,0x6d,0x00, 0x20,0x5e,0xa2,0x00, 0x4d,0x93,0xd9,0x00, 0x89,0xbe,0xef,0x00, 0xf0,0x65,0x1c,0x00, + 0x02,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x03,0x05,0x05,0x00, 0x30,0x33,0x33,0x00, 0x62,0x65,0x65,0x00, 0x96,0x9a,0x99,0x00, 0xca,0xce,0xd0,0x00, 0xfa,0xf8,0xf0,0x00, 0xc3,0xa9,0x21,0x00, 0x18,0x12,0x23,0x00, 0x00,0x00,0x4e,0x00, 0x17,0x22,0x79,0x00, 0x48,0x57,0xae,0x00, 0x7b,0x8b,0xe5,0x00, 0xb0,0xb8,0xf1,0x00, 0x96,0x78,0x1c,0x00, + 0x01,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x03,0x05,0x05,0x00, 0x30,0x33,0x33,0x00, 0x62,0x65,0x65,0x00, 0x96,0x9a,0x99,0x00, 0xcc,0xce,0xd0,0x00, 0xf5,0xf9,0xf0,0x00, 0x57,0xb5,0x21,0x00, 0x07,0x14,0x22,0x00, 0x15,0x00,0x4f,0x00, 0x41,0x1d,0x7a,0x00, 0x78,0x52,0xaf,0x00, 0xad,0x85,0xe6,0x00, 0xd9,0xb4,0xf2,0x00, 0x2e,0x85,0x1d,0x00, + 0x01,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x03,0x05,0x05,0x00, 0x30,0x33,0x33,0x00, 0x62,0x65,0x65,0x00, 0x96,0x9a,0x99,0x00, 0xcd,0xce,0xd0,0x00, 0xf1,0xfa,0xf1,0x00, 0x27,0xba,0x22,0x00, 0x1b,0x14,0x1a,0x00, 0x41,0x00,0x45,0x00, 0x6d,0x1c,0x6f,0x00, 0xa3,0x50,0xa5,0x00, 0xdb,0x83,0xdb,0x00, 0xf1,0xb3,0xf1,0x00, 0x1e,0x8a,0x1f,0x00, + 0x02,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x03,0x05,0x05,0x00, 0x30,0x33,0x33,0x00, 0x62,0x65,0x65,0x00, 0x96,0x9a,0x99,0x00, 0xcd,0xce,0xd0,0x00, 0xef,0xfa,0xf3,0x00, 0x22,0xb3,0x28,0x00, 0x36,0x12,0x0b,0x00, 0x67,0x00,0x30,0x00, 0x91,0x1e,0x5c,0x00, 0xc5,0x53,0x92,0x00, 0xfa,0x86,0xc8,0x00, 0xf6,0xb5,0xed,0x00, 0x1f,0x83,0x21,0x00, + 0x02,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x03,0x05,0x05,0x00, 0x30,0x33,0x33,0x00, 0x62,0x65,0x65,0x00, 0x95,0x9a,0x99,0x00, 0xcd,0xce,0xcf,0x00, 0xef,0xf9,0xf6,0x00, 0x22,0xa1,0x56,0x00, 0x46,0x0e,0x02,0x00, 0x7b,0x00,0x15,0x00, 0xa3,0x23,0x43,0x00, 0xd7,0x58,0x78,0x00, 0xff,0x8b,0xaf,0x00, 0xf5,0xba,0xd8,0x00, 0x1f,0x74,0x2c,0x00, +}; + +unsigned char colours_bmp[86*3]={ + 0x78,0x02,0x2a,0x83,0x0b,0x09,0x6e,0x39,0x1a,0x3b,0x2b,0x13,0x2c,0x29,0x1d,0x27,0x30,0x20,0x15,0x3f,0x11,0x14,0x35,0x1c,0x11,0x36,0x2f,0x13,0x3a,0x48,0x0e,0x37,0x58,0x07,0x22,0x73,0x1f,0x14,0x67,0x48,0x1e,0x74,0x45,0x11,0x4f,0x65,0x0f,0x42, + 0xb7,0x09,0x45,0xa8,0x13,0x12,0xa1,0x54,0x25,0x79,0x57,0x22,0x6b,0x62,0x41,0x57,0x6b,0x44,0x27,0x7b,0x1c,0x24,0x69,0x37,0x1f,0x68,0x5a,0x20,0x5e,0x72,0x14,0x4f,0x7b,0x0e,0x33,0xa1,0x32,0x25,0x9c,0x60,0x2b,0x98,0x6c,0x1a,0x79,0x96,0x1a,0x66, + 0xcf,0x4a,0x79,0xc0,0x4f,0x4d,0xc0,0x72,0x40,0xac,0x7c,0x2e,0xa0,0x8f,0x4f,0x85,0x9c,0x6d,0x3a,0xa2,0x32,0x42,0xa6,0x69,0x4c,0xa5,0x94,0x42,0x84,0x9f,0x37,0x76,0xa3,0x4c,0x6e,0xb8,0x7f,0x73,0xbc,0x91,0x68,0xb8,0x9d,0x43,0xac,0xc9,0x5a,0x9f, + 0xcb,0x8b,0xa3,0xbe,0x81,0x7e,0xc0,0x8d,0x6d,0xbe,0x9f,0x6c,0xbb,0xae,0x7f,0xa2,0xb4,0x8e,0x7b,0xb8,0x78,0x75,0xbd,0x92,0x86,0xb6,0xad,0x72,0xa0,0xb6,0x7b,0xa0,0xbc,0x91,0xa0,0xc0,0x9e,0x97,0xbb,0xa7,0x8d,0xbe,0xb5,0x85,0xbc,0xcb,0x85,0xb0, + 0xd7,0xb3,0xc0,0xca,0xa8,0xa8,0xcc,0xb4,0xa5,0xcc,0xbb,0xa2,0xc9,0xc3,0xaf,0xbf,0xca,0xb2,0xb5,0xcb,0xb3,0xb3,0xcc,0xbe,0xb0,0xcb,0xc8,0xa8,0xc0,0xcb,0xa5,0xba,0xca,0xb2,0xba,0xcc,0xb9,0xb4,0xcb,0xbd,0xaf,0xca,0xc5,0xb2,0xc8,0xd6,0xb7,0xcb, + 0x00,0x00,0x00,0x33,0x33,0x33,0x77,0x77,0x77,0xaa,0xaa,0xaa,0xee,0xee,0xee,0xff,0xff,0xff, +}; + +unsigned char colours_idx[86]={ + 0x0a,0x1a,0x2a,0x3a,0x4a,0x5a,0x6a,0x7a,0x8a,0x9a,0xaa,0xba,0xca,0xda,0xea,0xfa, + 0x0b,0x1b,0x2b,0x3b,0x4b,0x5b,0x6b,0x7b,0x8b,0x9b,0xab,0xbb,0xcb,0xdb,0xeb,0xfb, + 0x0c,0x1c,0x2c,0x3c,0x4c,0x5c,0x6c,0x7c,0x8c,0x9c,0xac,0xbc,0xcc,0xdc,0xec,0xfc, + 0x0d,0x1d,0x2d,0x3d,0x4d,0x5d,0x6d,0x7d,0x8d,0x9d,0xad,0xbd,0xcd,0xdd,0xed,0xfd, + 0x0e,0x1e,0x2e,0x3e,0x4e,0x5e,0x6e,0x7e,0x8e,0x9e,0xae,0xbe,0xce,0xde,0xee,0xfe, + 0x02,0x03,0x04,0x05,0x06,0x07 +}; +unsigned char propcolours[256]; + +unsigned char getpixelcolour(int r,int g,int b) +{ +int tr,tg,tb; +int i,d,t; +unsigned char c; + if(doingvga) + if(r==255 && g==0 && b==255) return 0; + return ((r>>6)<<2)+((g>>6)<<4)+((b>>6)<<6)+3; + c=80; + d=10000; + + for(i=0;i<256;i++) + { + tr=PropRGBs[i*4+0]-r; + tg=PropRGBs[i*4+1]-g; + tb=PropRGBs[i*4+2]-b; + tr=abs(tr); + tg=abs(tg); + tb=abs(tb); + t=tr; + if(tg>t) t=tg; + if(tb>t) t=tb; + + if (tt) t=tg; + if(tb>t) t=tb; + + if (t>3] =((src[i]&1)<<0); + if((i&7)==1) dst[i>>3]|=((src[i]&1)<<1); + if((i&7)==2) dst[i>>3]|=((src[i]&1)<<2); + if((i&7)==3) dst[i>>3]|=((src[i]&1)<<3); + if((i&7)==4) dst[i>>3]|=((src[i]&1)<<4); + if((i&7)==5) dst[i>>3]|=((src[i]&1)<<5); + if((i&7)==6) dst[i>>3]|=((src[i]&1)<<6); + if((i&7)==7) dst[i>>3]|=((src[i]&1)<<7); + } +} + +void convcharto2bit(int chr) +{ +unsigned char *src=&chars[chr*64]; +unsigned char *dst=&convchar[0]; +int i; + if(fat) + { + for(i=0;i<64;i++) + { + if((i&7)==0) dst[i>>3] =((src[i]&3)<<0); + if((i&7)==2) dst[i>>3]|=((src[i]&3)<<2); + if((i&7)==4) dst[i>>3]|=((src[i]&3)<<4); + if((i&7)==6) dst[i>>3]|=((src[i]&3)<<6); + } + } + else + { + for(i=0;i<64;i++) + { + if((i&3)==0) dst[i>>2] =((src[i]&3)<<0); + if((i&3)==1) dst[i>>2]|=((src[i]&3)<<2); + if((i&3)==2) dst[i>>2]|=((src[i]&3)<<4); + if((i&3)==3) dst[i>>2]|=((src[i]&3)<<6); + } + } +} + +void convcharto4bit(int chr) +{ +unsigned char *src=&chars[chr*64]; +unsigned char *dst=&convchar[0]; +int i; + if(fat) + { + for(i=0;i<64;i++) + { + if((i&3)==0) dst[i>>2] =((src[i]&15)<<0); + if((i&3)==2) dst[i>>2]|=((src[i]&15)<<4); + } + } + else + { + for(i=0;i<64;i++) + { + if((i&1)==0) dst[i>>1] =((src[i]&15)<<0); + if((i&1)==1) dst[i>>1]|=((src[i]&15)<<4); + } + } +} + +void convcharto8bit(int chr) +{ +unsigned char *src=&chars[chr*64]; +unsigned char *dst=&convchar[0]; +int i; + for(i=0;i<64;i++) + { + dst[i]=src[i]; + } +} + +void getcharacter(int x,int y) +{ +int xx,yy,i,j; + currentattr=0; + for(yy=0;yy<8;yy++) + { + for(xx=0;xx<8;xx++) + { + charcell[yy*8+xx]=screen[(((y*8)+yy)*scrwidth)+((x*8)+xx)]; + if(charcell[yy*8+xx]&paland) + { + currentattr=( ( charcell[yy*8+xx] & paland ) >> palshift ); + } + charcell[yy*8+xx]&=charand; + } + } + + if(repeatable) + { + j=0; + for(i=0;i>3))+x]=currentattr; + } + else + { + for(i=0;i<64;i++) chars[(charnum*64)+i]=charcell[i]; + currentattr=(currentattr&0x3c00)+charnum; + charnum++; + } +} + +void get4x8character(int x,int y) +{ +int xx,yy,i,j; + currentattr=0; + for(yy=0;yy<8;yy++) + { + for(xx=0;xx<4;xx++) + { + charcell[yy*8+xx]=proppal[screen[(((y*8)+yy)*scrwidth)+((x*4)+xx)]]; + if(charcell[yy*8+xx]&paland) + { + currentattr=( ( charcell[yy*8+xx] & paland ) >> palshift ); + } + charcell[yy*8+xx]&=charand; + charcell[yy*8+xx+4]=0; + } + } + + if(repeatable) + { + j=0; + for(i=0;i>(7-x))&1; + } + if(mode==charmap4) + { + if(fat) + pix=(buf[y]>>(6-((x&3)*2)))&3; + else + pix=(buf[y*2+1-(x>>2)]>>(6-((x&3)*2)))&3; + } + if(mode==charmap16) + { + if(fat) + pix=(buf[y*2+1-(x>>1)]>>(4-((x&1)*4)))&15; + else + pix=(buf[y*4+3-(x>>1)]>>(4-((x&1)*4)))&15; + } + if(mode==charmap256) + { + pix=buf[y*8+x]; + } + if(mode==VGAchars4x8) + { + pix=buf[y*4+x]; + } + chars[i*64+y*8+7-x]=pix; + } + if(fat) + { + chars[i*64+y*8+0]=chars[i*64+y*8+4]; + chars[i*64+y*8+1]=chars[i*64+y*8+4]; + chars[i*64+y*8+2]=chars[i*64+y*8+5]; + chars[i*64+y*8+3]=chars[i*64+y*8+5]; + chars[i*64+y*8+4]=chars[i*64+y*8+6]; + chars[i*64+y*8+5]=chars[i*64+y*8+6]; + chars[i*64+y*8+6]=chars[i*64+y*8+7]; + chars[i*64+y*8+7]=chars[i*64+y*8+7]; + } + } + } + fclose(f); +} +int main(int c,char **s) +{ +unsigned char palbuf[256*4]; +int i,j,x,y,w,h,xx,yy; +int bytesize,byteand,byteshift,byteout; +FILE *f; +int getcharfileindex=0; + + doingvga=0; + justcharmap=0; + blocknum=0; + charnum=0; + blocksize=1; + blockmapsize=1; + charnum=0; + blocknum=0; + yfirst=0; + fat=0; + + if(c<2) + { + printf("bmp8toLite.exe (C) 2009 Jim Bagley\n"); + printf("usage :-\n"); + printf("bmp8toLite.exe Filename <-options>\n"); + printf("Filename is without the '.bmp' extension\n"); + printf("-vga use VGA colours for the palette\n"); + printf("-c64s Grab C64 sprites, C64 sprites are 24x21, it will grab the size of the bmp\n"); + printf(" C64 sprites can be either fat pixel(4colour) or fine pixel(2colour)\n"); + printf("-c64bitmap2 Grab a C64 2 colour mode bitmap image\n"); + printf("-c64bitmap4 Grab a C64 4 colour mode bitmap image ( fat pixels )\n"); + printf("-amsbitmap4 Grab Amstrad 4 colour bitmap mode ( fine pixels )\n"); + printf("-amsbitmap16 Grab Amstrad 16 colour bitmap mode ( fat pixels )\n"); + printf("-bitmap2 Grab screen as 1bit ( 2 colour with attributes ) bitmap\n"); + printf("-bitmap4 Grab screen as 2bit ( 4 colour with attributes ) bitmap\n"); + printf("-bitmap16 Grab screen as 4bit ( 16 colour with attributes ) bitmap\n"); + printf("-bitmap256 Grab screen as 8bit ( 256 colour ) bitmap\n"); + printf("-charmap2 Grab screen as 1bit ( 2 colour with attributes ) character map\n"); + printf("-charmap4 Grab screen as 2bit ( 4 colour with attributes ) character map\n"); + printf("-charmap16 Grab screen as 4bit ( 16 colour with attributes ) character map\n"); + printf("-charmap256 Grab screen as 8bit ( 256 colour ) character map\n"); + printf("-c64charmap4 Grab screen as 2bit fat pixel ( 4 colour with attributes ) character map\n"); + printf("-amscharmap16 Grab screen as 4bit fat pixel ( 16 colour with attributes ) character map\n"); + printf("-invx Invert X pixel order per byte\n"); +// printf("-flip Turns on Character repeat check and flip checking for X and Y flippable characters\n"); + printf("-rpt Turns on Character repeat check, for maps, ie doesn't store same character twice.\n"); + printf("-repeat same as -rpt.\n"); + printf("-repeatable same as -rpt.\n"); + printf("-1x1 Sets blocks to 1x1 (8x8 pixels) for charmap grabbing.\n"); + printf("-2x2 Sets blocks to 2x2 (16x16 pixels) for charmap grabbing.\n"); + printf("-4x4 Sets blocks to 4x4 (32x32 pixels) for charmap grabbing.\n"); + printf("-8x8 Sets blocks to 8x8 (64x64 pixels) for charmap grabbing.\n"); + printf("-yfirst Sets Y grab first for map layout\n"); + printf("-xfirst Sets X grab first for map layout (default)\n"); + printf("-invx inverts the pixel order in a byte for spectrum and fast spectrum\n"); + printf("-nopal Don't save palette in 8bit mode, use real colour values\n"); + printf("-2600 Grab a 2600 style background\n"); + printf("-using grab chars from screen, but using a file as a base font\n"); + } + + while(c>2) + { + if(jcmp(s[c-1],"-vga")) {doingvga=1;c--;} + else if(jcmp(s[c-1],"-c64s")) {mode=C64sprites;ext=extjcs;charand=1;paland=0xfe;palshift=1;c--;} + else if(jcmp(s[c-1],"-c64bitmap2")) {mode=C64bitmap2;ext=extcb2;charand=1;paland=0xfe;palshift=1;c--;} + else if(jcmp(s[c-1],"-c64bitmap4")) {mode=C64bitmap4;ext=extcb4;charand=3;paland=0xfc;palshift=2;c--;} + else if(jcmp(s[c-1],"-amsbitmap4")) {mode=AMSbitmap4;ext=extab4;charand=3;paland=0xfc;palshift=2;c--;} + else if(jcmp(s[c-1],"-amsbitmap16")) {mode=AMSbitmap16;ext=exta16;charand=15;paland=0xf0;palshift=4;c--;} + else if(jcmp(s[c-1],"-bitmap2")) {mode=bitmap2;ext=extbm2;charand=1;paland=0xfe;palshift=1;c--;} + else if(jcmp(s[c-1],"-bitmap4")) {mode=bitmap4;ext=extbm4;charand=3;paland=0xfc;palshift=2;c--;} + else if(jcmp(s[c-1],"-bitmap16")) {mode=bitmap16;ext=extb16;charand=15;paland=0xfe;palshift=4;c--;} + else if(jcmp(s[c-1],"-bitmap256")) {mode=bitmap256;ext=extb8b;charand=255;paland=0;palshift=0;c--;} + else if(jcmp(s[c-1],"-charmap2")) {mode=charmap2;ext=extjb2;charand=1;paland=0xfe;palshift=1;c--;} + else if(jcmp(s[c-1],"-charmap4")) {mode=charmap4;ext=extjb4;charand=3;paland=0xfc;palshift=2;c--;} + else if(jcmp(s[c-1],"-charmap16")) {mode=charmap16;ext=extj16;charand=15;paland=0xf0;palshift=4;c--;} + else if(jcmp(s[c-1],"-charmap256")) {mode=charmap256;ext=extj8b;charand=255;paland=0;palshift=0;c--;} + else if(jcmp(s[c-1],"-vga4x8")) {mode=VGAchars4x8;ext=extj8b;charand=255;paland=0;palshift=0;c--;fat=1;doingvga=1;repeatable=1;nopalette=1;justcharmap=1;blockmapsize=1;blocksize=1;} + else if(jcmp(s[c-1],"-c64charmap4")) {mode=charmap4;ext=extjb4;charand=3;paland=0xfc;palshift=2;c--;fat=1;} + else if(jcmp(s[c-1],"-amscharmap16")){mode=charmap16;ext=extj16;charand=15;paland=0xf0;palshift=4;c--;fat=1;} + else if(jcmp(s[c-1],"-flip")) {repeatable=1;flipable=1;c--;} + else if(jcmp(s[c-1],"-flipable")) {repeatable=1;flipable=1;c--;} + else if(jcmp(s[c-1],"-norpt")) {repeatable=0;c--;} + else if(jcmp(s[c-1],"-norepeat")) {repeatable=0;c--;} + else if(jcmp(s[c-1],"-notrepeatable")) {repeatable=0;c--;} + else if(jcmp(s[c-1],"-rpt")) {repeatable=1;c--;} + else if(jcmp(s[c-1],"-repeat")) {repeatable=1;c--;} + else if(jcmp(s[c-1],"-repeatable")) {repeatable=1;c--;} + else if(jcmp(s[c-1],"-1x1")) {justcharmap=1;blockmapsize=1;blocksize=1;c--;} + else if(jcmp(s[c-1],"-2x2")) {justcharmap=0;blockmapsize=2;blocksize=4;c--;} + else if(jcmp(s[c-1],"-4x4")) {justcharmap=0;blockmapsize=4;blocksize=16;c--;} + else if(jcmp(s[c-1],"-8x8")) {justcharmap=0;blockmapsize=8;blocksize=64;c--;} + else if(jcmp(s[c-1],"-yfirst")) {yfirst=1;c--;} + else if(jcmp(s[c-1],"-xfirst")) {yfirst=0;c--;} + else if(jcmp(s[c-1],"-invx")) {invx=(1-invx)&1;c--;} + else if(jcmp(s[c-1],"-nopal")) {nopalette=1;c--;} + else if(jcmp(s[c-1],"-pal16")) {pal16=1;c--;} + else if(jcmp(s[c-1],"-2600")) {getting_2600=1;c--;} + else if(jcmp(s[c-2],"-using")) {getcharfileindex=c-1;c-=2;} + else if(jcmp(s[c-2],"-fat")) {fat=1;} + else {printf("Unknown option '%s'\n",s[c-1]);exit(1);} + } + if(c!=2) + { + printf("exename filename\n"); + exit(0); + } + if(getcharfileindex) + { + getcharfile(s[getcharfileindex]); + } + setuppropcolours(); + + sprintf(fname,"%s.bmp",s[1]); + f=fopen(fname,"rb"); + if(f!=NULL) + { + fread(header,0x36,1,f); + scrwidth=header[9]; + scrheight=header[11]; + printf("w=%d\nh=%d\n",scrwidth,scrheight); + fread(palbuf,256,4,f); + for(i=0;i<256;i++) + { + proppal[i]=getpixelcolour(palbuf[i*4+0],palbuf[i*4+1],palbuf[i*4+2]); + } + + fseek(f,header[5],SEEK_SET); + for(i=0;i=charmap2 && mode<=charmap256 ) + printf("Char map size = ( %d,%d )\nChars Used = %d\n",scrwidth/8,scrheight/8,charnum); + if( mode==VGAchars4x8 ) + printf("Char map size = ( %d,%d )\nChars Used = %d\n",scrwidth/4,scrheight/8,charnum); + + if(nopalette==0) + { + sprintf(fname,"%s.pal",s[1]); + f=fopen(fname,"wb"); + if(f!=NULL) + { + if(pal16) + fwrite(proppal,16,1,f); + else + fwrite(proppal,256,1,f); + fclose(f); + } + } + + if(mode!=C64sprites && repeatable!=0) + { + if(justcharmap) + { + sprintf(fname,"%s.map",s[1]); + f=fopen(fname,"wb"); + if(f!=NULL) + { + if(mode==VGAchars4x8) + { + if(yfirst==0) + { + fwrite(charmap,scrheight/8,(scrwidth/4)*2,f); + } + else + { + for(x=0;x<(scrwidth/(blockmapsize*4));x++) + { + for(y=0;y<(scrheight/(blockmapsize*8));y++) + { + fwrite(&charmap[y*(scrwidth/(blockmapsize*4))+x],1,2,f); + } + } + } + } + else + { + if(yfirst==0) + { + fwrite(charmap,scrheight/8,(scrwidth/8)*2,f); + } + else + { + for(x=0;x<(scrwidth/(blockmapsize*8));x++) + { + for(y=0;y<(scrheight/(blockmapsize*8));y++) + { + fwrite(&charmap[y*(scrwidth/(blockmapsize*8))+x],1,2,f); + } + } + } + } + fclose(f); + } + } + else + { + sprintf(fname,"%s.mpb",s[1]); + f=fopen(fname,"wb"); + if(f!=NULL) + { + if(yfirst==0) + { + fwrite(blockmap,scrheight/(blockmapsize*8),(scrwidth/(blockmapsize*8))*2,f); + } + else + { + for(x=0;x<(scrwidth/(blockmapsize*8));x++) + { + for(y=0;y<(scrheight/(blockmapsize*8));y++) + { + fwrite(&blockmap[y*(scrwidth/(blockmapsize*8))+x],1,2,f); + } + } + } + fclose(f); + } + + sprintf(fname,"%s.blx",s[1]); + f=fopen(fname,"wb"); + if(f!=NULL) + { + fwrite(blocks,blocknum,blocksize*2,f); + fclose(f); + } + } + } + +// sprintf(fname,"%s.%s",s[1],ext); + if( (mode>=charmap2 && mode<=charmap256 ) || mode==VGAchars4x8) + { + sprintf(fname,"%s.chr",s[1]); + } + else if(mode==C64sprites) + { + sprintf(fname,"%s.JCS",s[1]); + } + else if( (mode>=bitmap2 && mode<=AMSbitmap16 ) ) + { + sprintf(fname,"%s.bit",s[1]); + } + else + { + printf("Don't know Graphics mode :(\n"); + return 0; + } + f=fopen(fname,"wb"); + if(f!=NULL) + { + if( (mode>=charmap2 && mode<=charmap256) || mode==VGAchars4x8 ) + { + for(i=0;i=bitmap2 && mode<=AMSbitmap16 ) ) + { + if(mode==C64bitmap2) {bytesize=8;byteand= 1;byteshift=1;fat=0;} + if(mode==C64bitmap4) {bytesize=4;byteand= 3;byteshift=2;fat=1;} + if(mode==AMSbitmap4) {bytesize=4;byteand= 3;byteshift=2;fat=0;} + if(mode==AMSbitmap16){bytesize=2;byteand= 15;byteshift=4;fat=1;} + if(mode==bitmap2) {bytesize=8;byteand= 1;byteshift=1;fat=0;} + if(mode==bitmap4) {bytesize=4;byteand= 3;byteshift=2;fat=0;} + if(mode==bitmap16) {bytesize=2;byteand= 15;byteshift=4;fat=0;} + if(mode==bitmap256) {bytesize=1;byteand=255;byteshift=0;fat=0;} + for(y=0;y1) + { + byteand=3;byteshift=2; + j=1; + xx=24;yy=21; + } + } + } + for(yy=0;yy<21;yy++) + { + for(xx=0;xx<24;xx+=byteshift) + { + if((xx&7)==0) byteout=0; + byteout+=((screen[((y+yy)*scrwidth)+(x+xx)]&byteand)<<((8-byteshift)-(xx&7))); + if((xx&7)==(8-(byteshift))) + { + fwrite(&byteout,1,1,f); + } + } + } + byteout=0; + fwrite(&byteout,1,1,f); // to keep nice round 64bytes per sprite :) + } + } + } + + fclose(f); + } + else + { + printf("Error Creating '%s'\n",fname); + } + } + else + { + printf("Error Opening '%s'\n",fname); + } + return 0; +} + diff --git a/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/bmp8toLite.exe b/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/bmp8toLite.exe new file mode 100644 index 0000000..10a0a0d Binary files /dev/null and b/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/bmp8toLite.exe differ diff --git a/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/font.bmp b/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/font.bmp new file mode 100644 index 0000000..85b1ce0 Binary files /dev/null and b/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/font.bmp differ diff --git a/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/font.chr b/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/font.chr new file mode 100644 index 0000000..89083cc Binary files /dev/null and b/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/font.chr differ diff --git a/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/jbdemo1.bel b/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/jbdemo1.bel new file mode 100644 index 0000000..0f54467 Binary files /dev/null and b/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/jbdemo1.bel differ diff --git a/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/mario.bmp b/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/mario.bmp new file mode 100644 index 0000000..2db3969 Binary files /dev/null and b/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/mario.bmp differ diff --git a/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/mario.chr b/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/mario.chr new file mode 100644 index 0000000..e69683f --- /dev/null +++ b/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/mario.chr @@ -0,0 +1 @@ +ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëƒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëÿë׃׃ƒÃÃÃÃÃÿÿÿÿÿÿÿÿÿÿÿëÿë—ƒƒƒƒÃƒÃÃÃÃÃÃÃÃÃÃÃÿÿÿÿÿÿÿÿë׃ƒƒƒƒƒÃÃÃÃÃÃÃÃÃÃÃÿÿÿÿëëë냃ƒƒƒƒƒƒÃƒƒƒÃƒƒÃƒƒƒƒƒƒƒƒÿÿÿÿ§§ëëƒCCCƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒCƒ——ÿÿÿÿÿÿÿÿC—ëÿƒƒCCƒƒƒƒƒƒƒƒƒƒCƒ——“Cÿÿÿÿÿÿÿÿÿÿÿÿ—ÿÿÿCCëÿƒƒC—ƒƒCCCCCƒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ—ÿÿÿC‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿëÿÿÿƒÿÿÿÿÿÿÿÿÿÿÿ×ÿÿ׃ÿ׃Ã׃ÃÃÃÃÃÃÃÃÃÃÿëƒÃëƒÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃëÃÿƒƒƒÿƒƒƒ×ƒƒëÿƒëÿÿëÿÿÿÿÿÿÿÿÿÿëÿÿÿëÿÿÿ×ëÿÿÿÿÿÿÿûÿÿÿƒ×ëÿƒƒƒ×ÃÃÃÃÃ׃ƒÃÿëÿÿÿÿÿÿëÿÿÿƒ×ÿ׃ƒëÃÃÃ׃ÃÃ냃×ë×CCƒÿëƒCÿÿëƒ×ëûûƒëûÿƒƒëûƒƒ“ë냃׃C“ÿƒCC—CƒƒCCƒCC§CƒƒëCCƒÿ“Cƒÿ×CƒÿÿÿÿÿÿÿÿëÿÿÿCÿÿÿC—ÿÿƒCëÿƒƒ‡ÿƒƒC«ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëÿÿÿƒÿÿëƒÿÿƒÃÿÿ×ÃÿëƒÃëƒÃÃ׃ÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃ×ÿÃ×ÿƒƒƒÿƒÃƒÿÃ×ÃÃÃÿÿÿ×ÿÿÿƒÿÿëÃÿÿ×Ãÿÿ—ƒëÿëׇÿÿûƒ×ë냃ûÿÃûûÃûûÃÃëÿÃ×ëëƒ×ëëëëëëëë׃ë“ëëÿëëëûûëëÿëëëëëëëëëëëë×׃ƒƒƒƒëƒƒƒë׃ƒë냃ëë—ƒëëë×ëëë냃ƒƒƒƒƒƒëëCƒ××Cƒ××CCëƒCC׃CƒƒCƒƒƒƒƒƒƒƒƒƒƒƒC“CƒƒCCƒƒCCCƒƒCƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒÿÿÿÿëÿÿÿƒÿÿÿCëÿÿC“ÿÿCCëÿCCçÿƒƒƒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëÿÿÿ×ÿÿëƒÿÿ×ÃÿëƒÃÿƒÃÃëƒÃÇÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃ×ÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÓƒƒÃÃÃÃÃÃÃÃCCƒƒƒCƒƒCCƒƒCWÃCCCCCCCCCCƒƒƒƒƒƒƒƒƒƒƒƒCCCCCCCCCCCCƒƒƒCƒƒƒƒƒƒƒCCCCCCCCCCCCƒCCCCCCCCS—ëÿCCCCCCCCCƒƒCƒCCCCCCCCCCCCCCÿÿÿÿëÿÿÿCëÿÿCSÿÿCCÿÿCWÿÿCÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ««ûÿÿÿÿÿÿÿÿÿÿÿëÿÿëƒÿëÃÃÿ×ÃÃëÃÃÇÃÃÃÿëƒÃëƒÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃCÃCƒCÃÃÃÃÃÃÃÃÃÃÃÃCCƒCCS—§×ÃÃCCCC———C×ç×냃“ƒƒ“ƒ“S“—“C———C—“S—C—ëçCƒ“ƒƒƒƒ“—“—““““—““—“——————————ç———ƒ“SSƒ““S“—““——“—————————————ç××—SWSC—“S—“C———“————————§§CWCCC———ƒ———×——“×—“×——“——§———CCCCCCƒ—Cƒÿÿƒƒ“—׃ƒC—ƒƒC׃Cƒ×ƒCƒCC—ÿ—§««ë§—«ëÿ§«—ë«—C—ë—CC——CCS—ÿÿÿû««ûû«««««§«««§W«—««§—§—«—WWWû«««««««««««««««———«§«——————WW——§«««««««««««§§««««§«—[§§«§«§—§§§«ÿÿÿ«««ÿ«««««««««§««§§««§—§«§§§§ÿÿÿÿÿÿÿÿÿÿÿÿ«ÿÿÿ««ÿÿ[««ÿ«««ÿ«§§«ÿÿÿÿÿÿÿëÿÿÿ×ÿÿÿ×ÿÿÿ×ÿÿÿ×ÿÿÿ×ÿÿÿÿÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃCÃÃÃÃÃÃÃÃÃÃÃÃÃCCƒCCCCCCCÃÃÃÃÃÃÃÓ—ƒ“———ûûû—ûûû—ÿûûÃ׃××————×———çûûûûûÿûÿûûûû—CC×CC§———§×—ç—ç×——ûëëçûûëçûûûë—§—×——§—§—§—————秗W§—WWë—§«ë—«Wç××ק§———————«««WW«Wk[ookkççë×——ë秧§ç«««§««««k««ë¿ÿûk«ÿÿçç——çç××çççç§çç×ëëçëëçëëûëûëÿûÿûדח××——××——×××—×××—ëç×—ëçç—ûëç×—CCW—CW—Sk————CC«§——[«——W§§—W«—W«—W§§C§§W§«çדCƒ×—Cƒ——Cƒ—×CC—׃C—׃C—דCç§×ƒCCC—CCCWCCCSCCCSCCCSCCCSCCSSCCS—WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW——WWW—WWW—WWWWWWWWWWWWWWWWWWWW§§§§—§§——§§——§§—W——§WWW§WWW§WWW—§§§§§§«—§§«W§«§W§«§W§§«W—§«W§§««§§§[WW§§WW—§WWWWW—WWW—W§W——ÿ«Wÿÿ«ÿÿÿ«ÿÿÿ«ÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ׃ƒÃÿƒƒƒÿ냃ÿÿëƒÿÿÿëÿÿÿÿÿÿÿÿÿÿÿûÃÃÃÃÃÃÃדëûûÿÿÿÿÿûûûûëçÃÃÃÃCûûë×ûûûûûÿûëççç냃CCƒƒCCƒCCCCCCCƒCCCëƒCCûçCCûëëCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCƒCSëûÿC§ÿÿC—ÿÿCC§ÿCCCçCCCCCCCCCCÿûûûûÿûûûÿÿûÿûÿûÿûûÿëÿûûSÿÿûûÿûûûûëûûûëÿûûûÿûûûûÿûëûûûûûûûûûûÿû«§«맫«««ë««ëë«Wëë««ûëë§ûûë««ÿ[WW[o[ÿÿo[¿ÿk¯ÿo«ÿ[k¯ÿ[[¿ÿ[ÿÿ¿ÿÿÿûÿûÿûûÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿûûûë§ûûëëÿûûûûûûûûûûÿÿÿÿÿÿÿÿÿÿÿÿÿ——ëëëëëÿûûëÿûÿûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûëëëëëëëëûûûûÿûûûûûûëûûûûûûûëÿûëëëëëëëëëëûëëëëçççëçççëççççççççç秗——S秗—秧맧§§ç§§«§—§§—§§§ç§ç§—WWWë«WWÿÿÿ«ëÿÿÿ§ÿÿÿ§ûÿÿ§ëÿÿ§ëÿÿWWWWWWWW«WWWÿÿÿ«ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿWWWWWWWWWWWW«—WWÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿW—««—«««W§§§WWW«ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ«§ÿÿ§«ÿÿ§ûÿÿ«ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûûççûëçëûççûûçëûûëëûÿëëûÿûëûÿÿûûçëççûûëçûëççûç××ûç××ûçççûëççûûëçûûë×ççëë××çëד×ëç××çëëëçëëëëëûûûCCCCƒCCC×CƒCë“CCûçCCûû“CûûëCûûûSCCCCCCCCCCSCCC«CCëCCûCCSÿ«ÿCûÿÿSÿÿÿëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûûÿÿÿÿÿÿÿûÿÿÿûÿÿÿ«ÿÿÿ«ÿÿÿÿÿÿÿÿûÿëûS§ÿû—CW««[«ëÿÿÿëûûÿCSÿÿÿÿÿÿÿÿÿûûÿ—WWWÿÿûÿÿÿûÿÿÿÿÿSCWÿûWÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûûûÿûû«ûûû—ûëÿÿÿÿÿÿÿûÿÿûûûûûûûûûûûûûëûûëëëëëëûëëëûëëçûëççûëççëçççëçççëçççëë——ççç§ç秧秧—秧—秧—ç×——×——————§§×§ç—§§ç§§§§——§——§§§§§—§—§SW§C«—ëÿÿ—ÿÿÿ§ÿÿÿëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿûÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûûûëÿÿûûûÿûûÿÿûûÿÿûûÿûÿûÿÿÿûÿÿÿÿëûûûûûûÿûûÿûûûÿÿûûÿÿûûûûûûûûÿ—CSûûûÿÿûûÿÿûÿÿûÿûÿûÿûûûûÿëû«—CC«ëÿÿÿÿÿÿÿûÿÿÿûÿÿÿÿûûëûûûëÿÿCÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûûûûûûûûûûûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûûûûÿûûûûûûûûûûûûÿÿÿWûûÿ«ûÿûûûûÿûûûûûûûûûûûëëSSSÿ««—ûûëëûûëëûëëçëëëçSë—Cç맗ç秧[«W«S««WCCCCë맧C—§§CWGëç——§———C—WCWCS—C——§—CSC—C——————————————§Cÿ—«ÿ—§ëÿ§—ûÿ—ëÿÿ—ÿÿÿëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿ[ÿÿ[Gÿ«‡ÿ§ÿÿ[ÿ¿«¿[[[[WGGG‡ƒƒ‡ÇÃÃÇÃÃÃ[[__GGG[ƒƒƒƒÃÃÃÃÃÃÃÃWû[[_ƒG[[ƒƒC[ÃGëûûû«ëëë[«ëë[«[G_ûûûûëëûëëëëëëëëçS«ëëW—ûûëëëëëëëëëëëëëëëëëç§ëëëCW—çCëëççëëççëçççççççççççççççëçç×C———ç秧ççççç秧çççççççççççççççç——çç§C§—CC§çCCçç×Cççç—çççëçëççç××çCCCCCCCCCCC—ƒCCçç——çëëëGCCCCCCCCCCCCCCCCƒCCƒ—“———§———CC—“CC““C———“—————————————Sÿ——«ÿ———ÿ——ëÿ—«ÿÿ—ÿÿÿëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ뫧痗—ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ«««ÿCCCSÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿«ÿÿoÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ«ÿÿ¿[ÿ¯_o/ÿ[G‡«GÃ[G‡ÃCÃÃÃÃGƒÃÃÃÃÃÃÃÃCÃÃÃÃG C[CCCƒCCCCGƒƒCGƒƒƒC    GG[G   CCC“CCCCCCCCCCCCCCCCCCCCCC———×CC“—CCCCCCCCCCCCCCCCCCCCCCCC×××——××—C“——CCCCCCCCCCCCCCCCCC———ë—““————WCCCC————W——WS——ûSWÿÿÿÿûÿWWû[«ûû—§ÿÿ«ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿûÿÿûçÿûççÿëëëÿûûëÿûûëÿÿë×ûëç×ççççççççëëç—ëë—Wë—W«[ ×ד“××—S§—SC—SCCWCG CCCCCCCCCCCC  C[oGCƒƒCG[ƒÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÇÃÃǃÃÃGƒÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃCCCƒƒCGÃÃÃÃÃÃÃÃÃÃÃÃƒ× GƒCGƒƒGCƒ‡ëÿ×ÿÿÿÿÿÿ«CCGCC[«««ÿÿÿ««««ÿ««ÿÿCCCCCCCCCCC—[WÿÿÿÿÿÿÿÿÿÿÿÿûÿCCCCCC«C«ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿS«ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ«ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ«ÿûû«û««««««§ÿÿÿÿÿÿÿûÿÿûûÿ««û««««««««««««««««ÿÿÿÿÿÿÿÿûû«ÿûû«û««««««««««««««««ÿÿÿÿÿÿÿÿÿÿÿÿ«ÿÿÿ««««««««««««««««ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ«ÿÿÿ§«ÿÿ§—ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿûÿÿûûÿÿûÿÿÿÿûÿÿÿûÿûûûûûûûûÿÿûÿÿûûÿûûëûûû§ûûë—ûÿÿ«ûÿ«[ûë[û««[—WW[     [K‡ƒƒKG‡ƒKGƒGGG  ÃÃÃÃÃÃÃÃÃÃÃÃCƒÃÃGƒÃÃGƒƒÃGƒÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃ×ÃÃëÃÃ×ÿÃëÿÃ×ûÃ×ÿÿƒÿÿëëÿÿ«ÿÿ««ÿë««ÿ«««û«««ÿû««ë««««««ÿ««¿ÿ«ûÿÿ«ÿÿÿÿÿÿÿÿÿÿÿ«ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ«ÿÿÿ«ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿ«««§[««««Wÿÿ«ûÿÿÿûÿÿÿÿÿÿÿÿ««ûÿ««««««««W[[§«[WWÿÿÿÿÿÿÿÿÿÿÿÿûûÿÿ««««««««§[[§WWW§«—WWÿÿÿ§ÿÿÿÿûûÿ«««««««««§§§§§«§[W§§§WWW§«WWW«WSW««—W§W«ÿ«W«ÿ§§[ÿ§§§ÿ§§§«§§W§W§W[WWW§ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ«ÿÿÿWÿÿÿÿÿÿûÿÿûûÿûûûûûûëÿûûçûûççëëç×ëëç×ûë×Wûç—CçדCç“CC§“CC““CC“ƒCC“ƒ“SWWWWWWW[      GCƒGƒGƒCGÃÃÃÃÃÃÃÃÃÃÃGƒƒƒCƒƒGCƒGCÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃCƒƒƒÃƒëÿÃÿÿƒ×ÿûƒëû«ƒëû«ƒëû«ƒëû«ƒëÿ«ë««««««ÿ«««ÿ«««ÿ«««ÿ««ÿÿ««ÿÿ««ÿÿÿÿ«ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ«ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿû««««««««§§[û««[ûûûûÿûÿÿûûûûûûûÿ««««««««§««§W[W««««Wÿÿÿÿûÿÿÿÿÿÿû««««««««««««««««WWW§««WWÿÿÿ«ûÿÿ««««««««§«««§««««§§§«WW§§WWWW«WSS««§W§§§—«§§§«§§««§§«§§§«—§««WW§WWWW—WWWWWWWW—WWW—WWWWWWWWWW[WW—WWÿÿÿW«ÿÿW«ÿÿWûÿÿWÿÿÿ§ÿÿÿ«ÿÿÿÿÿÿÿëçç“ûçç“ÿë—“ÿë—“ÿûç“ÿÿû§ÿÿÿûÿÿÿÿ““CS““ƒS“ƒ“““ƒƒ“““ƒ“““““—“““ÿ«S“S[S[S[SWSW[“W[“W[“SW[     k«GGCƒƒGGCGGƒëû«Cëë«C«û«—ÿ«W¿«¿««¿«««ÿÿ««ÿÿ««ÿÿ««ûÿ«««ÿ«««ÿ««§«««««ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûûûÿûÿ««««ÿÿ««ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûûÿÿÿûÿÿÿ«ÿÿ««ÿ«««ÿ««Wÿ«««ÿûûÿûûûÿ««ûû««««««««««««—«««§WWWû«««ÿÿÿÿû««û««««««««««««««««WW««WWSWÿ«WSûû««««««««««««««««««««««W§««SSW—«WWW«§WW«§§§«««§«««««««§«««§«§««WWWWWWWWWWWWWWW——«——«ÿÿÿÿÿÿÿÿÿÿÿW§W«W§WÿWW«ÿ§«ÿÿ«ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ——WWÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿[ÿ¿ÿÿÿ[ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ¿k[[ÿÿÿÿÿÿÿÿÿÿÿÿ[[k¿ÿÿÿÿÿÿÿÿÿÿÿÿW«ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯Wÿÿ«ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ[ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿kÿÿÿÿÿÿ[ÿÿ[ÿÿkÿÿ« [«««««««W««««û[««ûû««««§««««§««««««««««ûûû«ÿ««««««««««««««««û«WW«ûÿÿÿ«ûûû««ûû««««««««««««««««ÿÿû«ûûûûû«««««««««««««««««««««««««««ûÿÿÿ«ûÿÿ«ûûû«««««««««««««««««ûÿÿÿû«Wÿ««§««§W««««««««««««««««û«««WSSWWWWW——WS§§§W«§§—««§««««ÿ«ûÿÿW—«ÿ«ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯ÿÿ¯ÿÿ¿ÿÿ¿ÿÿÿÿÿÿÿÿÿoÿÿÿo          «ÿÿÿkÿÿÿWÿÿÿÿÿÿÿÿÿ¿ÿÿ«ÿÿ[ÿÿÿÿÿoÿÿÿ¯ÿÿÿ¯ÿÿÿoÿÿÿoÿÿÿoÿÿÿoÿÿÿ¯        [ÿÿÿÿÿÿ¿ÿ«ÿ[ÿÿÿÿÿÿ¯ÿÿÿ¿ÿÿÿ¿ÿÿÿ¿ÿÿÿ¿ÿÿÿ¿ÿÿÿÿÿÿÿÿooo///         ÿ¿«[ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿkÿÿÿo/¯/¿/¿/¯/o/o//o_   _   S§W«ë«ûûûCWW§«§ëëëçëëççûûûëCSW————§çççççç×ççççççç×—————“——çד“×ד“×ד“ד““ÿÿÿÿÿÿS——«“““C““S—““SC“SCCSSCCÿÿÿÿÿÿÿÿûÿÿÿCC«ÿCWSCCCCCCCCCCCÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿûÿÿÿÿCÿoook¿[ÿ¿¿ÿÿ«ÿûÿ«ëëÿ—§çÿ——§_[S—««ûûûûûëçççëçççç—ç×ç[«W«ÿûûûûûûûûûûûûûëëëçççççççççûûûûûûëûûëëûûûëëëçëçççççççççççç×ûûûëûûûëëëëçëççççççççç××ç××××ד“ççç×ççç×ççדç×—“×———ד““ד“““““Cד““—““C““ƒC““CC“ƒCC“CCCSCCCCCCCSCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC«CCCCCCCCCCCCCCCCCCCCCCCCCÿÿÿÿÿÿÿÿ«ÿÿÿWÿÿÿÿÿÿûÿÿ«ÿÿ§ÿÿÿ§S—ÿëS“ÿÿSSÿÿûCÿÿÿëÿÿÿÿÿÿÿûÿÿÿÿ““×ד“““C“““CCC“§—“Cûûëûëëëëÿûëë×××ד××ד“““““““CC““—CCSë—CCë§ë§×××ד““““““—“““““““““CC“CCCCSCCCד““———————“““““““ƒƒƒCCCCCCCCCCC—““C—“SC“CCCƒCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCSS—CCCCCCCCCCCCCCCCCCCCCCCCCCCC————CCCCCCCCCCCCCCCCCCCC—SSSû—SS«—ÿÿ—ÿÿ«ÿÿûÿÿ—ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëëë—ûûëëÿûûëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“““Sëçççëëë«ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ““——§——“ççç«ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ————“““Sëëëûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ————“———ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿSWSS§«ûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ—§«ûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ \ No newline at end of file diff --git a/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/mario.map b/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/mario.map new file mode 100644 index 0000000..7a4f5e3 Binary files /dev/null and b/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/mario.map differ diff --git a/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/spiderman.bmp b/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/spiderman.bmp new file mode 100644 index 0000000..c871ab4 Binary files /dev/null and b/demo/VGA_JB_Demo - Archive [Date 2010.11.22 Time 14.53] - Hive/spiderman.bmp differ diff --git a/demo/graphics/Graphics.spin b/demo/graphics/Graphics.spin new file mode 100644 index 0000000..dbe7e03 Binary files /dev/null and b/demo/graphics/Graphics.spin differ diff --git a/demo/graphics/Mouse.spin b/demo/graphics/Mouse.spin new file mode 100644 index 0000000..c37ad5c Binary files /dev/null and b/demo/graphics/Mouse.spin differ diff --git a/demo/graphics/TV.spin b/demo/graphics/TV.spin new file mode 100644 index 0000000..b58adcf Binary files /dev/null and b/demo/graphics/TV.spin differ diff --git a/demo/graphics/demo-1.spin b/demo/graphics/demo-1.spin new file mode 100644 index 0000000..4e54a5f Binary files /dev/null and b/demo/graphics/demo-1.spin differ diff --git a/demo/graphics/demo-10-animation1.spin b/demo/graphics/demo-10-animation1.spin new file mode 100644 index 0000000..d8d79a5 Binary files /dev/null and b/demo/graphics/demo-10-animation1.spin differ diff --git a/demo/graphics/demo-10-animation2.spin b/demo/graphics/demo-10-animation2.spin new file mode 100644 index 0000000..53d4c31 Binary files /dev/null and b/demo/graphics/demo-10-animation2.spin differ diff --git a/demo/graphics/demo-10-logo.spin b/demo/graphics/demo-10-logo.spin new file mode 100644 index 0000000..2f3cf38 Binary files /dev/null and b/demo/graphics/demo-10-logo.spin differ diff --git a/demo/graphics/demo-10-logo2.binary b/demo/graphics/demo-10-logo2.binary new file mode 100644 index 0000000..3e172a2 Binary files /dev/null and b/demo/graphics/demo-10-logo2.binary differ diff --git a/demo/graphics/demo-10-logo2.spin b/demo/graphics/demo-10-logo2.spin new file mode 100644 index 0000000..e0b809d Binary files /dev/null and b/demo/graphics/demo-10-logo2.spin differ diff --git a/demo/graphics/demo-11-matrix1.spin b/demo/graphics/demo-11-matrix1.spin new file mode 100644 index 0000000..a84259d Binary files /dev/null and b/demo/graphics/demo-11-matrix1.spin differ diff --git a/demo/graphics/demo-2.spin b/demo/graphics/demo-2.spin new file mode 100644 index 0000000..7fbc303 Binary files /dev/null and b/demo/graphics/demo-2.spin differ diff --git a/demo/graphics/demo-3-objekte.spin b/demo/graphics/demo-3-objekte.spin new file mode 100644 index 0000000..946767e Binary files /dev/null and b/demo/graphics/demo-3-objekte.spin differ diff --git a/demo/graphics/demo-4-boing.spin b/demo/graphics/demo-4-boing.spin new file mode 100644 index 0000000..25ad295 Binary files /dev/null and b/demo/graphics/demo-4-boing.spin differ diff --git a/demo/graphics/demo-5-scroller.spin b/demo/graphics/demo-5-scroller.spin new file mode 100644 index 0000000..03792a3 Binary files /dev/null and b/demo/graphics/demo-5-scroller.spin differ diff --git a/demo/graphics/demo-6-mouse.spin b/demo/graphics/demo-6-mouse.spin new file mode 100644 index 0000000..c9c837f Binary files /dev/null and b/demo/graphics/demo-6-mouse.spin differ diff --git a/demo/graphics/demo-7-satellite.spin b/demo/graphics/demo-7-satellite.spin new file mode 100644 index 0000000..56a4fd1 Binary files /dev/null and b/demo/graphics/demo-7-satellite.spin differ diff --git a/demo/graphics/demo-7-satellite2.spin b/demo/graphics/demo-7-satellite2.spin new file mode 100644 index 0000000..e7e1ad8 Binary files /dev/null and b/demo/graphics/demo-7-satellite2.spin differ diff --git a/demo/graphics/demo-8-sinus.spin b/demo/graphics/demo-8-sinus.spin new file mode 100644 index 0000000..06f9810 Binary files /dev/null and b/demo/graphics/demo-8-sinus.spin differ diff --git a/demo/graphics/demo-9-lissajou.spin b/demo/graphics/demo-9-lissajou.spin new file mode 100644 index 0000000..b888fcf Binary files /dev/null and b/demo/graphics/demo-9-lissajou.spin differ diff --git a/demo/graphics/demo-9-lissajou2.spin b/demo/graphics/demo-9-lissajou2.spin new file mode 100644 index 0000000..0a55d73 Binary files /dev/null and b/demo/graphics/demo-9-lissajou2.spin differ diff --git a/demo/graphics/demo-9-lissajou3.spin b/demo/graphics/demo-9-lissajou3.spin new file mode 100644 index 0000000..3def7be Binary files /dev/null and b/demo/graphics/demo-9-lissajou3.spin differ diff --git a/demo/graphics/dlEngine-Test.spin b/demo/graphics/dlEngine-Test.spin new file mode 100644 index 0000000..9a896b9 Binary files /dev/null and b/demo/graphics/dlEngine-Test.spin differ diff --git a/demo/graphics/gra-emu.spin b/demo/graphics/gra-emu.spin new file mode 100644 index 0000000..af95a36 Binary files /dev/null and b/demo/graphics/gra-emu.spin differ diff --git a/demo/graphics/graphics_XOR.spin b/demo/graphics/graphics_XOR.spin new file mode 100644 index 0000000..617bb27 Binary files /dev/null and b/demo/graphics/graphics_XOR.spin differ diff --git a/demo/graphics/ios.spin b/demo/graphics/ios.spin new file mode 100644 index 0000000..71f16e1 Binary files /dev/null and b/demo/graphics/ios.spin differ diff --git a/demo/graphics/potato-commented-graphics-color.spin b/demo/graphics/potato-commented-graphics-color.spin new file mode 100644 index 0000000..70d42b0 Binary files /dev/null and b/demo/graphics/potato-commented-graphics-color.spin differ diff --git a/demo/hallo.spin b/demo/hallo.spin new file mode 100644 index 0000000..b4a7654 Binary files /dev/null and b/demo/hallo.spin differ diff --git a/demo/ios.spin b/demo/ios.spin new file mode 100644 index 0000000..caf5b03 Binary files /dev/null and b/demo/ios.spin differ diff --git a/demo/matrix/gfx1.spin b/demo/matrix/gfx1.spin new file mode 100644 index 0000000..fc2226a --- /dev/null +++ b/demo/matrix/gfx1.spin @@ -0,0 +1,178 @@ +DAT +{ + video-treiber-frame + - basiert auf dem tollen tutorial von bamse + +30-09-2009-dr235 driver 1 - originalcode, anpassung an hive + driver 2 - senkrechte balken + driver 3 - einfarbige fläche + driver 4 - wandernde farbbalken, 1 byte pro pixel :) + driver 5 - + + +} + +CON + _CLKMODE = xtal1 + pll16x + _XINFREQ = 5_000_000 + +PUB start + + cognew(@entry,0) ' neue cog mit video-treiber starten + +DAT org 0 +entry jmp #Start_of_driver ' Start here... + +' NTSC sync stuff. +NTSC_color_freq long 3_579_545 ' NTSC Color Frequency +NTSC_hsync_VSCL long 39 << 12 + 624 ' Used for the Horisontal Sync +NTSC_active_VSCL long 188 << 12 + 3008 ' Used for the Vertical sync +NTSC_hsync_pixels long %%11_0000_1_2222222_11 ' Horizontal sync pixels +NTSC_vsync_high_1 long %%1111111_2222222_11 ' Vertical sync signal part one for lines 1-6 and 13 to 18 +NTSC_vsync_high_2 long %%1111111111111111 ' Vertical sync signal part two for lines 1-6 and 13 to 18 +NTSC_vsync_low_1 long %%2222222222222222 ' Vertical sync signal part one for lines 7-12 +NTSC_vsync_low_2 long %%22_1111111_2222222 ' Vertical sync signal part two for lines 7-12 +NTSC_sync_signal_palette long $00_00_02_8A ' The sync Palette + +' hbeat --------+ +------------------------- /cs +' clk -------+| | +' /wr ------+|| | +---------------------- videopins +' /hs -----+||| | | +' |||| |--+ -------- d0..d7 +tvport_mask long %00000000_01110000_00000000_00000000 ' Maske für Video-Pins am Hive +vsu_cfg long %01110100_00000000_00000100_01110000 ' Wert für VCFG-Register + +NTSC_Graphic_Lines long 244 ' Anzahl der sichtbaren Zeilen +NTSC_Graphics_Pixels_VSCL long 16 << 12 + 16 ' 16 clocks per pixel, 64 clocks per frame. + + +PAL0 long $01 +PAL1 long $0E +PAL2 long $0D +PAL3 long $0C +PAL4 long $0B +DIF1 long $00_10 +CNT_ANIM long $4 + +' Loop counters. +line_loop long $0 ' Line counter... +pix_loop long $0 +anim_loop long $0 + +' General Purpose Registers +r0 long $0 ' Initialize to 0 +r1 long $0 +r2 long $0 +r3 long $0 +c1 long $0 ' colorregister +c2 long $0 +c3 long $0 + +'========================== Start of the actual driver ============================================= + +Start_of_driver + ' VCFG, setup Video Configuration register and 3-bit tv DAC pins to output + mov VCFG, vsu_cfg ' Konfiguration der VSU + or DIRA, tvport_mask ' Set DAC pins to output + + ' CTRA, setup Frequency to Drive Video + movi CTRA,#%00001_111 ' pll internal routed to Video, PHSx+=FRQx (mode 1) + pll(16x) + mov r1, NTSC_color_freq ' r1: Color frequency in Hz (3.579_545MHz) + rdlong r2, #0 ' Copy system clock from main memory location 0. (80Mhz) + ' perform r3 = 2^32 * r1 / r2 + mov r0,#32+1 +:loop cmpsub r1,r2 wc + rcl r3,#1 + shl r1,#1 + djnz r0,#:loop + mov FRQA, r3 ' Set frequency for counter A + + +'========================== Start of Frame Loop ============================================== + +frame_loop + mov anim_loop, CNT_ANIM +frame_loop2 + +'========================== Screen ============================================= + + mov line_loop, NTSC_Graphic_Lines ' anzahl der zeilen laden (244) + +user_lines + '------ zeilensynchronisation + mov VSCL, NTSC_hsync_VSCL ' Setup VSCL for horizontal sync. + waitvid NTSC_sync_signal_palette, NTSC_hsync_pixels ' Generate sync. + + + '------ sichtbarer zeileninhalt + mov VSCL, NTSC_Graphics_Pixels_VSCL ' Setup VSCL for user pixels. + + '------ verschiedenfarbige balken ausgeben + mov c1, PAL4 + add c1, c3 + mov pix_loop, #23 +bar_loop + add c1, #$10 ' 8 x pixel einzeln! ausgeben + mov c2, c1 ' also 2 tiles + waitvid c2, #0 ' 8 bit pro pixel! + add c2, #1 + waitvid c2, #0 + add c2, #1 + waitvid c2, #0 + add c2, #1 + waitvid c2, #0 + sub c2, #1 + waitvid c2, #0 + sub c2, #1 + waitvid c2, #0 + sub c2, #1 + waitvid c2, #0 + sub c2, #1 + waitvid c2, #0 + + djnz pix_loop, #bar_loop + + sub c2, #1 + waitvid c2, #0 ' 4 mal extrapixel, für das timing + sub c2, #1 ' also insgesamt 188 pixel pro zeile + waitvid c2, #0 + sub c2, #1 + waitvid c2, #0 + sub c2, #1 + waitvid c2, #0 + + djnz line_loop, #user_lines ' schleife durch alle zeilen + +'========================== The 16 lines of Horizontal sync ================================== + + mov line_loop, #6 ' Line 244, start of first high sync. +vsync_high1 mov VSCL, NTSC_hsync_VSCL + waitvid NTSC_sync_signal_palette, NTSC_vsync_high_1 + mov VSCL, NTSC_active_VSCL + waitvid NTSC_sync_signal_palette, NTSC_vsync_high_2 + djnz line_loop, #vsync_high1 + + mov line_loop, #6 ' Line 250, start of the Seration pulses. +vsync_low mov VSCL, NTSC_active_VSCL + waitvid NTSC_sync_signal_palette, NTSC_vsync_low_1 + mov VSCL,NTSC_hsync_VSCL + waitvid NTSC_sync_signal_palette, NTSC_vsync_low_2 + djnz line_loop, #vsync_low + + mov line_loop, #6 ' Line 256, start of second high sync. +vsync_high2 mov VSCL, NTSC_hsync_VSCL + waitvid NTSC_sync_signal_palette, NTSC_vsync_high_1 + mov VSCL, NTSC_active_VSCL + waitvid NTSC_sync_signal_palette, NTSC_vsync_high_2 + djnz line_loop, #vsync_high2 + +'========================== End of Frame Loop ============================================= + djnz anim_loop, #frame_loop2 + add c3, #$10 + + +'========================== Animation ================================== + + jmp #frame_loop ' And repeat for ever... +FIT + \ No newline at end of file diff --git a/demo/matrix/keyb-treiber.spin b/demo/matrix/keyb-treiber.spin new file mode 100644 index 0000000..5333e3a Binary files /dev/null and b/demo/matrix/keyb-treiber.spin differ diff --git a/demo/matrix/matrix.spin b/demo/matrix/matrix.spin new file mode 100644 index 0000000..e4f1e23 Binary files /dev/null and b/demo/matrix/matrix.spin differ diff --git a/demo/matrix/vga-treiber.spin b/demo/matrix/vga-treiber.spin new file mode 100644 index 0000000..9acf513 Binary files /dev/null and b/demo/matrix/vga-treiber.spin differ diff --git a/demo/para.spin b/demo/para.spin new file mode 100644 index 0000000..4744617 Binary files /dev/null and b/demo/para.spin differ diff --git a/demo/sid/sid1.spin b/demo/sid/sid1.spin new file mode 100644 index 0000000..74dd688 Binary files /dev/null and b/demo/sid/sid1.spin differ diff --git a/demo/sid/sid2.spin b/demo/sid/sid2.spin new file mode 100644 index 0000000..b261e2d Binary files /dev/null and b/demo/sid/sid2.spin differ diff --git a/demo/spritedriver/NTSC240H.zip b/demo/spritedriver/NTSC240H.zip new file mode 100644 index 0000000..f6efad1 Binary files /dev/null and b/demo/spritedriver/NTSC240H.zip differ diff --git a/demo/spritedriver/NTSC240H/NTSC240H.spin b/demo/spritedriver/NTSC240H/NTSC240H.spin new file mode 100644 index 0000000..266955e Binary files /dev/null and b/demo/spritedriver/NTSC240H/NTSC240H.spin differ diff --git a/demo/spritedriver/NTSC240H/demo240H.spin b/demo/spritedriver/NTSC240H/demo240H.spin new file mode 100644 index 0000000..ea1c55e Binary files /dev/null and b/demo/spritedriver/NTSC240H/demo240H.spin differ diff --git a/demo/spritedriver/NTSC240H/ppm2ntsc.c b/demo/spritedriver/NTSC240H/ppm2ntsc.c new file mode 100644 index 0000000..a186f6d --- /dev/null +++ b/demo/spritedriver/NTSC240H/ppm2ntsc.c @@ -0,0 +1,72 @@ +#include +#include +#include + +unsigned int clut[] = {0x22222222, 0x33333333, 0x44444444, 0x55555555, 0x66666666, 0x77777777, 0x1144EE55, 0x11337755, 0x2244EE66, 0x22447755, 0x3355EE66, 0x22335544, 0x33446655, 0x44557766, 0x1133EE66, 0x2233EE77, 0x22337766, 0x3344EE77, 0x22336655, 0x33447766, 0x4455EE77, 0x3333EEEE, 0x33337777, 0x33336666, 0x44447777, 0x33335555, 0x44446666, 0x55557777, 0x33334444, 0x44445555, 0x55556666, 0x66667777, 0x443377EE, 0x44336677, 0x554477EE, 0x553366EE, 0x44335566, 0x55446677, 0x665577EE, 0x55335577, 0x664466EE, 0x44334455, 0x55445566, 0x66556677, 0x663355EE, 0x55334466, 0x66445577, 0x775566EE, 0x773344EE, 0x66334477, 0x774455EE, 0x77333377, 0x66333366, 0x77444477, 0x55333355, 0x66444466, 0x77555577, 0x44333344, 0x55444455, 0x66555566, 0x77666677, 0xEE331166, 0xEE332277, 0x77332266, 0x66332255, 0x77443366, 0xEE330055, 0x77330044, 0xEE441155, 0x77331155, 0xEE442266, 0x66331144, 0x77442255, 0x55332244, 0x66443355, 0x77554466, 0xEE440044, 0x66330033, 0x77441144, 0xEE552255, 0x55331133, 0x66442244, 0x77553355, \ +0x44332233, 0x55443344, 0x66554455, 0x77665566, 0xEE550033, 0x77440033, 0xEE551144, 0x77551133, 0xEE662244, 0x66441133, 0x77552244, 0x55442233, 0x66553344, 0x77664455, 0xEE660022, 0x77550022, 0xEE661133, 0x77661122, 0x66551122, 0x77662233, 0x55441122, 0x66552233, 0x77663344, 0x66661111, 0x66662222, 0x55552222, 0x66663333, 0x44442222, 0x55553333, 0x66664444, 0x33332222, 0x44443333, 0x55554444, 0x66665555, 0x55662211, 0x44552211, 0x55663322, 0x44662200, 0x44663311, 0x33442211, 0x44553322, 0x55664433, 0x33663300, 0x33553311, 0x44664422, 0x33443322, 0x44554433, 0x55665544, 0x22664400, 0x22553300, 0x33664411, 0x22443311, 0x33554422, 0x44665533, 0x22665511, 0x22554411, 0x33665522, 0x22666622, 0x22555522, 0x33666633, 0x22444422, 0x33555533, 0x44666644, 0x22333322, 0x33444433, 0x44555544, 0x55666655, 0x1166EE33, 0x11667722, 0x22667733, 0x22556633, 0x33667744, 0x1155EE44, 0x11557733, 0x2266EE44, 0x22557744, 0x3366EE55, 0x22445533, 0x33556644, 0x44667755, 0x11447744, 0x2255EE55, 0x22446644, 0x33557755, 0x4466EE66, \ +0x22334433, 0x33445544, 0x44556655, 0x55667766}; +int red[] = {-1, 0, 51, 102, 153, 204, 255, 17, 8, 59, 49, 100, 29, 80, 131, 17, 59, 49, 100, 39, 90, 141, 100, 90, 80, 131, 71, 122, 173, 61, 112, 163, 214, 131, 122, 173, 163, 112, 163, 214, 153, 204, 102, 153, 204, 194, 143, 194, 245, 226, 184, 235, 216, 175, 226, 133, 184, 235, 92, 143, 194, 245, 238, 247, 206, 165, 216, 228, 187, 238, 196, 247, 155, 206, 124, 175, 226, 228, 145, 196, 247, 114, 165, 216, 82, 133, 184, 235, 228, 187, 238, 196, 247, 155, 206, 124, 175, 226, 228, 187, 238, 196, 155, 206, 114, 165, 216, 155, 165, 124, 175, 82, 133, 184, 41, 92, 143, 194, 124, 82, 133, 82, 92, 41, 92, 143, 51, 51, 102, 51, 102, 153, 20, 10, 61, 10, 61, 112, 29, 20, 71, 39, 29, 80, 20, 71, 122, 10, 61, 112, 163, 17, 8, 49, 39, 90, 17, 8, 59, 49, 100, 29, 80, 131, 8, 59, 39, 90, 141, 20, 71, 122, 173, -1}; +int grn[] = {-1, 0, 51, 102, 153, 204, 255, 189, 161, 212, 173, 224, 106, 157, 208, 200, 223, 184, 235, 145, 196, 247, 246, 207, 168, 219, 129, 180, 231, 90, 141, 192, 243, 230, 191, 242, 214, 152, 203, 254, 175, 226, 113, 164, 215, 198, 136, 187, 238, 182, 159, 210, 143, 120, 171, 97, 148, 199, 74, 125, 176, 227, 88, 127, 104, 81, 132, 49, 26, 77, 65, 116, 42, 93, 58, 109, 160, 38, 3, 54, 105, 19, 70, 121, 35, 86, 137, 188, 27, 15, 66, 43, 94, 31, 82, 47, 98, 149, 16, 4, 55, 32, 20, 71, 8, 59, 110, 9, 48, 36, 87, 24, 75, 126, 12, 63, 114, 165, 25, 13, 64, 2, 41, 1, 52, 103, 18, 29, 80, 40, 91, 142, 34, 6, 57, 17, 68, 119, 73, 45, 96, 112, 84, 135, 56, 107, 158, 28, 79, 130, 181, 167, 128, 151, 123, 174, 178, 139, 190, 162, 213, 95, 146, 197, 150, 201, 134, 185, 236, 67, 118, 169, 220, -1}; +int blu[] = {-1, 0, 51, 102, 153, 204, 255, 99, 46, 97, 99, 150, 48, 99, 150, 43, 41, 43, 94, 46, 97, 148, 38, 41, 43, 94, 46, 97, 148, 48, 99, 150, 201, 38, 41, 92, 38, 43, 94, 145, 41, 92, 46, 97, 148, 38, 43, 94, 145, 38, 41, 92, 41, 43, 94, 46, 97, 148, 48, 99, 150, 201, 43, 41, 43, 46, 97, 46, 48, 99, 46, 97, 48, 99, 48, 99, 150, 102, 51, 102, 153, 51, 102, 153, 51, 102, 153, 204, 158, 105, 156, 158, 209, 105, 156, 105, 156, 207, 214, 161, 212, 214, 161, 212, 107, 158, 209, 217, 214, 161, 212, 107, 158, 209, 54, 105, 156, 207, 217, 163, 214, 219, 217, 110, 161, 212, 219, 163, 214, 107, 158, 209, 219, 166, 217, 110, 161, 212, 217, 163, 214, 214, 161, 212, 107, 158, 209, 54, 105, 156, 207, 212, 214, 212, 158, 209, 156, 158, 209, 156, 207, 105, 156, 207, 102, 153, 102, 153, 204, 51, 102, 153, 204, -1}; +int num[256]; +char iline[1024]; + + +void main( void ) +{ + int x, y, r, g, b, i, j, m, n; + unsigned char *ptr, *dat; + + if ( ( ptr = dat = malloc( 2<<16 ) ) == NULL ) + return; + + for ( i = 0; i < 256; i++ ) + num[i] = 0; + + fgets( iline, 1024, stdin ); + if ( strncmp( iline, "P3", 2 ) ) + return; + fgets( iline, 1024, stdin ); + fscanf( stdin, "%d %d\n", &x, &y ); + fgets( iline, 1024, stdin ); + while( !feof( stdin ) ) + { + fscanf( stdin, "%d %d %d", &r, &g, &b ); + if ( feof( stdin ) ) + break; + if ( red[0] < 0 ) + { + red[0] = r; grn[0] = g; blu[0] = b; + } + for ( i = 0; red[i] >=0; i++ ) + { + m = (red[i]-r)*(red[i]-r)+(grn[i]-g)*(grn[i]-g)+(blu[i]-b)*(blu[i]-b); + if ( i == 0 || m < n ) + { + j = i; n = m; + } + } + num[j]++; + *ptr++ = j; + } + for ( j = i = 0; i < 256; i++ ) + { + if ( num[i] ) + { + num[i] = j++; + if ( i > 0 ) + fprintf( stdout, "%08X\n", clut[i-1] ); + } + } + for ( i = 0; dat < ptr; dat++) + if ( ++i == x ) + { + fprintf( stdout, "%2d\n", num[*dat] ); + i = 0; + } + else + { + fprintf( stdout, "%2d, ", num[*dat] ); + } + fprintf( stdout, "\n" ); +} diff --git a/demo/spritedriver/NTSC240H/ppm2ntsc.exe b/demo/spritedriver/NTSC240H/ppm2ntsc.exe new file mode 100644 index 0000000..2bce2a4 Binary files /dev/null and b/demo/spritedriver/NTSC240H/ppm2ntsc.exe differ diff --git a/demo/spritedriver/composite NTSC sprite driver Parallax Forums.URL b/demo/spritedriver/composite NTSC sprite driver Parallax Forums.URL new file mode 100644 index 0000000..580e40c --- /dev/null +++ b/demo/spritedriver/composite NTSC sprite driver Parallax Forums.URL @@ -0,0 +1,2 @@ +[InternetShortcut] +URL=http://forums.parallax.com/forums/default.aspx?f=25&m=343999 diff --git a/doku/Thumbs.db b/doku/Thumbs.db new file mode 100644 index 0000000..2db4c55 Binary files /dev/null and b/doku/Thumbs.db differ diff --git a/doku/TriOS - Logo 1.jpg b/doku/TriOS - Logo 1.jpg new file mode 100644 index 0000000..82b891e Binary files /dev/null and b/doku/TriOS - Logo 1.jpg differ diff --git a/doku/TriOS - Logo 2.jpg b/doku/TriOS - Logo 2.jpg new file mode 100644 index 0000000..44ee962 Binary files /dev/null and b/doku/TriOS - Logo 2.jpg differ diff --git a/doku/TriOS-1.jpg b/doku/TriOS-1.jpg new file mode 100644 index 0000000..aa72063 Binary files /dev/null and b/doku/TriOS-1.jpg differ diff --git a/doku/TriOS.ods b/doku/TriOS.ods new file mode 100644 index 0000000..5424920 Binary files /dev/null and b/doku/TriOS.ods differ diff --git a/doku/TriOS.rtf b/doku/TriOS.rtf new file mode 100644 index 0000000..c3c43fd --- /dev/null +++ b/doku/TriOS.rtf @@ -0,0 +1,51 @@ +{\rtf1\ansi\deff1\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset128 Liberation Serif{\*\falt Times New Roman};}{\f1\fswiss\fprq0\fcharset0 Arial;}{\f2\fswiss\fprq2\fcharset128 Liberation Sans{\*\falt Arial};}{\f3\fswiss\fprq0\fcharset0 Arial;}{\f4\fnil\fprq2\fcharset128 DejaVu Sans;}} +{\colortbl;\red0\green0\blue0;\red128\green128\blue128;} +{\stylesheet{\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs24\lang1081\ltrch\dbch\af1\langfe2052\hich\f1\fs24\lang1031\loch\f1\fs24\lang1031\snext1 Normal;} +{\s2\sb240\sa120\keepn\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af4\afs28\lang1081\ltrch\dbch\af4\langfe2052\hich\f2\fs28\lang1031\loch\f2\fs28\lang1031\sbasedon1\snext3 Heading;} +{\s3\sa120\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs24\lang1081\ltrch\dbch\af1\langfe2052\hich\f1\fs24\lang1031\loch\f1\fs24\lang1031\sbasedon1\snext3 Body Text;} +{\s4\sa120\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs24\lang1081\ltrch\dbch\af1\langfe2052\hich\f1\fs24\lang1031\loch\f1\fs24\lang1031\sbasedon3\snext4 List;} +{\s5\sb120\sa120\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs24\lang1081\ai\ltrch\dbch\af1\langfe2052\hich\f1\fs24\lang1031\i\loch\f1\fs24\lang1031\i\sbasedon1\snext5 caption;} +{\s6\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs24\lang1081\ltrch\dbch\af1\langfe2052\hich\f1\fs24\lang1031\loch\f1\fs24\lang1031\sbasedon1\snext6 Index;} +{\*\cs8\cf0\rtlch\af1\afs24\lang1081\ltrch\dbch\af1\langfe2052\hich\f1\fs24\lang1031\loch\f1\fs24\lang1031 Numbering Symbols;} +}{\*\listtable{\list\listtemplateid1 +{\listlevel\levelnfc0\leveljc0\levelstartat6\levelfollow0{\leveltext \'02\'00.;}{\levelnumbers\'01;}\fi-360\li360} +{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'03\'00.\'01;}{\levelnumbers\'01\'03;}\fi-360\li720} +{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'06\'00.\'01.\'02.;}{\levelnumbers\'01\'03\'05;}\fi-360\li1080} +{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'08\'00.\'01.\'02.\'03.;}{\levelnumbers\'01\'03\'05\'07;}\fi-360\li1440} +{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'0a\'00.\'01.\'02.\'03.\'04.;}{\levelnumbers\'01\'03\'05\'07\'09;}\fi-360\li1800} +{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'0c\'00.\'01.\'02.\'03.\'04.\'05.;}{\levelnumbers\'01\'03\'05\'07\'09\'0b;}\fi-360\li2160} +{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'0e\'00.\'01.\'02.\'03.\'04.\'05.\'06.;}{\levelnumbers\'01\'03\'05\'07\'09\'0b\'0d;}\fi-360\li2520} +{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'10\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07.;}{\levelnumbers\'01\'03\'05\'07\'09\'0b\'0d\'0f;}\fi-360\li2880} +{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'12\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07.\'08.;}{\levelnumbers\'01\'03\'05\'07\'09\'0b\'0d\'0f\'11;}\fi-360\li3240} +{\*\soutlvl{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'14\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07.\'08.\'09.;}{\levelnumbers\'01\'03\'05\'07\'09\'0b\'0d\'0f\'11\'13;}\fi-360\li3600}}\listid1} +{\list\listtemplateid2 +{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02\'00.;}{\levelnumbers\'01;}\fi-360\li360}\listid2} +}{\listoverridetable{\listoverride\listid1\listoverridecount0\ls0}{\listoverride\listid2\listoverridecount0\ls1}} + +{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment StarWriter}{\vern3200}}\deftab720 +{\*\pgdsctbl +{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Standard;}} +{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc +\pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang1081\ltrch\dbch\af1\langfe2052\hich\f1\fs20\lang1031\loch\f1\fs20\lang1031 +\par \pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang1081\ltrch\dbch\af1\langfe2052\hich\f1\fs20\lang1031\loch\f1\fs20\lang1031 +\par \pard\plain \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af1\afs20\lang1081\ltrch\dbch\af1\langfe2052\hich\f1\fs20\lang1031\loch\f1\fs20\lang1031 +\par \pard\plain {\listtext\pard\plain \li360\ri0\lin360\rin0\fi-360\fs20\fs20\fs20 1.\tab}\ilvl0 \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ls1\li720\ri0\lin720\rin0\fi-360\rtlch\af1\afs20\lang1081\ltrch\dbch\af1\langfe2052\hich\f1\fs20\lang1031\loch\f1\fs20\lang1031 {\rtlch \ltrch\loch\f1\fs20\lang1031\i0\b0 \'dcbersicht} +\par \pard\plain {\listtext\pard\plain \li360\ri0\lin360\rin0\fi-360\fs20\fs20\fs20 2.\tab}\ilvl0 \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ls1\li720\ri0\lin720\rin0\fi-360\rtlch\af1\afs20\lang1081\ltrch\dbch\af1\langfe2052\hich\f1\fs20\lang1031\loch\f1\fs20\lang1031 {\rtlch \ltrch\loch\f1\fs20\lang1031\i0\b0 Installation} +\par \pard\plain {\listtext\pard\plain \li360\ri0\lin360\rin0\fi-360\fs20\fs20\fs20 3.\tab}\ilvl0 \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ls1\li720\ri0\lin720\rin0\fi-360\rtlch\af1\afs20\lang1081\ltrch\dbch\af1\langfe2052\hich\f1\fs20\lang1031\loch\f1\fs20\lang1031 {\rtlch \ltrch\loch\f1\fs20\lang1031\i0\b0 Regime CLI} +\par \pard\plain {\listtext\pard\plain \li360\ri0\lin360\rin0\fi-360\fs20\fs20\fs20 4.\tab}\ilvl0 \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ls1\li720\ri0\lin720\rin0\fi-360\rtlch\af1\afs20\lang1081\ltrch\dbch\af1\langfe2052\hich\f1\fs20\lang1031\loch\f1\fs20\lang1031 {\rtlch \ltrch\loch\f1\fs20\lang1031\i0\b0 Ordnerstruktur und Tools} +\par \pard\plain {\listtext\pard\plain \li360\ri0\lin360\rin0\fi-360\fs20\fs20\fs20 5.\tab}\ilvl0 \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ls1\li720\ri0\lin720\rin0\fi-360\rtlch\af1\afs20\lang1081\ltrch\dbch\af1\langfe2052\hich\f1\fs20\lang1031\loch\f1\fs20\lang1031 {\rtlch \ltrch\loch\f1\fs20\lang1031\i0\b0 Systemstart} +\par \pard\plain {\listtext\pard\plain \li360\ri0\lin360\rin0\fi-360\fs20\fs20\fs20 6.\tab}\ilvl0 \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ls1\li720\ri0\lin720\rin0\fi-360\rtlch\af1\afs20\lang1081\ltrch\dbch\af1\langfe2052\hich\f1\fs20\lang1031\loch\f1\fs20\lang1031 {\rtlch \ltrch\loch\f1\fs20\lang1031\i0\b0 Programmieren} +\par \pard\plain {\listtext\pard\plain \li360\ri0\lin360\rin0\fi-360\fs20\fs20\fs20 \tab}\ilvl0 \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\li720\ri0\lin720\rin0\fi-360\rtlch\af1\afs20\lang1081\ltrch\dbch\af1\langfe2052\hich\f1\fs20\lang1031\loch\f1\fs20\lang1031 {\rtlch \ltrch\loch\f1\fs20\lang1031\i0\b0 5.1 IOS} +\par \pard\plain {\listtext\pard\plain \li360\ri0\lin360\rin0\fi-360\fs20\fs20\fs20 \tab}\ilvl0 \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\li720\ri0\lin720\rin0\fi-360\rtlch\af1\afs20\lang1081\ltrch\dbch\af1\langfe2052\hich\f1\fs20\lang1031\loch\f1\fs20\lang1031 {\rtlch \ltrch\loch\f1\fs20\lang1031\i0\b0 5.2 Regnatix-Loader} +\par \pard\plain {\listtext\pard\plain \li360\ri0\lin360\rin0\fi-360\fs20\fs20\fs20 \tab}\ilvl0 \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\li720\ri0\lin720\rin0\fi-360\rtlch\af1\afs20\lang1081\ltrch\dbch\af1\langfe2052\hich\f1\fs20\lang1031\loch\f1\fs20\lang1031 {\rtlch \ltrch\loch\f1\fs20\lang1031\i0\b0 5.3 Administra-Code} +\par \pard\plain {\listtext\pard\plain \li720\ri0\lin720\rin0\fi-360\fs20\fs20\fs20 \tab}\ilvl1 \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\li1080\ri0\lin1080\rin0\fi-360\rtlch\af1\afs20\lang1081\ltrch\dbch\af1\langfe2052\hich\f1\fs20\lang1031\loch\f1\fs20\lang1031 {\rtlch \ltrch\loch\f1\fs20\lang1031\i0\b0 5.3.1 SD-Card} +\par \pard\plain {\listtext\pard\plain \li720\ri0\lin720\rin0\fi-360\fs20\fs20\fs20 \tab}\ilvl1 \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\li1080\ri0\lin1080\rin0\fi-360\rtlch\af1\afs20\lang1081\ltrch\dbch\af1\langfe2052\hich\f1\fs20\lang1031\loch\f1\fs20\lang1031 {\rtlch \ltrch\loch\f1\fs20\lang1031\i0\b0 5.3.2 Sound (HSS, Wav, SIDCog)} +\par \pard\plain {\listtext\pard\plain \li720\ri0\lin720\rin0\fi-360\fs20\fs20\fs20 \tab}\ilvl1 \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\li1080\ri0\lin1080\rin0\fi-360\rtlch\af1\afs20\lang1081\ltrch\dbch\af1\langfe2052\hich\f1\fs20\lang1031\loch\f1\fs20\lang1031 {\rtlch \ltrch\loch\f1\fs20\lang1031\i0\b0 5.3.3 LAN} +\par \pard\plain {\listtext\pard\plain \li720\ri0\lin720\rin0\fi-360\fs20\fs20\fs20 \tab}\ilvl1 \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\li1080\ri0\lin1080\rin0\fi-360\rtlch\af1\afs20\lang1081\ltrch\dbch\af1\langfe2052\hich\f1\fs20\lang1031\loch\f1\fs20\lang1031 {\rtlch \ltrch\loch\f1\fs20\lang1031\i0\b0 5.3.4 COM} +\par \pard\plain {\listtext\pard\plain \li720\ri0\lin720\rin0\fi-360\fs20\fs20\fs20 \tab}\ilvl1 \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\li1080\ri0\lin1080\rin0\fi-360\rtlch\af1\afs20\lang1081\ltrch\dbch\af1\langfe2052\hich\f1\fs20\lang1031\loch\f1\fs20\lang1031 {\rtlch \ltrch\loch\f1\fs20\lang1031\i0\b0 5.3.5 I2C} +\par \pard\plain {\listtext\pard\plain \li360\ri0\lin360\rin0\fi-360\fs20\fs20\fs20 \tab}\ilvl0 \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\li720\ri0\lin720\rin0\fi-360\rtlch\af1\afs20\lang1081\ltrch\dbch\af1\langfe2052\hich\f1\fs20\lang1031\loch\f1\fs20\lang1031 {\rtlch \ltrch\loch\f1\fs20\lang1031\i0\b0 5.4 Bellatrix-Code} +\par \pard\plain {\listtext\pard\plain \li720\ri0\lin720\rin0\fi-360\fs20\fs20\fs20 \tab}\ilvl1 \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\li1080\ri0\lin1080\rin0\fi-360\rtlch\af1\afs20\lang1081\ltrch\dbch\af1\langfe2052\hich\f1\fs20\lang1031\loch\f1\fs20\lang1031 {\rtlch \ltrch\loch\f1\fs20\lang1031\i0\b0 5.4.1 Textmodus} +\par \pard\plain {\listtext\pard\plain \li720\ri0\lin720\rin0\fi-360\fs20\fs20\fs20 \tab}\ilvl1 \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\li1080\ri0\lin1080\rin0\fi-360\rtlch\af1\afs20\lang1081\ltrch\dbch\af1\langfe2052\hich\f1\fs20\lang1031\loch\f1\fs20\lang1031 {\rtlch \ltrch\loch\f1\fs20\lang1031\i0\b0 5.4.2 Grafikmodus} +\par \pard\plain {\listtext\pard\plain \li720\ri0\lin720\rin0\fi-360\fs20\fs20\fs20 \tab}\ilvl1 \ltrpar\s1\cf0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\li1080\ri0\lin1080\rin0\fi-360\rtlch\af1\afs20\lang1081\ltrch\dbch\af1\langfe2052\hich\f1\fs20\lang1031\loch\f1\fs20\lang1031 {\rtlch \ltrch\loch\f1\fs20\lang1031\i0\b0 5.4.3 Keyboard und Maus} +\par } \ No newline at end of file diff --git a/flash/administra/admflash-fat.spin b/flash/administra/admflash-fat.spin new file mode 100644 index 0000000..896f90a Binary files /dev/null and b/flash/administra/admflash-fat.spin differ diff --git a/flash/administra/admflash-hss.spin b/flash/administra/admflash-hss.spin new file mode 100644 index 0000000..a41aeef --- /dev/null +++ b/flash/administra/admflash-hss.spin @@ -0,0 +1,738 @@ +''***************************** +''* Hydra Sound System v1.2 * +''* (C)2007 Andrew Arsenault * +''***************************** +''http://www.andrewarsenault.com/hss/ +''e-mail: ym2413a@yahoo.com +'' +'' Cogs used: 2 +'' HUB-RAM: ~2.7k + +'' Please visit the website for the latest version, documentation, examples and media files. +'' Thank you! --Ym2413a + +'' 25.01.2009 Anpassungen für ein komfortableres Interface zur Visualisierung und Steuerung + +CON +#0, iEndFlag 'Repeat oder Ende wurde erreicht + iRowFlag 'Flag das Songzeile fertig ist + iEngineC 'Patternzähler + iBeatC 'Beatzähler + iRepeat 'zähler für loops +#5, iChannel +#5, iChannel1 +#10, iChannel2 +#15, iChannel3 +#16, iChannel4 +#0, iNote + iOktave + iVolume + iEffekt + iInstrument + +VAR + +'Interface + word intreg[5 * 5] + +'Sound Engine Stack + long hsnd_stack[18] + long cog1, cog2 + +'WavSynth Parameters + long snd_regs[48] 'Regs for Sound Hardware (8x6)+5dpcm + long dpcm_regs[5] + +'DPCM Command Variables + word dpcmreg_ptr + +'Global Hmus Player Vars + word tempo + word song_pc + word song_div + word song_ptr + word chfre[4] + byte chfx[4] + byte chvol[4] + byte hmus_state + byte hmvol + byte fxphs + +'Sound FX Variables + word runlen[2] + word envamp[2] + word sfx_ptr[2] + byte envphs[2] + byte fmcnt[2], fmfreq[2] + byte loadsfx[2] + +CON + +'' Hss Master Control + +PUB start: okay + + okay := cog1 := cognew(@entry, @snd_regs) + okay := cog2 := cognew(hsound, @hsnd_stack) + +PUB stop + + cogstop(cog2) + cogstop(cog1) + +PUB peek(addrptr) : var1 + + var1 := LONG[@snd_regs][addrptr] + +PUB intread(index): wert 'interface: auslesen eines interfaceregisters + + wert := intreg[index] + + +CON + +'' Hydra Music Commands + +PUB hmus_load(songptr) | z + + hmvol := 15 + song_div := 0 + song_ptr := songptr + song_pc := WORD[songptr][8] + tempo := WORD[songptr][12] + repeat z from 0 to 3 + chfx[z] := 0 + + repeat z from 0 to 5*5 'interface: playerinterface alle werte löschen + intreg[z] := 0 + + +PUB hmus_play + + hmus_state := 1 + +PUB hmus_stop | z + + hmus_state := 0 + repeat z from 0 to 3 + chvol[z] := 0 + +PUB hmus_pause + + hmus_state := 0 + +PUB hmus_tempo(var1) + + tempo := var1 + +PUB get_hmus_tempo : var1 + + var1 := tempo + +PUB hmus_vol(var1) + + hmvol := var1 <# 15 #> 0 + +PUB get_hmus_vol : var1 + + var1 := hmvol + +CON + +'' FXsynth Commands + +PUB sfx_play(chan, soundptr) + + if(chan == 1) + sfx_ptr[0] := soundptr + loadsfx[0] := 0 + if(chan == 2) + sfx_ptr[1] := soundptr + loadsfx[1] := 0 + +PUB sfx_stop(chan) + + if(chan == 1) + sfx_ptr[0] := 0 + if(chan == 2) + sfx_ptr[1] := 0 + +PUB sfx_keyoff(chan) + + if(chan == 1) + envphs[0] := 3 + if(chan == 2) + envphs[1] := 3 + +CON + +'' Hydra DPCM Commands + +PUB dpcm_play(soundptr) + + dpcmreg_ptr := soundptr + +PUB dpcm_stop + + dpcmreg_ptr := 1 + +CON +''***************************** +''* Hss Sound Engine * +''***************************** +PRI Hsound +repeat + 'Update Music Engine + UpdateMus(song_ptr, Hmus_state) 'Update Music Player + 'volume/frequenzwerte werden in die soundregister geschrieben + VolumeInterpol 'Delay and Interpolate Volume to Remove Pops and Clicks. + + 'Update DPCM Engine + if(dpcmreg_ptr) + DpcmUpdate 'Update the DPCM registers + + 'Update SoundFX Engine + + 'FX channel A + FXSynth(0,32) + 'FX channel B + FXSynth(1, 40) + +PRI VolumeInterpol | z, channelmul, musvar, freqval + + fxphs += 5 + +'Volume Interpolation + repeat z from 0 to 3 step 1 + channelmul := 4+(8*z) + musvar := (chvol[z]*(hmvol+1))&$F0 + snd_regs[channelmul] := (snd_regs[channelmul] & 15)+musvar + + 'Freq Interpolation + channelmul -= 1 'Jump down a REG to Freq + musvar := chfre[z]<<16 + + if(chfx[z] == 0) 'None + snd_regs[channelmul] := musvar + + elseif(chfx[z] < 3) 'Vibrato (light/hard) + if(fxphs < 128) + snd_regs[channelmul] := musvar+(chfre[z]<<(7+chfx[z])) + else + snd_regs[channelmul] := musvar-(chfre[z]<<(7+chfx[z])) + + elseif(chfx[z] == 3) 'Tremolo + if(fxphs < 128) + snd_regs[channelmul] := musvar + else + snd_regs[channelmul] := musvar<<1 + + else 'Portamento + freqval := snd_regs[channelmul]>>16 + if(freqval & $F000 == chfre[z] & $F000) + snd_regs[channelmul] := musvar + elseif(freqval < chfre[z]) + snd_regs[channelmul] := snd_regs[channelmul]+(chfx[z]<<22) + else + snd_regs[channelmul] := snd_regs[channelmul]-(chfx[z]<<22) + +PRI UpdateMus(songptr, state) | i, channel, channelmul, scrdat, freq, freqoct, flag + + if(state == 0) + return ''Song is not playing. + + song_div++ 'zeitfaktor; wird erhöht bis... + + if(song_div => tempo) 'Tempo Divider 'schwellwert erreicht, dann nächster beat + song_div := 0 + flag := 0 + intreg[iBeatC] := intreg[iBeatC] + 1 'interface: beatconter erhöhen + intreg[iRowFlag] := 0 'interface: Kennung das Zeile bearbeitet wird + repeat i from 5 to 5*5 'interface: channelwerte löschen + intreg[i] := 0 + + repeat 'Score Decoder and Processor + scrdat := BYTE[song_ptr][song_pc] 'song_pc ist zeiger auf wert in MusicDat + channel := scrdat & 3 'untere zwei bit enthalten die kanalnummer + channelmul := channel<<3 'jedem channel sind 8 registerwerte zugeordent + intreg[iEngineC] := song_pc 'interface: enginecounter setzen + song_pc++ 'zeiger auf nächsten wert setzen + + ''Base Commands + if(scrdat == 0) 'End Row 'nächste trackerzeile + intreg[iRowFlag] := 1 'interface: Zeile fertig bearbeitet + quit + + if(scrdat == 1) 'Repeat Song 'wiederholt ab MusicLoop (MusicDat ist also die einleitung) + song_pc := WORD[songptr][9] + intreg[iRepeat] := intreg[iRepeat] + 1 'interface: flag das songende erreicht wurde + quit + + if(scrdat == 2) 'End Song 'status wird auf 0 gesetzt + intreg[iEndFlag] := 1 'interface: flag das songende erreicht wurde + hmus_stop + quit + + if(scrdat == 3) 'Set Flag + flag := 1 + next + + if((scrdat & $3C) == $20) 'Patch HI Note 'oktave erhöhen und veränderung zu "Change Note" + flag := 2 + scrdat := scrdat>>3 + scrdat += 64+channel + + if(scrdat & 4) 'Change Note + freq := scrdat>>3 'note Bit3 bis Bit7 (32 Noten) + freqoct := freq/12 + freq -= freqoct*12 + case flag + 1 : freqoct += 2 + 2 : freqoct += 6 + other : freqoct += 4 + flag := 0 + snd_regs[4+channelmul] := snd_regs[4+channelmul] & $FE + intreg[(channel*iChannel)+iChannel+iNote] := freq + 1 'interface: note setzen (0 ist erste note!) + intreg[(channel*iChannel)+iChannel+iOktave] := freqoct 'interface: oktave setzen + 'frequenz aus tabelle holen + 'je nach oktave wird nach rechts verschoben (/2) + chfre[channel] := NoteFreqs[freq]>>(6-freqoct) + snd_regs[4+channelmul] := (snd_regs[4+channelmul] & $FE)+1 + next 'Repeat To Next Datum + + if(scrdat & 8) 'Change Evelope / Channel Effect + if(flag) + intreg[(channel*iChannel)+iChannel+iEffekt] := scrdat>>4 + 1 'interface: effektwert setzen + chfx[channel] := scrdat>>4 + flag := 0 + else + intreg[(channel*iChannel)+iChannel+iVolume] := scrdat>>4 'interface: volume setzen + chvol[channel] := scrdat>>4 + next 'Repeat To Next Datum + + if(scrdat & 16) 'Change Instrument + freq := (scrdat & $E0)>>3 + freq += flag<<5 + flag := 0 + intreg[(channel*iChannel)+iChannel+iInstrument] := freq>>2 + 1 'interface: instrument setzen + snd_regs[0+channelmul] := songptr+WORD[songptr+32][freq] 'zeiger auf neues instrumentensample + snd_regs[1+channelmul] := WORD[songptr+32][freq+1] 'ende des samples + snd_regs[2+channelmul] := WORD[songptr+32][freq+2] 'loop + snd_regs[4+channelmul] := WORD[songptr+32][freq+3] & $0F 'flags? + next 'Repeat To Next Datum + + if(scrdat & 64) 'Detune + chfre[channel] := chfre[channel]+(chfre[channel]>>8) + + + +PRI DpcmUpdate + + if(dpcmreg_ptr > 15) 'Play Sample. + dpcm_regs[2] := 65535 'End sample if one was playing + dpcm_regs[0] := dpcmreg_ptr+8 + dpcm_regs[4] := 128 + dpcm_regs[3] := LONG[dpcmreg_ptr][1] 'Get sampling rate + dpcm_regs[1] := WORD[dpcmreg_ptr][1] 'Get length + dpcm_regs[2] := 0 'Reset play counter + elseif(dpcmreg_ptr == 1) 'Stop Sample + dpcm_regs[2] := 65535 'End sample + dpcm_regs[4] := 128 + + dpcmreg_ptr := 0 + +PRI FXSynth(SoundVars, ChannelFX) | TimeCnt, SoundFX, Modwav, FMwav, AMwav + TimeCnt := Cnt + SoundFX := sfx_ptr[SoundVars] + + if(loadsfx[SoundVars] == 0) + 'Setup OSC WaveForm + case BYTE[SoundFX][0] + $00: 'Sine + snd_regs[ChannelFX] := @SineTable + snd_regs[1+ChannelFX] := 64 + $01: 'Fast Sine + snd_regs[ChannelFX] := @FastSine + snd_regs[1+ChannelFX] := 32 + $02: 'Sawtooth + snd_regs[ChannelFX] := @Sawtooth + snd_regs[1+ChannelFX] := 64 + $03: 'Square + snd_regs[ChannelFX] := @SqrTable + snd_regs[1+ChannelFX] := 32 + $04: 'Fast Square + snd_regs[ChannelFX] := @FastSqr + snd_regs[1+ChannelFX] := 8 + $05: 'Buzz + snd_regs[ChannelFX] := @NoteFreqs + snd_regs[1+ChannelFX] := 24 + $06: 'Noise + snd_regs[ChannelFX] := $F002 + snd_regs[1+ChannelFX] := 3000 + + snd_regs[2+ChannelFX] := 0 + snd_regs[4+ChannelFX] := $01 + + loadsfx[SoundVars] := 1 + runlen[SoundVars] := 0 + fmcnt[SoundVars] := 0 + fmfreq[SoundVars] := 0 + envamp[SoundVars] := 0 + envphs[SoundVars] := 0 + +''Modulation Code + fmfreq[SoundVars]++ + if(fmfreq[SoundVars] => BYTE[SoundFX][4]) + fmfreq[SoundVars] := 0 + fmcnt[SoundVars]++ + fmcnt[SoundVars] := fmcnt[SoundVars] & $3F + + case BYTE[SoundFX][5] + $00: + Modwav := BYTE[@SineTable][fmcnt[SoundVars]] + $01: + Modwav := BYTE[@FastSine][fmcnt[SoundVars] & 31] + $02: + Modwav := fmcnt[SoundVars]<<2 + $03: + Modwav := !fmcnt[SoundVars]<<2 + $04: + if(fmcnt[SoundVars] & 8) + Modwav := $ff + else + Modwav := $00 + $05: + Modwav := BYTE[$F002][fmcnt[SoundVars]] + $FF: + Modwav := BYTE[SoundFX+12][fmcnt[SoundVars] & 15] + + fmwav := Modwav/(BYTE[SoundFX][6]) 'FM amount + amwav := 256-(Modwav/(BYTE[SoundFX][7])) 'AM amount + amwav := (BYTE[SoundFX][3]*amwav)>>8 + +''Envelope Generator + if(envphs[SoundVars] == 0) 'Attack + envamp[SoundVars] += BYTE[SoundFX][8] + if(envamp[SoundVars] > 8191) + envamp[SoundVars] := 8191 + envphs[SoundVars] := 1 + if(BYTE[SoundFX][8] == $ff) + envamp[SoundVars] := 8191 + if(envphs[SoundVars] == 1) 'Decay + envamp[SoundVars] -= BYTE[SoundFX][9] + if(envamp[SoundVars] & $8000) + envphs[SoundVars] := 2 + if(envamp[SoundVars] =< (BYTE[SoundFX][10]<<5)) + envphs[SoundVars] := 2 + if(envphs[SoundVars] == 2) 'Sustain + envamp[SoundVars] := (BYTE[SoundFX][10]<<5) + if(envphs[SoundVars] == 3) 'Release + envamp[SoundVars] -= BYTE[SoundFX][11] + if(envamp[SoundVars] & $8000) + envamp[SoundVars] := 4 + + amwav := ((envamp[SoundVars]>>9)*(amwav+1))>>4 + +''Run Length and Outputing + if(SoundFX > 15) + runlen[SoundVars]++ + snd_regs[3+ChannelFX] := (BYTE[SoundFX][2]+fmwav)<<24 'Update Frequency + snd_regs[4+ChannelFX] := (amwav<<4)+(snd_regs[4+ChannelFX] & $0F) 'Update Amplitude + else + snd_regs[4+ChannelFX] := $00 'Mute + + if(BYTE[SoundFX][1] == $ff) '$ff = never stop + runlen[SoundVars] := 0 + + if(runlen[SoundVars] > (BYTE[SoundFX][1]<<5)) 'Duration KeyOff + envphs[SoundVars] := 3 + +WaitCnt(TimeCnt + 52_000) ''Delay for Synth Engine Update. + +DAT + +SineTable byte $80, $8c, $98, $a5, $b0, $bc, $c6, $d0 + byte $da, $e2, $ea, $f0, $f5, $fa, $fd, $fe + byte $ff, $fe, $fd, $fa, $f5, $f0, $ea, $e2 + byte $da, $d0, $c6, $bc, $b0, $a5, $98, $8c + byte $80, $73, $67, $5a, $4f, $43, $39, $2f + byte $25, $1d, $15, $0f, $0a, $05, $02, $01 + byte $00, $01, $02, $05, $0a, $0f, $15, $1d + byte $25, $2f, $39, $43, $4f, $5a, $67, $73 + +Sawtooth byte $ff, $fb, $f7, $f3, $ef, $eb, $e7, $e3 + byte $df, $db, $d7, $d3, $cf, $cb, $c7, $c3 + byte $bf, $bb, $b7, $b3, $af, $ab, $a7, $a3 + byte $9f, $9b, $97, $93, $8f, $8b, $87, $83 + byte $80, $7c, $78, $74, $70, $6c, $68, $64 + byte $60, $5c, $58, $54, $50, $4c, $48, $44 + byte $40, $3c, $38, $34, $30, $2c, $28, $24 + byte $20, $1c, $18, $14, $10, $0c, $08, $04 + +FastSine byte $80, $98, $b0, $c6, $da, $ea, $f5, $fd + byte $ff, $fd, $f5, $ea, $da, $c6, $b0, $98 + byte $80, $67, $4f, $39, $25, $15, $0a, $02 + byte $00, $02, $0a, $15, $25, $39, $4f, $67 + +SqrTable byte $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff + byte $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff + byte $00, $00, $00, $00, $00, $00, $00, $00 + byte $00, $00, $00, $00, $00, $00, $00, $00 + +FastSqr byte $ff, $ff, $ff, $ff, $00, $00, $00, $00 + +'Note LookupTable. +NoteFreqs word $85F3, $8DEA, $965B, $9F4B, $A8C4, $B2CD, $BD6F, $C8B3, $D4A2, $E147, $EEAC, $FCDE 'Top Octave Lookup + +CON +''***************************** +''* WaveTable Synth v1.2 * +''* DPCM Synth v1.1 * +''* (C)2006 Andrew Arsenault * +''***************************** +DAT + org +entry mov dira,Port_Pins 'Setup output pins + + mov ctra,Right_ctra 'Setup Right Audio Channel + mov ctrb,Left_ctra 'Setup Left Audio Channel + + mov ChlA_wave,#256 'Set channel signals. + mov ChlA_offset,#0 'Set channel's offset. + mov ChlA_counter,#0 + + mov Time,#10 + add Time,cnt 'Prepare for asm type WAITCNT loop. + +'MAIN LOOP +update waitcnt Time,Timing_delay 'Wait for CNT = D, then add S into D + + 'Transfer Sound Registers + mov addrregs,par + mov y,NumberOfChannels + + 'Fetch Channel's Registers +transferchl rdlong ChlAp_sampptr,addrregs + add addrregs,#4 + rdlong ChlAp_sampend,addrregs + add addrregs,#4 + rdlong Ch1Ap_samplpp,addrregs + add addrregs,#4 + rdlong Ch1Ap_freq,addrregs + add addrregs,#4 + rdlong ChlAp_keyon,addrregs + + 'Fetch Channel's Static Variables + add addrregs,#8 + rdlong ChlA_offset,addrregs + add addrregs,#4 + rdlong ChlA_counter,addrregs + + 'Run Synth Engine on Channel + call #wvsynth + + 'Store Channel's Static Variables (Tucked Center X move to Wave) + wrlong ChlA_counter,addrregs + sub addrregs,#4 + sub x,#256 + wrlong ChlA_offset,addrregs + sub addrregs,#4 + mov ChlA_wave,x 'Doesn't Waste anything doing this. + wrlong ChlA_wave,addrregs + add addrregs,#12 + + 'Loop Until All Channel's Are Done. + djnz y,#transferchl + + 'Run DPCM Engine + call #dpcm + + 'Mix Channels Together + mov addrregs,par + mov ChlA_wave,#0 + add addrregs,#5*4 + mov y,NumberOfChannels + +mixchls rdlong x,addrregs + add ChlA_wave,x + add addrregs,#8*4 + djnz y,#mixchls + + mov x,DPCM_wave 'Add DPCM + shl x,#2 + add ChlA_wave,x + + shl ChlA_wave,#20 'Convert 12bit singal into a 32bit one. + + 'Update output Channels then repeat again. + mov frqa,ChlA_wave + mov frqb,ChlA_wave + + jmp #update + + + + +'-------------------------Dpcm Engine-------------------------' + +dpcm mov addrregs,par + add addrregs,#192 + + rdlong DPCM_address,addrregs 'Start Address + add addrregs,#4 + rdlong DPCM_runlen,addrregs 'File Lenght + add addrregs,#4 + rdlong DPCM_offset,addrregs 'File Offset + add addrregs,#4 + rdlong DPCM_freq,addrregs 'Playback Speed + add addrregs,#4 + rdlong DPCM_wave,addrregs 'Waveform Amp + + 'Check for if keyon/length is set. + cmp DPCM_offset,DPCM_runlen wc + if_ae jmp #mute_dpcm 'End of file + + 'Freq Timer/Divider and Increase sampling offset + add DPCM_counter,DPCM_freq wc + if_nc jmp #done_dpcm + + 'Decode DPCM + add DPCM_address,DPCM_offset + rdbyte x,DPCM_address 'Fetch Datum + + mov DPCM_delta,x + shr DPCM_delta,#6 + mov y,#1 + shl y,DPCM_delta + mov DPCM_delta,y + + mov y,#1 + shl y,DPCM_phs + test x,y wc + if_c add DPCM_wave,DPCM_delta + if_nc sub DPCM_wave,DPCM_delta + + add DPCM_phs,#1 + cmp DPCM_phs,#6 wc + if_b jmp #done_dpcm + + mov DPCM_phs,#0 + add DPCM_offset,#1 + jmp #done_dpcm + +mute_dpcm mov DPCM_wave, #128 + +done_dpcm mov addrregs,par + add addrregs,#200 + wrlong DPCM_offset,addrregs 'File Offset + add addrregs,#8 + wrlong DPCM_wave,addrregs 'Wave +dpcm_ret ret + +'-----------------------Dpcm Engine End-----------------------' + + + +'-------------------------Sound Engine-------------------------' + + 'Freq Timer/Divider and Increase sampling offset +wvsynth add ChlA_counter,Ch1Ap_freq wc + if_c add ChlA_offset,#1 + + 'Reset sample position and lock at zero if Keyoff. + test ChlAp_keyon,#%0001 wc + if_nc mov ChlA_offset,#0 + + 'Reset(loop) if needed + cmp ChlA_offset,ChlAp_sampend wc + if_ae mov ChlA_offset,Ch1Ap_samplpp + + 'Check BitRate and Set Offset + mov x,ChlA_offset + test ChlAp_keyon,#%0010 wc + if_c shr x,#1 + + 'Fetch WaveTable + mov ChlA_wave,ChlAp_sampptr + add ChlA_wave,x + rdbyte ChlA_wave,ChlA_wave + + 'Check BitRate and Skip if 8bit + test ChlAp_keyon,#%0010 wc + if_nc jmp #skip_4bitsam + + 'Convert 4bit to 8bit + test ChlA_offset,#%0001 wc + if_c shr ChlA_wave,#4 + if_nc and ChlA_wave,#%00001111 + + mov x,ChlA_wave + shl ChlA_wave,#4 + add ChlA_wave,x + + 'Center Amplitude and mute if Keyoff. +skip_4bitsam test ChlAp_keyon,#%0001 wc + if_nc mov ChlA_wave,#128 + + 'Volume Multiply + mov x,#0 + test ChlAp_keyon,#%10000000 wc + if_c add x,ChlA_wave + if_nc add x,#128 + + shr ChlA_wave,#1 + test ChlAp_keyon,#%01000000 wc + if_c add x,ChlA_wave + if_nc add x,#64 + add x,#64 + + shr ChlA_wave,#1 + test ChlAp_keyon,#%00100000 wc + if_c add x,ChlA_wave + if_nc add x,#32 + add x,#96 + + shr ChlA_wave,#1 + test ChlAp_keyon,#%00010000 wc + if_c add x,ChlA_wave + if_nc add x,#16 + add x,#112 + +'Return Audio as X. +wvsynth_ret ret + +'-----------------------Sound Engine End-----------------------' + +Port_Pins long %00000000_00000000_00000011_00000000 + + '- CTR PLL -------- BPIN --- APIN +Right_ctra long %0_00110_000_00000000_000000_000_001000 +Left_ctra long %0_00110_000_00000000_000000_000_001001 + +Timing_delay long 2500 'Sampling Rate = 32,000.00hz +NumberOfChannels long 6 + +Time res 1 +addrregs res 1 +x res 1 +y res 1 + +'WaveTable Synth Accumulators +ChlA_wave res 1 +ChlA_offset res 1 +ChlA_counter res 1 +ChlAp_sampptr res 1 +ChlAp_sampend res 1 +Ch1Ap_samplpp res 1 +Ch1Ap_freq res 1 +ChlAp_keyon res 1 + +'DPCM Accumulators +DPCM_wave res 1 +DPCM_address res 1 +DPCM_offset res 1 +DPCM_counter res 1 +DPCM_freq res 1 +DPCM_runlen res 1 +DPCM_phs res 1 +DPCM_delta res 1 \ No newline at end of file diff --git a/flash/administra/admflash-plx.spin b/flash/administra/admflash-plx.spin new file mode 100644 index 0000000..6917a14 Binary files /dev/null and b/flash/administra/admflash-plx.spin differ diff --git a/flash/administra/admflash-rtc.spin b/flash/administra/admflash-rtc.spin new file mode 100644 index 0000000..8cd6854 Binary files /dev/null and b/flash/administra/admflash-rtc.spin differ diff --git a/flash/administra/admflash-wav.spin b/flash/administra/admflash-wav.spin new file mode 100644 index 0000000..a623355 Binary files /dev/null and b/flash/administra/admflash-wav.spin differ diff --git a/flash/administra/admflash.spin b/flash/administra/admflash.spin new file mode 100644 index 0000000..9dcab38 Binary files /dev/null and b/flash/administra/admflash.spin differ diff --git a/flash/administra/pterm.spin b/flash/administra/pterm.spin new file mode 100644 index 0000000..a525a4b Binary files /dev/null and b/flash/administra/pterm.spin differ diff --git a/flash/bellatrix/belflash.spin b/flash/bellatrix/belflash.spin new file mode 100644 index 0000000..0517176 Binary files /dev/null and b/flash/bellatrix/belflash.spin differ diff --git a/flash/regnatix/regflash.spin b/flash/regnatix/regflash.spin new file mode 100644 index 0000000..a193466 Binary files /dev/null and b/flash/regnatix/regflash.spin differ diff --git a/license.spin b/license.spin new file mode 100644 index 0000000..6f1fc2e Binary files /dev/null and b/license.spin differ diff --git a/logbuch.rtf b/logbuch.rtf new file mode 100644 index 0000000..6ea2203 --- /dev/null +++ b/logbuch.rtf @@ -0,0 +1,82 @@ +{\rtf1\ansi\ansicpg1252\deff0\deftab709{\fonttbl{\f0\fnil\fcharset0 Times New Roman;}{\f1\fnil\fcharset128 Times New Roman;}{\f2\fnil\fcharset0 Courier New;}{\f3\fnil\fcharset2 Symbol;}} +{\*\generator Msftedit 5.41.15.1515;}\viewkind4\uc1\pard\lang1031\f0\fs20 18-09-2010-dr235\tab\tab - regime: free zeigt jetzt auch die speicherbelegung des eram an\par +\tab\tab\tab - speicherverwaltung/ramdisk integriert (beispielcode siehe eram.spin & regime.spin)\par +\tab\tab\tab - eram.bin kann jetzt auch mit ramdisk umgehen\par +\tab\tab\tab - regime: neue kommandos f\'fcr ramdisk\par +\tab\tab\tab - egalisierung der namen f\'fcr den ramzugriff (\'e4lterer code mu\'df leicht angepasst werden)\par +\tab\tab\tab - user- und systemmode f\'fcr ramzugriff eingef\'fcgt\par +\tab\tab\tab - erste version eine make-batch um das gesamte system zu kompilieren (nur grundsystem)\par +\tab\tab\tab - \'e4nderung zur ios: da bst eine pfadliste zu bibliotheksordnern unterst\'fctzt, liegt (soweit das m\'f6glich ist)\par +\tab\tab\tab die ios nun nur noch unter system\\regnatix \par +\tab\tab\tab WICHTIG: Pfad zur ios.spin im bst einstellen\par +23-08-2010-dr040\tab\tab - integration ay-emulator (admay.adm) und yplay\f1\par +19-07-2010-dr235 \f0\tab\f1 - booten eines alternativen administra-codes: befindet sich auf der karte\par + \f0\tab\tab \f1 in der root eine datei "adm.sys", so wird diese datei automatisch in\par + \f0\tab\tab \f1 administra geladen\par +11-07-2010-dr235\tab\f0\tab\f1 - integration sid1/2-funktionen in admsid/ios\line\tab\tab\tab - anpassung sid-demo von ahle2 als regnatix-code (verzeichnis demo)\line\tab\tab\tab - diverse graphics-spielereien (verzeichnis demo)\line\tab\tab\tab - sysconf /af - administra neu booten (admflash.adm\line\tab\tab\tab wird dadurch \u252?berfl\u252?ssig)\line 27-06-2010-dr085/235\tab - admin mountet nun automatisch nach einem boot\tab\tab\line 26-06-2010-dr235\tab\f0\tab\f1 - div. demos zugef\u252?gt\line\tab\tab\tab - shooter angepasst und eingef\u252?gt\line 20-06-2010-dr235\tab\f0\tab\f1 - erste lauff\u228?hige SID-Player-Version\line\tab\tab\tab f\u252?r die Kommandozeile (splay)\line 14-06-2010-dr085/235\tab - Semaphoren in FATEngine korrekt eingesetzt\line\tab\tab\tab - Abfrage des Volume-Labels korrigiert\line 10-06-2010-dr235\tab\f0\tab\f1 - Kommando "ramtest" zugef\u252?gt\line 09-06-2010-dr085\tab\f0\tab\f1 - Fehler in Administra-Bootfunktion behoben\line\line -----------------------------------------------------------------------------------------------\line\line\f0 02-10-2010-dr235\par +\par +\ul\b Speicherverwaltung:\par +\ulnone\b0\par +In dieser Version ist eine erste Beta-Version der Speicherverwaltung des externen RAM's enthalten. Der Speicher kann dabei in einem einfachen oder einem strukturierten Modus verwendet werden. Klingt kompliziert, ist aber ganz einfach. \par +\par +\b Einfacher Modus:\par +\b0\par +Hierbei kann ein Programm auf den eRAM \'fcber die IOS-Routinen ios.ram_* zugreifen. Wahlweise kann der Speicher im Systemmode direkt von 0 bis $07FFFF angesprochen werden, oder nur der Userbereich. Im Systemmodus ist darauf zu achten, dass eine eventuell vorhandene Ramdisk und die Systemvariablen nicht \'fcberschrieben werden, man sollte also wissen was man tut... ;) Die Ramdisk wird ab der physischen Adresse 0 als verkettete Liste verwaltet, die Systemvariablen befinden sich ab $07FFFF abw\'e4rts. \par +\par +ios.ram_wrbyte(ios#sysmod,0,ios#MAGIC)\tab\tab - Schreibt den Wert 0 in die Systemvariable, um einen Kaltstart auszul\'f6sen.\par +ios.ram_wrbyte(ios#sysmod,$20,$100)\tab\tab - Schreibt den Wert $20 an die physische Adresse $100 im eRAM.\par +\par +Da es nun m\'fchsam ist in einem kleinen Code solche Konflikte mit dem Systemspeicher zu vermeiden, gibt es den Usermodus. Im Usermodus wird nur genau jener freie Speicher adressiert, welcher sich zwischen Ramdisk und Systemvariablen befindet. In diesem Fall ist die Adressierung also virtualisiert.\par +\par +ios.ram_wrbyte(ios#usrmod,0,$100)\tab\tab - Schreibt den Wert 0 an die Adresse $100 im Userspeicher!\par +\par +In Regime kann man mit dem Kommando "free" jetzt auch die wichtigsten Systemvariablen der Speicherverwaltung anzeigen.\par +\par +RBAS\tab\tab - Erste physische Adresse des Userspeichers\par +REND\tab\tab - Physische Adresse der letzten freien Speicherstelle des Userspeichers.\par +USER\tab\tab - Gr\'f6sse des Userspeichers (REND - RBAS).\par +RAMDRV\tab 0 - Ramdisk ist nicht initialisiert\par +\tab\tab 1 - Ramdisk ist initialisiert\par +SYSVAR\tab - Erste physische Adresse der Systemvariablen.\par +\par +Noch genauer kann man sich die Speicherbelegung mit dem Tool "eram" anschauen. Nur ein paar Beispiele:\par +\par +d\tab - Anzeige des Speichers. Es werden zwei Adressspalten angezeigt. Die zweite schwarze Adresse in jeder Zeile zeigt die physische Adresse, die erste gr\'fcne Adresse die virtuelle Adresse im Userspeicher. Man kann sehr gut erkennen, ab welcher Adrese der Userbereich anf\'e4ngt und wo er endet.\par +d 100\tab - Anzeige ab physischer Adresse $100\par +d bas\tab - Anzeige vom Start des Userspeichers.\par +n \tab - Anzeige inkrementell fortsetzen\par +\par +Die Nutzung des Userspeichers ist sehr einfach. Es sind dabei nur folgende Regeln zu beachten:\par +\par +\pard{\pntext\f3\'B7\tab}{\*\pn\pnlvlblt\pnf3\pnindent0{\pntxtb\'B7}}\fi-720\li720 Man muss selbst darauf achten die Speichergrenzen nicht zu \'fcberschreiten. Bei \'dcberschreitung kann aber nichts passieren - die IOS-Routinen brechen einfach ab, allerdings werden die eigenen Daten halt nicht korrekt verarbeitet. Es werden also die Systemvariablen und die Daten in der Ramdisk gesch\'fctzt.\par +{\pntext\f3\'B7\tab}Der Userbereich im eRAM ist nur zur Laufzeit der Anwendung g\'fcltig. Wird die Anwendung beendet, so kann durch Regime oder eine andere Anwendung mit den Daten der Ramdisk gearbeitet werden, wodurch sich der physische Bereich des Userbereiches ver\'e4ndert. Wer also residente Daten \'fcber die Laufzeit der Anwendung hinaus braucht, muss im strukturierten Modus mit der Ramdisk arbeiten.\par +{\pntext\f3\'B7\tab}In einer Anwendung nicht den einfachen oder strukturierten Modus mischen - das gibt Chaos, wenn man nicht ganz genau aufpasst\par +\pard\par +Ansonsten kann man wie gehabt die schon bekannten IOS-Routinen verwenden, einzig der \'dcbergabeparameter zur Wahl des System- oder Usermodus sind hinzugekommen. Als Beispiel kann man sich die Soundplayer anschauen, die ihre Dateiliste im Userspeicher ablegen.\par + \par +\b Strukturierter Modus:\b0\par +\par +Was ist aber, wenn wir einen kleinen Texteditor schreiben wollen, der seine Textdaten resident im eRAM speichern kann? Ich m\'f6chte also den Texteditor verlassen k\'f6nnen, um in Regime zum Beispiel einen Assembler aufzurufen, welcher den Text dann assembliert. Darauf folgend m\'f6chte ich meinen Texteditor wieder starten und an dem Text weiter arbeiten. Daf\'fcr muss es meiner Anwendung - dem Textprogramm - m\'f6glich sein, einen Speicherbereich im eRAM zu reservieren, der von System und anderen Anwendungen respektvoll behandelt wird.\par +\par +Gedacht, getan: Im strukturierten Modus wird der Speicher in Form einer Ramdisk verwaltet. Die Dateien/Daten k\'f6nnen \'fcber ihren Namen angesprochen werden. Es kann mit put & get sequentiell, oder mit read & write direkt adressierbar auf die Daten in der Datei zugegriffen werden.\par +\par +Als erstes praktisches Beispiel m\'f6gen die neuen Kommandos in Regime selbst dienen, mit denen man die Ramdisk verwalten kann:\par +Neue Regime-Kommandos:\par +\par +\f2 xload - datei in ram laden\par +xsave - datei aus ram speichern\par +xdir - verzeichnis im ram anzeigen\par +xrename - datei im ram umbenennen\par +xdel - datei im ram l\'f6schen\par +xtype - text im ram anzeigen\par +\f0\par +So ist es also m\'f6glich, sich in der Kommandozeile anzuschauen, welche residenten Daten die Programme aktuell angelegt haben. Sofern es Textdaten sind, k\'f6nnen diese Daten auch einafch angezeigt werden.\par +\par +Die Speicherverwaltung ist allerdings noch sehr experimentell - was bedeutet, dass wohl noch einige Bugs drin sein d\'fcrften. :)\par +\par +\ul\b MAKE.BAT\par +\par +\ulnone\b0 Diese Batchdatei im obersten Verzeichnis kompiliert das Grundsystem, bestehend aus den drei Flashdateien und den grundlegenden Kommandos im Systemverzeichnis. Ist ein erster Versuch. Was noch fehlt ist ein Fehlerlog und vielleicht noch die anderen Programme.\par +\f1\line 09-06-2010-dr235\line\line Nach nur zwei Tagen hat drohne085 (frida) das Geheimnis um die Bootroutine gel\u246?st: Die Ursache lag in einer von der FATEngine verwendeten Semaphore, welche fest auf den Lock 0 "verdrahtet" war. Diese Semaphore wird an diversen Stellen in der Engine verwendet, wurde aber beim Bootvorgang nicht gel\u246?scht oder freigegeben! Gedacht war sie, um den Bus zur SD-Card bei einem Zugriff zu verriegeln, falls mehrere Instanzen der Engine laufen, und gleichzeitig zugreifen wollen. Somit hat sich die Engine quasi selbst verriegelt und nach dem Bootvorgang als "neue Instanz" nun auch keinen Zugriff mehr - so sch\u246?n kann praktische Parallelverarbeitung sein... ;)\line\line Hier nun eine neue und aktuelle Version mit einer tempor\u228?ren funktionierenden L\u246?sung des Problems.\line\line Im System-Ordner gibt es jetzt folgende ausf\u252?hrbare Administra-Dateien:\line\line admflash.adm\tab\tab Standard-Flash, welches auch im EEProm gespeichert ist\line admini.adm\tab\tab Mini-Flash ohne Sound, nor SDCard + Managment-Routinen\line admled.adm\tab\tab Das Heartbeat-LED-Testprogramm zum direkten laden\line aterm96.adm\tab\tab Die leicht modifizierte Kommandozeile vom Programmierer der FATEngine. Mit \line\tab\tab\tab diesem Administra-Code kann man direkt \u252?ber die Hostschnittstelle (9600 Baud)\line\tab\tab\tab mit dem Chip kommunizieren. Dokumentation der Kommandos findet man im \line\tab\tab\tab Verzeichnis "komponenten/fat/fatengine beta"\line \line\line 07-06-2010-dr235\line\line Hier der aktuelle Stand von TriOS. Momentan k\u228?mpfe ich an einem \line Komplexfehler mit dem Bootloader von Administra. Das Problem ist recht \line einfach zu reproduzieren, aber leider (f\u252?r mich) nur schwer zu\line erfasen: Die verwendete FATEngine besitzt eine Bootfunktion um einen\line neuen BIN-Objektcode in den Propeller zu laden. Dieser Code funktioniert \line auch teilweise. So kann man das Administra-Bios selbst laden und dann\line auch per Regime-Kommandos verwenden: Die Kommandos "cogs" und "sysinfo"\line sprechen Administra-Funktionen an, welche auch korrekt ausgef\u252?hrt werden.\line Das Problem: Nach dem Bootprozess kann man keine SD-Card mehr mounten.\line\line Es ist auch m\u246?glich den Fehler noch weiter einzugrenzen: Wenn man die \line originale FATEngine (im Verzeichnis komponenten/fat) vom Host direkt in \line Administra startet, meldet sich diese in Form einer einfachen Kommando-\line zeile per Hostschnittstelle. Versucht man dort eine erzeugte BIN-Datei\line genau dieser Kommandozeile (demo.spin) zu booten, so hat man das gleiche\line Ergebnis.\line\line Verzeichnisstruktur:\line\line bin\tab\tab\tab - BIN-Dateien f\u252?r die Flash's und die SD-Card\line doku\tab\tab\tab - \line flash\tab\tab\tab - Quelltexte f\u252?r die Software in den EEProms\line system\tab\tab\tab - Quelltext f\u252?r ausf\u252?hrbare BIN-Dateien\line zubeh\u246?r\tab\tab\tab - Kleine Zusatzprogramme (StarTracker, Boulder Dash...)\line komponenten\tab\tab - Div. verwendete Objekte (FATEngine, SIDCog...)\line\line Installation:\line\line 1. \tab Flashen der drei EEProms mit den BIN-Dateien aus "bin/flash" oder\line\tab\u252?ber das Propellertool aus den Quellen "flash".\line\line 2. \tab SD-Card erstellen: Einfach alles aus "bin/sd-card" auf eine FAT16/32\line\tab Karte kopieren.\line\line Das System bootet Regnatix und Bellatrix beim Systemstart aus den Dateien\line\f0 "adm.sys", \f1 "reg.sys" bzw. "bel.sys". Diese Dateien k\u246?nnen auch das Hidden-Bit gesetzt\line haben. Externe Kommandos bzw. ausf\u252?hrbare BIN-Dateien werden im aktuellen\line UND im System-Verzeichnis gesucht - alle Systemkommandos k\u246?nnen also in das \line System-Verzeichnis kopiert werden.\line\line Hilfe gibt es meist \u252?ber das Kommando "help" oder den Parameter "/h".\line\line\tab\line\line\par +} + \ No newline at end of file diff --git a/make.bat b/make.bat new file mode 100644 index 0000000..9e87225 --- /dev/null +++ b/make.bat @@ -0,0 +1,97 @@ +REM Pfade +set sd=".\bin\sd-card-basic" +set sd-sys=".\bin\sd-card-basic\system" +set flash=".\bin\flash" +set libpath="C:\Programme\Parallax Inc\Propeller Tool v1.2.7 (R2)" + +REM ---------------------------------------------------------------- +REM Flashdateien erzeugen +REM --> \bin\flash + +bstc -L %libpath% -b -O a .\flash\administra\admflash.spin +move admflash.binary %flash% +bstc -L %libpath% -b -O a .\flash\bellatrix\belflash.spin +move belflash.binary %flash% +bstc -L %libpath% -b -O a .\flash\regnatix\regflash.spin +move regflash.binary %flash% + + + +REM ---------------------------------------------------------------- +REM Startdateien erzeugen +REM reg.sys (Regime) +REM bel.sys (VGA) +REM --> \bin\sd-card-basic\ + +bstc -L %libpath% -b -O a .\system\regnatix\regime.spin +rename regime.binary reg.sys +move reg.sys %sd% + +bstc -L %libpath% -b -O a .\system\bellatrix\vga-text-1024x768-pix-64x24-zeichen\vga.spin +rename vga.binary bel.sys +move bel.sys %sd% + +REM ---------------------------------------------------------------- +REM Systemdateien erzeugen +REM - div. externe Kommandos +REM - div. Systemdateien (Farbtabellen usw.) +REM --> \bin\sd-card-basic\system\ + +bstc -L %libpath% -b -O a .\system\regnatix\admtest.spin +rename admtest.binary admtest.bin +move admtest.bin %sd-sys% + +bstc -L %libpath% -b -O a .\system\regnatix\basic.spin +rename basic.binary basic.bin +move basic.bin %sd-sys% + +bstc -L %libpath% -b -O a .\system\regnatix\beltest.spin +rename beltest.binary beltest.bin +move beltest.bin %sd-sys% + +bstc -L %libpath% -b -O a .\system\regnatix\charmap.spin +rename charmap.binary charmap.bin +move charmap.bin %sd-sys% + +bstc -L %libpath% -b -O a .\system\regnatix\eram.spin +rename eram.binary eram.bin +move eram.bin %sd-sys% + +bstc -L %libpath% -b -O a .\system\regnatix\hplay.spin +rename hplay.binary hplay.bin +move hplay.bin %sd-sys% + +bstc -L %libpath% -b -O a .\system\regnatix\keycode.spin +rename keycode.binary keycode.bin +move keycode.bin %sd-sys% + +bstc -L %libpath% -b -O a .\system\regnatix\ramtest.spin +rename ramtest.binary ramtest.bin +move ramtest.bin %sd-sys% + +bstc -L %libpath% -b -O a .\system\regnatix\sfxtool.spin +rename sfxtool.binary sfxtool.bin +move sfxtool.bin %sd-sys% + +bstc -L %libpath% -b -O a .\system\regnatix\splay.spin +rename splay.binary splay.bin +move splay.bin %sd-sys% + +bstc -L %libpath% -b -O a .\system\regnatix\sysconf.spin +rename sysconf.binary sysconf.bin +move sysconf.bin %sd-sys% + +bstc -L %libpath% -b -O a .\system\regnatix\wplay.spin +rename wplay.binary wplay.bin +move wplay.bin %sd-sys% + +bstc -L %libpath% -b -O a .\system\regnatix\yplay.spin +rename yplay.binary yplay.bin +move yplay.bin %sd-sys% + +REM ---------------------------------------------------------------- +REM Zusatzdateien kopieren + +copy .\system\sonstiges %sd-sys% + +pause diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..c661b7f --- /dev/null +++ b/readme.txt @@ -0,0 +1,23 @@ + +Hive-Project +------------------------------------------------------------------------- +Der Hive ist ein Open-Hardware und Free-Software DIY-Computersystem auf +der Basis von drei Parallax P8X32 "Propeller" Mikrocontrollern. + + +Lizenze +------------------------------------------------------------------------- +Das Betriebssystem TriOS steht unter MIT-Lizenz. Die Schaltung und das +Board-Layout ist unter Creative-Commons CC-BY-SA 3.0 lizensiert. + +MIT-Lizenz: http://www.opensource.org/licenses/mit-license.php +CC-BY-SA 3.0: http://creativecommons.org/licenses/by-sa/3.0/de/ + +Informationen zum Projekt +------------------------------------------------------------------------- +http://hive-project.de + + +Urheberrechtsangabe +------------------------------------------------------------------------- +Copyright (c) 2009 Ingo Kripahle \ No newline at end of file diff --git a/system/administra/admini/admflash-fat.spin b/system/administra/admini/admflash-fat.spin new file mode 100644 index 0000000..02dd4f9 Binary files /dev/null and b/system/administra/admini/admflash-fat.spin differ diff --git a/system/administra/admini/admflash-rtc.spin b/system/administra/admini/admflash-rtc.spin new file mode 100644 index 0000000..8cd6854 Binary files /dev/null and b/system/administra/admini/admflash-rtc.spin differ diff --git a/system/administra/admini/admini.spin b/system/administra/admini/admini.spin new file mode 100644 index 0000000..d160d16 Binary files /dev/null and b/system/administra/admini/admini.spin differ diff --git a/system/administra/admini/pterm.spin b/system/administra/admini/pterm.spin new file mode 100644 index 0000000..a525a4b Binary files /dev/null and b/system/administra/admini/pterm.spin differ diff --git a/system/administra/admsid/CombinedWaveforms.bin b/system/administra/admsid/CombinedWaveforms.bin new file mode 100644 index 0000000..d95fe68 Binary files /dev/null and b/system/administra/admsid/CombinedWaveforms.bin differ diff --git a/system/administra/admsid/admflash-fat.spin b/system/administra/admsid/admflash-fat.spin new file mode 100644 index 0000000..8cfc5fe Binary files /dev/null and b/system/administra/admsid/admflash-fat.spin differ diff --git a/system/administra/admsid/admflash-rtc.spin b/system/administra/admsid/admflash-rtc.spin new file mode 100644 index 0000000..8cd6854 Binary files /dev/null and b/system/administra/admsid/admflash-rtc.spin differ diff --git a/system/administra/admsid/admflash-sid.spin b/system/administra/admsid/admflash-sid.spin new file mode 100644 index 0000000..2a5485d Binary files /dev/null and b/system/administra/admsid/admflash-sid.spin differ diff --git a/system/administra/admsid/admsid.spin b/system/administra/admsid/admsid.spin new file mode 100644 index 0000000..664ef91 Binary files /dev/null and b/system/administra/admsid/admsid.spin differ diff --git a/system/administra/admsid/pterm.spin b/system/administra/admsid/pterm.spin new file mode 100644 index 0000000..a525a4b Binary files /dev/null and b/system/administra/admsid/pterm.spin differ diff --git a/system/administra/admym/AYcog_V0-22.spin b/system/administra/admym/AYcog_V0-22.spin new file mode 100644 index 0000000..f46e5eb Binary files /dev/null and b/system/administra/admym/AYcog_V0-22.spin differ diff --git a/system/administra/admym/admflash-fat.spin b/system/administra/admym/admflash-fat.spin new file mode 100644 index 0000000..5dff0c1 Binary files /dev/null and b/system/administra/admym/admflash-fat.spin differ diff --git a/system/administra/admym/admflash-rtc.spin b/system/administra/admym/admflash-rtc.spin new file mode 100644 index 0000000..8cd6854 Binary files /dev/null and b/system/administra/admym/admflash-rtc.spin differ diff --git a/system/administra/admym/admym.spin b/system/administra/admym/admym.spin new file mode 100644 index 0000000..bf301ae Binary files /dev/null and b/system/administra/admym/admym.spin differ diff --git a/system/administra/admym/ios.spin b/system/administra/admym/ios.spin new file mode 100644 index 0000000..d8fc8fe Binary files /dev/null and b/system/administra/admym/ios.spin differ diff --git a/system/administra/admym/pterm.spin b/system/administra/admym/pterm.spin new file mode 100644 index 0000000..a525a4b Binary files /dev/null and b/system/administra/admym/pterm.spin differ diff --git a/system/administra/aterm/COMEngine.spin b/system/administra/aterm/COMEngine.spin new file mode 100644 index 0000000..bdd205a Binary files /dev/null and b/system/administra/aterm/COMEngine.spin differ diff --git a/system/administra/aterm/Read Me.rtf b/system/administra/aterm/Read Me.rtf new file mode 100644 index 0000000..8e60f75 --- /dev/null +++ b/system/administra/aterm/Read Me.rtf @@ -0,0 +1,272 @@ +{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff31507\deff0\stshfdbch0\stshfloch31506\stshfhich31506\stshfbi31506\deflang1033\deflangfe1033\themelang1033\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;} +{\f37\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} +{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria;} +{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} +{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;} +{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f39\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f40\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} +{\f42\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f43\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f44\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f45\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\f46\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f47\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f379\fbidi \froman\fcharset238\fprq2 Cambria Math CE;}{\f380\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;} +{\f382\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f383\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f386\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;}{\f387\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);} +{\f409\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\f410\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\f412\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\f413\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;} +{\f416\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\f417\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} +{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} +{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} +{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} +{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} +{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} +{\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE;}{\fhimajor\f31529\fbidi \froman\fcharset204\fprq2 Cambria Cyr;}{\fhimajor\f31531\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\fhimajor\f31532\fbidi \froman\fcharset162\fprq2 Cambria Tur;} +{\fhimajor\f31535\fbidi \froman\fcharset186\fprq2 Cambria Baltic;}{\fhimajor\f31536\fbidi \froman\fcharset163\fprq2 Cambria (Vietnamese);}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} +{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} +{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} +{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} +{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} +{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} +{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} +{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;} +{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;} +{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} +{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} +{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} +{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0; +\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\*\defchp \f31506\fs22 }{\*\defpap +\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 +\af31507\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext0 \sqformat \spriority0 \styrsid3755876 Normal;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\* +\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa200\sl276\slmult1 +\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31506\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext11 \ssemihidden \sunhideused \sqformat Normal Table;}} +{\*\rsidtbl \rsid410870\rsid1726074\rsid3366185\rsid3755876\rsid3833722\rsid4740689\rsid5992232\rsid6245947\rsid8655232\rsid8809290\rsid11759436\rsid14891351\rsid15496811}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0 +\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\author Kwabena W. Agyeman}{\operator Kwabena W. Agyeman}{\creatim\yr2010\mo1\dy8\hr16\min46}{\revtim\yr2010\mo1\dy8\hr17\min52}{\version5}{\edmins66}{\nofpages3}{\nofwords944}{\nofchars4608} +{\nofcharsws5541}{\vern32771}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}}\paperw12240\paperh15840\margl1440\margr1440\margt1440\margb1440\gutter0\ltrsect +\widowctrl\ftnbj\aenddoc\trackmoves1\trackformatting1\donotembedsysfont1\relyonvml0\donotembedlingdata0\grfdocevents0\validatexml1\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors1\noxlattoyen +\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1440\dgvorigin1440\dghshow1\dgvshow1 +\jexpand\viewkind1\viewscale102\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct +\asianbrkrule\rsidroot6245947\newtblstyruls\nogrowautofit\usenormstyforlist\noindnmbrts\felnbrelev\nocxsptable\indrlsweleven\noafcnsttbl\afelev\utinl\hwelev\spltpgpar\notcvasp\notbrkcnstfrctbl\notvatxbx\krnprsnet\cachedcolbal \nouicompat \fet0 +{\*\wgrffmtfilter 2450}\nofeaturethrottle1\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\endnhere\sectlinegrid360\sectdefaultcl\sectrsid3755876\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2 +\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6 +\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\contextualspace \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 +\f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \b\ul\insrsid6245947\charrsid6245947 FATEngine Beta Demo}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \b\ul\insrsid6245947 +\par +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid6245947 Thank you for taking the time help test out the FATEngine}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid11759436 : a}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid6245947 fully functional FAT16/32 file system + driver library. To help you get started working with this tool please refer to the rest of this document. +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \b\ul\insrsid6245947\charrsid6245947 +\par System Configuration}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \b\ul\insrsid6245947 +\par +\par }\pard \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid6245947\contextualspace {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid6245947 +You will need to first edit the included spin files to match your system configuration so that you can test out the demo. If you have a DS1307 real time clock please attach it to the specified pins below. +\par +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid11759436 \tab Open the RTCEnigne.spin file in}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid6245947 this folder and change the pin numbers to match the pin numbers of where you}{\rtlch\fcs1 \af31507 \ltrch\fcs0 +\insrsid11759436 r}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid6245947 DS1307 RTC is attached in the CON block at the top of the code. If you do not have a DS1307 RTC the included demo code will still function, however all time stamps will be invalid. + +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid11759436 +\par \tab Open the FATEnigne.spin file in this folder and change the pin numbers to match the pin numbers of where SD/SDHC/MMC Card is attached in the CON block at the top of the code. +\par +\par }\pard \ltrpar\ql \fi720\li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid11759436\contextualspace {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid11759436 +Open the COMEngine.spin file in this folder and change the pin numbers to match the pin numbers of where Prop Plug is attached in the CON block at the top of the code.}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid6245947 +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid11759436 +\par Open the Demo.spin file in this folder and chang +e the baud rate to match the baud rate of the specified baud rate when using parallax serial terminal. Additionally please change the clock frequency to your system configuration at the top of the Demo.spin file to match your setup. +\par +\par }\pard \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid11759436\contextualspace {\rtlch\fcs1 \af31507 \ltrch\fcs0 \b\ul\insrsid11759436 Serial Terminal +\par +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid11759436 Pleas +e open parallax serial terminal and connect to the propeller chip using the specified baud rate you set in the Demo.spin file. The demo program waits 5 seconds to let you get ready before running. After this the demo program should display a welcome messa +ge and a \'93>_\'94 command cursor. +\par +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \b\ul\insrsid11759436 Serial Terminal Commands +\par +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid11759436 The following is a complete list of commands that the serial terminal demo program will execute.}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid4740689 + Please note that the max command length is 255 characters after which a buffer overflow error will occur. The serial terminal will recover from this error but your command will be discarded. }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid11759436 +\par +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid4740689 General Commands: +\par +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid11759436 \'93clear\'94 - Clears the terminal screen. +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid3833722 +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid11759436 \'93echo\'94 - }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid4740689 Echoes}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid11759436 back whatever was typed}{\rtlch\fcs1 \af31507 \ltrch\fcs0 +\insrsid4740689 after the command.}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid11759436 +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid3833722 +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid4740689 \'93date\'94 - Returns the current date fetched from the DS1307 RTC. If you do not have the DS1307 RTC the date returned will be invalid. +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid3833722 +\par }\pard \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid4740689\contextualspace {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid4740689 \'93time\'94 + - Ask the user for all specified timing parameters to set the date on the DS1307 RTC. +\par }\pard \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid11759436\contextualspace {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid4740689 +\par File System Commands +\par +\par \'93mount\'94 - Mounts the specified partition on the SD Card for file system access. An SD card must be attached to the system or an error message will be displayed. A partition must be mounted for + any other commands to execute. Please un-mount the partition when finished. The check disk flag causes windows to run check disk o}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid3833722 n the SD Card if not un-mo +unted properly when the disk is plugged into a windows machine.}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid4740689 +\par +\par \'93umount\'94 - Un-mounts the active partition allowing another to be mounted and + writes file system optimization data back to the disk. Additionally deactivates the rest of the file system functions the turns off any raised check disk flags. +\par +\par \'93df\'94 <}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid5992232 fast mode (f)> - Computes the count of free 512 byte sectors on the partition. Use the +fast mode flag (f) to ask the function to return previously computed values instead of computing new ones. If no previously computed values are available this function will compute them after which fast mode will be valid. Computing the free sector count +can take a long time.}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid4740689 +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid5992232 +\par \'93du\'94 - Computes the count of used 512 byte sectors on the partition. Use the fast mode flag (f) to ask the function to return previously computed values instead of computing new ones. If no previously computed values +are available this function will compute them after which fast mode will be valid. Computing the used sector count can take a long time. +\par +\par \'93ls\'94 - List all files and folders in the current directory with along with their last access date, last modification date, and creation date as well as their size and attributes. Directories have no size. Only files have size.}{ +\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid410870 The attributes letters mean:}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid5992232 R \endash Read Only, H \endash Hidden, S \endash System, A \endash Archive, }{\rtlch\fcs1 \af31507 \ltrch\fcs0 +\insrsid410870 and }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid5992232 D- Directory. +\par +\par \'93find\'94 - Verifies the specified file exist in the current directory. +\par +\par \'93cd\'94}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid5992232\charrsid5992232 }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid5992232 - Enters into the specified directory allowing file system access to all files within that directory. +\par +\par \'93attrib\'94 - Changes the attributes of the specified file or directory to the new specified attributes.}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid8655232 The new attributes are: }{\rtlch\fcs1 \af31507 \ltrch\fcs0 +\insrsid5992232 R \endash Read Only, H \endash Hidden, S \endash System, A \endash Archive. +\par +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid15496811 \'93rename\'94 - Changes the specified file or directory\rquote s entry name to the new specified entry name. +\par +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid5992232 \'93rm\'94 - Removes the specified file from the current directory or deletes any empty directory from the file system permanently. +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid15496811 +\par \'93mkfile\'94 - Makes a new file in the current directory with the specified name. +\par +\par \'93mkdir\'94 - Makes a new directory in the current directory with the specified name. +\par +\par \'93cat\'94 - Displays the contents of the specified file in either binary, hexadecimal, decimal, or ASCII characters.}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid8655232 The type flag can be:}{\rtlch\fcs1 \af31507 \ltrch\fcs0 +\insrsid15496811 B \endash Binary, D \endash Decimal, H \endash Hexadecimal, A \endash ASCII. +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid8655232 +\par \'93test\'94 - Creates a temporary file to test read and write character and block performance of the driver}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid1726074 +. After which results are printed to the screen and the file temporary file is deleted.}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid8655232 +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid4740689 +\par }\pard \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid8655232\contextualspace {\rtlch\fcs1 \af31507 \ltrch\fcs0 \b\ul\insrsid8655232 That\rquote s all folks! +\par }\pard \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid11759436\contextualspace {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid4740689 +\par +\par +\par +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid4740689\charrsid11759436 +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid11759436 +\par +\par }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid11759436\charrsid11759436 +\par }\pard \ltrpar\qj \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid11759436\contextualspace {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid11759436\charrsid11759436 +\par }\pard \ltrpar\ql \fi720\li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid11759436\contextualspace {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid11759436\charrsid11759436 +\par }\pard \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid6245947\contextualspace {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid6245947\charrsid6245947 +\par }\pard \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\contextualspace {\rtlch\fcs1 \af31507 \ltrch\fcs0 \b\ul\insrsid6245947\charrsid6245947 +\par }{\*\themedata 504b030414000600080000002100828abc13fa0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb6ac3301045f785fe83d0b6d8 +72ba28a5d8cea249777d2cd20f18e4b12d6a8f843409c9df77ecb850ba082d74231062ce997b55ae8fe3a00e1893f354e9555e6885647de3a8abf4fbee29bbd7 +2a3150038327acf409935ed7d757e5ee14302999a654e99e393c18936c8f23a4dc072479697d1c81e51a3b13c07e4087e6b628ee8cf5c4489cf1c4d075f92a0b +44d7a07a83c82f308ac7b0a0f0fbf90c2480980b58abc733615aa2d210c2e02cb04430076a7ee833dfb6ce62e3ed7e14693e8317d8cd0433bf5c60f53fea2fe7 +065bd80facb647e9e25c7fc421fd2ddb526b2e9373fed4bb902e182e97b7b461e6bfad3f010000ffff0300504b030414000600080000002100a5d6a7e7c00000 +00360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4fc7060abb08 +84a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b63095120f88d94fbc +52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462a1a82fe353 +bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f7468656d652f7468 +656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b4b0d592c9c +070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b4757e8d3f7 +29e245eb2b260a0238fd010000ffff0300504b03041400060008000000210096b5ade296060000501b0000160000007468656d652f7468656d652f7468656d65 +312e786d6cec594f6fdb3614bf0fd87720746f6327761a07758ad8b19b2d4d1bc46e871e698996d850a240d2497d1bdae38001c3ba618715d86d87615b8116d8 +a5fb34d93a6c1dd0afb0475292c5585e9236d88aad3e2412f9e3fbff1e1fa9abd7eec70c1d1221294fda5efd72cd4324f1794093b0eddd1ef62fad79482a9c04 +98f184b4bd2991deb58df7dfbb8ad755446282607d22d771db8b944ad79796a40fc3585ee62949606ecc458c15bc8a702910f808e8c66c69b9565b5d8a314d3c +94e018c8de1a8fa94fd05093f43672e23d06af89927ac06762a049136785c10607758d9053d965021d62d6f6804fc08f86e4bef210c352c144dbab999fb7b471 +7509af678b985ab0b6b4ae6f7ed9ba6c4170b06c788a705430adf71bad2b5b057d03606a1ed7ebf5babd7a41cf00b0ef83a6569632cd467faddec9699640f671 +9e76b7d6ac355c7c89feca9cccad4ea7d36c65b258a206641f1b73f8b5da6a6373d9c11b90c537e7f08dce66b7bbeae00dc8e257e7f0fd2badd5868b37a088d1 +e4600ead1ddaef67d40bc898b3ed4af81ac0d76a197c86826828a24bb318f3442d8ab518dfe3a20f000d6458d104a9694ac6d88728eee2782428d60cf03ac1a5 +193be4cbb921cd0b495fd054b5bd0f530c1931a3f7eaf9f7af9e3f45c70f9e1d3ff8e9f8e1c3e3073f5a42ceaa6d9c84e5552fbffdeccfc71fa33f9e7ef3f2d1 +17d57859c6fffac327bffcfc793510d26726ce8b2f9ffcf6ecc98baf3efdfdbb4715f04d814765f890c644a29be408edf3181433567125272371be15c308d3f2 +8acd249438c19a4b05fd9e8a1cf4cd296699771c393ac4b5e01d01e5a30a787d72cf1178108989a2159c77a2d801ee72ce3a5c545a6147f32a99793849c26ae6 +6252c6ed637c58c5bb8b13c7bfbd490a75330f4b47f16e441c31f7184e140e494214d273fc80900aedee52ead87597fa824b3e56e82e451d4c2b4d32a423279a +668bb6690c7e9956e90cfe766cb37b077538abd27a8b1cba48c80acc2a841f12e698f13a9e281c57911ce298950d7e03aba84ac8c154f8655c4f2af074481847 +bd804859b5e696007d4b4edfc150b12addbecba6b18b148a1e54d1bc81392f23b7f84137c2715a851dd0242a633f900710a218ed715505dfe56e86e877f0034e +16bafb0e258ebb4faf06b769e888340b103d3311da9750aa9d0a1cd3e4efca31a3508f6d0c5c5c398602f8e2ebc71591f5b616e24dd893aa3261fb44f95d843b +5974bb5c04f4edafb95b7892ec1108f3f98de75dc97d5772bdff7cc95d94cf672db4b3da0a6557f70db629362d72bcb0431e53c6066acac80d699a6409fb44d0 +8741bdce9c0e4971624a2378cceaba830b05366b90e0ea23aaa241845368b0eb9e2612ca8c742851ca251ceccc70256d8d87265dd96361531f186c3d9058edf2 +c00eafe8e1fc5c509031bb4d680e9f39a3154de0accc56ae644441edd76156d7429d995bdd88664a9dc3ad50197c38af1a0c16d684060441db02565e85f3b966 +0d0713cc48a0ed6ef7dedc2dc60b17e92219e180643ed27acffba86e9c94c78ab90980d8a9f0913ee49d62b512b79626fb06dccee2a432bbc60276b9f7dec44b +7904cfbca4f3f6443ab2a49c9c2c41476dafd55c6e7ac8c769db1bc399161ee314bc2e75cf8759081743be1236ec4f4d6693e5336fb672c5dc24a8c33585b5fb +9cc24e1d4885545b58463634cc5416022cd19cacfccb4d30eb45296023fd35a458598360f8d7a4003bbaae25e331f155d9d9a5116d3bfb9a95523e51440ca2e0 +088dd844ec6370bf0e55d027a012ae264c45d02f708fa6ad6da6dce29c255df9f6cae0ec38666984b372ab5334cf640b37795cc860de4ae2816e95b21be5ceaf +8a49f90b52a51cc6ff3355f47e0237052b81f6800fd7b802239daf6d8f0b1571a8426944fdbe80c6c1d40e8816b88b8569082ab84c36ff0539d4ff6dce591a26 +ade1c0a7f669880485fd484582903d284b26fa4e2156cff62e4b9265844c4495c495a9157b440e091bea1ab8aaf7760f4510eaa69a6465c0e04ec69ffb9e65d0 +28d44d4e39df9c1a52ecbd3607fee9cec7263328e5d661d3d0e4f62f44acd855ed7ab33cdf7bcb8ae889599bd5c8b3029895b6825696f6af29c239b75a5bb1e6 +345e6ee6c28117e73586c1a2214ae1be07e93fb0ff51e133fb65426fa843be0fb515c187064d0cc206a2fa926d3c902e907670048d931db4c1a44959d366ad93 +b65abe595f70a75bf03d616c2dd959fc7d4e6317cd99cbcec9c58b34766661c7d6766ca1a9c1b327531486c6f941c638c67cd22a7f75e2a37be0e82db8df9f30 +254d30c1372581a1f51c983c80e4b71ccdd28dbf000000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d652f74 +68656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d363f24 +51eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e3198 +720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d9850528 +a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100828abc13fa0000001c0200001300000000000000000000000000 +000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b000000000000000000000000 +002b0100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c00000000000000000000000000140200007468 +656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d001400060008000000210096b5ade296060000501b000016000000000000000000 +00000000d10200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b010000270000000000 +00000000000000009b0900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000960a00000000} +{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d +617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 +6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 +656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} +{\*\latentstyles\lsdstimax267\lsdlockeddef0\lsdsemihiddendef1\lsdunhideuseddef1\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4; +\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9; +\lsdpriority39 \lsdlocked0 toc 1;\lsdpriority39 \lsdlocked0 toc 2;\lsdpriority39 \lsdlocked0 toc 3;\lsdpriority39 \lsdlocked0 toc 4;\lsdpriority39 \lsdlocked0 toc 5;\lsdpriority39 \lsdlocked0 toc 6;\lsdpriority39 \lsdlocked0 toc 7; +\lsdpriority39 \lsdlocked0 toc 8;\lsdpriority39 \lsdlocked0 toc 9;\lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdpriority1 \lsdlocked0 Default Paragraph Font; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority59 \lsdlocked0 Table Grid;\lsdunhideused0 \lsdlocked0 Placeholder Text;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdunhideused0 \lsdlocked0 Revision; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 4; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 4; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 4; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 6; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 6; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 6; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdpriority37 \lsdlocked0 Bibliography;\lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;}}{\*\datastore 010500000200000018000000 +4d73786d6c322e534158584d4c5265616465722e352e30000000000000000000000e0000 +d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff0900060000000000000000000000010000000100000000000000001000000200000001000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffdffffff04000000feffffff05000000fefffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffff01000000ec69d9888b8b3d4c859eaf6cd158be0f0000000000000000000000004047 +ec51b590ca010300000080020000000000004d0073006f004400610074006100530074006f0072006500000000000000000000000000000000000000000000000000000000000000000000000000000000001a000101ffffffffffffffff0200000000000000000000000000000000000000000000004047ec51b590ca01 +4047ec51b590ca01000000000000000000000000c70033005a005100d4004700cd0056004b0055004300c700d1004a004400dc00d200c3004400c700d000c0003d003d000000000000000000000000000000000032000101ffffffffffffffff0300000000000000000000000000000000000000000000004047ec51b590 +ca014047ec51b590ca010000000000000000000000004900740065006d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000201ffffffff04000000ffffffff000000000000000000000000000000000000000000000000 +00000000000000000000000000000000cf00000000000000010000000200000003000000feffffff0500000006000000070000000800000009000000feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3c623a536f757263657320786d6c6e733a623d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f6f6666696365446f63756d656e742f323030362f6269626c696f6772617068792220786d6c6e733d +22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f6f6666696365446f63756d656e742f323030362f6269626c696f677261706879222053656c65637465645374796c653d225c4150412e58534c22205374796c654e616d653d22415041222f3e0d0a00000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000003c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d226e6f223f3e0d0a3c64733a6461746173746f72654974656d2064733a6974656d49443d227b44303530 +443639442d353536422d343032392d413743342d3930464343413330453743327d2220786d6c6e733a64733d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f6f6666696365446f63756d656e742f323030362f637573746f6d586d6c223e3c64733a736368656d61526566733e3c +64733a736368656d615265662064733a7572693d22687474703a2f2f736368656d61732e6f70656e500072006f007000650072007400690065007300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000200ffffffffffffffffffffffff000000000000 +0000000000000000000000000000000000000000000000000000000000000400000055010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000786d6c666f726d6174732e6f72672f6f6666696365446f63756d656e742f323030362f6269626c696f677261706879222f3e3c2f64733a736368656d61526566733e3c2f64733a6461746173746f +72654974656d3e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000105000000000000}} \ No newline at end of file diff --git a/system/administra/aterm/admflash-fat.spin b/system/administra/aterm/admflash-fat.spin new file mode 100644 index 0000000..2ad363f Binary files /dev/null and b/system/administra/aterm/admflash-fat.spin differ diff --git a/system/administra/aterm/admflash-rtc.spin b/system/administra/aterm/admflash-rtc.spin new file mode 100644 index 0000000..8cd6854 Binary files /dev/null and b/system/administra/aterm/admflash-rtc.spin differ diff --git a/system/administra/aterm/aterm96.spin b/system/administra/aterm/aterm96.spin new file mode 100644 index 0000000..018519e Binary files /dev/null and b/system/administra/aterm/aterm96.spin differ diff --git a/system/administra/aterm/stringEngine.spin b/system/administra/aterm/stringEngine.spin new file mode 100644 index 0000000..acc112b Binary files /dev/null and b/system/administra/aterm/stringEngine.spin differ diff --git a/system/bellatrix/graphics-palette/Graphics.spin b/system/bellatrix/graphics-palette/Graphics.spin new file mode 100644 index 0000000..dbe7e03 Binary files /dev/null and b/system/bellatrix/graphics-palette/Graphics.spin differ diff --git a/system/bellatrix/graphics-palette/Graphics_Palette.spin b/system/bellatrix/graphics-palette/Graphics_Palette.spin new file mode 100644 index 0000000..55f72da Binary files /dev/null and b/system/bellatrix/graphics-palette/Graphics_Palette.spin differ diff --git a/system/bellatrix/graphics-palette/Mouse.spin b/system/bellatrix/graphics-palette/Mouse.spin new file mode 100644 index 0000000..c37ad5c Binary files /dev/null and b/system/bellatrix/graphics-palette/Mouse.spin differ diff --git a/system/bellatrix/graphics-palette/TV.spin b/system/bellatrix/graphics-palette/TV.spin new file mode 100644 index 0000000..b58adcf Binary files /dev/null and b/system/bellatrix/graphics-palette/TV.spin differ diff --git a/system/bellatrix/graphics/Graphics.spin b/system/bellatrix/graphics/Graphics.spin new file mode 100644 index 0000000..dbe7e03 Binary files /dev/null and b/system/bellatrix/graphics/Graphics.spin differ diff --git a/system/bellatrix/graphics/Graphics_Demo.spin b/system/bellatrix/graphics/Graphics_Demo.spin new file mode 100644 index 0000000..d202295 Binary files /dev/null and b/system/bellatrix/graphics/Graphics_Demo.spin differ diff --git a/system/bellatrix/graphics/Mouse.spin b/system/bellatrix/graphics/Mouse.spin new file mode 100644 index 0000000..c37ad5c Binary files /dev/null and b/system/bellatrix/graphics/Mouse.spin differ diff --git a/system/bellatrix/graphics/TV.spin b/system/bellatrix/graphics/TV.spin new file mode 100644 index 0000000..b58adcf Binary files /dev/null and b/system/bellatrix/graphics/TV.spin differ diff --git a/system/bellatrix/htext-treiber/htext-keyb.spin b/system/bellatrix/htext-treiber/htext-keyb.spin new file mode 100644 index 0000000..5333e3a Binary files /dev/null and b/system/bellatrix/htext-treiber/htext-keyb.spin differ diff --git a/system/bellatrix/htext-treiber/htext-old.spin b/system/bellatrix/htext-treiber/htext-old.spin new file mode 100644 index 0000000..cd20581 Binary files /dev/null and b/system/bellatrix/htext-treiber/htext-old.spin differ diff --git a/system/bellatrix/htext-treiber/htext-vid.spin b/system/bellatrix/htext-treiber/htext-vid.spin new file mode 100644 index 0000000..d14ddbb Binary files /dev/null and b/system/bellatrix/htext-treiber/htext-vid.spin differ diff --git a/system/bellatrix/htext-treiber/htext.spin b/system/bellatrix/htext-treiber/htext.spin new file mode 100644 index 0000000..a72900e Binary files /dev/null and b/system/bellatrix/htext-treiber/htext.spin differ diff --git a/system/bellatrix/htext-treiber/logo-hive-8x2.dat b/system/bellatrix/htext-treiber/logo-hive-8x2.dat new file mode 100644 index 0000000..109ef59 Binary files /dev/null and b/system/bellatrix/htext-treiber/logo-hive-8x2.dat differ diff --git a/system/bellatrix/tv-text-13x40-zeichen/tv-core.spin b/system/bellatrix/tv-text-13x40-zeichen/tv-core.spin new file mode 100644 index 0000000..b58adcf Binary files /dev/null and b/system/bellatrix/tv-text-13x40-zeichen/tv-core.spin differ diff --git a/system/bellatrix/tv-text-13x40-zeichen/tv-keyb.spin b/system/bellatrix/tv-text-13x40-zeichen/tv-keyb.spin new file mode 100644 index 0000000..5333e3a Binary files /dev/null and b/system/bellatrix/tv-text-13x40-zeichen/tv-keyb.spin differ diff --git a/system/bellatrix/tv-text-13x40-zeichen/tv.spin b/system/bellatrix/tv-text-13x40-zeichen/tv.spin new file mode 100644 index 0000000..55b85a3 Binary files /dev/null and b/system/bellatrix/tv-text-13x40-zeichen/tv.spin differ diff --git a/system/bellatrix/vectron-1-vecdem1/ios.spin b/system/bellatrix/vectron-1-vecdem1/ios.spin new file mode 100644 index 0000000..95b5012 Binary files /dev/null and b/system/bellatrix/vectron-1-vecdem1/ios.spin differ diff --git a/system/bellatrix/vectron-1-vecdem1/notizen-asm.rtf b/system/bellatrix/vectron-1-vecdem1/notizen-asm.rtf new file mode 100644 index 0000000..2eaf858 Binary files /dev/null and b/system/bellatrix/vectron-1-vecdem1/notizen-asm.rtf differ diff --git a/system/bellatrix/vectron-1-vecdem1/notizen-drv.rtf b/system/bellatrix/vectron-1-vecdem1/notizen-drv.rtf new file mode 100644 index 0000000..a84c054 Binary files /dev/null and b/system/bellatrix/vectron-1-vecdem1/notizen-drv.rtf differ diff --git a/system/bellatrix/vectron-1-vecdem1/vecdem1-bel.spin b/system/bellatrix/vectron-1-vecdem1/vecdem1-bel.spin new file mode 100644 index 0000000..393c7e1 Binary files /dev/null and b/system/bellatrix/vectron-1-vecdem1/vecdem1-bel.spin differ diff --git a/system/bellatrix/vectron-1-vecdem1/vecdem1.bel b/system/bellatrix/vectron-1-vecdem1/vecdem1.bel new file mode 100644 index 0000000..baba2b7 Binary files /dev/null and b/system/bellatrix/vectron-1-vecdem1/vecdem1.bel differ diff --git a/system/bellatrix/vectron-1-vecdem1/vecdem1.bin b/system/bellatrix/vectron-1-vecdem1/vecdem1.bin new file mode 100644 index 0000000..8802c60 Binary files /dev/null and b/system/bellatrix/vectron-1-vecdem1/vecdem1.bin differ diff --git a/system/bellatrix/vectron-1-vecdem1/vecdem1.spin b/system/bellatrix/vectron-1-vecdem1/vecdem1.spin new file mode 100644 index 0000000..cc908a2 --- /dev/null +++ b/system/bellatrix/vectron-1-vecdem1/vecdem1.spin @@ -0,0 +1,115 @@ +{{ --------------------------------------------------------------------------------------------------------- + +Hive-Computer-Projekt + +Name : Vectron-Demo 1 +Chip : Regnatix-Code +Version : 0.1 +Dateien : vecdem1.spin + +Beschreibung : + +Eigenschaften : + +Logbuch : + +Kommandoliste: + + --------------------------------------------------------------------------------------------------------- }} + +OBJ + ios: "ios" + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + +OS_TIBLEN = 64 'größe des inputbuffers + +VAR +'systemvariablen + byte tib[OS_TIBLEN] 'tastatur-input-buffer + byte cmdstr[OS_TIBLEN] 'kommandostring für interpreter + byte parastr[OS_TIBLEN] 'parameterstring für interpreter + byte tibpos 'aktuelle position im tib + + long lcnt 'zeiger für dateiliste + byte fn[12] 'puffer für dateinamen + +PUB main | wflag + + wflag := ios.start 'ios initialisieren + + 'muß auskommentiert werden für bin-datei + 'ios.startram 'testcode für ramupload + + ios.breset 'bellatrix neu starten + waitcnt(cnt + 200_000_000) 'warte bis bel fertig ist + ios.bload(string("vecdem1.bel")) 'grafiktreiber laden + waitcnt(cnt + 200_000_000) 'warte bis bel fertig ist + + ios.sdmount 'medium mounten + repeat + repsongs + + +PUB repsongs | fnadr,len,fcnt,i 'alle songs auf der sd-card abspielen + + ios.sddir 'kommando: verzeichnis öffnen + startlist 'zum listenanfang + fcnt := 0 'zähler für dateianzahl + repeat 'dateiliste einlesen + fnadr := ios.sdnext + if fnadr <> 0 'ist eintrag gültig? + len := strsize(fnadr) + if strcomp(@ext1,(fnadr+len-4)) + fcnt++ + wrfn(fnadr) + while fnadr <> 0 'wiederholen solange stradr <> 0 + startlist 'zum listenanfang + repeat i from 0 to fcnt-1 'dateiliste abspielen + rdfn(@fn) + playsong(@fn) + fadeout + +PUB fadeout | i 'song langsam ausblenden + repeat i from 0 to 15 + ios.hss_vol(15 - i) + waitcnt(cnt + 60_000_000) + waitcnt(cnt + 30_000_000) + +CON + +' long lcnt 'zeiger für dateiliste +' byte fn[12] 'puffer für dateinamen + +PUB wrfn(stradr) | len,i 'kopiert dateinamen in eram + len := strsize(stradr) + repeat i from 0 to len-1 + ios.ram_write(byte[stradr][i],lcnt++) + ios.ram_write(0,lcnt++) + + +PUB rdfn(stradr) | i,n 'liest dateinamen aus eram + i := 0 + repeat + n := ios.ram_read(lcnt++) + byte[stradr][i++] := n + while n <> 0 + +PUB startlist 'zeiger auf listenanfang (dateinamen) + lcnt := 0 + +PUB playsong(stradr) | n 'spielt die musikdatei bis zum ende + + ios.hss_stop + ios.hss_playfile(stradr) + repeat + n := ios.hss_intreg(ios#iRepeat) + until n == 3 + + + +DAT +ext1 byte ".HSS",0 \ No newline at end of file diff --git a/system/bellatrix/vectron-1-vecdem1/vectron-1-asm.spin b/system/bellatrix/vectron-1-vecdem1/vectron-1-asm.spin new file mode 100644 index 0000000..3b1c280 Binary files /dev/null and b/system/bellatrix/vectron-1-vecdem1/vectron-1-asm.spin differ diff --git a/system/bellatrix/vectron-1-vecdem1/vectron-1-drv.spin b/system/bellatrix/vectron-1-vecdem1/vectron-1-drv.spin new file mode 100644 index 0000000..5309379 Binary files /dev/null and b/system/bellatrix/vectron-1-vecdem1/vectron-1-drv.spin differ diff --git a/system/bellatrix/vectron-1-vecdem1/vectron-1-keyb.spin b/system/bellatrix/vectron-1-vecdem1/vectron-1-keyb.spin new file mode 100644 index 0000000..dad7275 Binary files /dev/null and b/system/bellatrix/vectron-1-vecdem1/vectron-1-keyb.spin differ diff --git a/system/bellatrix/vectron-1-vecdem1/vectron-1.spin b/system/bellatrix/vectron-1-vecdem1/vectron-1.spin new file mode 100644 index 0000000..396b307 --- /dev/null +++ b/system/bellatrix/vectron-1-vecdem1/vectron-1.spin @@ -0,0 +1,118 @@ +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + +'signaldefinitionen regnatix + +#0, D0,D1,D2,D3,D4,D5,D6,D7 'datenbus +#8, BEL_VGABASE 'vga-signale (8pin) +#16, BEL_KEYBC,BEL_KEYBD 'keyboard-signale +#18, BEL_MOUSEC,BEL_MOUSED 'maus-signale +#20, BEL_VIDBASE 'video-signale(3pin) +#23, BEL_SELECT 'belatrix-auswahlsignal +#24, HBEAT 'front-led + BUSCLK 'bustakt + BUS_WR '/wr - schreibsignal + BUS_HS ' '/hs - quittungssignal + + +VGA_BASPORT = 8 'vga startport +KEYB_DPORT = BEL_KEYBD 'tastatur datenport +KEYB_CPORT = BEL_KEYBC 'tastatur taktport + +DB_WAIT = %00000001_00000000_00000000_00000000 'dira-wert f?r wait-status am bus +DB_IN = %00001001_00000000_00000000_00000000 'dira-wert f?r datenbuseingabe +DB_OUT = %00001001_00000000_00000000_11111111 'dira-wert f?r datenbusausgabe +CNT_HBEAT = 5_000_0000 'blinkgeschw. front-led + +'512x384 + +tiles = vec#tiles + +OBJ + + vec : "vectron-1-asm" + key : "vectron-1-keyb" + +PUB MainLoop|h,i,deg,x,y,mask,ii,char,j,k,n + + vec.start + key.start(keyb_dport, keyb_cport) 'tastaturport starten + + repeat i from 0 to tiles - 1 'init tile colors to white on black + vec.color(i,$0800) + 'vec.color(i,$FF<<8+i) 'init tile colors "Nice view" + + vec.pointcolor(1) + vec.text(0,0,string("Vektordemo")) + + repeat + vec.pointcolor(1) + + repeat 1 + repeat j from 1 to 260 step 5 + repeat i from 0 to 359 step 1 + 'vec.syncvid + n := vec.deg(i) + vec.shape(256,192,j,j,3,n) + keyreb + + repeat 1 + repeat j from 260 to 1 step 5 + repeat i from 0 to 359 step 1 + 'vec.syncvid + n := vec.deg(i) + vec.shape(256,192,j,j,3,n) + keyreb + + repeat 20 + repeat i from 0 to 359 + 'vec.syncvid + n := vec.deg(i) + vec.shape(256,192,145,145,3,n) + keyreb + + repeat 3 + repeat i from 0 to 359 + 'vec.syncvid + n := vec.deg(i) + vec.shape(256,192,145,145,3,n) + vec.shape(256,192,70,70,4,vec.deg(359-i*2)) + vec.shape(256,192,30,30,5,vec.deg(i*3)) + keyreb + + repeat 1 + repeat i from 0 to 359 + 'vec.syncvid + n := vec.deg(i) + vec.shape(256,192,200,200,6,n) + vec.shape(256,192,190,190,6,n) + vec.shape(256,192,180,180,6,n) + vec.shape(256,192,170,170,6,n) + vec.shape(256,192,160,160,6,n) + + vec.shape(256,192,150,150,6,n) + vec.shape(256,192,145,145,3,n) + vec.shape(256,192,70,70,4,vec.deg(359-i*2)) + vec.shape(256,192,30,30,5,vec.deg(i*3)) + keyreb + + repeat 3 + repeat i from 0 to 359 step 5 + repeat x from 100 to 400 step 150 + repeat y from 100 to 300 step 150 + shapes1(x,y,i) + keyreb + +PRI shapes1(x,y,i) + 'vec.syncvid + vec.shape(x,y,145,145,3,vec.deg(i)) + vec.shape(x,y,70,70,4,vec.deg(359-i*2)) + vec.shape(x,y,30,30,5,vec.deg(i*3)) + +PRI keyreb 'bei teastendruck reboot + + if key.key + reboot + \ No newline at end of file diff --git a/system/bellatrix/vectron-1-vecdem1/vga_frame.png b/system/bellatrix/vectron-1-vecdem1/vga_frame.png new file mode 100644 index 0000000..0365919 Binary files /dev/null and b/system/bellatrix/vectron-1-vecdem1/vga_frame.png differ diff --git a/system/bellatrix/vectron-1-vecdem1/vga_line.png b/system/bellatrix/vectron-1-vecdem1/vga_line.png new file mode 100644 index 0000000..24613b8 Binary files /dev/null and b/system/bellatrix/vectron-1-vecdem1/vga_line.png differ diff --git a/system/bellatrix/vga-gui/.~lock.Document.rtf# b/system/bellatrix/vga-gui/.~lock.Document.rtf# new file mode 100644 index 0000000..a0fc19d --- /dev/null +++ b/system/bellatrix/vga-gui/.~lock.Document.rtf# @@ -0,0 +1 @@ +ingo ,ingo,anaximander,22.06.2010 19:59,file:///home/ingo/.openoffice.org/3; \ No newline at end of file diff --git a/system/bellatrix/vga-gui/Document.rtf b/system/bellatrix/vga-gui/Document.rtf new file mode 100644 index 0000000..1184eab Binary files /dev/null and b/system/bellatrix/vga-gui/Document.rtf differ diff --git a/system/bellatrix/vga-gui/GUIBase.spin b/system/bellatrix/vga-gui/GUIBase.spin new file mode 100644 index 0000000..3b58415 Binary files /dev/null and b/system/bellatrix/vga-gui/GUIBase.spin differ diff --git a/system/bellatrix/vga-gui/GUIDemo.spin b/system/bellatrix/vga-gui/GUIDemo.spin new file mode 100644 index 0000000..bbfa2c0 Binary files /dev/null and b/system/bellatrix/vga-gui/GUIDemo.spin differ diff --git a/system/bellatrix/vga-gui/InputField.spin b/system/bellatrix/vga-gui/InputField.spin new file mode 100644 index 0000000..f4a7fb3 Binary files /dev/null and b/system/bellatrix/vga-gui/InputField.spin differ diff --git a/system/bellatrix/vga-gui/Keyboard.spin b/system/bellatrix/vga-gui/Keyboard.spin new file mode 100644 index 0000000..d8c197e Binary files /dev/null and b/system/bellatrix/vga-gui/Keyboard.spin differ diff --git a/system/bellatrix/vga-gui/MenuItem.spin b/system/bellatrix/vga-gui/MenuItem.spin new file mode 100644 index 0000000..fcd6fe6 Binary files /dev/null and b/system/bellatrix/vga-gui/MenuItem.spin differ diff --git a/system/bellatrix/vga-gui/Mouse.spin b/system/bellatrix/vga-gui/Mouse.spin new file mode 100644 index 0000000..c37ad5c Binary files /dev/null and b/system/bellatrix/vga-gui/Mouse.spin differ diff --git a/system/bellatrix/vga-gui/PropUI_L_80.jpg b/system/bellatrix/vga-gui/PropUI_L_80.jpg new file mode 100644 index 0000000..1c06e92 Binary files /dev/null and b/system/bellatrix/vga-gui/PropUI_L_80.jpg differ diff --git a/system/bellatrix/vga-gui/PushButton.spin b/system/bellatrix/vga-gui/PushButton.spin new file mode 100644 index 0000000..3d94f8b Binary files /dev/null and b/system/bellatrix/vga-gui/PushButton.spin differ diff --git a/system/bellatrix/vga-gui/RadioCheck.spin b/system/bellatrix/vga-gui/RadioCheck.spin new file mode 100644 index 0000000..0849d44 Binary files /dev/null and b/system/bellatrix/vga-gui/RadioCheck.spin differ diff --git a/system/bellatrix/vga-gui/SimpleBox.spin b/system/bellatrix/vga-gui/SimpleBox.spin new file mode 100644 index 0000000..2e3eb4e Binary files /dev/null and b/system/bellatrix/vga-gui/SimpleBox.spin differ diff --git a/system/bellatrix/vga-gui/Simple_Numbers.spin b/system/bellatrix/vga-gui/Simple_Numbers.spin new file mode 100644 index 0000000..331dabc Binary files /dev/null and b/system/bellatrix/vga-gui/Simple_Numbers.spin differ diff --git a/system/bellatrix/vga-gui/SpinBox.spin b/system/bellatrix/vga-gui/SpinBox.spin new file mode 100644 index 0000000..0a0c8ca Binary files /dev/null and b/system/bellatrix/vga-gui/SpinBox.spin differ diff --git a/system/bellatrix/vga-gui/StatusLamp.spin b/system/bellatrix/vga-gui/StatusLamp.spin new file mode 100644 index 0000000..3ec29d5 Binary files /dev/null and b/system/bellatrix/vga-gui/StatusLamp.spin differ diff --git a/system/bellatrix/vga-gui/TextBox.spin b/system/bellatrix/vga-gui/TextBox.spin new file mode 100644 index 0000000..d138579 Binary files /dev/null and b/system/bellatrix/vga-gui/TextBox.spin differ diff --git a/system/bellatrix/vga-gui/Timer.spin b/system/bellatrix/vga-gui/Timer.spin new file mode 100644 index 0000000..cd6cf71 Binary files /dev/null and b/system/bellatrix/vga-gui/Timer.spin differ diff --git a/system/bellatrix/vga-gui/VGA_HiRes_Text.spin b/system/bellatrix/vga-gui/VGA_HiRes_Text.spin new file mode 100644 index 0000000..ed3ea2d Binary files /dev/null and b/system/bellatrix/vga-gui/VGA_HiRes_Text.spin differ diff --git a/system/bellatrix/vga-gui/vga-vid.spin b/system/bellatrix/vga-gui/vga-vid.spin new file mode 100644 index 0000000..6cd859e Binary files /dev/null and b/system/bellatrix/vga-gui/vga-vid.spin differ diff --git a/system/bellatrix/vga-text-1024x768-pix-64x24-zeichen/logo-hive-8x2.dat b/system/bellatrix/vga-text-1024x768-pix-64x24-zeichen/logo-hive-8x2.dat new file mode 100644 index 0000000..109ef59 Binary files /dev/null and b/system/bellatrix/vga-text-1024x768-pix-64x24-zeichen/logo-hive-8x2.dat differ diff --git a/system/bellatrix/vga-text-1024x768-pix-64x24-zeichen/logo-hive-8x2/dat.rtf b/system/bellatrix/vga-text-1024x768-pix-64x24-zeichen/logo-hive-8x2/dat.rtf new file mode 100644 index 0000000..e758f9d --- /dev/null +++ b/system/bellatrix/vga-text-1024x768-pix-64x24-zeichen/logo-hive-8x2/dat.rtf @@ -0,0 +1,275 @@ +{\rtf1\ansi\deff0{\fonttbl{\f0\fswiss\fcharset0 Arial;}} +{\*\generator Msftedit 5.41.15.1515;}\viewkind4\uc1\pard\lang1031\f0\fs20 char y=0, x=0 \par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=0, x=1 \par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0003_3333_3300_0000\par + LONG %%0033_3000_3330_0000\par + LONG %%0330_0000_0033_0000\par + LONG %%3300_0000_0003_3000\par + LONG %%3300_0000_0000_3000\par + LONG %%3000_0000_0000_3300\par + LONG %%3000_0000_0000_3300\par + LONG %%3300_0000_0000_3000\par + LONG %%3300_0000_0003_3000\par + LONG %%0330_0000_0033_0000\par + LONG %%0033_3000_0333_0000\par + LONG %%0033_3333_3330_0000\par + LONG %%0333_0000_0333_0000\par +char y=0, x=2 \par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=0, x=3 \par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3003_3330_0333_3300\par + LONG %%3033_3333_0333_3300\par + LONG %%3033_3333_0333_3300\par +char y=0, x=4 \par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%3000_3333_0000_3333\par + LONG %%3003_3333_3000_3333\par + LONG %%3003_3333_3000_3333\par + LONG %%3003_3333_3000_3333\par + LONG %%3003_3333_3000_3333\par + LONG %%3000_3333_0000_3333\par + LONG %%3000_0000_0000_3333\par + LONG %%3000_0000_0000_3333\par +char y=0, x=5 \par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0000_3333\par +char y=0, x=6 \par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%3333_3000_0000_0033\par + LONG %%3333_3333_0000_0033\par + LONG %%3333_3333_3000_0033\par + LONG %%3333_3333_3300_0033\par + LONG %%3333_3333_3330_0033\par + LONG %%0000_3333_3330_0033\par + LONG %%0000_0033_3333_0033\par + LONG %%3333_0003_3333_0033\par +char y=0, x=7 \par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=1, x=0 \par + LONG %%0000_0000_0000_0000\par + LONG %%3330_0000_0000_0000\par + LONG %%0033_3000_0000_0000\par + LONG %%0000_3300_0000_0000\par + LONG %%0000_3300_0000_0000\par + LONG %%0000_0330_0000_0000\par + LONG %%0000_0330_0000_0000\par + LONG %%0000_0330_0000_0000\par + LONG %%0000_0330_0000_0000\par + LONG %%0000_3300_0000_0000\par + LONG %%0003_3000_0000_0000\par + LONG %%0333_0000_0000_0000\par + LONG %%3330_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=1, x=1 \par + LONG %%3330_0000_0033_3000\par + LONG %%3300_0000_0003_3333\par + LONG %%3300_0000_0003_3300\par + LONG %%0330_0000_0033_0000\par + LONG %%0033_0000_0030_0000\par + LONG %%0033_0000_0330_0000\par + LONG %%0003_3333_3330_0000\par + LONG %%0003_3333_3330_0000\par + LONG %%0033_0000_0330_0000\par + LONG %%0033_0000_0030_0000\par + LONG %%0330_0000_0033_0000\par + LONG %%3300_0000_0003_3330\par + LONG %%0000_0000_0000_0333\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=1, x=2 \par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0033_3333\par + LONG %%0000_0000_3330_0000\par + LONG %%0000_0000_3300_0000\par + LONG %%0000_0003_3000_0000\par + LONG %%0000_0003_0000_0000\par + LONG %%0000_0033_0000_0000\par + LONG %%0000_0003_0000_0000\par + LONG %%0000_0003_0000_0000\par + LONG %%0000_0003_3000_0000\par + LONG %%0000_0000_3300_0000\par + LONG %%0000_0000_0333_3033\par + LONG %%0000_0000_0003_3333\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=1, x=3 \par + LONG %%3033_3333_0333_3300\par + LONG %%3033_3333_0333_3300\par + LONG %%3003_3330_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%3000_0000_0333_3300\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=1, x=4 \par + LONG %%3003_3333_3000_3333\par + LONG %%3003_3333_3000_3333\par + LONG %%3003_3333_3000_3333\par + LONG %%3003_3333_3000_3333\par + LONG %%3003_3333_3000_3333\par + LONG %%0003_3333_3000_3333\par + LONG %%0003_3333_3000_3333\par + LONG %%0003_3333_3000_3333\par + LONG %%0003_3333_3000_3333\par + LONG %%0003_3333_3000_3333\par + LONG %%0003_3333_3000_3333\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=1, x=5 \par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0000_3333\par + LONG %%3330_0000_0003_3333\par + LONG %%3330_0000_0003_3333\par + LONG %%3330_0000_0033_3333\par + LONG %%3333_3333_3333_3333\par + LONG %%3333_3333_3333_3330\par + LONG %%3333_3333_3333_3300\par + LONG %%3333_3333_3333_3000\par + LONG %%3333_3333_3330_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=1, x=6 \par + LONG %%3333_3003_3333_0033\par + LONG %%3333_3003_3333_0033\par + LONG %%3333_3003_3333_0033\par + LONG %%3333_3003_3333_0033\par + LONG %%3333_0033_3333_0033\par + LONG %%0000_3333_3330_0033\par + LONG %%3333_3333_3330_0033\par + LONG %%3333_3333_3300_0033\par + LONG %%3333_3333_3000_0033\par + LONG %%3333_3333_0000_0033\par + LONG %%3333_3000_0000_0033\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +char y=1, x=7 \par + LONG %%0000_0000_0000_0003\par + LONG %%0000_0000_0000_0003\par + LONG %%0000_0000_0000_0003\par + LONG %%0000_0000_0000_0003\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_3333\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par + LONG %%0000_0000_0000_0000\par +} + \ No newline at end of file diff --git a/system/bellatrix/vga-text-1024x768-pix-64x24-zeichen/logo-hive-8x2/logo-hive-8x2.dat b/system/bellatrix/vga-text-1024x768-pix-64x24-zeichen/logo-hive-8x2/logo-hive-8x2.dat new file mode 100644 index 0000000..109ef59 Binary files /dev/null and b/system/bellatrix/vga-text-1024x768-pix-64x24-zeichen/logo-hive-8x2/logo-hive-8x2.dat differ diff --git a/system/bellatrix/vga-text-1024x768-pix-64x24-zeichen/vga-keyb.spin b/system/bellatrix/vga-text-1024x768-pix-64x24-zeichen/vga-keyb.spin new file mode 100644 index 0000000..5333e3a Binary files /dev/null and b/system/bellatrix/vga-text-1024x768-pix-64x24-zeichen/vga-keyb.spin differ diff --git a/system/bellatrix/vga-text-1024x768-pix-64x24-zeichen/vga-vid.spin b/system/bellatrix/vga-text-1024x768-pix-64x24-zeichen/vga-vid.spin new file mode 100644 index 0000000..a2f9a70 Binary files /dev/null and b/system/bellatrix/vga-text-1024x768-pix-64x24-zeichen/vga-vid.spin differ diff --git a/system/bellatrix/vga-text-1024x768-pix-64x24-zeichen/vga.spin b/system/bellatrix/vga-text-1024x768-pix-64x24-zeichen/vga.spin new file mode 100644 index 0000000..9ead70d Binary files /dev/null and b/system/bellatrix/vga-text-1024x768-pix-64x24-zeichen/vga.spin differ diff --git a/system/license.spin b/system/license.spin new file mode 100644 index 0000000..c2b7622 Binary files /dev/null and b/system/license.spin differ diff --git a/system/regnatix/FemtoBasic Manual.rtf b/system/regnatix/FemtoBasic Manual.rtf new file mode 100644 index 0000000..5f43836 --- /dev/null +++ b/system/regnatix/FemtoBasic Manual.rtf @@ -0,0 +1,797 @@ +{\rtf1\ansi\ansicpg1252\cocoartf949 +{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fnil\fcharset0 Verdana;} +{\colortbl;\red255\green255\blue255;\red0\green5\blue50;\red238\green238\blue238;} +\margl1440\margr1440\vieww12580\viewh18760\viewkind0 +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\f0\b\fs24 \cf0 \ul \ulc0 FemtoBasic Manual - Version 3.006 +\b0 \ulnone \ +\ +Program lines consist of a line number from 1 to 65535, then a space,\ +then one or more statements separated by a colon (":"). Most statements\ +can be given without a line number and will be executed immediately if so.\ +\ +If a line is entered with the same line number as that of an existing line in\ +the current program, the existing line is deleted and the new line is stored.\ +\ +A line number by itself may be entered. Any existing line in the current\ +program with the same line number will be deleted. No new line will be\ +stored.\ +\ +When FemtoBasic is first started after a Propeller reset, if an SD card is\ +provided and it has a file "autoexec.bas" in its root directory, then the\ +line 'LOAD "autoexec.bas" : RUN' is automatically executed.\ +\ +The ESC key is a "break key". If it is entered, the running program will\ +stop after the current statement finishes executing. PAUSE and IRBRECV\ +are handled specially so the "break key" can interrupt their execution.\ +\ +Pre-compiled binaries are provided for both a VGA display and a TV\ +display and for either the Propeller Demo Board, Propeller Proto Board,\ +or a Hydra. The Hydra version cannot use an SD card with a VGA\ +display because the SD card interface uses the same I/O pins as the\ +VGA display. The names of the binary files indicate which display and\ +board they are intended for.\ +\ +The basic SD card wiring is shown below. "Pull-up" refers to a 20K\ +pull up resistor from the pin indicated to +3.3V. For the Demo Board\ +version, the pins are as indicated below. For the Proto Board version,\ +P0 = I/O pin 8, P1 = I/O pin 9, P2 = I/O pin 10, and P3 = I/O pin 11. For\ +the Hydra version, P0 = I/O pin 16, P1 = I/O pin 17, P2 = I/O pin 18, and\ +P3 = I/O pin 19.\ +\ +\pard\pardeftab720\ql\qnatural + +\f1 \cf2 \cb3 SD CARD Socket Pin-out:\ +\'a0\ +PIN\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0 SD CARD\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0 Propeller\ +-----------------------------------------------------\ +\'a01\'a0(NC)\ +\'a02\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0 (PIN-9) DAT2\'a0\'a0\'a0 Pull-up\ +\'a03\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0(PIN-1) CS\'a0\'a0\'a0\'a0\'a0 Pull-up\'a0\'a0\'a0 P3\ +\'a04\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0 (PIN-2) DI\'a0\'a0\'a0\'a0\'a0 Pull-up\'a0\'a0\'a0\'a0 P2\ +\'a05\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0 (PIN-3) GND\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0 GND\ +\'a06\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0 (PIN-4) +3.3\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0 VCC\ +\'a07\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0 (PIN-5) CLK\'a0\'a0\'a0\'a0 Pull-up\'a0\'a0\'a0\'a0 P1\ +\'a08\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0 (PIN-6) GND\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0 GND\'a0\'a0\'a0\'a0\'a0 \ +\'a09\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0 (PIN-7) DO\'a0\'a0\'a0\'a0\'a0 Pull-up\'a0\'a0\'a0\'a0 P0\ +10\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0\'a0 (PIN-8) DAT1\'a0\'a0 Pull-up\ +11\'a0(CD SW)\ + +\f0 \cf0 \cb1 \ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\b \cf0 \ul Expressions\ + +\b0 \ulnone \ +Expressions consist of variables, constants, and "pseudo-variables"\ +that function like variables, but may have complex actions like FILE or\ +EEPROM[5]. Constants may be decimal, hexadecimal (prefixed with "$"),\ +or binary (prefixed with "%"). All expressions use 32-bit integer values.\ +\ +\ +\ +There are 26 variables designated by the letters A through Z.\ +Upper and lower case letters are equivalent.\ +\ +INA [ \{.. \} ]\ +\ +This has the value of the specified input pin or pins. If two pin values are\ +given, the first is the most significant bit number and the second is the\ +least significant bit number of the value. The pin or pins specified are\ +changed to input mode (the default).\ +\ +BYTE [ ]\ +\ +This has the value of the main memory byte at the address provided.\ +\ +WORD [ ]\ +\ +This has the value of the main memory word at the address provided.\ +The least significant bit of the address is ignored.\ +\ +LONG [ ]\ +\ +This has the value of the main memory long word at the address provided.\ +The least significant two bits of the address are ignored.\ +\ +EEPROM [ \{, \} ]\ +\ +This has the value of the byte in the EEPROM attached to the boot I2C bus\ +(on pins 28-29) at the address specified. If two expressions are provided,\ +the first gives the pin number of the SCL line of the EEPROM while the\ +second expression is the address. The address may be any value from\ +zero to $7FFFF and the upper 3 bits are used to form the device select code.\ +\ +FILE\ +\ +This has the value of the next byte in the currently open SD card file or -1\ +at the end of the file. The file must be open for reading.\ +\ +MEM\ +\ +This has the value of the amount of space available for program storage.\ +\ +CNT\ +\ +The current system clock value.\ +\ +PHSA\ +\ +The cog counter phase register A value.\ +\ +PHSB\ +\ +The cog counter phase register B value.\ +\ +FRQA\ +\ +The cog counter frequency register A value.\ +\ +FRQB\ +\ +The cog counter frequency register B value.\ +\ +CTRA\ +\ +The cog counter control register A value.\ +\ +CTRB\ +\ +The cog counter control register B value.\ +\ +KEYCODE\ +\ +The value of the next keyboard key value or zero if the keyboard buffer\ +is empty.\ +\ +RND \ +\ +The value is a pseudo-random number in the range zero to one less than\ +that of the expression given.\ +\ +- \ +! \ +\ +"-" is negate. "!" is bit-wise logical not.\ +\ +<9> SHL <9>\ +<9> SHR <9>\ +<9> ROL <9>\ +<9> ROR <9>\ +<9> SAR <9>\ +<9> REV <9>\ +\ +"SHL" is logical shift left. "SHR" is logical shift right. "ROL" is rotate left.\ +"ROR" is rotate right. "SAR" is arithmetic shift right. "REV" is bit reverse.\ +In all cases, the value to be shifted is the left operand and the shift count\ +is the right operand. "REV" reverses the order of the specified number of\ +least significant bits with the most significant bits set to zero.\ +\ +<8> & <8>\ +\ +"&" is bit-wise logical and.\ +\ +<7> | <7>\ +\ +"|" is bit-wise logical or\ +\ +<6> *<6>\ +<6> / <6>\ +<6> // <6>\ +\ +"*" is a 32 bit unsigned multiplication. "/" is the quotient of a 32 bit unsigned\ +division. "//" is the remainder of a 32 bit unsigned division.\ +\ +<5> + <5>\ +<5> - <5>\ +\ +"+" is a 32 bit addition. "-" is a 32 bit subtraction\ +\ +<4> = <4>\ +<4> < <4>\ +<4> > <4>\ +<4> <= <4>\ +<4> >= <4>\ +<4> <> <4>\ +\ +"=" is equal to. "<" is less than. ">" is greater than.\ +"<=" is less than or equal to. ">=" is greater or equal to.\ +"<>" is not equal to.\ +\ +NOT <3>\ +\ +"NOT" is logical not.\ +\ +<2> AND <2>\ +\ +"AND" is logical and.\ +\ +<1> OR <1>\ +\ +"OR" is logical or.\ +\ +Note that the numbers in the brackets () are used to\ +indicate the operator precedence.\ +\ + +\b \ul Statements +\b0 \ulnone \ +\ +Note that multiple statements may be given on a line separated by\ +a colon (":"). There are some restrictions on what can be combined on\ +a line. These are described in the individual statements' descriptions.\ +\ +\{LET\} = \ +\ +Set the variable to the value of the expression .\ +\ +INPUT \{ "";\} \{,\}\ +\ +If given, the is displayed and an input line may be entered.\ +For each variable given, an expression is evaluated from the input line.\ +The expressions may be separated by commas (",") or, if unambiguous,\ +by spaces. These expressions may contain variable names, operators,\ +or "pseudo-variables". If more expressions are given than variables,\ +the excess are ignored. An error is treated as if it occurred on the line\ +where the INPUT statement is given.\ +\ +PRINT \{\{"" | \} \{, | ;\}\}\ +\ +A series of expressions or string constants are given, separated by\ +commas (",") or semicolons (";"). If a comma is used, enough spaces\ +are inserted to display the next item at the next display column divisible\ +by 8. If a semicolon is used, the next item begins at the next column.\ +If the statement ends with a comma or semicolon, an end of line is not\ +inserted. A PRINT statement by itself causes an end of line to be displayed\ +\ +GOTO \ +\ +Go to the label whose value is equal to the expression\ +\ +GOSUB \ +\ +Call (as a subroutine) the label whose value is equal to the expression.\ +Note that a GOSUB must be the only or last statement on a line.\ +\ +RETURN\ +\ +Return from a GOSUB call\ +\ +REM \ +\ +The rest of the line in the program is considered part of the comment and\ +is otherwise ignored.\ +\ +NEW\ +\ +Erase the current program and clear all the variables.\ +\ +LIST \{ \{,\}\}\ +\ +List the current program. If no expressions are given, the whole program\ +is listed. If one expression is given, that line is listed. If two expressions\ +are given, all lines between those two values are listed.\ +\ +RUN\ +\ +Clear all the variables (to zero) and start executing the current program\ +from the first line.\ +\ +OPEN "", \{R | W | A \}\ +\ +Open the specified file on the SD card in the mode requested (R - read,\ +W - write, A - append). If a file is already open, it is closed first. Only one\ +file may be open at a time.\ +\ +READ \{,\}\ +\ +Read a line from the currently opened SD card file and set the variables\ +specified to the expressions supplied on that line. The expressions may\ +be separated by commas or, if unambiguous, may be separated by spaces.\ +These expressions may be any expression including operators, variables,\ +pseudo-variables (like CNT). Effectively, this is as if " = " were\ +executed for each variable given and each expression in the SD card file.\ +\ +WRITE \{\{"" | \} \{, | ;\}\}\ +\ +This works just like the PRINT statement except that the characters produced\ +are written to the currently opened SD card file. An end of line is written as\ +a carriage return / line feed pair (ASCII CR/LF ... 13, 10).\ +\ +CLOSE\ +\ +Close the currently opened SD card file, if any.\ +\ +DELETE ""\ +\ +Delete the specified SD card file. Any opened SD card file will be closed.\ +\ +RENAME "", ""\ +\ +Rename the specified SD card file. Any opened SD card file will be closed.\ +This is not currently implemented and will produce an error message.\ +\ +FILES\ +\ +List all files on the SD card (at the root level). Neither subdirectories nor the files\ +within them are included in this listing. Any opened SD card file will be closed.\ +\ +SAVE\ +\ +Save the current program to an otherwise unused area in the boot EEPROM.\ +Note that downloading a program to the EEPROM using the Propeller Tool or\ +an equivalent downloading program will erase any saved program.\ +\ +SAVE [ \{, \} ]\ +\ +This saves the current program in the EEPROM attached to the boot I2C bus\ +(on pins 28-29) at the address specified. If two expressions are provided,\ +the first gives the pin number of the SCL line of the EEPROM while the\ +second expression is the address. The address may be any value from\ +zero to $7FFFF and the upper 3 bits are used to form the device select code.\ +The address is adjusted to 2 bytes below the next 64 byte boundary and the\ +total program length is stored in those two bytes followed by the program itself.\ +If the address is adjusted upwards, only the last two bytes of that 64 byte block\ +are changed.\ +\ +SAVE ""\ +\ +Save the current program to the specified file on a SD card. Any existing file\ +by that name will be overwritten with the program which will be saved in text\ +file format, as if they were displayed with the LIST statement.\ +\ +LOAD\ +\ +Erase the current program and load in a program previously saved with the\ +SAVE statement.\ +\ +LOAD [ \{, \} ]\ +\ +Erase the current program and load in a program previously saved with the\ +SAVE [ \{, \} ] statement.\ +\ +LOAD ""\ +\ +Erase the current program and load in a program from an SD card file. This\ +program must be in text format, just as if it were to be typed in. All lines must\ +be numbered (with a line number) except lines that are completely blank.\ +\ +FOR = TO \{STEP \}\ +\ +This sets up a standard Basic FOR/NEXT loop. The variable is set to the value\ +of the first expression and tested against the limit given by the value of the\ +second expression (which is evaluated only once). The optional step size\ +may be positive or negative. If negative, the limit test is appropriately changed.\ +The FOR statement must be the last statement on a multi-statement line and\ +improperly nested FOR/NEXT statement pairs may cause incorrect execution\ +without an error message. Default STEP value is +1.\ +\ +NEXT \ +\ +This terminates a standard Basic FOR/NEXT loop. The STEP value is added\ +to the variable and the result is tested against the limit value. If still within the\ +limit, program execution continues with the statement after the matching FOR\ +statement. If not, execution continues with the next statement.\ +\ +OUTA [ \{.. \} ] = \ +\ +This sets the specified output pin or pins to the expression to the right of the\ +assignment. If one pin value is given, that is the pin to be changed. If two\ +pin values are given, the first is the most significant bit number and the\ +second is the least significant bit number of the value. The pin or pins\ +specified are changed to output mode.\ +\ +PAUSE \{, \}\ +\ +The program is paused for the number of milliseconds given by the first\ +(or only) value given. If two values are given, the first is in milliseconds\ +while the second is in microseconds and they're added together for the\ +total pause time. The minimum pause time is 50us. If the pause time is\ +more than 10ms, The pause statement is interrupted after 10ms and\ +reexecuted with a 10ms shorter pause time. This is to allow for the\ +interruption of the program using a "break key". The PAUSE statement\ +must be the first or only statement on a line.\ +\ +BYTE [ ] = \ +\ +This sets the value of the main memory byte at the address provided to\ +the expression on the right side of the assignment.\ +\ +WORD [ ] = \ +\ +This sets the value of the main memory word at the address provided to\ +the expression on the right side of the assignment. The least significant\ +bit of the address is ignored.\ +\ +LONG [ ] = \ +\ +This sets the value of the main memory long word at the address provided\ +to the expression on the right side of the assignment. The least significant\ +two bits of the address are ignored.\ +\ +PHSA = \ +\ +Set the cog counter phase register A to the expression.\ +\ +PHSB = \ +\ +Set the cog counter phase register B to the expression.\ +\ +FRQA = \ +\ +Set the cog counter frequency register A to the expression.\ +\ +FRQB = \ +\ +Set the cog counter frequency register B to the expression.\ +\ +CTRA = \ +\ +Set the cog counter control register A to the expression.\ +\ +CTRB = \ +\ +Set the cog counter control register B to the expression.\ +\ +DISPLAY \{, \}\ +\ +Send the specified byte values to the display driver. The specific control\ +codes, their parameters, and their meaning depend on the display driver.\ +See the display driver documentation for descriptions.\ +\ +STOP\ +\ +Stop execution of the program.\ +\ +END\ +\ +Stop execution of the program (works like STOP).\ +\ +EEPROM [ \{, \} ] = \ +\ +This sets the value of the byte in the EEPROM attached to the boot I2C bus\ +(on pins 28-29) at the address specified. If two expressions are provided,\ +the first gives the pin number of the SCL line of the EEPROM while the\ +second expression is the address. The address may be any value from\ +zero to $7FFFF and the upper 3 bits are used to form the device select code.\ +\ +FILE = \ +\ +This sets the value of the next byte in the currently open SD card file.\ +The file must be open for writing or appending.\ +\ +SPIN [ \{, \} ]\ +\ +This causes a Spin program to be loaded into the Propeller's main memory\ +from a 32K EEPROM "page". If only one expression is provided, it is the\ +starting address in a 512K byte address space made up of one or more\ +EEPROMs attached to the I2C bus on Propeller pins 28 (SCL) and 29 (SDA).\ +The boot EEPROM is the first 32K of this address space. The lower order\ +15 bits of the address are ignored so the loading process always begins on\ +a 32K byte boundary. If two expressions are provided, the first gives the\ +pin number of the SCL line of the EEPROM while the second expression\ +gives the starting address. The address may be any value from zero to\ +$7FFFF and the upper 3 bits are used to form the device select code.\ +Once the Spin program has been successfully loaded, it begins execution.\ +The loaded Spin program completely replaces the running FemtoBasic.\ +\ +SPIN ""\ +\ +This causes a Spin program to be loaded into the Propeller's main memory\ +from a specified file on an attached SD card. This file should be a copy of\ +the binary form of a Spin program as saved from the Propeller Tool.\ +Once the Spin program has been successfully loaded, it begins execution.\ +The loaded Spin program completely replaces the running FemtoBasic.\ +\ +DUMP , \ +\ +This displays a portion of the Propeller's main memory. The first expression\ +gives the starting address and the second expression gives the number\ +of bytes to be displayed. The information is formatted 8 bytes per line with\ +both hexadecimal and ASCII displayed.\ +\ +DUMP [ \{, \} ] , \ +\ +This displays a portion of the EEPROM. The last expression gives the number\ +of bytes to be displayed. The first portion describes a starting address in EEPROM.\ +See the SPIN statement for a description of the values.\ +\ +COPY [ \{, \} ] , [ \{, \}]\ +\ +This copies a Spin program from the first 32K byte EEPROM "page" specified\ +to the second. As with the SPIN statement, if only one expression is supplied,\ +it provides the starting EEPROM address. If two are supplied, the first is the\ +pin number of the SCL line while the seconds is the EEPROM address.\ +The amount of data copied is taken from the beginning of the Spin program\ +binary file.\ +\ +COPY "" , [ \{, \}]\ +\ +This copies a Spin program from an SD card file to a 32K byte EEPROM "page".\ +\ +COPY [ \{, \} ] , ""\ +\ +This copies a Spin program from a 32K byte EEPROM "page" to an SD card file.\ +\ + +\b \ul BOE-BOT Extensions +\b0 \ulnone \ +\ +The BOE-BOT version of FemtoBasic is similar to the regular version\ +except that it uses a full duplex serial port for its keyboard input and\ +display output and several "pseudo-variables" and statements have\ +been added to control servos, a PING distance sensor, IR distance\ +sensors, and an HM55B compass connected via a PCA9554 I2C\ +I/O Expander. A Propeller Proto Board or equivalent is assumed.\ +\ +The left servo is connected to I/O pin 0, the right servo to pin 1, and the\ +PING bracket servo to pin 2. An IR detector is connected to pin 3 and\ +an IR LED is connected to pin 4. The PING control signal is connected\ +to pin 5. The "console" receive line is pin 6 and the transmit line is pin 7.\ +This "console" is implemented using a configured xBee transceiver.\ +A PCA9554 I2C I/O Expander is connected to the boot EEPROM bus\ +using I/O pins 28 (SCL) and 29 (SDA).\ +\ +The HM55B Ena pin is connected to PCA9554 I/O pin 0. The Clk pin\ +is connected to pin1. DI is connected to pin 2 and DO to pin 3.\ +\ +Two different binary versions are provided. One uses the programming\ +serial port for the "console" (BoeBotBasicUS.binary) and the other uses\ +pins 6 and 7 for wireless operation via an xBee transceiver\ +(BoeBotBasicXB.binary).\ +\ + +\b \ul Expressions +\b0 \ulnone \ +\ +PING\ +\ +This value is the distance in mm of the last PING reading (one-way). It\ +will be zero if a new reading has been initiated, but a value isn't ready yet.\ +\ +IRZONE [ , , ]\ +\ +The first expression is the center frequency (in Hz). The second expression\ +is the number of zones. The third expression is the width of a zone (in Hz).\ +The IR emitter frequency is swept from the last zone to the center frequency\ +with about 200 cycles of each frequency emitted per zone. This value is the\ +number of the first zone where a response is detected (#zones-1 to 0) or -1\ +to indicate that no response was detected.\ +\ +EXPAND [ ]\ +\ +This is the value of the PCA9554 I2C I/O Expander's register whose address\ +is supplied.\ +\ +COMPASS\ +\ +This value is the compass heading in brads (0 to 359 degrees is the same\ +as 0-255).\ +\ + +\b \ul Statements +\b0 \ulnone \ +\ +SRVLEFT \{[ ]\} = \ +SRVRIGHT \{[ ]\} = \ +SRVPING \{[ ]\} = \ +\ +Send a pulse stream to the specified servo with a width (in us) given by the\ +expression on the right side of the assignment. If a square bracketed\ +expression is provided, this is the number of pulses to send (at 20ms intervals).\ +If no pulse count is provided, the pulse train continues indefinitely. If either the\ +pulse count is zero or the pulse width is zero, the pulse train will stop. The\ +pulse width must lie between 500us and 2500us.\ +\ +PING\ +\ +Initiates a new PING cycle. The one-way path length will be zero until the new\ +reading is complete.\ +\ +COMPASS , \ +\ +Reads the raw x and y values of the HM55B compass and assign them to the\ +first and second variables specified respectively.\ +\ +EXPAND [ ] = \ +\ +The PCA9554 I2C I/O Expander's register whose address is supplied is set\ +to the value on the right side of the assignment.\ +\ + +\b \ul IR Buddy Extensions +\b0 \ulnone \ +\ +The IR Buddy version of FemtoBasic is identical to the regular version\ +except that statements have been added to control one or more IR Buddy\ +devices. These may be connected to any otherwise available I/O pin.\ +\ + +\b \ul Statements +\b0 \ulnone \ +\ +IRBSEND \ +\ +The expression is the I/O pin number to be used. This resets the IR Buddy.\ +\ +IRBSEND , \{, \}\ +\ +The first expression is the I/O pin to be used. The remaining expressions\ +are byte values to be sent to the IR Buddy (at 9600 Baud).\ +\ +IRBRECV , , \{, \}\ +\ +The first expression is the I/O pin to be used. The second expression is\ +an initial timeout (in ms) to use. Subsequent timeouts are 10ms. The\ +number of bytes specified are received, one in each variable. If a timeout\ +occurs, that variable and all subsequent ones are set to -1.\ +\ + +\b \ul uOLED-96-Prop Extensions +\b0 \ulnone \ +\ +UOLED SETUP\ +\ +Initialize the uOLED-96-Prop. This must be done before any other operations are done.\ +\ +UOLED START\ +\ +Power up the screen electronics and display any data previously written to graphics RAM.\ +\ +UOLED STOP\ +\ +Power down the screen electronics without disturbing any data in graphics RAM.\ +\ +UOLED LEVEL \ +\ +Set the master contrast setting (range 0-15).\ +\ +UOLED COLOR , , \ +\ +Set the individual color contrast values (range 0-255).\ +\ +UOLED DIM , , , \ +\ +Dim a designated screen window given the coordinates of the left upper corner and the\ +right lower corner.\ +\ +UOLED PIXEL , , , , \ +\ +Writes 2 bytes of color data to the pixel at the coordinate specified. The color information\ +range is 0-255.\ +\ +UOLED SCROLL SETUP , ,
, <# Lines> , \ +\ +X is he number of columns of horizontal offset. Y is the number of lines of vertical offset.\ +Address is the starting line address. # Lines is the number of lines to be scrolled\ +horizontally. Interval is the time interval between scroll steps. 0 = 6 frames, 1 = 10 frames,\ +2 = 100 frames, and 3 = 200 frames.\ +\ +UOLED SCROLL START\ +\ +Activate the scrolling function as set up previously\ +\ +UOLED SCROLL STOP\ +\ +Deactivate the scrolling function\ +\ +UOLED LINE , , , , , , \ +\ +Display a line from the specified left upper corner to the specified right lower corner in the color\ +specified.\ +\ +UOLED RECT , , , , , , \{, , , \}\ +\ +Display a rectangle from the specified left upper corner to the specified right lower corner of the\ +display. The first set of color values is used for the outline color. If the second set of color values\ +is given, it's used for the fill color. If not, the outline color is used for the fill color as well.\ +\ +UOLED COPY , , , , , \ +\ +Copy one area of the display screen to another. The left upper corner and the right lower corner\ +of the source area is supplied followed by the left upper corner of the destination area.\ +\ +UOLED TEXT , , , , , " ... "\ +UOLED TEXT , , , , , \ +\ +Display text using the current font starting at the coordinates provided. These are in terms of character\ +positions, not pixels (range X: 0-11/15, Y: 0-7). Wraparound occurs at the right and bottom of the display.\ +The first form displays the contents of the string while the second form displays the decimally\ +formatted value of the expression given with a leading minus sign if negative. With the 5x7 font, there\ +are 16 characters per line. With the 8x8 font, there are 12 characters per line.\ +\ +UOLED TEXT , , \ +\ +Set the default background color for text. It's set to black during the initialization of FemtoBasic.\ +\ +UOLED TEXT \ +\ +Set the current font. 0 - 5x7 font. 1 - 8x8 font (default).\ +\ +UOLED ERASE\ +\ +Erase the screen (to black).\ +\ +UOLED RESET\ +\ +Resets the display. You must do a UOLED SETUP afterwards.\ +\ +UOLED CIRCLE , , , , , \ +\ +Display a circle whose center is at X,Y and whose radius is Rad using the color specified. If Rad\ +is negative, the circle is filled with the color specified and the radius is the absolute value of Rad.\ +\ +UOLED CIRCLE , , , , , , \ +\ +Display a one eighth circle arc whose center is at X,Y and whose radius is Rad using the color\ +specified. If Rad is negative, the one eighth circle pie slice is filled with the color specified and\ +the radius is the absolute value of Rad. Arc indicates which one eighth circle is to be displayed.\ +1 - 0 to 45 degrees, 2 - 45 to 90 degrees, 3 - 90 to 135 degrees, 4 - 135 to 180 degrees.\ +\ + +\b \ul HC-OSD Extensions +\b0 \ulnone \ +\ +The Hitt Consulting's Overlay Screen Display version uses the PS/2 keyboard for input and the\ +overlay screen driver for output. None of the commands that use SD card files are present.\ +\ + +\b \ul Expressions +\b0 \ulnone \ +\ +SERIAL [ ]\ +\ +The parameter is a timeout in milliseconds. This returns the character received from the 19.2Kbps\ +serial interface or a -1 if the timeout occurs.\ +\ +SERCHK [ ]\ +\ +The parameter is a character. This searches the entire buffered serial input stream for the speciied\ +character and returns true (-1) if the character is present and false (0) otherwise. The serial buffer\ +is not changed.\ +\ +TIME [ ]\ +\ +If the value is between 0 and 6, this returns the binary value of the most recently read time unit\ +(0 - Seconds, 1 - Minutes, 2 - Hours, 3 - Day of Week, 4 - Day, 5 - Month, 6 - Year). If the value\ +is 7, this returns the control register value read from the DS1307. For values from 8 to 63, this\ +returns the value stored in the DS1307's RAM at that address.\ +\ +GPS [ ]\ +\ +If the value is negative, this returns the next character from the GPS serial buffer with the absolute\ +value of the expression used as a timeout in milliseconds. It returns a -1 if the timeout is exceeded.\ +If the value is positive, this returns a character from the saved GPS phrase whose index is the\ +value provided. It returns a -1 if the value is out of range or if there's no saved GPS phrase.\ +\ + +\b \ul Statements +\b0 \ulnone \ +\ +TIME\ +\ +This reads the current time from the DS1307 into an internal buffer used by TIME [ ].\ +\ +TIME [
] = \ +\ +This writes the expression on the right side of the "=" into the control register or RAM whose address\ +is given. Addresses less than 7 or greater than 63 are not allowed.\ +\ +TIME , , , , , , \ +\ +This writes the time / date indicated to the appropriate locations in the DS1307 clock. The values are\ +given in binary and are translated to BCD. The BCD values are also stored in the internal buffer\ +used by TIME [ ]. The BCD values are written to the DS1307 in a single operation.\ +\ +GPS\ +\ +This starts up a background routine (in a cog) that discards any buffered GPS phrase, then begins\ +discarding any buffered serial input up to the first "$" character which begins the next GPS phrase.\ +Characters are then stored in the internal GPS phrase buffer (used by GPS [ ]) until a "*" is\ +seen. The next two characters must be hexadecimal values which are used as a checksum for the\ +phrase. If the checksum is invalid, the phrase is discarded and the routine begins searching for the\ +next phrase. If this background routine is already active, it is stopped and any saved information\ +is discarded before starting it again. Once this background routine successfully finds a complete\ +GPS phrase, it stops itself.\ +} \ No newline at end of file diff --git a/system/regnatix/admtest.spin b/system/regnatix/admtest.spin new file mode 100644 index 0000000..e223330 Binary files /dev/null and b/system/regnatix/admtest.spin differ diff --git a/system/regnatix/basic.spin b/system/regnatix/basic.spin new file mode 100644 index 0000000..974028a Binary files /dev/null and b/system/regnatix/basic.spin differ diff --git a/system/regnatix/beltest.spin b/system/regnatix/beltest.spin new file mode 100644 index 0000000..e108395 Binary files /dev/null and b/system/regnatix/beltest.spin differ diff --git a/system/regnatix/charmap.spin b/system/regnatix/charmap.spin new file mode 100644 index 0000000..b432ce3 Binary files /dev/null and b/system/regnatix/charmap.spin differ diff --git a/system/regnatix/eram.spin b/system/regnatix/eram.spin new file mode 100644 index 0000000..b816e8c Binary files /dev/null and b/system/regnatix/eram.spin differ diff --git a/system/regnatix/eram.txt b/system/regnatix/eram.txt new file mode 100644 index 0000000..92024bf --- /dev/null +++ b/system/regnatix/eram.txt @@ -0,0 +1,33 @@ + +cls - bildschirm löschen +bye - player beenden +d - anzeige eram +n - anzeige fortsetzen +m ... - ram modifizieren (byte) +l ... - ram modifizieren (long) +load - ladei datei in eram +sysvar - anzeige systemvariablen +rbas - basisadresse setzen +info - speicheraufteilung anzeigen +f - speicherbereich füllen (sysmod) +fu - speicherbereich füllen (usermod) +xinit - rdisk initialisieren +xnew - neue datei anlegen +xhead - header anzeigen +xdir - dir anzeigen +xdel - datei löschen +xren - datei umbenennen +xftab - ftab anzeigen +xopen - datei öffnen +xseek - zeiger positionieren +xput - zeichen in datei schreiben +xget - zeichenh aus datei lesen +xwrite - wert schreiben +xread - wert lesen +xload - datei in rd laden +xsave - datei fn1 auf sd fn2 speichern + +bas - basisadresse +end - endadresse (startsysvar) +sys - start systemvariablen +rd: - daten datei diff --git a/system/regnatix/hplay.spin b/system/regnatix/hplay.spin new file mode 100644 index 0000000..3132192 Binary files /dev/null and b/system/regnatix/hplay.spin differ diff --git a/system/regnatix/hplay.txt b/system/regnatix/hplay.txt new file mode 100644 index 0000000..78a0da2 --- /dev/null +++ b/system/regnatix/hplay.txt @@ -0,0 +1,7 @@ +/? : hilfetext +/p name.wav : hss-datei abspielen +/d : verzeichnis abspielen +/s : wiedergabe stoppen +/t : anzeige trackerliste +/r : anzeige engine-register +/i : anzeige interface-register diff --git a/system/regnatix/ios.spin b/system/regnatix/ios.spin new file mode 100644 index 0000000..8e8baa3 Binary files /dev/null and b/system/regnatix/ios.spin differ diff --git a/system/regnatix/keycode.spin b/system/regnatix/keycode.spin new file mode 100644 index 0000000..ba3ae86 Binary files /dev/null and b/system/regnatix/keycode.spin differ diff --git a/system/regnatix/perplex.spin b/system/regnatix/perplex.spin new file mode 100644 index 0000000..90cdb8e Binary files /dev/null and b/system/regnatix/perplex.spin differ diff --git a/system/regnatix/perplex.txt b/system/regnatix/perplex.txt new file mode 100644 index 0000000..1ec44d1 --- /dev/null +++ b/system/regnatix/perplex.txt @@ -0,0 +1,7 @@ +open - plexus öffnen +close - plexus schliessen +put - zeichen zu plexus senden +get - zeichen von plexus empfangen +testout - werte an port ausgeben +testin - eingangswerte port anzeigen +scan - 0..anz plexus abfragen \ No newline at end of file diff --git a/system/regnatix/pterm.spin b/system/regnatix/pterm.spin new file mode 100644 index 0000000..a525a4b Binary files /dev/null and b/system/regnatix/pterm.spin differ diff --git a/system/regnatix/ramtest.spin b/system/regnatix/ramtest.spin new file mode 100644 index 0000000..b2ec4d2 Binary files /dev/null and b/system/regnatix/ramtest.spin differ diff --git a/system/regnatix/regime.spin b/system/regnatix/regime.spin new file mode 100644 index 0000000..4529811 Binary files /dev/null and b/system/regnatix/regime.spin differ diff --git a/system/regnatix/regime.txt b/system/regnatix/regime.txt new file mode 100644 index 0000000..17682c0 Binary files /dev/null and b/system/regnatix/regime.txt differ diff --git a/system/regnatix/sfxtool.spin b/system/regnatix/sfxtool.spin new file mode 100644 index 0000000..e223d21 Binary files /dev/null and b/system/regnatix/sfxtool.spin differ diff --git a/system/regnatix/splay.spin b/system/regnatix/splay.spin new file mode 100644 index 0000000..86b108d Binary files /dev/null and b/system/regnatix/splay.spin differ diff --git a/system/regnatix/splay.txt b/system/regnatix/splay.txt new file mode 100644 index 0000000..5f2eb23 --- /dev/null +++ b/system/regnatix/splay.txt @@ -0,0 +1,8 @@ +/? : Hilfetext +/m name.dmp : DMP-Datei mono auf SID2 abspielen +/s name.dmp : DMP-Datei stereo auf beiden SIDs abspielen +/d : Verzeichnis wiedergeben + q - quit + n - next + p - pause + diff --git a/system/regnatix/stringEngine.spin b/system/regnatix/stringEngine.spin new file mode 100644 index 0000000..acc112b Binary files /dev/null and b/system/regnatix/stringEngine.spin differ diff --git a/system/regnatix/sysconf.spin b/system/regnatix/sysconf.spin new file mode 100644 index 0000000..31c6162 Binary files /dev/null and b/system/regnatix/sysconf.spin differ diff --git a/system/regnatix/sysconf.txt b/system/regnatix/sysconf.txt new file mode 100644 index 0000000..484e2f7 --- /dev/null +++ b/system/regnatix/sysconf.txt @@ -0,0 +1,18 @@ +/? : Hilfe +/l : Konfiguration anzeigen +----------- Administra-Funktionen +/ah 0|1 : hss ab-/anschalten +/aw 0|1 : wav ab-/anschalten +/as 0|1 : systemklänge ab-/anschalten +/al 0..100 : wav-lautstärke links +/ar 0..100 : wav-lautstärke rechts +/ah 0..15 : hss-lautstärke +/af : administra reset, flash booten +/at : transfergeschwindigkeit messen +----------- Bellatrix-Funktionen +/ci : farbtabelle anzeigen +/cs datei : farbtabelle speichern +/cl datei : farbtabelle laden +----------- Port-Funktionen +/po nr anz : Impulse an port ausgeben +/pi : Status der Port abfragen \ No newline at end of file diff --git a/system/regnatix/wplay.spin b/system/regnatix/wplay.spin new file mode 100644 index 0000000..9586830 Binary files /dev/null and b/system/regnatix/wplay.spin differ diff --git a/system/regnatix/wplay.txt b/system/regnatix/wplay.txt new file mode 100644 index 0000000..d2301d9 --- /dev/null +++ b/system/regnatix/wplay.txt @@ -0,0 +1,9 @@ +/? : Hilfetext +/p name.wav : WAV-Datei abspielen +/d : Verzeichnis wiedergeben + q - quit + n - next + p - pause +/l 0..100 : Lautstärke links +/r 0..100 : Lautstärke rechts +/i name.wav : Info zur Datei anzeigen diff --git a/system/regnatix/yplay.spin b/system/regnatix/yplay.spin new file mode 100644 index 0000000..787086b Binary files /dev/null and b/system/regnatix/yplay.spin differ diff --git a/system/regnatix/yplay.txt b/system/regnatix/yplay.txt new file mode 100644 index 0000000..03f0d0d --- /dev/null +++ b/system/regnatix/yplay.txt @@ -0,0 +1,8 @@ +Wiedergabe von YM-Dateien mittels AY-3-891X / YM2149 emulator + +/? : Hilfetext +/p name.YM : YM-Datei abspielen +/d : Verzeichnis wiedergeben + q - quit + n - next + p - pause diff --git a/system/sonstiges/BLUE.COL b/system/sonstiges/BLUE.COL new file mode 100644 index 0000000..0d8d9d8 --- /dev/null +++ b/system/sonstiges/BLUE.COL @@ -0,0 +1 @@ +<<<<ððððÀÀÀÀ0000<<<<üüüüÿ€ÿ€ÿÿ€€ˆˆˆˆ \ No newline at end of file diff --git a/system/sonstiges/BW.COL b/system/sonstiges/BW.COL new file mode 100644 index 0000000..ecbace2 Binary files /dev/null and b/system/sonstiges/BW.COL differ diff --git a/system/sonstiges/BWHALF.COL b/system/sonstiges/BWHALF.COL new file mode 100644 index 0000000..d23a6fe Binary files /dev/null and b/system/sonstiges/BWHALF.COL differ diff --git a/system/sonstiges/CHESS.COL b/system/sonstiges/CHESS.COL new file mode 100644 index 0000000..1bd21ce Binary files /dev/null and b/system/sonstiges/CHESS.COL differ diff --git a/system/sonstiges/PAR.COL b/system/sonstiges/PAR.COL new file mode 100644 index 0000000..6ead846 Binary files /dev/null and b/system/sonstiges/PAR.COL differ diff --git a/system/sonstiges/regime.txt b/system/sonstiges/regime.txt new file mode 100644 index 0000000..17682c0 Binary files /dev/null and b/system/sonstiges/regime.txt differ diff --git a/system/sonstiges/test1.txt b/system/sonstiges/test1.txt new file mode 100644 index 0000000..15d01ca --- /dev/null +++ b/system/sonstiges/test1.txt @@ -0,0 +1,7 @@ + +"Die Blütenträume +Von Faltern, wie ich hörte, +So lautlos wie sie -" +Reikan + + diff --git a/system/sonstiges/test2.txt b/system/sonstiges/test2.txt new file mode 100644 index 0000000..72e62d4 --- /dev/null +++ b/system/sonstiges/test2.txt @@ -0,0 +1,115 @@ +Johann Wolfgang Goethe + +Der Zauberlehrling + +Hat der alte Hexenmeister +Sich doch einmal wegbegeben! +Und nun sollen seine Geister +Auch nach meinem Willen leben! +Seine Wort' und Werke +Merkt' ich und den Brauch, +Und mit Geistesstärke +Tu' ich Wunder auch. + +Walle! Walle +Manche Strecke, +Dass, zum Zwecke, +Wasser fließe +Und mit reichem, vollem Schwalle +Zu dem Bade sich ergieße. + +Und nun komm, du alter Besen! +Nimm die schlechten Lumpenhüllen! +Bist schon lange Knecht gewesen; +Nun erfülle meinen Willen! +Auf zwei Beinen stehe, +Oben sei ein Kopf, +Eile nun und gehe +Mit dem Wassertopf! + +Walle! Walle +Manche Strecke, +Dass, zum Zwecke, +Wasser fließe +Und mit reichem, vollem Schwalle +Zu dem Bade sich ergieße. + +Seht, er läuft zum Ufer nieder; +Wahrlich! ist schon an dem Flusse, +Und mit Blitzesschnelle wieder +Ist er hier mit raschem Gusse. +Schon zum zweiten Male! +Wie das Becken schwillt! +Wie sich jede Schale +Voll mit Wasser füllt! + +Stehe! Stehe! +Denn wir haben +Deiner Gaben +Voll gemessen! +Ach, ich merk' es! Wehe! Wehe! +Hab' ich doch das Wort vergessen! + +Ach, das Wort, worauf am Ende +Er das wird, was er gewesen. +Ach, er läuft und bringt behände! +Wärst du doch der alte Besen! +Immer neue Güsse +Bringt er schnell herein, +Ach! und hundert Flüsse +Stürzen auf mich ein. + +Nein, nicht länger +Kann ich's lassen; +Will ihn fassen. +Das ist Tücke! +Ach! nun wird mir immer bänger! +Welche Miene! Welche Blicke! + +Oh, du Ausgeburt der Hölle! +Soll das ganze Haus ersaufen? +Seh' ich über jede Schwelle +Doch schon Wasserströme laufen. +Ein verruchter Besen, +Der nicht hören will! +Stock, der du gewesen, +Steh doch wieder still! + +Willst's am Ende +Gar nicht lassen? +Will dich fassen, +Will dich halten +Und das alte Holz behände +Mit dem scharfen Beile spalten. + +Seht, da kommt er schleppend wieder! +Wie ich mich nun auf dich werfe, +Gleich, o Kobold, liegst du nieder; +Krachend trifft die glatte Schärfe! +Wahrlich, brav getroffen! +Seht, er ist entzwei! +Und nun kann ich hoffen +Und ich atme frei! + +Wehe! Wehe! +Beide Teile +Stehn in Eile +Schon als Knechte +Völlig fertig in die Höhe! +Helft mir, ach! ihr hohen Mächte! + +Und sie laufen! Nass und nässer +Wird's im Saal und auf den Stufen. +Welch entsetzliches Gewässer! +Herr und Meister! Hör' mich rufen! - +Ach, da kommt der Meister! +Herr, die Not ist groß! +Die ich rief, die Geister, +Werd' ich nun nicht los. + +In die Ecke, +Besen! Besen! +Seid's gewesen! +Denn als Geister +Ruft euch nur, zu seinem Zwecke, +Erst hervor der alte Meister." \ No newline at end of file diff --git a/zubehör/PropForth/PropForth.spin b/zubehör/PropForth/PropForth.spin new file mode 100644 index 0000000..67891cb --- /dev/null +++ b/zubehör/PropForth/PropForth.spin @@ -0,0 +1,6547 @@ + + +{{ + +Copyright (c) 2009 Sal Sanci + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + + +Yet Another Forth + +PropForth is built on SpinForth and is really rev 2 of SpinForth. There have been many changes. As opposed to describing +them all, suffice it to say PropForth is really tuned to freeing up as many cog longs as possible. Found this was the +resource that was of most limit. Of course this is always traded against performance, and the performance considered +was compile performance. + +This forth is case sensitive!!!!!! BIG CHANGE! + +By default there are now 161 longs free in the cog. The stacks are still in the cogs, and this takes up 64 longs, +32 for the data stack and 32 for the return stack. Found this tradeoff to be worth it. + +The core of function is kept small, and functions like debugging can be loaded in if they are needed. + +There is a forth time slicer available for background tasks, and it can respond to items that are need service +on the order of hundreds of milliseconds or more. + +It is a cooperative time slicer and works by long running routines calling _fslice. The forth kernel words +key? emit? all call _fslice. + +When PropForth starts, cog 0 is the spin cog which starts everything up, and then loads the serial driver (57.6Kb if you need +different modify in the main spin startup routine), in cog 7 and starts cog 6 as a PropForth cogs. + + +There is a coopreative time slicer for the assembler, aslicer. An example of this is the serial driver which +load into cog 7. aslicer slices up between forth, the bit receive, the bit transmit, and the circular buffer +manager for received characters. The forth slicer which runs, and monitors for CTLa, CTLb and CTLc. +Cog 7 still has juice left over! + +57.6K Baud is ok no delays necessary. + +THIS IS NOT AN ANSI FORTH! +It is a minimal forth tuned for the propeller. However most words adhere to the ANSI standard. + +Locks 0 - 1 are allocated by the spin startup code are by forth. +0 - the forth dictionary +1 - the eeprom + +Forth is a language which I like for microcontrollers. It is intended to allow interactive development +on the microcontroller. + +The Propeller architecture is different enough from the norm to require a slightly different Forth. +So this is uniquely developed for the propeller. If you don't like it, the source follows. Indulge yourself. + +Names are case unique in THIS forth, so aCount and acount are NOT the same, in this implementation the max +length for a name is 31 characters. Names are stored as a counted string. 1 byte for the length, and up to 31 bytes +for the name. The upper bits are used as follows. +$80 - 0 - this is an assembler word + 1 - this is a forth word +$40 - 0 - this is not an immediate word + 1 - this is an immediate word +$20 - 0 - do not execute in interactive mode if the immediate word flag is set + 1 - execute this word in intercactive mode if the immediate flag is set + +Be sure these flags are masked if you are manipulating names with the counted string routines. + +The cog memory is used for the assembler code and variables to run Forth, a 32 long stack, +and a 32 long return stack. There are about 160 free registers for code and data in each cog running forth. +Memory accesses in forth are ! (store) and @ (fetch). All memory access to the cog are long. They are done via ! and @ + +Naming conventions: + +cog: + a_xxx - a forth word, an address poiting to code which can be executed as forth word + c_xxx - cog code, point to code, but can not be executed as a forth word, for instance a subroutine + v_xxx - a cog long, points to a variable + +The execption to this is the special cog registers, which are named exactly as they are in the propeller +documentation. eg par, phsa, ctra, etc. + +Of course given the nature of self-modifying code, these names may be used otherwise + + +cogdata: + +Each cog has a 256 byte area assigned to it, and this area is used forth cog specific data. Though this are is in +main memory there is an agreed upon isolation. When a cog is started the par register points to this 256 byte area. + + +cogdata long mc ex mcCount (main cog) m! m@ + word mcw ex mcwCount (main cog word) w! w@ + char mcc ex mccCount (main cog char) c! c@ + + +The forth dictionary is stored in main memory and is shared. So updating the dictionary requires it be +locked so only one cog at a time can update the dictionary. Variables can be defined in the dictionary +or in the cog. + +In the cog, there is only a long variable. + +In main memory, variables can be a long (32 bits), a word (16 bits). The most efficient +are words. This forth is implemented using words. Longs need to be long aligned and can waste bytes. + + +main memory: + +Main memory can be accessed as a long, m! m@, a word, w! w@, and as a character c! c@ , + +There is an area of main memory reserved for each cog, the cogdata area. The PAR register is +initialized with the start of the 256 bytes allocated to each cog. This area is where IO communcation is done, +and system variables for each cog are stored. + +Naming convention: +cog long a ex aCount ! @ + +cogdata long mc ex mcCount (main cog) m! m@ + word mcw ex mcwCount (main cog word) w! w@ + char mcc ex mccCount (main cog char) c! c@ + +dictionary long ms ex msCount (main shared) m! m@ + word msw ex mswCount (main shared word) w! w@ + char msc ex mscCount (main shared char) c! c@ + +This is done to clearly differentiate how a variable should be accessed. Strange bugs happen if these are +confused and the naming convention helps. + +There is stack and return stack checking for overflow and underflow. +For the stack, this only occurs on words which access more then the top item on the stack. +So using c@ with an empty stack will return a value and not trigger stack checking. However +c! with an empty stack will trigger a stack underflow. +Trade between size performance and error checking, seemed reasonable. + + +2009 AUG 14, on vacation had time for a few changes. The assembler divide is now a 64bit divided by 32 bits and +yields a 32 bit result and remainder. Very useful in conjuction with the 64 bit multiply, allows scaling of counter +values easily. + +Added underflow/overflow detection, useful for understanding what is going on. Fixed a few minor bugs. + + +}} +CON + + _clkmode = xtal1 + pll16x + _xinfreq = 5_000_000 + _cogDataSize = 256 + _wordMASK = $FFFF + _buffer_length = 256 'can be 2, 4, 8, 16, 32, 64, 128, 256 + _buffer_mask = _buffer_length - 1 + +VAR + +OBJ + +PUB Main | key +{{ +Start the serial port rx pin - 31, tx pin - 30, 115KBaud +If ok start forth, providing we can can a lock resource +}} + key := locknew + key := locknew + stPtr := ((@stTop - @a_base) /4) - 1 ' and initialize values for forth + rsPtr := ((@rsTop - @a_base) /4) - 1 + IP := WORD[ @cm_fstartPFA + 2] + WORD[ @mswDictendPFA + 2] := @ForthDictEnd + WORD[ @mswMemendPFA + 2] := @ForthMemoryEnd + WORD[ @ffcogPFA + 2] := 6 + WORD[ @lfcogPFA + 2] := 6 + v_bitticks := clkfreq / 57600 + v_rxmask := 1 << 31 + v_txmask := 1 << 30 + v_rxbuff := @serentryPFA + v_in := @inCONPFA + 2 + v_out := @outCONPFA + 2 + coginit(7, @serentryPFA, @cogdataPFA + (7 * _cogDataSize)) + coginit(6, @entryPFA, @cogdataPFA + (6 * _cogDataSize)) +{{ + Stop cog zero, or comment this out to keep spin running +}} + cogstop( 0) +DAT + +'*********************************** +'* Assembly language serial driver * +'*********************************** + + org 0 +' +' +' Entry +' +serentryPFA + mov task1Ptr,#transmit + mov task2Ptr,#task2Code + or dira , v_txmask +' +' Receive +' +receive jmpret task0Ptr, task1Ptr 'run a chunk of transmit code, then return + + test v_rxmask , ina wz + if_nz jmp # receive + + mov rxbits , # 9 'ready to receive byte + mov rxcnt , v_bitticks + mov rxcnt , cnt '+ the current clock + +:bit add rxcnt , v_bitticks 'ready for the middle of the bit period + +:wait jmpret task0Ptr, task1Ptr 'run a chuck of transmit code, then return + + mov t1 , rxcnt 'check if bit receive period done + sub t1 , cnt + cmps t1 , # 0 wc + if_nc jmp #:wait + + test v_rxmask , ina wc 'receive bit on rx pin into carry + rcr rxdata , # 1 'shift carry into receiver + djnz rxbits , # :bit 'go get another bit till done + + if_nc jmp # receive 'abort if no stop bit + + shr rxdata , # 32-9 'justify and trim received byte + and rxdata , # $FF + + add v_rxh , v_rxbuff 'plus the buffer offset + wrbyte rxdata , v_rxh 'write the byte + sub v_rxh , v_rxbuff + add v_rxh ,# 1 'update rx_head + and v_rxh , # _buffer_mask + + jmp # receive 'byte done, receive next byte +' +' +' Transmit +' +transmit jmpret task1Ptr, task2Ptr 'run a chunk of receive code, then return + rdword txdata, v_in + test txdata, #$100 wz + if_nz jmp #transmit + mov t1 , #$100 + wrword t1 , v_in + + or txdata,#$100 'or in a stop bit + shl txdata,#2 + or txdata,#1 'or in a idle line state and a start bit + mov txbits,#11 + mov txcnt,cnt + +:bit shr txdata,#1 wc + muxc outa , v_txmask + add txcnt , v_bitticks 'ready next cnt + +:wait jmpret task1Ptr, task2Ptr 'run a chunk of receive code, then return + + mov t1,txcnt 'check if bit transmit period done + sub t1,cnt + cmps t1,#0 wc + if_nc jmp #:wait + + djnz txbits,#:bit 'another bit to transmit? + + jmp #transmit 'byte done, transmit next byte + +task2Code + jmpret task2Ptr, task0Ptr + cmp v_rxh , v_rxt wz + if_z jmp #task2Code + mov t1 , v_out + rdword t2 , t1 wz + if_nz rdword t3 , t2 + if_nz test t3 , # $100 wz + if_z jmp #task2Code + + add v_rxt , v_rxbuff 'plus the buffer offset + rdbyte t3 , v_rxt 'write the byte + sub v_rxt , v_rxbuff + add v_rxt ,# 1 + wrword t3 , t2 'update rx_head + and v_rxt , # _buffer_mask + jmp #task2Code + +v_rxh long 0 +v_rxt long 0 +v_bitticks long 0 +v_rxmask long 0 +v_txmask long 0 +v_rxbuff long 0 +v_in long 0 +v_out long 0 +' +' Uninitialized data +' + +task0Ptr res 1 +task1Ptr res 1 +task2Ptr res 1 +t1 res 1 +t2 res 1 +t3 res 1 + +rxdata res 1 +rxbits res 1 +rxcnt res 1 + + +txbuff res 1 +txdata res 1 +txbits res 1 +txcnt res 1 + + +a_base + org 0 +{{ + +Assembler Code +entry - abs is effectively a nop on stTOS initialized to zero + +Assembler routines which correspond to forth words are documented in the forth area + +}} +entryPFA + + jmp #a_next +a_ifunc + rdword treg1, IP + movi a_ifunci, treg1 + add IP, #2 + call #a_stpoptreg +a_ifunci + and stTOS, treg1 + jmp #a_next + +a_ifuncone + rdword treg1, IP + movi a_ifunc1i, treg1 + add IP, #2 +a_ifunc1i + abs stTOS, stTOS + jmp #a_next + +a_ifunctwo + rdword treg1, IP + movi a_ifunc2i, treg1 + add IP, #2 + call #a_stpoptreg +a_ifunc2i + abs stTOS, treg1 +a_drop + call #a_stPop + jmp #a_next + +a_at + movs a_atget, stTOS + nop ' necessary, really needs to be documented +a_atget mov stTOS, stTOS + jmp #a_next +a_bang + movd a_bangput, stTOS + call #a_stPop +a_bangput mov stTOS, stTOS + jmp #a_drop +a_branch + rdword treg1,IP ' the next word + add IP, treg1 ' add the offset + and IP , fAddrMask + jmp #a_next +a_doconw + call #a_stPush + rdword stTOS, IP + jmp #a_exit +a_dovar + add IP, #3 + andn IP, #3 ' align to a long boundary +a_dovarw + call #a_stPush + mov stTOS, IP + jmp #a_exit +a_literal + call #a_stPush + add IP, #3 + andn IP, #3 ' align to a long boundary + rdlong stTOS, IP + add IP, #4 + jmp #a_next +a_docon + call #a_stPush + add IP, #3 + andn IP, #3 ' align to a long boundary + rdlong stTOS, IP + jmp #a_exit +a_dup + call #a_stPush + jmp #a_next + +' treg1 - cstr2 (name) +' stTOS - cstr1 (name) +' uses treg2, treg4, and treg5 +' z flag set if strings are equal + +c_streq +c_streq5 + mov treg4 , # $1F +' length of cstr2 (name) + rdbyte treg2 , treg1 wz +' length of cstr2 (name) - truncate to appropriate length + if_nz and treg2 , treg4 wz +' length of cstr1 (name) + if_nz rdbyte treg5 , stTOS wz +' length of cstr1 (name) - truncate to appropriate length + if_nz and treg5 , treg4 wz +' if either length is 0, move -1 into length of cstr1 to cause a mismatch + if_z mov treg5 , fLongMask + cmp treg2 , treg5 wz + if_nz jmp # c_streq7 +a_cstreqloop + add stTOS , # 1 + rdbyte treg4 , stTOS + add treg1 , # 1 +a_cstreqlp + if_never jmpret a_stPop_ret, # a_stPop_ret ' when task manager is loaded these addresses wil be patched + rdbyte treg5 , treg1 + cmp treg4 , treg5 wz + if_z djnz treg2 , # a_cstreqloop +c_streq7 +c_streq_ret + ret + +' a_nameeq (name name -- t/f) +a_nameeq + movs c_streq5 , # $1F + jmp # a_nameeq4 +' a_cstreq (cstr1 cstr2 -- t/f) +a_cstreq + movs c_streq5 , # $FF +a_nameeq4 + call #a_stpoptreg +' treg1 - cstr2 +' stTOS - dict cstr1 + jmpret c_streq_ret , # c_streq + muxz stTOS , fLongMask + jmp # a_next + +a_fin + call #a_stpoptreg + mov treg6 , treg1 + mov treg3 , stTOS + movs c_streq5 , # $1F +' treg6 - cstr +' treg3 - nfa +a_finlp + if_never jmpret a_stPop_ret, # a_stPop_ret ' when task manager is loaded these addresses wil be patched +' treg1 - nfa +' stTOS - cstr + mov treg1 , treg6 + mov stTOS , treg3 + jmpret c_streq_ret , # c_streq + if_nz jmp # a_fin2 +a_fin1 + mov stTOS , treg3 + jmp # a_next +a_fin2 + mov treg2 , treg3 + sub treg2 , # 2 + rdword treg3 , treg2 wz + if_z jmp # a_fin1 + jmp # a_finlp + +a_eq + call #a_stpoptreg + cmp treg1, stTOS wz, wc + muxz stTOS, fLongMask + jmp #a_next +a_gt + '( n1 n2 -- flag ) + call #a_stpoptreg ' flag is true if and only if n1 is greater than n2 + cmps stTOS, treg1 wz, wc + if_a neg stTOS, #1 + if_be mov stTOS, #0 + jmp #a_next +a_hubop + call #a_stpoptreg + hubop stTOS, treg1 wr,wc + muxc treg1, fLongMask + call #a_stPush + mov stTOS, treg1 + jmp #a_next +a_litw + call #a_stPush + rdword stTOS, IP +a_litw1 + add IP, #2 + jmp #a_next +a_lt + '( n1 n2 -- flag ) + call #a_stpoptreg ' flag is true if and only if n1 is less than n2 + cmps stTOS, treg1 wz, wc + if_b neg stTOS, #1 + if_ae mov stTOS, #0 + jmp #a_next +a_exit + call #a_rsPop + mov IP, treg5 +' jmp #a_next SINCE WE ARE ALREADY THERE +a_next + if_never jmpret a_stPop_ret, # a_stPop_ret ' when task manager is loaded these addresses wil be patched +a_debugonoff + if_never jmpret a_dum_ret, # a_dum ' when debug is loaded this address will be patched + + rdword treg1,IP ' the next word + test treg1, fMask wz + if_z add IP, #2 ' if the one of the hi bits is not set, it is an assembler word, inc IP + if_z jmp treg1 + rdword treg1, IP ' otherwise it is a forth word + mov treg5, IP + add treg5, #2 + mov IP, treg1 + call #a_rsPush + jmp #a_next +a_over + call #a_stpoptreg + mov treg2, stTOS + call #a_stPush + mov stTOS, treg1 + call #a_stPush + mov stTOS, treg2 + jmp #a_next +a_mpx + and stTOS, ina wz + muxnz stTOS, fLongMask + jmp # a_next + +a_mpxh + jmp # a_mpxex wz + +a_mpxl + test stTOS, #0 wz +a_mpxex + muxnz outa, stTOS + jmp # a_drop + +a_rot + call #a_stpoptreg + mov treg2, stTOS + call #a_stPop + mov treg3, stTOS + + mov stTOS, treg2 + call #a_stPush + mov stTOS, treg1 + call #a_stPush + mov stTOS, treg3 + jmp #a_next +a_rgt + call #a_rsPop + call #a_stPush + mov stTOS, treg5 + jmp #a_next +a_twogtr + mov treg5, stTOS + call #a_stPop + call #a_rsPush +a_gtr + mov treg5, stTOS + call #a_stPop + call #a_rsPush + jmp #a_next +a_lparenlooprparen + mov treg1, #1 + jmp #a_lparenpluslooprparen1 +a_lparenpluslooprparen + call #a_stpoptreg +a_lparenpluslooprparen1 + call #a_rsPop + mov treg2, treg5 + call #a_rsPop + add treg5, treg1 + cmp treg2, treg5 wc ,wz + if_a call #a_rsPush ' branch + if_a mov treg5, treg2 ' branch + if_a call #a_rsPush ' branch + if_a jmp #a_branch + jmp #a_litw1 + +a_swap + call #a_stpoptreg + mov treg2, stTOS + mov stTOS, treg1 + call #a_stPush + mov stTOS, treg2 + jmp #a_next + +a_umstar + call #a_stpoptreg + mov treg4, #0 + mov treg2, #0 + mov treg3, #0 +a_umstarlp + if_never jmpret a_stPop_ret, # a_stPop_ret ' when task manager is loaded these addresses wil be patched + shr stTOS, #1 wz,wc + if_nc jmp #a_umstar1 + add treg4, treg1 wc + addx treg2, treg3 +a_umstar1 + shl treg1, #1 wc + rcl treg3, #1 + if_nz jmp #a_umstarlp + mov stTOS, treg4 + call #a_stPush + mov stTOS, treg2 + jmp #a_next +a_umslashmod + call #a_stpoptreg + mov treg6, stTOS + call #a_stPop + mov treg3, #$40 + mov treg2, #0 +a_umslashmodlp + if_never jmpret a_stPop_ret, # a_stPop_ret ' when task manager is loaded these addresses wil be patched + shl stTOS, #1 wc ' dividend + rcl treg6, #1 wc + + rcl treg2, #1 wc ' hi bit from dividend + + if_c sub treg2, treg1 + if_nc cmpsub treg2, treg1 wc ' cmp divisor + + rcl treg4, #1 ' treg1 - quotient + djnz treg3, #a_umslashmodlp + mov stTOS, treg2 + call #a_stPush + mov stTOS, treg4 + jmp #a_next +a_zbranch + call #a_stpoptreg + cmp treg1, #0 wz ' is the TOS zero? + if_z jmp #a_branch + jmp #a_litw1 + +a_reset + if_never jmpret a_stPop_ret, # a_stPop_ret ' when task manager is loaded these addresses will be patched + wrlong fLongMask , par + wrword treg6 , par + coginit resetDreg + +{{ + +a_stPush - push stTOS on to stack + +}} +a_stPush + if_never jmpret a_stPop_ret, # a_stPop_ret ' when task manager is loaded these addresses wil be patched + movd a_stPush1, stPtr + cmp stPtr, #stBot wc + if_b mov treg6 , # $11 + if_b jmp # a_reset +a_stPush1 mov stPtr, stTOS + sub stPtr, #1 +a_stPush_ret + ret +{{ + +a_rsPush - push treg5 on to return stack + +}} +a_rsPush + if_never jmpret a_stPop_ret, # a_stPop_ret ' when task manager is loaded these addresses wil be patched + movd a_rsPush1, rsPtr + cmp rsPtr, #rsBot wc + if_b mov treg6 , # $12 + if_b jmp # a_reset +a_rsPush1 mov treg1, treg5 + sub rsPtr, #1 +a_rsPush_ret + ret + +{{ + +a_stpoptreg - move stTOS to treg1, and pop stTOS from stack + +}} +a_stpoptreg + mov treg1, stTOS +{{ + +a_stPop - pop stTOS from stack + +}} +a_stPop + if_never jmpret a_stPop_ret, # a_stPop_ret ' when task manager is loaded these addresses wil be patched + add stPtr, #1 + movs a_stPop1, stPtr + cmp stPtr, #stTop wc,wz + if_ae mov treg6 , # $21 + if_ae jmp # a_reset +a_stPop1 mov stTOS, stPtr +a_stPop_ret +a_stpoptreg_ret + ret + +{{ + +a_rsPop - pop treg5 from return stack + +}} +a_rsPop + if_never jmpret a_stPop_ret, # a_stPop_ret ' when task manager is loaded these addresses wil be patched + add rsPtr, #1 + movs a_rsPop1, rsPtr + cmp rsPtr, #rsTop wc,wz + if_ae mov treg6 , # $22 + if_ae jmp # a_reset +a_rsPop1 +a_dum + mov treg5, treg1 +a_dum_ret +a_rsPop_ret + ret + + +' +' variables used by the forth interpreter, do not change the order or size -- or if you do, be really careful and update the forth code +' +varStart +fMask long $FE00 ' 0 +fAddrMask long $7FFF ' 1 +fLongMask long $FFFFFFFF ' 2 +resetDreg long 0 ' 3 +IP long 0 ' 4 +stPtr long 0 ' 5 +rsPtr long 0 ' 6 +stTOS long 0 ' 7 + +treg1 long 0 ' 8 working reg +treg2 long 0 ' 9 working reg +treg3 long 0 ' a working reg +treg4 long 0 ' b working reg +treg5 long 0 ' c working reg / call parameter reg +treg6 long 0 ' d working reg +stBot ' e +{{ +These variables are overlapped with the cog data area variables to save space +}} +cogdataPFA + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 ' e + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 ' 1e +stTop ' 2e +rsBot + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 ' 2e + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 ' 3e +rsTop ' 4e + + +varEnd + +{{ + +cogdata + +This data area is used for 2 purposes. +The first is for inByte, outByte, debugCmd and debugValue - these are used to commincate with the spin program +which routes IO to/from the serial port. They can also be used between forths running on different cogs. + +The second purpose is for variables which are unique to each instance of forth, like >in, pad, etc... + +Variables can be defined here for each forth or in cog memory. Since cog memory is at a premium, "slow" variables +are defined here. + +}} +'cogdataPFA long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 ' 256 bytes cog 0 +' long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 +' long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 +' long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 ' 256 bytes cog 1 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 ' 256 bytes cog 2 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 ' 256 bytes cog 3 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 ' 256 bytes cog 4 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 ' 256 bytes cog 5 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 ' 256 bytes cog 6 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 ' 256 bytes cog 7 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 +{{ + +Start of the Forth Dicitonary + +Dictionary Entry Structure + - there is no code pointer, it is inherent +LinkField - points to the previous name field in the dictionary + word +NameField + byte - length of the name field (lo 5 bits) + - bit 7 ($80) set if it is a forth word + - bit 6 ($40) set if it is an immediate word + - bit 4 ($20) set if it is an eXecute word - execute this word in interactive mode as well + if the immediate flag is set + bytes - the actual name + - if the name is a word constant, and it starts with ca_ the spinMaker assumes it to be a reference to the cog data + space and sets the constant to be (name - a_base) /4. If it starts with cm_ it is assumed to be a main memory + reference and the constant is set to be namePFA +$10 (SPIN BUG? requires the +$10) + if the name is an assembler word the address is set to (a_name - a_base)/4 assembler names are not constants, they + are a different type of dictionary entry + +ParameterField - the list of addresses to execute, and literals for a forth word + - if it is a forth word one ofthe hi bit ($FE00) will be set + - assembler addresses are always < 512 + - this of course means that the ForthDictStart must have at least 512 bytes used before it, since this is only + 128 longs, and the assembler code, and forth stacks are before this, this is not an issue + - if it is an assembler word there is only 1 word and it is the assembler address + + +Generated form forth code from here on in - written in forth spin generated +*************************************************************************************************************** +*************************************************************************************************************** +*************************************************************************************************************** +}} + +ForthDictStart + + word 0 +mswHereNFA byte $87,"mswHere" +mswHerePFA word (@a_dovarw - @a_base)/4 + word $0000 + + word @mswHereNFA + $10 +mswDictendNFA byte $8A,"mswDictend" +mswDictendPFA word (@a_dovarw - @a_base)/4 + word $7FFF + + word @mswDictendNFA + $10 +mswMemendNFA byte $89,"mswMemend" +mswMemendPFA word (@a_dovarw - @a_base)/4 + word $7FFF + + word @mswMemendNFA + $10 +vxcogNFA byte $85,"vxcog" +vxcogPFA word (@a_dovarw - @a_base)/4 + word $FFFF + + word @vxcogNFA + $10 +ffcogNFA byte $85,"ffcog" +ffcogPFA word (@a_dovarw - @a_base)/4 + word $0005 + + word @ffcogNFA + $10 +lfcogNFA byte $85,"lfcog" +lfcogPFA word (@a_dovarw - @a_base)/4 + word $0006 + + word @lfcogNFA + $10 +cm_serentryNFA byte $8B,"cm_serentry" +cm_serentryPFA word (@a_doconw - @a_base)/4 + word @serentryPFA + $10 + + word @cm_serentryNFA + $10 +cm_entryNFA byte $88,"cm_entry" +cm_entryPFA word (@a_doconw - @a_base)/4 + word @entryPFA + $10 + + word @cm_entryNFA + $10 +cm_cogdataNFA byte $8A,"cm_cogdata" +cm_cogdataPFA word (@a_doconw - @a_base)/4 + word @cogdataPFA + $10 + + word @cm_cogdataNFA + $10 +cm_cqNFA byte $85,"cm_cq" +cm_cqPFA word (@a_doconw - @a_base)/4 + word @cqPFA + $10 + + word @cm_cqNFA + $10 +cm_dqNFA byte $85,"cm_dq" +cm_dqPFA word (@a_doconw - @a_base)/4 + word @dqPFA + $10 + + word @cm_dqNFA + $10 +ca_a_exitNFA byte $89,"ca_a_exit" +ca_a_exitPFA word (@a_doconw - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @ca_a_exitNFA + $10 +ca_a_dovarwNFA byte $8B,"ca_a_dovarw" +ca_a_dovarwPFA word (@a_doconw - @a_base)/4 + word (@a_dovarw - @a_base)/4 + + word @ca_a_dovarwNFA + $10 +ca_a_doconwNFA byte $8B,"ca_a_doconw" +ca_a_doconwPFA word (@a_doconw - @a_base)/4 + word (@a_doconw - @a_base)/4 + + word @ca_a_doconwNFA + $10 +ca_a_branchNFA byte $8B,"ca_a_branch" +ca_a_branchPFA word (@a_doconw - @a_base)/4 + word (@a_branch - @a_base)/4 + + word @ca_a_branchNFA + $10 +ca_a_litwNFA byte $89,"ca_a_litw" +ca_a_litwPFA word (@a_doconw - @a_base)/4 + word (@a_litw - @a_base)/4 + + word @ca_a_litwNFA + $10 +ca_a_twogtrNFA byte $88,"ca_a_2>r" +ca_a_twogtrPFA word (@a_doconw - @a_base)/4 + word (@a_twogtr - @a_base)/4 + + word @ca_a_twogtrNFA + $10 +ca_a_lparenlooprparenNFA byte $8B,"ca_a_(loop)" +ca_a_lparenlooprparenPFA word (@a_doconw - @a_base)/4 + word (@a_lparenlooprparen - @a_base)/4 + + word @ca_a_lparenlooprparenNFA + $10 +ca_a_lparenpluslooprparenNFA byte $8C,"ca_a_(+loop)" +ca_a_lparenpluslooprparenPFA word (@a_doconw - @a_base)/4 + word (@a_lparenpluslooprparen - @a_base)/4 + + word @ca_a_lparenpluslooprparenNFA + $10 +ca_a_zbranchNFA byte $8C,"ca_a_0branch" +ca_a_zbranchPFA word (@a_doconw - @a_base)/4 + word (@a_zbranch - @a_base)/4 + + word @ca_a_zbranchNFA + $10 +ca_a_dovarNFA byte $8A,"ca_a_dovar" +ca_a_dovarPFA word (@a_doconw - @a_base)/4 + word (@a_dovar - @a_base)/4 + + word @ca_a_dovarNFA + $10 +ca_a_doconNFA byte $8A,"ca_a_docon" +ca_a_doconPFA word (@a_doconw - @a_base)/4 + word (@a_docon - @a_base)/4 + + word @ca_a_doconNFA + $10 +ca_a_literalNFA byte $8C,"ca_a_literal" +ca_a_literalPFA word (@a_doconw - @a_base)/4 + word (@a_literal - @a_base)/4 + + word @ca_a_literalNFA + $10 +ca_a_debugonoffNFA byte $8F,"ca_a_debugonoff" +ca_a_debugonoffPFA word (@a_doconw - @a_base)/4 + word (@a_debugonoff - @a_base)/4 + + word @ca_a_debugonoffNFA + $10 +ca_a_resetNFA byte $8A,"ca_a_reset" +ca_a_resetPFA word (@a_doconw - @a_base)/4 + word (@a_reset - @a_base)/4 + + word @ca_a_resetNFA + $10 +ca_a_ifuncNFA byte $8A,"ca_a_ifunc" +ca_a_ifuncPFA word (@a_doconw - @a_base)/4 + word (@a_ifunc - @a_base)/4 + + word @ca_a_ifuncNFA + $10 +ca_a_ifunconeNFA byte $8B,"ca_a_ifunc1" +ca_a_ifunconePFA word (@a_doconw - @a_base)/4 + word (@a_ifuncone - @a_base)/4 + + word @ca_a_ifunconeNFA + $10 +ca_a_ifunctwoNFA byte $8B,"ca_a_ifunc2" +ca_a_ifunctwoPFA word (@a_doconw - @a_base)/4 + word (@a_ifunctwo - @a_base)/4 + + word @ca_a_ifunctwoNFA + $10 +ca_a_umstarlpNFA byte $8D,"ca_a_umstarlp" +ca_a_umstarlpPFA word (@a_doconw - @a_base)/4 + word (@a_umstarlp - @a_base)/4 + + word @ca_a_umstarlpNFA + $10 +ca_a_umslashmodlpNFA byte $91,"ca_a_umslashmodlp" +ca_a_umslashmodlpPFA word (@a_doconw - @a_base)/4 + word (@a_umslashmodlp - @a_base)/4 + + word @ca_a_umslashmodlpNFA + $10 +ca_a_cstreqlpNFA byte $8D,"ca_a_cstreqlp" +ca_a_cstreqlpPFA word (@a_doconw - @a_base)/4 + word (@a_cstreqlp - @a_base)/4 + + word @ca_a_cstreqlpNFA + $10 +ca_a_finlpNFA byte $8A,"ca_a_finlp" +ca_a_finlpPFA word (@a_doconw - @a_base)/4 + word (@a_finlp - @a_base)/4 + + word @ca_a_finlpNFA + $10 +ca_a_stPushNFA byte $8B,"ca_a_stPush" +ca_a_stPushPFA word (@a_doconw - @a_base)/4 + word (@a_stPush - @a_base)/4 + + word @ca_a_stPushNFA + $10 +ca_a_stPush_retNFA byte $8F,"ca_a_stPush_ret" +ca_a_stPush_retPFA word (@a_doconw - @a_base)/4 + word (@a_stPush_ret - @a_base)/4 + + word @ca_a_stPush_retNFA + $10 +ca_a_rsPushNFA byte $8B,"ca_a_rsPush" +ca_a_rsPushPFA word (@a_doconw - @a_base)/4 + word (@a_rsPush - @a_base)/4 + + word @ca_a_rsPushNFA + $10 +ca_a_rsPush_retNFA byte $8F,"ca_a_rsPush_ret" +ca_a_rsPush_retPFA word (@a_doconw - @a_base)/4 + word (@a_rsPush_ret - @a_base)/4 + + word @ca_a_rsPush_retNFA + $10 +ca_a_stPopNFA byte $8A,"ca_a_stPop" +ca_a_stPopPFA word (@a_doconw - @a_base)/4 + word (@a_stPop - @a_base)/4 + + word @ca_a_stPopNFA + $10 +ca_a_stPoptregNFA byte $8E,"ca_a_stPoptreg" +ca_a_stPoptregPFA word (@a_doconw - @a_base)/4 + word (@a_stPoptreg - @a_base)/4 + + word @ca_a_stPoptregNFA + $10 +ca_a_stPop_retNFA byte $8E,"ca_a_stPop_ret" +ca_a_stPop_retPFA word (@a_doconw - @a_base)/4 + word (@a_stPop_ret - @a_base)/4 + + word @ca_a_stPop_retNFA + $10 +ca_a_stPoptreg_retNFA byte $92,"ca_a_stPoptreg_ret" +ca_a_stPoptreg_retPFA word (@a_doconw - @a_base)/4 + word (@a_stPoptreg_ret - @a_base)/4 + + word @ca_a_stPoptreg_retNFA + $10 +ca_a_rsPopNFA byte $8A,"ca_a_rsPop" +ca_a_rsPopPFA word (@a_doconw - @a_base)/4 + word (@a_rsPop - @a_base)/4 + + word @ca_a_rsPopNFA + $10 +ca_a_rsPop_retNFA byte $8E,"ca_a_rsPop_ret" +ca_a_rsPop_retPFA word (@a_doconw - @a_base)/4 + word (@a_rsPop_ret - @a_base)/4 + + word @ca_a_rsPop_retNFA + $10 +ca_a_nextNFA byte $89,"ca_a_next" +ca_a_nextPFA word (@a_doconw - @a_base)/4 + word (@a_next - @a_base)/4 + + word @ca_a_nextNFA + $10 +ca_varStartNFA byte $8B,"ca_varStart" +ca_varStartPFA word (@a_doconw - @a_base)/4 + word (@varStart - @a_base)/4 + + word @ca_varStartNFA + $10 +ca_varEndNFA byte $89,"ca_varEnd" +ca_varEndPFA word (@a_doconw - @a_base)/4 + word (@varEnd - @a_base)/4 + + word @ca_varEndNFA + $10 +_cvNFA byte $83,"_cv" +_cvPFA word @ca_varStartPFA + $10 + word @plusPFA + $10 + word (@a_exit - @a_base)/4 + + word @_cvNFA + $10 +fMaskNFA byte $85,"fMask" +fMaskPFA word @zPFA + $10 + word @_cvPFA + $10 + word (@a_exit - @a_base)/4 + + word @fMaskNFA + $10 +fAddrMaskNFA byte $89,"fAddrMask" +fAddrMaskPFA word (@a_litw - @a_base)/4 + word $0001 + word @_cvPFA + $10 + word (@a_exit - @a_base)/4 + + word @fAddrMaskNFA + $10 +fLongMaskNFA byte $89,"fLongMask" +fLongMaskPFA word (@a_litw - @a_base)/4 + word $0002 + word @_cvPFA + $10 + word (@a_exit - @a_base)/4 + + word @fLongMaskNFA + $10 +resetDregNFA byte $89,"resetDreg" +resetDregPFA word (@a_litw - @a_base)/4 + word $0003 + word @_cvPFA + $10 + word (@a_exit - @a_base)/4 + + word @resetDregNFA + $10 +IPNFA byte $82,"IP" +IPPFA word (@a_litw - @a_base)/4 + word $0004 + word @_cvPFA + $10 + word (@a_exit - @a_base)/4 + + word @IPNFA + $10 +stPtrNFA byte $85,"stPtr" +stPtrPFA word (@a_litw - @a_base)/4 + word $0005 + word @_cvPFA + $10 + word (@a_exit - @a_base)/4 + + word @stPtrNFA + $10 +rsPtrNFA byte $85,"rsPtr" +rsPtrPFA word (@a_litw - @a_base)/4 + word $0006 + word @_cvPFA + $10 + word (@a_exit - @a_base)/4 + + word @rsPtrNFA + $10 +stTOSNFA byte $85,"stTOS" +stTOSPFA word (@a_litw - @a_base)/4 + word $0007 + word @_cvPFA + $10 + word (@a_exit - @a_base)/4 + + word @stTOSNFA + $10 +tregoneNFA byte $85,"treg1" +tregonePFA word (@a_litw - @a_base)/4 + word $0008 + word @_cvPFA + $10 + word (@a_exit - @a_base)/4 + + word @tregoneNFA + $10 +stBotNFA byte $85,"stBot" +stBotPFA word (@a_litw - @a_base)/4 + word $000E + word @_cvPFA + $10 + word (@a_exit - @a_base)/4 + + word @stBotNFA + $10 +stTopNFA byte $85,"stTop" +stTopPFA word (@a_litw - @a_base)/4 + word $002E + word @_cvPFA + $10 + word (@a_exit - @a_base)/4 + + word @stTopNFA + $10 +rsBotNFA byte $85,"rsBot" +rsBotPFA word @stTopPFA + $10 + word (@a_exit - @a_base)/4 + + word @rsBotNFA + $10 +rsTopNFA byte $85,"rsTop" +rsTopPFA word (@a_litw - @a_base)/4 + word $004E + word @_cvPFA + $10 + word (@a_exit - @a_base)/4 + + word @rsTopNFA + $10 +blNFA byte $82,"bl" +blPFA word (@a_doconw - @a_base)/4 + word $0020 + + word @blNFA + $10 +minusoneNFA byte $82,"-1" +minusonePFA word (@a_docon - @a_base)/4 + long $FFFFFFFF + + word @minusoneNFA + $10 +zNFA byte $81,"0" +zPFA word (@a_doconw - @a_base)/4 + word $0000 + + word @zNFA + $10 +parNFA byte $83,"par" +parPFA word (@a_doconw - @a_base)/4 + word $01F0 + + word @parNFA + $10 +cntNFA byte $83,"cnt" +cntPFA word (@a_doconw - @a_base)/4 + word $01F1 + + word @cntNFA + $10 +inaNFA byte $83,"ina" +inaPFA word (@a_doconw - @a_base)/4 + word $01F2 + + word @inaNFA + $10 +outaNFA byte $84,"outa" +outaPFA word (@a_doconw - @a_base)/4 + word $01F4 + + word @outaNFA + $10 +diraNFA byte $84,"dira" +diraPFA word (@a_doconw - @a_base)/4 + word $01F6 + + word @diraNFA + $10 +ctraNFA byte $84,"ctra" +ctraPFA word (@a_doconw - @a_base)/4 + word $01F8 + + word @ctraNFA + $10 +ctrbNFA byte $84,"ctrb" +ctrbPFA word (@a_doconw - @a_base)/4 + word $01F9 + + word @ctrbNFA + $10 +frqaNFA byte $84,"frqa" +frqaPFA word (@a_doconw - @a_base)/4 + word $01FA + + word @frqaNFA + $10 +frqbNFA byte $84,"frqb" +frqbPFA word (@a_doconw - @a_base)/4 + word $01FB + + word @frqbNFA + $10 +phsaNFA byte $84,"phsa" +phsaPFA word (@a_doconw - @a_base)/4 + word $01FC + + word @phsaNFA + $10 +phsbNFA byte $84,"phsb" +phsbPFA word (@a_doconw - @a_base)/4 + word $01FD + + word @phsbNFA + $10 +vcfgNFA byte $84,"vcfg" +vcfgPFA word (@a_doconw - @a_base)/4 + word $01FE + + word @vcfgNFA + $10 +vsclNFA byte $84,"vscl" +vsclPFA word (@a_doconw - @a_base)/4 + word $01FF + + word @vsclNFA + $10 +mswKeyTONFA byte $88,"mswKeyTO" +mswKeyTOPFA word (@a_dovarw - @a_base)/4 + word $0500 + + word @mswKeyTONFA + $10 +cnipNFA byte $C4,"cnip" +cnipPFA word @mswHerePFA + $10 + word @watPFA + $10 + word @twominusPFA + $10 + word (@a_dup - @a_base)/4 + word @watPFA + $10 + word (@a_over - @a_base)/4 + word @twominusPFA + $10 + word @wbangPFA + $10 + word @mswHerePFA + $10 + word @wbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @cnipNFA + $10 +ifuncNFA byte $05,"ifunc" +ifuncPFA word (@a_ifunc - @a_base)/4 + + word @ifuncNFA + $10 +ifunconeNFA byte $06,"ifunc1" +ifunconePFA word (@a_ifuncone - @a_base)/4 + + word @ifunconeNFA + $10 +ifunctwoNFA byte $06,"ifunc2" +ifunctwoPFA word (@a_ifunctwo - @a_base)/4 + + word @ifunctwoNFA + $10 +finNFA byte $03,"fin" +finPFA word (@a_fin - @a_base)/4 + + word @finNFA + $10 +mpxNFA byte $03,"mpx" +mpxPFA word (@a_mpx - @a_base)/4 + + word @mpxNFA + $10 +mpxlNFA byte $04,"mpxl" +mpxlPFA word (@a_mpxl - @a_base)/4 + + word @mpxlNFA + $10 +mpxhNFA byte $04,"mpxh" +mpxhPFA word (@a_mpxh - @a_base)/4 + + word @mpxhNFA + $10 +nameeqNFA byte $05,"name=" +nameeqPFA word (@a_nameeq - @a_base)/4 + + word @nameeqNFA + $10 +cstreqNFA byte $05,"cstr=" +cstreqPFA word (@a_cstreq - @a_base)/4 + + word @cstreqNFA + $10 +absNFA byte $83,"abs" +absPFA word (@a_ifuncone - @a_base)/4 + word $0151 + word (@a_exit - @a_base)/4 + + word @absNFA + $10 +andNFA byte $83,"and" +andPFA word (@a_ifunc - @a_base)/4 + word $00C1 + word (@a_exit - @a_base)/4 + + word @andNFA + $10 +andnNFA byte $84,"andn" +andnPFA word (@a_ifunc - @a_base)/4 + word $00C9 + word (@a_exit - @a_base)/4 + + word @andnNFA + $10 +bangdNFA byte $82,"!d" +bangdPFA word (@a_ifunc - @a_base)/4 + word $00A9 + word (@a_exit - @a_base)/4 + + word @bangdNFA + $10 +bangiNFA byte $82,"!i" +bangiPFA word (@a_ifunc - @a_base)/4 + word $00B1 + word (@a_exit - @a_base)/4 + + word @bangiNFA + $10 +bangsNFA byte $82,"!s" +bangsPFA word (@a_ifunc - @a_base)/4 + word $00A1 + word (@a_exit - @a_base)/4 + + word @bangsNFA + $10 +matNFA byte $82,"m@" +matPFA word (@a_ifuncone - @a_base)/4 + word $0011 + word (@a_exit - @a_base)/4 + + word @matNFA + $10 +catNFA byte $82,"c@" +catPFA word (@a_ifuncone - @a_base)/4 + word $0001 + word (@a_exit - @a_base)/4 + + word @catNFA + $10 +watNFA byte $82,"w@" +watPFA word (@a_ifuncone - @a_base)/4 + word $0009 + word (@a_exit - @a_base)/4 + + word @watNFA + $10 +atNFA byte $01,"@" +atPFA word (@a_at - @a_base)/4 + + word @atNFA + $10 +mbangNFA byte $82,"m!" +mbangPFA word (@a_ifunctwo - @a_base)/4 + word $0010 + word (@a_exit - @a_base)/4 + + word @mbangNFA + $10 +cbangNFA byte $82,"c!" +cbangPFA word (@a_ifunctwo - @a_base)/4 + word $0000 + word (@a_exit - @a_base)/4 + + word @cbangNFA + $10 +wbangNFA byte $82,"w!" +wbangPFA word (@a_ifunctwo - @a_base)/4 + word $0008 + word (@a_exit - @a_base)/4 + + word @wbangNFA + $10 +bangNFA byte $01,"!" +bangPFA word (@a_bang - @a_base)/4 + + word @bangNFA + $10 +branchNFA byte $06,"branch" +branchPFA word (@a_branch - @a_base)/4 + + word @branchNFA + $10 +hubopNFA byte $05,"hubop" +hubopPFA word (@a_hubop - @a_base)/4 + + word @hubopNFA + $10 +doconwNFA byte $06,"doconw" +doconwPFA word (@a_doconw - @a_base)/4 + + word @doconwNFA + $10 +doconNFA byte $05,"docon" +doconPFA word (@a_docon - @a_base)/4 + + word @doconNFA + $10 +dovarwNFA byte $06,"dovarw" +dovarwPFA word (@a_dovarw - @a_base)/4 + + word @dovarwNFA + $10 +dovarNFA byte $05,"dovar" +dovarPFA word (@a_dovar - @a_base)/4 + + word @dovarNFA + $10 +dropNFA byte $04,"drop" +dropPFA word (@a_drop - @a_base)/4 + + word @dropNFA + $10 +dupNFA byte $03,"dup" +dupPFA word (@a_dup - @a_base)/4 + + word @dupNFA + $10 +eqNFA byte $01,"=" +eqPFA word (@a_eq - @a_base)/4 + + word @eqNFA + $10 +exitNFA byte $04,"exit" +exitPFA word (@a_exit - @a_base)/4 + + word @exitNFA + $10 +gtNFA byte $01,">" +gtPFA word (@a_gt - @a_base)/4 + + word @gtNFA + $10 +litwNFA byte $04,"litw" +litwPFA word (@a_litw - @a_base)/4 + + word @litwNFA + $10 +literalNFA byte $07,"literal" +literalPFA word (@a_literal - @a_base)/4 + + word @literalNFA + $10 +lshiftNFA byte $86,"lshift" +lshiftPFA word (@a_ifunc - @a_base)/4 + word $0059 + word (@a_exit - @a_base)/4 + + word @lshiftNFA + $10 +ltNFA byte $01,"<" +ltPFA word (@a_lt - @a_base)/4 + + word @ltNFA + $10 +maxNFA byte $83,"max" +maxPFA word (@a_ifunc - @a_base)/4 + word $0081 + word (@a_exit - @a_base)/4 + + word @maxNFA + $10 +minNFA byte $83,"min" +minPFA word (@a_ifunc - @a_base)/4 + word $0089 + word (@a_exit - @a_base)/4 + + word @minNFA + $10 +minusNFA byte $81,"-" +minusPFA word (@a_ifunc - @a_base)/4 + word $0109 + word (@a_exit - @a_base)/4 + + word @minusNFA + $10 +orNFA byte $82,"or" +orPFA word (@a_ifunc - @a_base)/4 + word $00D1 + word (@a_exit - @a_base)/4 + + word @orNFA + $10 +overNFA byte $04,"over" +overPFA word (@a_over - @a_base)/4 + + word @overNFA + $10 +plusNFA byte $81,"+" +plusPFA word (@a_ifunc - @a_base)/4 + word $0101 + word (@a_exit - @a_base)/4 + + word @plusNFA + $10 +rotNFA byte $03,"rot" +rotPFA word (@a_rot - @a_base)/4 + + word @rotNFA + $10 +ratNFA byte $82,"r@" +ratPFA word @rsPtrPFA + $10 + word (@a_at - @a_base)/4 + word @twoplusPFA + $10 + word (@a_at - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @ratNFA + $10 +rshiftNFA byte $86,"rshift" +rshiftPFA word (@a_ifunc - @a_base)/4 + word $0051 + word (@a_exit - @a_base)/4 + + word @rshiftNFA + $10 +rashiftNFA byte $87,"rashift" +rashiftPFA word (@a_ifunc - @a_base)/4 + word $0071 + word (@a_exit - @a_base)/4 + + word @rashiftNFA + $10 +rgtNFA byte $02,"r>" +rgtPFA word (@a_rgt - @a_base)/4 + + word @rgtNFA + $10 +gtrNFA byte $02,">r" +gtrPFA word (@a_gtr - @a_base)/4 + + word @gtrNFA + $10 +twogtrNFA byte $03,"2>r" +twogtrPFA word (@a_twogtr - @a_base)/4 + + word @twogtrNFA + $10 +zbranchNFA byte $07,"0branch" +zbranchPFA word (@a_zbranch - @a_base)/4 + + word @zbranchNFA + $10 +lparenlooprparenNFA byte $06,"(loop)" +lparenlooprparenPFA word (@a_lparenlooprparen - @a_base)/4 + + word @lparenlooprparenNFA + $10 +lparenpluslooprparenNFA byte $07,"(+loop)" +lparenpluslooprparenPFA word (@a_lparenpluslooprparen - @a_base)/4 + + word @lparenpluslooprparenNFA + $10 +swapNFA byte $04,"swap" +swapPFA word (@a_swap - @a_base)/4 + + word @swapNFA + $10 +umstarNFA byte $03,"um*" +umstarPFA word (@a_umstar - @a_base)/4 + + word @umstarNFA + $10 +umslashmodNFA byte $06,"um/mod" +umslashmodPFA word (@a_umslashmod - @a_base)/4 + + word @umslashmodNFA + $10 +uslashmodNFA byte $85,"u/mod" +uslashmodPFA word @zPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_umslashmod - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @uslashmodNFA + $10 +xorNFA byte $83,"xor" +xorPFA word (@a_ifunc - @a_base)/4 + word $00D9 + word (@a_exit - @a_base)/4 + + word @xorNFA + $10 +waitcntNFA byte $87,"waitcnt" +waitcntPFA word (@a_ifunc - @a_base)/4 + word $01F1 + word (@a_exit - @a_base)/4 + + word @waitcntNFA + $10 +waitpeqNFA byte $87,"waitpeq" +waitpeqPFA word (@a_ifunctwo - @a_base)/4 + word $01E0 + word (@a_exit - @a_base)/4 + + word @waitpeqNFA + $10 +waitpneNFA byte $87,"waitpne" +waitpnePFA word (@a_ifunctwo - @a_base)/4 + word $01E8 + word (@a_exit - @a_base)/4 + + word @waitpneNFA + $10 +vfcogNFA byte $85,"vfcog" +vfcogPFA word (@a_dup - @a_base)/4 + word @ffcogPFA + $10 + word @watPFA + $10 + word @lfcogPFA + $10 + word @watPFA + $10 + word @betweenPFA + $10 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word (@a_drop - @a_base)/4 + word @ffcogPFA + $10 + word @watPFA + $10 + word (@a_exit - @a_base)/4 + + word @vfcogNFA + $10 +rebootNFA byte $86,"reboot" +rebootPFA word (@a_litw - @a_base)/4 + word $00FF + word @zPFA + $10 + word (@a_hubop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @rebootNFA + $10 +cogstopNFA byte $87,"cogstop" +cogstopPFA word (@a_litw - @a_base)/4 + word $0003 + word (@a_hubop - @a_base)/4 + word @twodropPFA + $10 + word (@a_exit - @a_base)/4 + + word @cogstopNFA + $10 +cogresetNFA byte $88,"cogreset" +cogresetPFA word (@a_litw - @a_base)/4 + word $0007 + word @andPFA + $10 + word (@a_dup - @a_base)/4 + word @cogstopPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_dup - @a_base)/4 + word @cogdPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0100 + word @zPFA + $10 + word @fillPFA + $10 + word (@a_litw - @a_base)/4 + word $0010 + word @lshiftPFA + $10 + word @cm_entryPFA + $10 + word (@a_litw - @a_base)/4 + word $0002 + word @lshiftPFA + $10 + word @orPFA + $10 + word @orPFA + $10 + word (@a_litw - @a_base)/4 + word $0002 + word (@a_hubop - @a_base)/4 + word @twodropPFA + $10 + word @cogDebugvaluePFA + $10 + word (@a_litw - @a_base)/4 + word $8000 + word @zPFA + $10 + word (@a_twogtr - @a_base)/4 + word (@a_dup - @a_base)/4 + word @matPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0004 + word @leavePFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFF4 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @cogresetNFA + $10 +resetNFA byte $85,"reset" +resetPFA word @mydictlockPFA + $10 + word @watPFA + $10 + word @zgtPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000C + word (@a_litw - @a_base)/4 + word $0001 + word @mydictlockPFA + $10 + word @wbangPFA + $10 + word @freedictPFA + $10 + word @cogidPFA + $10 + word @cogresetPFA + $10 + word (@a_exit - @a_base)/4 + + word @resetNFA + $10 +disioNFA byte $85,"disio" +disioPFA word @cogEmitptrPFA + $10 + word @zPFA + $10 + word (@a_swap - @a_base)/4 + word @wbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @disioNFA + $10 +connioNFA byte $86,"connio" +connioPFA word (@a_litw - @a_base)/4 + word $0007 + word @andPFA + $10 + word @cogInbytePFA + $10 + word (@a_swap - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0007 + word @andPFA + $10 + word @cogEmitptrPFA + $10 + word @wbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @connioNFA + $10 +gtcogNFA byte $84,">cog" +gtcogPFA word @cogCONPFA + $10 + word @watPFA + $10 + word @disioPFA + $10 + word @inCONPFA + $10 + word (@a_over - @a_base)/4 + word @cogEmitptrPFA + $10 + word @wbangPFA + $10 + word (@a_dup - @a_base)/4 + word @cogInbytePFA + $10 + word @outCONPFA + $10 + word @wbangPFA + $10 + word @cogCONPFA + $10 + word @wbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @gtcogNFA + $10 +cogCONNFA byte $86,"cogCON" +cogCONPFA word (@a_dovarw - @a_base)/4 + word $0006 + + word @cogCONNFA + $10 +inCONNFA byte $85,"inCON" +inCONPFA word (@a_dovarw - @a_base)/4 + word $0100 + + word @inCONNFA + $10 +outCONNFA byte $86,"outCON" +outCONPFA word (@a_dovarw - @a_base)/4 + word $0000 + + word @outCONNFA + $10 +ctlCONNFA byte $86,"ctlCON" +ctlCONPFA word (@a_dovarw - @a_base)/4 + word $0000 + + word @ctlCONNFA + $10 +clkfreqNFA byte $87,"clkfreq" +clkfreqPFA word @zPFA + $10 + word @matPFA + $10 + word (@a_exit - @a_base)/4 + + word @clkfreqNFA + $10 +paratNFA byte $85,"parat" +paratPFA word @parPFA + $10 + word (@a_at - @a_base)/4 + word @plusPFA + $10 + word (@a_exit - @a_base)/4 + + word @paratNFA + $10 +cogdNFA byte $84,"cogd" +cogdPFA word (@a_litw - @a_base)/4 + word $0007 + word @andPFA + $10 + word (@a_litw - @a_base)/4 + word $0008 + word @lshiftPFA + $10 + word @cm_cogdataPFA + $10 + word @plusPFA + $10 + word (@a_exit - @a_base)/4 + + word @cogdNFA + $10 +mcwInbyteNFA byte $89,"mcwInbyte" +mcwInbytePFA word @zPFA + $10 + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @mcwInbyteNFA + $10 +cogInbyteNFA byte $89,"cogInbyte" +cogInbytePFA word @cogdPFA + $10 + word (@a_exit - @a_base)/4 + + word @cogInbyteNFA + $10 +mcwEmitptrNFA byte $8A,"mcwEmitptr" +mcwEmitptrPFA word (@a_litw - @a_base)/4 + word $0002 + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @mcwEmitptrNFA + $10 +cogEmitptrNFA byte $8A,"cogEmitptr" +cogEmitptrPFA word @cogdPFA + $10 + word @twoplusPFA + $10 + word (@a_exit - @a_base)/4 + + word @cogEmitptrNFA + $10 +mcwStateNFA byte $88,"mcwState" +mcwStatePFA word (@a_litw - @a_base)/4 + word $0004 + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @mcwStateNFA + $10 +compileqNFA byte $88,"compile?" +compileqPFA word @mcwStatePFA + $10 + word @watPFA + $10 + word @zltgtPFA + $10 + word (@a_exit - @a_base)/4 + + word @compileqNFA + $10 +mcwDebugcmdNFA byte $8B,"mcwDebugcmd" +mcwDebugcmdPFA word (@a_litw - @a_base)/4 + word $0006 + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @mcwDebugcmdNFA + $10 +cogDebugcmdNFA byte $8B,"cogDebugcmd" +cogDebugcmdPFA word @cogdPFA + $10 + word (@a_litw - @a_base)/4 + word $0006 + word @plusPFA + $10 + word (@a_exit - @a_base)/4 + + word @cogDebugcmdNFA + $10 +mcwDebugvalueNFA byte $8D,"mcwDebugvalue" +mcwDebugvaluePFA word (@a_litw - @a_base)/4 + word $0008 + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @mcwDebugvalueNFA + $10 +cogDebugvalueNFA byte $8D,"cogDebugvalue" +cogDebugvaluePFA word @cogdPFA + $10 + word (@a_litw - @a_base)/4 + word $0008 + word @plusPFA + $10 + word (@a_exit - @a_base)/4 + + word @cogDebugvalueNFA + $10 +mcwBaseNFA byte $87,"mcwBase" +mcwBasePFA word (@a_litw - @a_base)/4 + word $000C + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @mcwBaseNFA + $10 +mcwAhereNFA byte $88,"mcwAhere" +mcwAherePFA word (@a_litw - @a_base)/4 + word $000E + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @mcwAhereNFA + $10 +execwordNFA byte $88,"execword" +execwordPFA word (@a_litw - @a_base)/4 + word $0010 + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @execwordNFA + $10 +executeNFA byte $87,"execute" +executePFA word (@a_dup - @a_base)/4 + word @fMaskPFA + $10 + word (@a_at - @a_base)/4 + word @andPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000A + word @IPPFA + $10 + word (@a_bang - @a_base)/4 + word (@a_branch - @a_base)/4 + word $0014 + word @execwordPFA + $10 + word @wbangPFA + $10 + word @ca_a_exitPFA + $10 + word @execwordPFA + $10 + word @twoplusPFA + $10 + word @wbangPFA + $10 + word @execwordPFA + $10 + word @IPPFA + $10 + word (@a_bang - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @executeNFA + $10 +mcwgtoutNFA byte $87,"mcw>out" +mcwgtoutPFA word (@a_litw - @a_base)/4 + word $0014 + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @mcwgtoutNFA + $10 +mcwgtinNFA byte $86,"mcw>in" +mcwgtinPFA word (@a_litw - @a_base)/4 + word $0016 + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @mcwgtinNFA + $10 +mydictlockNFA byte $8A,"mydictlock" +mydictlockPFA word (@a_litw - @a_base)/4 + word $0018 + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @mydictlockNFA + $10 +mcwFsliceptrNFA byte $8C,"mcwFsliceptr" +mcwFsliceptrPFA word (@a_litw - @a_base)/4 + word $001A + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @mcwFsliceptrNFA + $10 +mcLastcntNFA byte $89,"mcLastcnt" +mcLastcntPFA word (@a_litw - @a_base)/4 + word $001C + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @mcLastcntNFA + $10 +mcFslicecntNFA byte $8B,"mcFslicecnt" +mcFslicecntPFA word (@a_litw - @a_base)/4 + word $0020 + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @mcFslicecntNFA + $10 +_fSlicerNFA byte $88,"_fSlicer" +_fSlicerPFA word @cntPFA + $10 + word (@a_at - @a_base)/4 + word (@a_dup - @a_base)/4 + word @mcLastcntPFA + $10 + word @matPFA + $10 + word @plusPFA + $10 + word @mcFslicecntPFA + $10 + word @matPFA + $10 + word @maxPFA + $10 + word @mcFslicecntPFA + $10 + word @mbangPFA + $10 + word @negatePFA + $10 + word @mcLastcntPFA + $10 + word @mbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @_fSlicerNFA + $10 +_fSliceNFA byte $87,"_fSlice" +_fSlicePFA word @mcwFsliceptrPFA + $10 + word @watPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0008 + word @executePFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @_fSliceNFA + $10 +mcPadNFA byte $85,"mcPad" +mcPadPFA word (@a_litw - @a_base)/4 + word $0024 + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @mcPadNFA + $10 +cogPadNFA byte $86,"cogPad" +cogPadPFA word @cogdPFA + $10 + word (@a_litw - @a_base)/4 + word $0024 + word @plusPFA + $10 + word (@a_exit - @a_base)/4 + + word @cogPadNFA + $10 +_pclrNFA byte $85,"_pclr" +_pclrPFA word (@a_dup - @a_base)/4 + word @padsizePFA + $10 + word @plusPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_twogtr - @a_base)/4 + word (@a_literal - @a_base)/4 + long $20202020 + word @iPFA + $10 + word @mbangPFA + $10 + word (@a_litw - @a_base)/4 + word $0004 + word (@a_lparenpluslooprparen - @a_base)/4 + word $FFF0 + word (@a_exit - @a_base)/4 + + word @_pclrNFA + $10 +cogPadclrNFA byte $89,"cogPadclr" +cogPadclrPFA word @cogPadPFA + $10 + word @_pclrPFA + $10 + word (@a_exit - @a_base)/4 + + word @cogPadclrNFA + $10 +padgtinNFA byte $86,"pad>in" +padgtinPFA word @mcwgtinPFA + $10 + word @watPFA + $10 + word @mcPadPFA + $10 + word @plusPFA + $10 + word (@a_exit - @a_base)/4 + + word @padgtinNFA + $10 +namemaxNFA byte $87,"namemax" +namemaxPFA word (@a_litw - @a_base)/4 + word $001F + word (@a_exit - @a_base)/4 + + word @namemaxNFA + $10 +padsizeNFA byte $87,"padsize" +padsizePFA word (@a_litw - @a_base)/4 + word $0080 + word (@a_exit - @a_base)/4 + + word @padsizeNFA + $10 +mcwTzNFA byte $85,"mcwT0" +mcwTzPFA word (@a_litw - @a_base)/4 + word $00A4 + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @mcwTzNFA + $10 +mcwToneNFA byte $85,"mcwT1" +mcwTonePFA word (@a_litw - @a_base)/4 + word $00A6 + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @mcwToneNFA + $10 +mcTNFA byte $83,"mcT" +mcTPFA word (@a_litw - @a_base)/4 + word $00A8 + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @mcTNFA + $10 +mcNumpadNFA byte $88,"mcNumpad" +mcNumpadPFA word (@a_litw - @a_base)/4 + word $00C0 + word @paratPFA + $10 + word (@a_exit - @a_base)/4 + + word @mcNumpadNFA + $10 +padgtoutNFA byte $87,"pad>out" +padgtoutPFA word @mcwgtoutPFA + $10 + word @watPFA + $10 + word @mcNumpadPFA + $10 + word @plusPFA + $10 + word (@a_exit - @a_base)/4 + + word @padgtoutNFA + $10 +numpadsizeNFA byte $8A,"numpadsize" +numpadsizePFA word (@a_litw - @a_base)/4 + word $0030 + word (@a_exit - @a_base)/4 + + word @numpadsizeNFA + $10 +keytoNFA byte $85,"keyto" +keytoPFA word @zPFA + $10 + word @mswKeyTOPFA + $10 + word @watPFA + $10 + word @zPFA + $10 + word (@a_twogtr - @a_base)/4 + word @keyqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000A + word (@a_drop - @a_base)/4 + word @keyPFA + $10 + word @minusonePFA + $10 + word @leavePFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFF0 + word (@a_exit - @a_base)/4 + + word @keytoNFA + $10 +emitqNFA byte $85,"emit?" +emitqPFA word @_fSlicePFA + $10 + word @mcwEmitptrPFA + $10 + word @watPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0010 + word @watPFA + $10 + word (@a_litw - @a_base)/4 + word $0100 + word @andPFA + $10 + word @zltgtPFA + $10 + word (@a_branch - @a_base)/4 + word $0006 + word (@a_drop - @a_base)/4 + word @minusonePFA + $10 + word (@a_exit - @a_base)/4 + + word @emitqNFA + $10 +emitNFA byte $84,"emit" +emitPFA word @emitqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFFC + word (@a_litw - @a_base)/4 + word $00FF + word @andPFA + $10 + word @mcwEmitptrPFA + $10 + word @watPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0008 + word @wbangPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word @twodropPFA + $10 + word (@a_exit - @a_base)/4 + + word @emitNFA + $10 +keyqNFA byte $84,"key?" +keyqPFA word @_fSlicePFA + $10 + word @mcwInbytePFA + $10 + word @watPFA + $10 + word (@a_litw - @a_base)/4 + word $0100 + word @andPFA + $10 + word @zeqPFA + $10 + word (@a_exit - @a_base)/4 + + word @keyqNFA + $10 +keyNFA byte $83,"key" +keyPFA word @keyqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFFC + word @mcwInbytePFA + $10 + word @watPFA + $10 + word (@a_litw - @a_base)/4 + word $0100 + word @mcwInbytePFA + $10 + word @wbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @keyNFA + $10 +fkeyqNFA byte $85,"fkey?" +fkeyqPFA word @mcwInbytePFA + $10 + word @watPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0100 + word @andPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word @zPFA + $10 + word (@a_branch - @a_base)/4 + word $000C + word (@a_litw - @a_base)/4 + word $0100 + word @mcwInbytePFA + $10 + word @wbangPFA + $10 + word @minusonePFA + $10 + word (@a_exit - @a_base)/4 + + word @fkeyqNFA + $10 +nipNFA byte $83,"nip" +nipPFA word (@a_swap - @a_base)/4 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @nipNFA + $10 +tuckNFA byte $84,"tuck" +tuckPFA word (@a_swap - @a_base)/4 + word (@a_over - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @tuckNFA + $10 +twodupNFA byte $84,"2dup" +twodupPFA word (@a_over - @a_base)/4 + word (@a_over - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @twodupNFA + $10 +twodropNFA byte $85,"2drop" +twodropPFA word (@a_drop - @a_base)/4 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @twodropNFA + $10 +threedropNFA byte $85,"3drop" +threedropPFA word (@a_drop - @a_base)/4 + word (@a_drop - @a_base)/4 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @threedropNFA + $10 +uslashNFA byte $82,"u/" +uslashPFA word @uslashmodPFA + $10 + word @nipPFA + $10 + word (@a_exit - @a_base)/4 + + word @uslashNFA + $10 +ustarNFA byte $82,"u*" +ustarPFA word (@a_umstar - @a_base)/4 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @ustarNFA + $10 +invertNFA byte $86,"invert" +invertPFA word @minusonePFA + $10 + word @xorPFA + $10 + word (@a_exit - @a_base)/4 + + word @invertNFA + $10 +negateNFA byte $86,"negate" +negatePFA word (@a_ifuncone - @a_base)/4 + word $0149 + word (@a_exit - @a_base)/4 + + word @negateNFA + $10 +zeqNFA byte $82,"0=" +zeqPFA word @zPFA + $10 + word (@a_eq - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @zeqNFA + $10 +ltgtNFA byte $82,"<>" +ltgtPFA word (@a_eq - @a_base)/4 + word @invertPFA + $10 + word (@a_exit - @a_base)/4 + + word @ltgtNFA + $10 +zltgtNFA byte $83,"0<>" +zltgtPFA word @zeqPFA + $10 + word @invertPFA + $10 + word (@a_exit - @a_base)/4 + + word @zltgtNFA + $10 +zltNFA byte $82,"0<" +zltPFA word @zPFA + $10 + word (@a_lt - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @zltNFA + $10 +zgtNFA byte $82,"0>" +zgtPFA word @zPFA + $10 + word (@a_gt - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @zgtNFA + $10 +oneplusNFA byte $82,"1+" +oneplusPFA word (@a_litw - @a_base)/4 + word $0001 + word @plusPFA + $10 + word (@a_exit - @a_base)/4 + + word @oneplusNFA + $10 +oneminusNFA byte $82,"1-" +oneminusPFA word (@a_litw - @a_base)/4 + word $0001 + word @minusPFA + $10 + word (@a_exit - @a_base)/4 + + word @oneminusNFA + $10 +twoplusNFA byte $82,"2+" +twoplusPFA word (@a_litw - @a_base)/4 + word $0002 + word @plusPFA + $10 + word (@a_exit - @a_base)/4 + + word @twoplusNFA + $10 +fourplusNFA byte $82,"4+" +fourplusPFA word (@a_litw - @a_base)/4 + word $0004 + word @plusPFA + $10 + word (@a_exit - @a_base)/4 + + word @fourplusNFA + $10 +twominusNFA byte $82,"2-" +twominusPFA word (@a_litw - @a_base)/4 + word $0002 + word @minusPFA + $10 + word (@a_exit - @a_base)/4 + + word @twominusNFA + $10 +twostarNFA byte $82,"2*" +twostarPFA word (@a_litw - @a_base)/4 + word $0001 + word @lshiftPFA + $10 + word (@a_exit - @a_base)/4 + + word @twostarNFA + $10 +twoslashNFA byte $82,"2/" +twoslashPFA word (@a_litw - @a_base)/4 + word $0001 + word @rashiftPFA + $10 + word (@a_exit - @a_base)/4 + + word @twoslashNFA + $10 +rottwoNFA byte $84,"rot2" +rottwoPFA word (@a_rot - @a_base)/4 + word (@a_rot - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @rottwoNFA + $10 +gteqNFA byte $82,">=" +gteqPFA word @twodupPFA + $10 + word (@a_gt - @a_base)/4 + word @rottwoPFA + $10 + word (@a_eq - @a_base)/4 + word @orPFA + $10 + word (@a_exit - @a_base)/4 + + word @gteqNFA + $10 +lteqNFA byte $82,"<=" +lteqPFA word @twodupPFA + $10 + word (@a_lt - @a_base)/4 + word @rottwoPFA + $10 + word (@a_eq - @a_base)/4 + word @orPFA + $10 + word (@a_exit - @a_base)/4 + + word @lteqNFA + $10 +zgteqNFA byte $83,"0>=" +zgteqPFA word (@a_dup - @a_base)/4 + word @zPFA + $10 + word (@a_gt - @a_base)/4 + word (@a_swap - @a_base)/4 + word @zeqPFA + $10 + word @orPFA + $10 + word (@a_exit - @a_base)/4 + + word @zgteqNFA + $10 +wplusbangNFA byte $83,"w+!" +wplusbangPFA word (@a_dup - @a_base)/4 + word @watPFA + $10 + word (@a_rot - @a_base)/4 + word @plusPFA + $10 + word (@a_swap - @a_base)/4 + word @wbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @wplusbangNFA + $10 +orcbangNFA byte $84,"orc!" +orcbangPFA word (@a_dup - @a_base)/4 + word @catPFA + $10 + word (@a_rot - @a_base)/4 + word @orPFA + $10 + word (@a_swap - @a_base)/4 + word @cbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @orcbangNFA + $10 +andcbangNFA byte $85,"andc!" +andcbangPFA word (@a_dup - @a_base)/4 + word @catPFA + $10 + word (@a_rot - @a_base)/4 + word @andPFA + $10 + word (@a_swap - @a_base)/4 + word @cbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @andcbangNFA + $10 +betweenNFA byte $87,"between" +betweenPFA word @rottwoPFA + $10 + word (@a_over - @a_base)/4 + word @lteqPFA + $10 + word @rottwoPFA + $10 + word @gteqPFA + $10 + word @andPFA + $10 + word (@a_exit - @a_base)/4 + + word @betweenNFA + $10 +crNFA byte $82,"cr" +crPFA word (@a_litw - @a_base)/4 + word $000D + word @emitPFA + $10 + word (@a_exit - @a_base)/4 + + word @crNFA + $10 +spaceNFA byte $85,"space" +spacePFA word @blPFA + $10 + word @emitPFA + $10 + word (@a_exit - @a_base)/4 + + word @spaceNFA + $10 +spacesNFA byte $86,"spaces" +spacesPFA word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0010 + word @zPFA + $10 + word (@a_twogtr - @a_base)/4 + word @spacePFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFFC + word (@a_branch - @a_base)/4 + word $0004 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @spacesNFA + $10 +dothexNFA byte $84,".hex" +dothexPFA word (@a_litw - @a_base)/4 + word $000F + word @andPFA + $10 + word (@a_litw - @a_base)/4 + word $0030 + word @plusPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0039 + word (@a_gt - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0008 + word (@a_litw - @a_base)/4 + word $0007 + word @plusPFA + $10 + word @emitPFA + $10 + word (@a_exit - @a_base)/4 + + word @dothexNFA + $10 +dotbyteNFA byte $85,".byte" +dotbytePFA word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0004 + word @rshiftPFA + $10 + word @dothexPFA + $10 + word @dothexPFA + $10 + word (@a_exit - @a_base)/4 + + word @dotbyteNFA + $10 +dotwordNFA byte $85,".word" +dotwordPFA word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0008 + word @rshiftPFA + $10 + word @dotbytePFA + $10 + word @dotbytePFA + $10 + word (@a_exit - @a_base)/4 + + word @dotwordNFA + $10 +dotlongNFA byte $85,".long" +dotlongPFA word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0010 + word @rshiftPFA + $10 + word @dotwordPFA + $10 + word @dotwordPFA + $10 + word (@a_exit - @a_base)/4 + + word @dotlongNFA + $10 +boundsNFA byte $86,"bounds" +boundsPFA word (@a_over - @a_base)/4 + word @plusPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @boundsNFA + $10 +alignlNFA byte $86,"alignl" +alignlPFA word (@a_litw - @a_base)/4 + word $0003 + word @plusPFA + $10 + word (@a_literal - @a_base)/4 + long $FFFFFFFC + word @andPFA + $10 + word (@a_exit - @a_base)/4 + + word @alignlNFA + $10 +alignwNFA byte $86,"alignw" +alignwPFA word @oneplusPFA + $10 + word (@a_literal - @a_base)/4 + long $FFFFFFFE + word @andPFA + $10 + word (@a_exit - @a_base)/4 + + word @alignwNFA + $10 +catplusplusNFA byte $84,"c@++" +catplusplusPFA word (@a_dup - @a_base)/4 + word @catPFA + $10 + word (@a_swap - @a_base)/4 + word @oneplusPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @catplusplusNFA + $10 +ctolowerNFA byte $88,"ctolower" +ctolowerPFA word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0041 + word (@a_litw - @a_base)/4 + word $005A + word @betweenPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word (@a_litw - @a_base)/4 + word $0020 + word @orPFA + $10 + word (@a_exit - @a_base)/4 + + word @ctolowerNFA + $10 +ctoupperNFA byte $88,"ctoupper" +ctoupperPFA word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0061 + word (@a_litw - @a_base)/4 + word $007A + word @betweenPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word (@a_litw - @a_base)/4 + word $00DF + word @andPFA + $10 + word (@a_exit - @a_base)/4 + + word @ctoupperNFA + $10 +todigitNFA byte $87,"todigit" +todigitPFA word @ctoupperPFA + $10 + word (@a_litw - @a_base)/4 + word $0030 + word @minusPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0009 + word (@a_gt - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0016 + word (@a_litw - @a_base)/4 + word $0007 + word @minusPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $000A + word (@a_lt - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0004 + word @minusonePFA + $10 + word (@a_exit - @a_base)/4 + + word @todigitNFA + $10 +isdigitNFA byte $87,"isdigit" +isdigitPFA word @todigitPFA + $10 + word (@a_dup - @a_base)/4 + word @zgteqPFA + $10 + word (@a_swap - @a_base)/4 + word @mcwBasePFA + $10 + word @watPFA + $10 + word (@a_lt - @a_base)/4 + word @andPFA + $10 + word (@a_exit - @a_base)/4 + + word @isdigitNFA + $10 +isunumberNFA byte $89,"isunumber" +isunumberPFA word @boundsPFA + $10 + word @minusonePFA + $10 + word @rottwoPFA + $10 + word (@a_twogtr - @a_base)/4 + word @iPFA + $10 + word @catPFA + $10 + word @isdigitPFA + $10 + word @andPFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFF6 + word (@a_exit - @a_base)/4 + + word @isunumberNFA + $10 +unumberNFA byte $87,"unumber" +unumberPFA word @boundsPFA + $10 + word @zPFA + $10 + word @rottwoPFA + $10 + word (@a_twogtr - @a_base)/4 + word @mcwBasePFA + $10 + word @watPFA + $10 + word @ustarPFA + $10 + word @iPFA + $10 + word @catPFA + $10 + word @todigitPFA + $10 + word @plusPFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFF0 + word (@a_exit - @a_base)/4 + + word @unumberNFA + $10 +numberNFA byte $86,"number" +numberPFA word (@a_over - @a_base)/4 + word @catPFA + $10 + word (@a_litw - @a_base)/4 + word $002D + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0016 + word @oneminusPFA + $10 + word @zPFA + $10 + word @maxPFA + $10 + word (@a_swap - @a_base)/4 + word @oneplusPFA + $10 + word (@a_swap - @a_base)/4 + word @unumberPFA + $10 + word @negatePFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word @unumberPFA + $10 + word (@a_exit - @a_base)/4 + + word @numberNFA + $10 +isnumberNFA byte $88,"isnumber" +isnumberPFA word (@a_over - @a_base)/4 + word @catPFA + $10 + word (@a_litw - @a_base)/4 + word $002D + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $000E + word @oneminusPFA + $10 + word @zPFA + $10 + word @maxPFA + $10 + word (@a_swap - @a_base)/4 + word @oneplusPFA + $10 + word (@a_swap - @a_base)/4 + word @isunumberPFA + $10 + word (@a_exit - @a_base)/4 + + word @isnumberNFA + $10 +dotstrNFA byte $84,".str" +dotstrPFA word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0020 + word @boundsPFA + $10 + word (@a_twogtr - @a_base)/4 + word @iPFA + $10 + word @catPFA + $10 + word (@a_litw - @a_base)/4 + word $0020 + word @maxPFA + $10 + word (@a_litw - @a_base)/4 + word $007F + word @minPFA + $10 + word @emitPFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFEC + word (@a_branch - @a_base)/4 + word $0004 + word @twodropPFA + $10 + word (@a_exit - @a_base)/4 + + word @dotstrNFA + $10 +npfxNFA byte $84,"npfx" +npfxPFA word @namelenPFA + $10 + word (@a_rot - @a_base)/4 + word @namelenPFA + $10 + word (@a_rot - @a_base)/4 + word @twodupPFA + $10 + word (@a_gt - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0024 + word @minPFA + $10 + word @boundsPFA + $10 + word (@a_twogtr - @a_base)/4 + word @catplusplusPFA + $10 + word @iPFA + $10 + word @catPFA + $10 + word @ltgtPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word (@a_drop - @a_base)/4 + word @zPFA + $10 + word @leavePFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFEC + word @zltgtPFA + $10 + word (@a_branch - @a_base)/4 + word $0008 + word @twodropPFA + $10 + word @twodropPFA + $10 + word @zPFA + $10 + word (@a_exit - @a_base)/4 + + word @npfxNFA + $10 +namelenNFA byte $87,"namelen" +namelenPFA word @catplusplusPFA + $10 + word @namemaxPFA + $10 + word @andPFA + $10 + word (@a_exit - @a_base)/4 + + word @namelenNFA + $10 +cmoveNFA byte $85,"cmove" +cmovePFA word (@a_dup - @a_base)/4 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word @threedropPFA + $10 + word (@a_branch - @a_base)/4 + word $0010 + word @boundsPFA + $10 + word (@a_twogtr - @a_base)/4 + word @catplusplusPFA + $10 + word @iPFA + $10 + word @cbangPFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFF8 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @cmoveNFA + $10 +namecopyNFA byte $88,"namecopy" +namecopyPFA word (@a_over - @a_base)/4 + word @namelenPFA + $10 + word @oneplusPFA + $10 + word @nipPFA + $10 + word @cmovePFA + $10 + word (@a_exit - @a_base)/4 + + word @namecopyNFA + $10 +ccopyNFA byte $85,"ccopy" +ccopyPFA word (@a_over - @a_base)/4 + word @catPFA + $10 + word @oneplusPFA + $10 + word @cmovePFA + $10 + word (@a_exit - @a_base)/4 + + word @ccopyNFA + $10 +cappendNFA byte $87,"cappend" +cappendPFA word (@a_dup - @a_base)/4 + word (@a_dup - @a_base)/4 + word @catPFA + $10 + word @plusPFA + $10 + word @oneplusPFA + $10 + word @rottwoPFA + $10 + word (@a_over - @a_base)/4 + word @catPFA + $10 + word (@a_over - @a_base)/4 + word @catPFA + $10 + word @plusPFA + $10 + word (@a_swap - @a_base)/4 + word @cbangPFA + $10 + word (@a_dup - @a_base)/4 + word @catPFA + $10 + word (@a_swap - @a_base)/4 + word @oneplusPFA + $10 + word @rottwoPFA + $10 + word @cmovePFA + $10 + word (@a_exit - @a_base)/4 + + word @cappendNFA + $10 +cappendcNFA byte $88,"cappendc" +cappendcPFA word (@a_dup - @a_base)/4 + word @catPFA + $10 + word @oneplusPFA + $10 + word (@a_over - @a_base)/4 + word @cbangPFA + $10 + word (@a_dup - @a_base)/4 + word @catPFA + $10 + word @plusPFA + $10 + word @cbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @cappendcNFA + $10 +cappendnNFA byte $88,"cappendn" +cappendnPFA word (@a_swap - @a_base)/4 + word @lthashPFA + $10 + word @hashsPFA + $10 + word @hashgtPFA + $10 + word (@a_swap - @a_base)/4 + word @cappendPFA + $10 + word (@a_exit - @a_base)/4 + + word @cappendnNFA + $10 +cappendncNFA byte $89,"cappendnc" +cappendncPFA word (@a_swap - @a_base)/4 + word @lthashPFA + $10 + word @hashsPFA + $10 + word @hashgtPFA + $10 + word (@a_over - @a_base)/4 + word @cappendPFA + $10 + word @blPFA + $10 + word (@a_swap - @a_base)/4 + word @cappendcPFA + $10 + word (@a_exit - @a_base)/4 + + word @cappendncNFA + $10 +cogXNFA byte $84,"cogX" +cogXPFA word @vfcogPFA + $10 + word (@a_dup - @a_base)/4 + word @cogInbytePFA + $10 + word (@a_dup - @a_base)/4 + word @watPFA + $10 + word (@a_litw - @a_base)/4 + word $0100 + word @andPFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFF4 + word @rottwoPFA + $10 + word (@a_dup - @a_base)/4 + word @cogPadclrPFA + $10 + word @cogPadPFA + $10 + word @oneplusPFA + $10 + word (@a_swap - @a_base)/4 + word @catplusplusPFA + $10 + word (@a_rot - @a_base)/4 + word (@a_swap - @a_base)/4 + word @cmovePFA + $10 + word (@a_litw - @a_base)/4 + word $000D + word (@a_swap - @a_base)/4 + word @wbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @cogXNFA + $10 +cogXONFA byte $85,"cogXO" +cogXOPFA word @zPFA + $10 + word @outCONPFA + $10 + word @wbangPFA + $10 + word @cogidPFA + $10 + word (@a_dup - @a_base)/4 + word @oneplusPFA + $10 + word @vfcogPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_rot - @a_base)/4 + word @connioPFA + $10 + word @cogXPFA + $10 + word (@a_exit - @a_base)/4 + + word @cogXONFA + $10 +qqqNFA byte $83,"???" +qqqPFA word @dqPFA + $10 + byte $03,"???" + word (@a_exit - @a_base)/4 + + word @qqqNFA + $10 +dotstrnameNFA byte $88,".strname" +dotstrnamePFA word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $000A + word @namelenPFA + $10 + word @dotstrPFA + $10 + word (@a_branch - @a_base)/4 + word $0006 + word (@a_drop - @a_base)/4 + word @qqqPFA + $10 + word (@a_exit - @a_base)/4 + + word @dotstrnameNFA + $10 +dotcstrNFA byte $85,".cstr" +dotcstrPFA word @catplusplusPFA + $10 + word @dotstrPFA + $10 + word (@a_exit - @a_base)/4 + + word @dotcstrNFA + $10 +dqNFA byte $82,"dq" +dqPFA word (@a_rgt - @a_base)/4 + word @catplusplusPFA + $10 + word @twodupPFA + $10 + word @plusPFA + $10 + word @alignwPFA + $10 + word (@a_gtr - @a_base)/4 + word @dotstrPFA + $10 + word (@a_exit - @a_base)/4 + + word @dqNFA + $10 +iNFA byte $81,"i" +iPFA word @rsPtrPFA + $10 + word (@a_at - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0003 + word @plusPFA + $10 + word (@a_at - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @iNFA + $10 +jNFA byte $81,"j" +jPFA word @rsPtrPFA + $10 + word (@a_at - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0005 + word @plusPFA + $10 + word (@a_at - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @jNFA + $10 +iboundNFA byte $86,"ibound" +iboundPFA word @rsPtrPFA + $10 + word (@a_at - @a_base)/4 + word @twoplusPFA + $10 + word (@a_at - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @iboundNFA + $10 +jboundNFA byte $86,"jbound" +jboundPFA word @rsPtrPFA + $10 + word (@a_at - @a_base)/4 + word @fourplusPFA + $10 + word (@a_at - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @jboundNFA + $10 +lastiqNFA byte $86,"lasti?" +lastiqPFA word @rsPtrPFA + $10 + word (@a_at - @a_base)/4 + word @twoplusPFA + $10 + word (@a_at - @a_base)/4 + word @oneminusPFA + $10 + word @rsPtrPFA + $10 + word (@a_at - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0003 + word @plusPFA + $10 + word (@a_at - @a_base)/4 + word (@a_eq - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @lastiqNFA + $10 +lastjqNFA byte $86,"lastj?" +lastjqPFA word @rsPtrPFA + $10 + word (@a_at - @a_base)/4 + word @fourplusPFA + $10 + word (@a_at - @a_base)/4 + word @oneminusPFA + $10 + word @rsPtrPFA + $10 + word (@a_at - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0005 + word @plusPFA + $10 + word (@a_at - @a_base)/4 + word (@a_eq - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @lastjqNFA + $10 +setiNFA byte $84,"seti" +setiPFA word @rsPtrPFA + $10 + word (@a_at - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0003 + word @plusPFA + $10 + word (@a_bang - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @setiNFA + $10 +setjNFA byte $84,"setj" +setjPFA word @rsPtrPFA + $10 + word (@a_at - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0005 + word @plusPFA + $10 + word (@a_bang - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @setjNFA + $10 +eolqNFA byte $84,"eol?" +eolqPFA word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $000A + word (@a_eq - @a_base)/4 + word (@a_over - @a_base)/4 + word (@a_litw - @a_base)/4 + word $000D + word (@a_eq - @a_base)/4 + word @orPFA + $10 + word (@a_exit - @a_base)/4 + + word @eolqNFA + $10 +bsqNFA byte $83,"bs?" +bsqPFA word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0008 + word (@a_eq - @a_base)/4 + word (@a_over - @a_base)/4 + word (@a_litw - @a_base)/4 + word $007F + word (@a_eq - @a_base)/4 + word @orPFA + $10 + word (@a_exit - @a_base)/4 + + word @bsqNFA + $10 +fillNFA byte $84,"fill" +fillPFA word @rottwoPFA + $10 + word @boundsPFA + $10 + word (@a_twogtr - @a_base)/4 + word (@a_dup - @a_base)/4 + word @iPFA + $10 + word @cbangPFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFF8 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @fillNFA + $10 +nfagtlfaNFA byte $87,"nfa>lfa" +nfagtlfaPFA word @twominusPFA + $10 + word (@a_exit - @a_base)/4 + + word @nfagtlfaNFA + $10 +nfagtpfaNFA byte $87,"nfa>pfa" +nfagtpfaPFA word (@a_litw - @a_base)/4 + word $7FFF + word @andPFA + $10 + word @namelenPFA + $10 + word @plusPFA + $10 + word @alignwPFA + $10 + word (@a_exit - @a_base)/4 + + word @nfagtpfaNFA + $10 +nfagtnextNFA byte $88,"nfa>next" +nfagtnextPFA word @nfagtlfaPFA + $10 + word @watPFA + $10 + word (@a_exit - @a_base)/4 + + word @nfagtnextNFA + $10 +lastnfaNFA byte $87,"lastnfa" +lastnfaPFA word @mswlastnfaPFA + $10 + word @watPFA + $10 + word (@a_exit - @a_base)/4 + + word @lastnfaNFA + $10 +fnamecharqNFA byte $8A,"fnamechar?" +fnamecharqPFA word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0020 + word (@a_gt - @a_base)/4 + word (@a_swap - @a_base)/4 + word (@a_litw - @a_base)/4 + word $007F + word (@a_lt - @a_base)/4 + word @andPFA + $10 + word (@a_exit - @a_base)/4 + + word @fnamecharqNFA + $10 +fpfagtnfaNFA byte $88,"fpfa>nfa" +fpfagtnfaPFA word (@a_litw - @a_base)/4 + word $7FFF + word @andPFA + $10 + word @oneminusPFA + $10 + word @oneminusPFA + $10 + word (@a_dup - @a_base)/4 + word @catPFA + $10 + word @fnamecharqPFA + $10 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFF4 + word (@a_exit - @a_base)/4 + + word @fpfagtnfaNFA + $10 +apfagtnfaNFA byte $88,"apfa>nfa" +apfagtnfaPFA word @lastnfaPFA + $10 + word @twodupPFA + $10 + word @nfagtpfaPFA + $10 + word @watPFA + $10 + word (@a_eq - @a_base)/4 + word (@a_over - @a_base)/4 + word @catPFA + $10 + word (@a_litw - @a_base)/4 + word $0080 + word @andPFA + $10 + word @zeqPFA + $10 + word @andPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word @minusonePFA + $10 + word (@a_branch - @a_base)/4 + word $0008 + word @nfagtnextPFA + $10 + word (@a_dup - @a_base)/4 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFD8 + word @nipPFA + $10 + word (@a_exit - @a_base)/4 + + word @apfagtnfaNFA + $10 +pfagtnfaNFA byte $87,"pfa>nfa" +pfagtnfaPFA word (@a_dup - @a_base)/4 + word @fMaskPFA + $10 + word (@a_at - @a_base)/4 + word @andPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word @fpfagtnfaPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word @apfagtnfaPFA + $10 + word (@a_exit - @a_base)/4 + + word @pfagtnfaNFA + $10 +acceptNFA byte $86,"accept" +acceptPFA word (@a_litw - @a_base)/4 + word $0003 + word @maxPFA + $10 + word @twodupPFA + $10 + word @blPFA + $10 + word @fillPFA + $10 + word @oneminusPFA + $10 + word (@a_swap - @a_base)/4 + word @oneplusPFA + $10 + word (@a_swap - @a_base)/4 + word @boundsPFA + $10 + word @zPFA + $10 + word @keyPFA + $10 + word @eolqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000C + word @crPFA + $10 + word (@a_drop - @a_base)/4 + word @minusonePFA + $10 + word (@a_branch - @a_base)/4 + word $0052 + word @bsqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $002E + word (@a_drop - @a_base)/4 + word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0020 + word (@a_litw - @a_base)/4 + word $0008 + word @emitPFA + $10 + word @blPFA + $10 + word @emitPFA + $10 + word (@a_litw - @a_base)/4 + word $0008 + word @emitPFA + $10 + word @oneminusPFA + $10 + word (@a_swap - @a_base)/4 + word @oneminusPFA + $10 + word @blPFA + $10 + word (@a_over - @a_base)/4 + word @cbangPFA + $10 + word (@a_swap - @a_base)/4 + word @zPFA + $10 + word (@a_branch - @a_base)/4 + word $0020 + word @blPFA + $10 + word @maxPFA + $10 + word (@a_dup - @a_base)/4 + word @emitPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_gtr - @a_base)/4 + word (@a_over - @a_base)/4 + word @cbangPFA + $10 + word @oneplusPFA + $10 + word @twodupPFA + $10 + word @oneplusPFA + $10 + word (@a_eq - @a_base)/4 + word (@a_rgt - @a_base)/4 + word @oneplusPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $FF9C + word @nipPFA + $10 + word @nipPFA + $10 + word (@a_exit - @a_base)/4 + + word @acceptNFA + $10 +parseNFA byte $85,"parse" +parsePFA word @padsizePFA + $10 + word @mcwgtinPFA + $10 + word @watPFA + $10 + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0008 + word @zPFA + $10 + word (@a_branch - @a_base)/4 + word $0020 + word @zPFA + $10 + word @twodupPFA + $10 + word @padgtinPFA + $10 + word @plusPFA + $10 + word @catPFA + $10 + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0008 + word @minusonePFA + $10 + word (@a_branch - @a_base)/4 + word $0006 + word @oneplusPFA + $10 + word @zPFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFE6 + word @nipPFA + $10 + word (@a_exit - @a_base)/4 + + word @parseNFA + $10 +skipblNFA byte $86,"skipbl" +skipblPFA word @padgtinPFA + $10 + word @catPFA + $10 + word @blPFA + $10 + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0016 + word @mcwgtinPFA + $10 + word @watPFA + $10 + word @oneplusPFA + $10 + word (@a_dup - @a_base)/4 + word @mcwgtinPFA + $10 + word @wbangPFA + $10 + word @padsizePFA + $10 + word (@a_eq - @a_base)/4 + word (@a_branch - @a_base)/4 + word $0004 + word @minusonePFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFDC + word (@a_exit - @a_base)/4 + + word @skipblNFA + $10 +nextwordNFA byte $88,"nextword" +nextwordPFA word @padsizePFA + $10 + word @mcwgtinPFA + $10 + word @watPFA + $10 + word (@a_gt - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0012 + word @padgtinPFA + $10 + word @catPFA + $10 + word @mcwgtinPFA + $10 + word @watPFA + $10 + word @plusPFA + $10 + word @oneplusPFA + $10 + word @mcwgtinPFA + $10 + word @wbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @nextwordNFA + $10 +parsewordNFA byte $89,"parseword" +parsewordPFA word @skipblPFA + $10 + word @parsePFA + $10 + word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0014 + word @mcwgtinPFA + $10 + word @watPFA + $10 + word @oneminusPFA + $10 + word @twodupPFA + $10 + word @mcPadPFA + $10 + word @plusPFA + $10 + word @cbangPFA + $10 + word @mcwgtinPFA + $10 + word @wbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @parsewordNFA + $10 +parseblNFA byte $87,"parsebl" +parseblPFA word @blPFA + $10 + word @parsewordPFA + $10 + word @zltgtPFA + $10 + word (@a_exit - @a_base)/4 + + word @parseblNFA + $10 +padnwNFA byte $85,"padnw" +padnwPFA word @nextwordPFA + $10 + word @parseblPFA + $10 + word (@a_exit - @a_base)/4 + + word @padnwNFA + $10 +parsenwNFA byte $87,"parsenw" +parsenwPFA word @parseblPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000A + word @padgtinPFA + $10 + word @nextwordPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word @zPFA + $10 + word (@a_exit - @a_base)/4 + + word @parsenwNFA + $10 +padclrNFA byte $86,"padclr" +padclrPFA word @padnwPFA + $10 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFFA + word (@a_exit - @a_base)/4 + + word @padclrNFA + $10 +findNFA byte $84,"find" +findPFA word @lastnfaPFA + $10 + word (@a_over - @a_base)/4 + word (@a_fin - @a_base)/4 + word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0048 + word @nipPFA + $10 + word (@a_dup - @a_base)/4 + word @nfagtpfaPFA + $10 + word (@a_over - @a_base)/4 + word @catPFA + $10 + word (@a_litw - @a_base)/4 + word $0080 + word @andPFA + $10 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0004 + word @watPFA + $10 + word (@a_swap - @a_base)/4 + word @catPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0040 + word @andPFA + $10 + word (@a_zbranch - @a_base)/4 + word $001C + word (@a_litw - @a_base)/4 + word $0020 + word @andPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000A + word (@a_litw - @a_base)/4 + word $0002 + word (@a_branch - @a_base)/4 + word $0006 + word (@a_litw - @a_base)/4 + word $0001 + word (@a_branch - @a_base)/4 + word $0006 + word (@a_drop - @a_base)/4 + word @minusonePFA + $10 + word (@a_exit - @a_base)/4 + + word @findNFA + $10 +lthashNFA byte $82,"<#" +lthashPFA word @numpadsizePFA + $10 + word @mcwgtoutPFA + $10 + word @wbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @lthashNFA + $10 +hashgtNFA byte $82,"#>" +hashgtPFA word (@a_drop - @a_base)/4 + word @numpadsizePFA + $10 + word @mcwgtoutPFA + $10 + word @watPFA + $10 + word @minusPFA + $10 + word @minusonePFA + $10 + word @mcwgtoutPFA + $10 + word @wplusbangPFA + $10 + word @padgtoutPFA + $10 + word @cbangPFA + $10 + word @padgtoutPFA + $10 + word (@a_exit - @a_base)/4 + + word @hashgtNFA + $10 +tocharNFA byte $86,"tochar" +tocharPFA word (@a_litw - @a_base)/4 + word $001F + word @andPFA + $10 + word (@a_litw - @a_base)/4 + word $0030 + word @plusPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0039 + word (@a_gt - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0008 + word (@a_litw - @a_base)/4 + word $0007 + word @plusPFA + $10 + word (@a_exit - @a_base)/4 + + word @tocharNFA + $10 +hashNFA byte $81,"#" +hashPFA word @mcwBasePFA + $10 + word @watPFA + $10 + word @uslashmodPFA + $10 + word (@a_swap - @a_base)/4 + word @tocharPFA + $10 + word @minusonePFA + $10 + word @mcwgtoutPFA + $10 + word @wplusbangPFA + $10 + word @padgtoutPFA + $10 + word @cbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @hashNFA + $10 +hashsNFA byte $82,"#s" +hashsPFA word @hashPFA + $10 + word (@a_dup - @a_base)/4 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFF8 + word (@a_exit - @a_base)/4 + + word @hashsNFA + $10 +dotNFA byte $81,"." +dotPFA word (@a_dup - @a_base)/4 + word @zltPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000A + word (@a_litw - @a_base)/4 + word $002D + word @emitPFA + $10 + word @negatePFA + $10 + word @lthashPFA + $10 + word @hashsPFA + $10 + word @hashgtPFA + $10 + word @dotcstrPFA + $10 + word (@a_litw - @a_base)/4 + word $0020 + word @emitPFA + $10 + word (@a_exit - @a_base)/4 + + word @dotNFA + $10 +cogidNFA byte $85,"cogid" +cogidPFA word @minusonePFA + $10 + word (@a_litw - @a_base)/4 + word $0001 + word (@a_hubop - @a_base)/4 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @cogidNFA + $10 +locknewNFA byte $87,"locknew" +locknewPFA word @minusonePFA + $10 + word (@a_litw - @a_base)/4 + word $0004 + word (@a_hubop - @a_base)/4 + word @minusonePFA + $10 + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0006 + word (@a_drop - @a_base)/4 + word @minusonePFA + $10 + word (@a_exit - @a_base)/4 + + word @locknewNFA + $10 +lockretNFA byte $87,"lockret" +lockretPFA word (@a_litw - @a_base)/4 + word $0005 + word (@a_hubop - @a_base)/4 + word @twodropPFA + $10 + word (@a_exit - @a_base)/4 + + word @lockretNFA + $10 +locksetNFA byte $87,"lockset" +locksetPFA word (@a_litw - @a_base)/4 + word $0006 + word (@a_hubop - @a_base)/4 + word @nipPFA + $10 + word (@a_exit - @a_base)/4 + + word @locksetNFA + $10 +lockclrNFA byte $87,"lockclr" +lockclrPFA word (@a_litw - @a_base)/4 + word $0007 + word (@a_hubop - @a_base)/4 + word @nipPFA + $10 + word (@a_exit - @a_base)/4 + + word @lockclrNFA + $10 +lockdictqNFA byte $89,"lockdict?" +lockdictqPFA word @mydictlockPFA + $10 + word @watPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0010 + word (@a_litw - @a_base)/4 + word $0001 + word @mydictlockPFA + $10 + word @wplusbangPFA + $10 + word @minusonePFA + $10 + word (@a_branch - @a_base)/4 + word $001C + word @zPFA + $10 + word @locksetPFA + $10 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0010 + word (@a_litw - @a_base)/4 + word $0001 + word @mydictlockPFA + $10 + word @wbangPFA + $10 + word @minusonePFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word @zPFA + $10 + word (@a_exit - @a_base)/4 + + word @lockdictqNFA + $10 +freedictNFA byte $88,"freedict" +freedictPFA word @mydictlockPFA + $10 + word @watPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $001A + word @oneminusPFA + $10 + word (@a_dup - @a_base)/4 + word @mydictlockPFA + $10 + word @wbangPFA + $10 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word @zPFA + $10 + word @lockclrPFA + $10 + word (@a_drop - @a_base)/4 + word (@a_branch - @a_base)/4 + word $0004 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @freedictNFA + $10 +lockdictNFA byte $88,"lockdict" +lockdictPFA word @lockdictqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFFC + word (@a_exit - @a_base)/4 + + word @lockdictNFA + $10 +_eoomNFA byte $85,"_eoom" +_eoomPFA word @dqPFA + $10 + byte $0D,"Out of memory" + word @crPFA + $10 + word (@a_exit - @a_base)/4 + + word @_eoomNFA + $10 +checkdictNFA byte $89,"checkdict" +checkdictPFA word @mswHerePFA + $10 + word @watPFA + $10 + word @plusPFA + $10 + word @mswDictendPFA + $10 + word @watPFA + $10 + word @gteqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0014 + word @crPFA + $10 + word @mswHerePFA + $10 + word @watPFA + $10 + word @dotPFA + $10 + word @mswDictendPFA + $10 + word @dotPFA + $10 + word @_eoomPFA + $10 + word @clearkeysPFA + $10 + word @resetPFA + $10 + word (@a_exit - @a_base)/4 + + word @checkdictNFA + $10 +_coneNFA byte $83,"_c1" +_conePFA word @lockdictPFA + $10 + word @mswlastnfaPFA + $10 + word @watPFA + $10 + word @mswHerePFA + $10 + word @watPFA + $10 + word (@a_dup - @a_base)/4 + word @twoplusPFA + $10 + word @mswlastnfaPFA + $10 + word @wbangPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_over - @a_base)/4 + word @wbangPFA + $10 + word @twoplusPFA + $10 + word (@a_exit - @a_base)/4 + + word @_coneNFA + $10 +_ctwoNFA byte $83,"_c2" +_ctwoPFA word (@a_over - @a_base)/4 + word @namecopyPFA + $10 + word @namelenPFA + $10 + word @plusPFA + $10 + word @alignwPFA + $10 + word @mswHerePFA + $10 + word @wbangPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @_ctwoNFA + $10 +ccreateNFA byte $87,"ccreate" +ccreatePFA word @_conePFA + $10 + word (@a_swap - @a_base)/4 + word @_ctwoPFA + $10 + word (@a_exit - @a_base)/4 + + word @ccreateNFA + $10 +createNFA byte $86,"create" +createPFA word @blPFA + $10 + word @parsewordPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000A + word @_conePFA + $10 + word @padgtinPFA + $10 + word @_ctwoPFA + $10 + word @nextwordPFA + $10 + word (@a_exit - @a_base)/4 + + word @createNFA + $10 +clabelNFA byte $86,"clabel" +clabelPFA word @lockdictPFA + $10 + word @ccreatePFA + $10 + word @ca_a_doconwPFA + $10 + word @wcommaPFA + $10 + word @mcwAherePFA + $10 + word @watPFA + $10 + word @wcommaPFA + $10 + word @forthentryPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @clabelNFA + $10 +herelalNFA byte $87,"herelal" +herelalPFA word @lockdictPFA + $10 + word (@a_litw - @a_base)/4 + word $0004 + word @checkdictPFA + $10 + word @mswHerePFA + $10 + word @watPFA + $10 + word @alignlPFA + $10 + word @mswHerePFA + $10 + word @wbangPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @herelalNFA + $10 +herewalNFA byte $87,"herewal" +herewalPFA word @lockdictPFA + $10 + word (@a_litw - @a_base)/4 + word $0002 + word @checkdictPFA + $10 + word @mswHerePFA + $10 + word @watPFA + $10 + word @alignwPFA + $10 + word @mswHerePFA + $10 + word @wbangPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @herewalNFA + $10 +allotNFA byte $85,"allot" +allotPFA word @lockdictPFA + $10 + word (@a_dup - @a_base)/4 + word @checkdictPFA + $10 + word @mswHerePFA + $10 + word @wplusbangPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @allotNFA + $10 +aallotNFA byte $86,"aallot" +aallotPFA word @mcwAherePFA + $10 + word @wplusbangPFA + $10 + word @mcwAherePFA + $10 + word @watPFA + $10 + word @parPFA + $10 + word @gteqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0006 + word @_eoomPFA + $10 + word @resetPFA + $10 + word (@a_exit - @a_base)/4 + + word @aallotNFA + $10 +commaNFA byte $81,"," +commaPFA word @lockdictPFA + $10 + word @herelalPFA + $10 + word @mswHerePFA + $10 + word @watPFA + $10 + word @mbangPFA + $10 + word (@a_litw - @a_base)/4 + word $0004 + word @allotPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @commaNFA + $10 +acommaNFA byte $82,"a," +acommaPFA word @mcwAherePFA + $10 + word @watPFA + $10 + word (@a_bang - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0001 + word @aallotPFA + $10 + word (@a_exit - @a_base)/4 + + word @acommaNFA + $10 +wcommaNFA byte $82,"w," +wcommaPFA word @lockdictPFA + $10 + word @herewalPFA + $10 + word @mswHerePFA + $10 + word @watPFA + $10 + word @wbangPFA + $10 + word (@a_litw - @a_base)/4 + word $0002 + word @allotPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @wcommaNFA + $10 +ccommaNFA byte $82,"c," +ccommaPFA word @lockdictPFA + $10 + word @mswHerePFA + $10 + word @watPFA + $10 + word @cbangPFA + $10 + word (@a_litw - @a_base)/4 + word $0001 + word @allotPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @ccommaNFA + $10 +orlnfaNFA byte $86,"orlnfa" +orlnfaPFA word @lockdictPFA + $10 + word @lastnfaPFA + $10 + word @orcbangPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @orlnfaNFA + $10 +forthentryNFA byte $8A,"forthentry" +forthentryPFA word @lockdictPFA + $10 + word (@a_litw - @a_base)/4 + word $0080 + word @orlnfaPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @forthentryNFA + $10 +immediateNFA byte $89,"immediate" +immediatePFA word @lockdictPFA + $10 + word (@a_litw - @a_base)/4 + word $0040 + word @orlnfaPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @immediateNFA + $10 +execNFA byte $84,"exec" +execPFA word @lockdictPFA + $10 + word (@a_litw - @a_base)/4 + word $0060 + word @orlnfaPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @execNFA + $10 +leaveNFA byte $85,"leave" +leavePFA word (@a_rgt - @a_base)/4 + word (@a_rgt - @a_base)/4 + word (@a_rgt - @a_base)/4 + word (@a_drop - @a_base)/4 + word (@a_dup - @a_base)/4 + word (@a_twogtr - @a_base)/4 + word (@a_gtr - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @leaveNFA + $10 +clearkeysNFA byte $89,"clearkeys" +clearkeysPFA word @zPFA + $10 + word @mcwStatePFA + $10 + word @wbangPFA + $10 + word @minusonePFA + $10 + word @mswKeyTOPFA + $10 + word @watPFA + $10 + word @zPFA + $10 + word (@a_twogtr - @a_base)/4 + word @keyqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000C + word @keyPFA + $10 + word (@a_drop - @a_base)/4 + word (@a_drop - @a_base)/4 + word @zPFA + $10 + word @leavePFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFEE + word (@a_zbranch - @a_base)/4 + word $FFE0 + word (@a_exit - @a_base)/4 + + word @clearkeysNFA + $10 +wgtlNFA byte $83,"w>l" +wgtlPFA word (@a_litw - @a_base)/4 + word $FFFF + word @andPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0010 + word @lshiftPFA + $10 + word @orPFA + $10 + word (@a_exit - @a_base)/4 + + word @wgtlNFA + $10 +lgtwNFA byte $83,"l>w" +lgtwPFA word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0010 + word @rshiftPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_litw - @a_base)/4 + word $FFFF + word @andPFA + $10 + word (@a_exit - @a_base)/4 + + word @lgtwNFA + $10 +colonNFA byte $81,":" +colonPFA word @lockdictPFA + $10 + word @createPFA + $10 + word (@a_litw - @a_base)/4 + word $3741 + word (@a_litw - @a_base)/4 + word $0001 + word @mcwStatePFA + $10 + word @wbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @colonNFA + $10 +_mmcsNFA byte $85,"_mmcs" +_mmcsPFA word @dqPFA + $10 + byte $1F,"MISMATCHED CONTROL STRUCTURE(S)" + word @crPFA + $10 + word @clearkeysPFA + $10 + word (@a_exit - @a_base)/4 + + word @_mmcsNFA + $10 +_scolonNFA byte $82,"_;" +_scolonPFA word @wcommaPFA + $10 + word @zPFA + $10 + word @mcwStatePFA + $10 + word @wbangPFA + $10 + word @forthentryPFA + $10 + word (@a_litw - @a_base)/4 + word $3741 + word @ltgtPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0004 + word @_mmcsPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @_scolonNFA + $10 +scolonscolonNFA byte $C2,";;" +scolonscolonPFA word @ca_a_exitPFA + $10 + word @_scolonPFA + $10 + word (@a_exit - @a_base)/4 + + word @scolonscolonNFA + $10 +scolonNFA byte $C1,";" +scolonPFA word @ca_a_exitPFA + $10 + word @_scolonPFA + $10 + word (@a_exit - @a_base)/4 + + word @scolonNFA + $10 +dothenNFA byte $86,"dothen" +dothenPFA word @lgtwPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $1235 + word (@a_eq - @a_base)/4 + word (@a_swap - @a_base)/4 + word (@a_litw - @a_base)/4 + word $1239 + word (@a_eq - @a_base)/4 + word @orPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0014 + word (@a_dup - @a_base)/4 + word @mswHerePFA + $10 + word @watPFA + $10 + word (@a_swap - @a_base)/4 + word @minusPFA + $10 + word (@a_swap - @a_base)/4 + word @wbangPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word @_mmcsPFA + $10 + word (@a_exit - @a_base)/4 + + word @dothenNFA + $10 +thenNFA byte $C4,"then" +thenPFA word @dothenPFA + $10 + word (@a_exit - @a_base)/4 + + word @thenNFA + $10 +thensNFA byte $C5,"thens" +thensPFA word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $FFFF + word @andPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $1235 + word (@a_eq - @a_base)/4 + word (@a_swap - @a_base)/4 + word (@a_litw - @a_base)/4 + word $1239 + word (@a_eq - @a_base)/4 + word @orPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000A + word @dothenPFA + $10 + word @zPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word @minusonePFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFD6 + word (@a_exit - @a_base)/4 + + word @thensNFA + $10 +ifNFA byte $C2,"if" +ifPFA word @ca_a_zbranchPFA + $10 + word @wcommaPFA + $10 + word @mswHerePFA + $10 + word @watPFA + $10 + word (@a_litw - @a_base)/4 + word $1235 + word @wgtlPFA + $10 + word @zPFA + $10 + word @wcommaPFA + $10 + word (@a_exit - @a_base)/4 + + word @ifNFA + $10 +elseNFA byte $C4,"else" +elsePFA word @ca_a_branchPFA + $10 + word @wcommaPFA + $10 + word @zPFA + $10 + word @wcommaPFA + $10 + word @dothenPFA + $10 + word @mswHerePFA + $10 + word @watPFA + $10 + word @twominusPFA + $10 + word (@a_litw - @a_base)/4 + word $1239 + word @wgtlPFA + $10 + word (@a_exit - @a_base)/4 + + word @elseNFA + $10 +untilNFA byte $C5,"until" +untilPFA word @lgtwPFA + $10 + word (@a_litw - @a_base)/4 + word $1317 + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0012 + word @ca_a_zbranchPFA + $10 + word @wcommaPFA + $10 + word @mswHerePFA + $10 + word @watPFA + $10 + word @minusPFA + $10 + word @wcommaPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word @_mmcsPFA + $10 + word (@a_exit - @a_base)/4 + + word @untilNFA + $10 +beginNFA byte $C5,"begin" +beginPFA word @mswHerePFA + $10 + word @watPFA + $10 + word (@a_litw - @a_base)/4 + word $1317 + word @wgtlPFA + $10 + word (@a_exit - @a_base)/4 + + word @beginNFA + $10 +doloopNFA byte $86,"doloop" +doloopPFA word (@a_swap - @a_base)/4 + word @lgtwPFA + $10 + word (@a_litw - @a_base)/4 + word $2329 + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0012 + word (@a_swap - @a_base)/4 + word @wcommaPFA + $10 + word @mswHerePFA + $10 + word @watPFA + $10 + word @minusPFA + $10 + word @wcommaPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word @_mmcsPFA + $10 + word (@a_exit - @a_base)/4 + + word @doloopNFA + $10 +loopNFA byte $C4,"loop" +loopPFA word @ca_a_lparenlooprparenPFA + $10 + word @doloopPFA + $10 + word (@a_exit - @a_base)/4 + + word @loopNFA + $10 +plusloopNFA byte $C5,"+loop" +plusloopPFA word @ca_a_lparenpluslooprparenPFA + $10 + word @doloopPFA + $10 + word (@a_exit - @a_base)/4 + + word @plusloopNFA + $10 +doNFA byte $C2,"do" +doPFA word @ca_a_twogtrPFA + $10 + word @wcommaPFA + $10 + word @mswHerePFA + $10 + word @watPFA + $10 + word (@a_litw - @a_base)/4 + word $2329 + word @wgtlPFA + $10 + word (@a_exit - @a_base)/4 + + word @doNFA + $10 +_ecsNFA byte $84,"_ecs" +_ecsPFA word (@a_litw - @a_base)/4 + word $003A + word @emitPFA + $10 + word @spacePFA + $10 + word (@a_exit - @a_base)/4 + + word @_ecsNFA + $10 +_udfNFA byte $84,"_udf" +_udfPFA word @dqPFA + $10 + byte $0F,"UNDEFINED WORD " + word (@a_exit - @a_base)/4 + + word @_udfNFA + $10 +dotquoteNFA byte $C2,".",$22 +dotquotePFA word @cm_dqPFA + $10 + word @wcommaPFA + $10 + word (@a_litw - @a_base)/4 + word $0001 + word @mcwgtinPFA + $10 + word @wplusbangPFA + $10 + word (@a_litw - @a_base)/4 + word $0022 + word @parsePFA + $10 + word (@a_dup - @a_base)/4 + word @ccommaPFA + $10 + word (@a_dup - @a_base)/4 + word @padgtinPFA + $10 + word @mswHerePFA + $10 + word @watPFA + $10 + word (@a_rot - @a_base)/4 + word @cmovePFA + $10 + word (@a_dup - @a_base)/4 + word @allotPFA + $10 + word @oneplusPFA + $10 + word @mcwgtinPFA + $10 + word @wplusbangPFA + $10 + word @herewalPFA + $10 + word (@a_exit - @a_base)/4 + + word @dotquoteNFA + $10 +fisnumberNFA byte $89,"fisnumber" +fisnumberPFA word @isnumberPFA + $10 + word (@a_exit - @a_base)/4 + + word @fisnumberNFA + $10 +fnumberNFA byte $87,"fnumber" +fnumberPFA word @numberPFA + $10 + word (@a_exit - @a_base)/4 + + word @fnumberNFA + $10 +interpretpadNFA byte $8C,"interpretpad" +interpretpadPFA word @zPFA + $10 + word @mcwgtinPFA + $10 + word @wbangPFA + $10 + word @blPFA + $10 + word @parsewordPFA + $10 + word (@a_zbranch - @a_base)/4 + word $00BE + word @padgtinPFA + $10 + word @nextwordPFA + $10 + word @findPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0062 + word (@a_dup - @a_base)/4 + word @minusonePFA + $10 + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0018 + word (@a_drop - @a_base)/4 + word @compileqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word @wcommaPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word @executePFA + $10 + word @zPFA + $10 + word (@a_branch - @a_base)/4 + word $003E + word (@a_litw - @a_base)/4 + word $0002 + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $000A + word @executePFA + $10 + word @zPFA + $10 + word (@a_branch - @a_base)/4 + word $002C + word @compileqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000A + word @executePFA + $10 + word @zPFA + $10 + word (@a_branch - @a_base)/4 + word $001E + word @pfagtnfaPFA + $10 + word @dqPFA + $10 + byte $0F,"IMMEDIATE WORD " + word @dotstrnamePFA + $10 + word @clearkeysPFA + $10 + word @crPFA + $10 + word @minusonePFA + $10 + word (@a_branch - @a_base)/4 + word $004E + word (@a_drop - @a_base)/4 + word (@a_dup - @a_base)/4 + word @catplusplusPFA + $10 + word @fisnumberPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0030 + word @catplusplusPFA + $10 + word @fnumberPFA + $10 + word @compileqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0020 + word (@a_dup - @a_base)/4 + word @zPFA + $10 + word (@a_litw - @a_base)/4 + word $FFFF + word @betweenPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000C + word @ca_a_litwPFA + $10 + word @wcommaPFA + $10 + word @wcommaPFA + $10 + word (@a_branch - @a_base)/4 + word $0008 + word @ca_a_literalPFA + $10 + word @wcommaPFA + $10 + word @commaPFA + $10 + word @zPFA + $10 + word (@a_branch - @a_base)/4 + word $0014 + word @zPFA + $10 + word @mcwStatePFA + $10 + word @wbangPFA + $10 + word @freedictPFA + $10 + word @_udfPFA + $10 + word @dotstrnamePFA + $10 + word @crPFA + $10 + word @clearkeysPFA + $10 + word @minusonePFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word @minusonePFA + $10 + word (@a_zbranch - @a_base)/4 + word $FF38 + word (@a_exit - @a_base)/4 + + word @interpretpadNFA + $10 +sbozmNFA byte $83,"[0m" +sbozmPFA word (@a_exit - @a_base)/4 + + word @sbozmNFA + $10 +interpretNFA byte $89,"interpret" +interpretPFA word (@a_litw - @a_base)/4 + word $001B + word @emitPFA + $10 + word (@a_litw - @a_base)/4 + word $005B + word @emitPFA + $10 + word (@a_litw - @a_base)/4 + word $0033 + word @emitPFA + $10 + word (@a_litw - @a_base)/4 + word $0031 + word @emitPFA + $10 + word (@a_litw - @a_base)/4 + word $006D + word @emitPFA + $10 + word @mcPadPFA + $10 + word @padsizePFA + $10 + word @acceptPFA + $10 + word (@a_drop - @a_base)/4 + word (@a_litw - @a_base)/4 + word $001B + word @emitPFA + $10 + word (@a_litw - @a_base)/4 + word $005B + word @emitPFA + $10 + word (@a_litw - @a_base)/4 + word $0030 + word @emitPFA + $10 + word (@a_litw - @a_base)/4 + word $006D + word @emitPFA + $10 + word @interpretpadPFA + $10 + word (@a_exit - @a_base)/4 + + word @interpretNFA + $10 +variableNFA byte $88,"variable" +variablePFA word @lockdictPFA + $10 + word @createPFA + $10 + word @ca_a_dovarPFA + $10 + word @wcommaPFA + $10 + word @zPFA + $10 + word @commaPFA + $10 + word @forthentryPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @variableNFA + $10 +_wconeNFA byte $84,"_wc1" +_wconePFA word @lockdictPFA + $10 + word @createPFA + $10 + word @ca_a_doconwPFA + $10 + word @wcommaPFA + $10 + word @wcommaPFA + $10 + word @forthentryPFA + $10 + word @lastnfaPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @_wconeNFA + $10 +wconstantNFA byte $89,"wconstant" +wconstantPFA word @_wconePFA + $10 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @wconstantNFA + $10 +avariableNFA byte $89,"avariable" +avariablePFA word @mcwAherePFA + $10 + word @watPFA + $10 + word @_wconePFA + $10 + word (@a_litw - @a_base)/4 + word $0001 + word @aallotPFA + $10 + word (@a_exit - @a_base)/4 + + word @avariableNFA + $10 +wvariableNFA byte $89,"wvariable" +wvariablePFA word @lockdictPFA + $10 + word @createPFA + $10 + word @ca_a_dovarwPFA + $10 + word @wcommaPFA + $10 + word @zPFA + $10 + word @wcommaPFA + $10 + word @forthentryPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @wvariableNFA + $10 +constantNFA byte $88,"constant" +constantPFA word @lockdictPFA + $10 + word @createPFA + $10 + word @ca_a_doconPFA + $10 + word @wcommaPFA + $10 + word @commaPFA + $10 + word @forthentryPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @constantNFA + $10 +asmlabelNFA byte $88,"asmlabel" +asmlabelPFA word @lockdictPFA + $10 + word @createPFA + $10 + word @wcommaPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @asmlabelNFA + $10 +hexNFA byte $83,"hex" +hexPFA word (@a_litw - @a_base)/4 + word $0010 + word @mcwBasePFA + $10 + word @wbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @hexNFA + $10 +decimalNFA byte $87,"decimal" +decimalPFA word (@a_litw - @a_base)/4 + word $000A + word @mcwBasePFA + $10 + word @wbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @decimalNFA + $10 +_wordsNFA byte $86,"_words" +_wordsPFA word @zPFA + $10 + word (@a_gtr - @a_base)/4 + word @lastnfaPFA + $10 + word @dqPFA + $10 + byte $26,"NFA (Forth/Asm Immediate eXecute) Name" + word @twodupPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0008 + word @npfxPFA + $10 + word (@a_branch - @a_base)/4 + word $0006 + word @twodropPFA + $10 + word @minusonePFA + $10 + word (@a_zbranch - @a_base)/4 + word $008A + word (@a_rgt - @a_base)/4 + word (@a_dup - @a_base)/4 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0004 + word @crPFA + $10 + word @oneplusPFA + $10 + word (@a_litw - @a_base)/4 + word $0003 + word @andPFA + $10 + word (@a_gtr - @a_base)/4 + word (@a_dup - @a_base)/4 + word @dotwordPFA + $10 + word @spacePFA + $10 + word (@a_dup - @a_base)/4 + word @catPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0080 + word @andPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000A + word (@a_litw - @a_base)/4 + word $0046 + word (@a_branch - @a_base)/4 + word $0006 + word (@a_litw - @a_base)/4 + word $0041 + word @emitPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0040 + word @andPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000A + word (@a_litw - @a_base)/4 + word $0049 + word (@a_branch - @a_base)/4 + word $0006 + word (@a_litw - @a_base)/4 + word $0020 + word @emitPFA + $10 + word (@a_litw - @a_base)/4 + word $0020 + word @andPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000A + word (@a_litw - @a_base)/4 + word $0058 + word (@a_branch - @a_base)/4 + word $0006 + word (@a_litw - @a_base)/4 + word $0020 + word @emitPFA + $10 + word @spacePFA + $10 + word (@a_dup - @a_base)/4 + word @dotstrnamePFA + $10 + word (@a_dup - @a_base)/4 + word @catPFA + $10 + word @namemaxPFA + $10 + word @andPFA + $10 + word (@a_litw - @a_base)/4 + word $0015 + word (@a_swap - @a_base)/4 + word @minusPFA + $10 + word @zPFA + $10 + word @maxPFA + $10 + word @spacesPFA + $10 + word @nfagtnextPFA + $10 + word (@a_dup - @a_base)/4 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $FF58 + word (@a_rgt - @a_base)/4 + word @threedropPFA + $10 + word @crPFA + $10 + word (@a_exit - @a_base)/4 + + word @_wordsNFA + $10 +wordsNFA byte $85,"words" +wordsPFA word @parsenwPFA + $10 + word @_wordsPFA + $10 + word (@a_exit - @a_base)/4 + + word @wordsNFA + $10 +del_msNFA byte $86,"del_ms" +del_msPFA word (@a_literal - @a_base)/4 + long $7FFFFFFF + word @clkfreqPFA + $10 + word (@a_litw - @a_base)/4 + word $03E8 + word @uslashPFA + $10 + word @uslashPFA + $10 + word @minPFA + $10 + word (@a_litw - @a_base)/4 + word $0001 + word @maxPFA + $10 + word @clkfreqPFA + $10 + word (@a_litw - @a_base)/4 + word $03E8 + word @uslashPFA + $10 + word @ustarPFA + $10 + word @cntPFA + $10 + word (@a_at - @a_base)/4 + word @plusPFA + $10 + word (@a_dup - @a_base)/4 + word @cntPFA + $10 + word (@a_at - @a_base)/4 + word @minusPFA + $10 + word @zltPFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFF4 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @del_msNFA + $10 +del_secNFA byte $87,"del_sec" +del_secPFA word (@a_litw - @a_base)/4 + word $0010 + word @uslashmodPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0014 + word @zPFA + $10 + word (@a_twogtr - @a_base)/4 + word (@a_litw - @a_base)/4 + word $3E80 + word @del_msPFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFF8 + word (@a_branch - @a_base)/4 + word $0004 + word (@a_drop - @a_base)/4 + word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0014 + word @zPFA + $10 + word (@a_twogtr - @a_base)/4 + word (@a_litw - @a_base)/4 + word $03E8 + word @del_msPFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFF8 + word (@a_branch - @a_base)/4 + word $0004 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @del_secNFA + $10 +gtmNFA byte $82,">m" +gtmPFA word (@a_litw - @a_base)/4 + word $0001 + word (@a_swap - @a_base)/4 + word @lshiftPFA + $10 + word (@a_exit - @a_base)/4 + + word @gtmNFA + $10 +pxiNFA byte $83,"pxi" +pxiPFA word @gtmPFA + $10 + word @invertPFA + $10 + word @diraPFA + $10 + word (@a_at - @a_base)/4 + word @andPFA + $10 + word @diraPFA + $10 + word (@a_bang - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @pxiNFA + $10 +pxoNFA byte $83,"pxo" +pxoPFA word @gtmPFA + $10 + word @diraPFA + $10 + word (@a_at - @a_base)/4 + word @orPFA + $10 + word @diraPFA + $10 + word (@a_bang - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @pxoNFA + $10 +pxlNFA byte $83,"pxl" +pxlPFA word @gtmPFA + $10 + word (@a_mpxl - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @pxlNFA + $10 +pxhNFA byte $83,"pxh" +pxhPFA word @gtmPFA + $10 + word (@a_mpxh - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @pxhNFA + $10 +pxNFA byte $82,"px" +pxPFA word (@a_swap - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0008 + word @pxhPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word @pxlPFA + $10 + word (@a_exit - @a_base)/4 + + word @pxNFA + $10 +pxqNFA byte $83,"px?" +pxqPFA word @gtmPFA + $10 + word (@a_mpx - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @pxqNFA + $10 +_sclNFA byte $84,"_scl" +_sclPFA word (@a_doconw - @a_base)/4 + word $001C + + word @_sclNFA + $10 +_sdaNFA byte $84,"_sda" +_sdaPFA word (@a_doconw - @a_base)/4 + word $001D + + word @_sdaNFA + $10 +_sclmNFA byte $85,"_sclm" +_sclmPFA word (@a_docon - @a_base)/4 + long $10000000 + + word @_sclmNFA + $10 +_sdamNFA byte $85,"_sdam" +_sdamPFA word (@a_docon - @a_base)/4 + long $20000000 + + word @_sdamNFA + $10 +_sdaiNFA byte $85,"_sdai" +_sdaiPFA word @_sdaPFA + $10 + word @pxiPFA + $10 + word (@a_exit - @a_base)/4 + + word @_sdaiNFA + $10 +_sdaoNFA byte $85,"_sdao" +_sdaoPFA word @_sdaPFA + $10 + word @pxoPFA + $10 + word (@a_exit - @a_base)/4 + + word @_sdaoNFA + $10 +_scliNFA byte $85,"_scli" +_scliPFA word @_sclPFA + $10 + word @pxiPFA + $10 + word (@a_exit - @a_base)/4 + + word @_scliNFA + $10 +_scloNFA byte $85,"_sclo" +_scloPFA word @_sclPFA + $10 + word @pxoPFA + $10 + word (@a_exit - @a_base)/4 + + word @_scloNFA + $10 +_sdalNFA byte $85,"_sdal" +_sdalPFA word @_sdamPFA + $10 + word (@a_mpxl - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @_sdalNFA + $10 +_sdahNFA byte $85,"_sdah" +_sdahPFA word @_sdamPFA + $10 + word (@a_mpxh - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @_sdahNFA + $10 +_scllNFA byte $85,"_scll" +_scllPFA word @_sclmPFA + $10 + word (@a_mpxl - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @_scllNFA + $10 +_sclhNFA byte $85,"_sclh" +_sclhPFA word @_sclmPFA + $10 + word (@a_mpxh - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @_sclhNFA + $10 +_sdaqNFA byte $85,"_sda?" +_sdaqPFA word @_sdamPFA + $10 + word (@a_mpx - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @_sdaqNFA + $10 +_eeInitNFA byte $87,"_eeInit" +_eeInitPFA word @_sclhPFA + $10 + word @_scloPFA + $10 + word @_sdaiPFA + $10 + word (@a_litw - @a_base)/4 + word $0009 + word @zPFA + $10 + word (@a_twogtr - @a_base)/4 + word @_scllPFA + $10 + word @_sclhPFA + $10 + word @_sdaqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0004 + word @leavePFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFF2 + word (@a_exit - @a_base)/4 + + word @_eeInitNFA + $10 +_eeStartNFA byte $88,"_eeStart" +_eeStartPFA word @_sclhPFA + $10 + word @_scloPFA + $10 + word @_sdahPFA + $10 + word @_sdaoPFA + $10 + word @_sdalPFA + $10 + word @_scllPFA + $10 + word (@a_exit - @a_base)/4 + + word @_eeStartNFA + $10 +_eeStopNFA byte $87,"_eeStop" +_eeStopPFA word @_sclhPFA + $10 + word @_sdahPFA + $10 + word @_scliPFA + $10 + word @_sdaiPFA + $10 + word (@a_exit - @a_base)/4 + + word @_eeStopNFA + $10 +_eeWriteNFA byte $88,"_eeWrite" +_eeWritePFA word (@a_litw - @a_base)/4 + word $0080 + word (@a_litw - @a_base)/4 + word $0008 + word @zPFA + $10 + word (@a_twogtr - @a_base)/4 + word @twodupPFA + $10 + word @andPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word @_sdahPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word @_sdalPFA + $10 + word @_sclhPFA + $10 + word @_scllPFA + $10 + word (@a_litw - @a_base)/4 + word $0001 + word @rshiftPFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFE4 + word @twodropPFA + $10 + word @_sdaiPFA + $10 + word @_sclhPFA + $10 + word @_sdaqPFA + $10 + word @_scllPFA + $10 + word @_sdalPFA + $10 + word @_sdaoPFA + $10 + word (@a_exit - @a_base)/4 + + word @_eeWriteNFA + $10 +_eeReadNFA byte $87,"_eeRead" +_eeReadPFA word @_sdaiPFA + $10 + word @zPFA + $10 + word (@a_litw - @a_base)/4 + word $0008 + word @zPFA + $10 + word (@a_twogtr - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0001 + word @lshiftPFA + $10 + word @_sclhPFA + $10 + word @_sdaqPFA + $10 + word @_scllPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word (@a_litw - @a_base)/4 + word $0001 + word @orPFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFE8 + word (@a_swap - @a_base)/4 + word @_sdaPFA + $10 + word @pxPFA + $10 + word @_sdaoPFA + $10 + word @_sclhPFA + $10 + word @_scllPFA + $10 + word @_sdalPFA + $10 + word (@a_exit - @a_base)/4 + + word @_eeReadNFA + $10 +eeReadPageNFA byte $8A,"eeReadPage" +eeReadPagePFA word (@a_litw - @a_base)/4 + word $0001 + word @locksetPFA + $10 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFF6 + word (@a_litw - @a_base)/4 + word $0001 + word @maxPFA + $10 + word (@a_rot - @a_base)/4 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $00FF + word @andPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0008 + word @rshiftPFA + $10 + word (@a_litw - @a_base)/4 + word $00FF + word @andPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0010 + word @rshiftPFA + $10 + word (@a_litw - @a_base)/4 + word $0007 + word @andPFA + $10 + word (@a_litw - @a_base)/4 + word $0001 + word @lshiftPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_gtr - @a_base)/4 + word @_eeStartPFA + $10 + word (@a_litw - @a_base)/4 + word $00A0 + word @orPFA + $10 + word @_eeWritePFA + $10 + word (@a_swap - @a_base)/4 + word @_eeWritePFA + $10 + word @orPFA + $10 + word (@a_swap - @a_base)/4 + word @_eeWritePFA + $10 + word @orPFA + $10 + word @_eeStartPFA + $10 + word (@a_rgt - @a_base)/4 + word (@a_litw - @a_base)/4 + word $00A1 + word @orPFA + $10 + word @_eeWritePFA + $10 + word @orPFA + $10 + word @rottwoPFA + $10 + word @boundsPFA + $10 + word (@a_twogtr - @a_base)/4 + word @lastiqPFA + $10 + word @_eeReadPFA + $10 + word @iPFA + $10 + word @cbangPFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFF6 + word @_eeStopPFA + $10 + word (@a_litw - @a_base)/4 + word $0001 + word @lockclrPFA + $10 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @eeReadPageNFA + $10 +eeWritePageNFA byte $8B,"eeWritePage" +eeWritePagePFA word (@a_litw - @a_base)/4 + word $0001 + word @locksetPFA + $10 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFF6 + word (@a_litw - @a_base)/4 + word $0001 + word @maxPFA + $10 + word (@a_rot - @a_base)/4 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $00FF + word @andPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0008 + word @rshiftPFA + $10 + word (@a_litw - @a_base)/4 + word $00FF + word @andPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0010 + word @rshiftPFA + $10 + word (@a_litw - @a_base)/4 + word $0007 + word @andPFA + $10 + word (@a_litw - @a_base)/4 + word $0001 + word @lshiftPFA + $10 + word @_eeStartPFA + $10 + word (@a_litw - @a_base)/4 + word $00A0 + word @orPFA + $10 + word @_eeWritePFA + $10 + word (@a_swap - @a_base)/4 + word @_eeWritePFA + $10 + word @orPFA + $10 + word (@a_swap - @a_base)/4 + word @_eeWritePFA + $10 + word @orPFA + $10 + word @rottwoPFA + $10 + word @boundsPFA + $10 + word (@a_twogtr - @a_base)/4 + word @iPFA + $10 + word @catPFA + $10 + word @_eeWritePFA + $10 + word @orPFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFF6 + word @_eeStopPFA + $10 + word (@a_litw - @a_base)/4 + word $0010 + word @del_msPFA + $10 + word (@a_litw - @a_base)/4 + word $0001 + word @lockclrPFA + $10 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @eeWritePageNFA + $10 +eeErrNFA byte $85,"eeErr" +eeErrPFA word @dqPFA + $10 + byte $0C,"eeProm error" + word (@a_exit - @a_base)/4 + + word @eeErrNFA + $10 +eeReadWordNFA byte $8A,"eeReadWord" +eeReadWordPFA word @mcwTzPFA + $10 + word (@a_litw - @a_base)/4 + word $0002 + word @eeReadPagePFA + $10 + word (@a_zbranch - @a_base)/4 + word $0006 + word @eeErrPFA + $10 + word @crPFA + $10 + word @mcwTzPFA + $10 + word @watPFA + $10 + word (@a_exit - @a_base)/4 + + word @eeReadWordNFA + $10 +eeWriteWordNFA byte $8B,"eeWriteWord" +eeWriteWordPFA word (@a_swap - @a_base)/4 + word @mcwTzPFA + $10 + word @wbangPFA + $10 + word @mcwTzPFA + $10 + word (@a_litw - @a_base)/4 + word $0002 + word @eeWritePagePFA + $10 + word (@a_zbranch - @a_base)/4 + word $0006 + word @eeErrPFA + $10 + word @crPFA + $10 + word (@a_exit - @a_base)/4 + + word @eeWriteWordNFA + $10 +eeReadByteNFA byte $8A,"eeReadByte" +eeReadBytePFA word @eeReadWordPFA + $10 + word (@a_litw - @a_base)/4 + word $00FF + word @andPFA + $10 + word (@a_exit - @a_base)/4 + + word @eeReadByteNFA + $10 +eeCopyNFA byte $86,"eeCopy" +eeCopyPFA word (@a_litw - @a_base)/4 + word $007F + word @invertPFA + $10 + word @andPFA + $10 + word (@a_rot - @a_base)/4 + word (@a_litw - @a_base)/4 + word $007F + word @invertPFA + $10 + word @andPFA + $10 + word (@a_rot - @a_base)/4 + word (@a_litw - @a_base)/4 + word $007F + word @invertPFA + $10 + word @andPFA + $10 + word (@a_rot - @a_base)/4 + word @zPFA + $10 + word (@a_twogtr - @a_base)/4 + word (@a_over - @a_base)/4 + word @iPFA + $10 + word @plusPFA + $10 + word (@a_dup - @a_base)/4 + word @dotPFA + $10 + word @mcPadPFA + $10 + word (@a_litw - @a_base)/4 + word $0080 + word @eeReadPagePFA + $10 + word (@a_zbranch - @a_base)/4 + word $0006 + word @eeErrPFA + $10 + word @leavePFA + $10 + word (@a_dup - @a_base)/4 + word @iPFA + $10 + word @plusPFA + $10 + word (@a_dup - @a_base)/4 + word @dotPFA + $10 + word @mcPadPFA + $10 + word (@a_litw - @a_base)/4 + word $0080 + word @eeWritePagePFA + $10 + word (@a_zbranch - @a_base)/4 + word $0006 + word @eeErrPFA + $10 + word @leavePFA + $10 + word @iPFA + $10 + word (@a_litw - @a_base)/4 + word $03FF + word @andPFA + $10 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0004 + word @crPFA + $10 + word (@a_litw - @a_base)/4 + word $0080 + word (@a_lparenpluslooprparen - @a_base)/4 + word $FFB6 + word @twodropPFA + $10 + word @cogidPFA + $10 + word @cogPadclrPFA + $10 + word (@a_exit - @a_base)/4 + + word @eeCopyNFA + $10 +_doneNFA byte $83,"_d1" +_donePFA word @crPFA + $10 + word (@a_over - @a_base)/4 + word @dotwordPFA + $10 + word @spacePFA + $10 + word (@a_dup - @a_base)/4 + word @dotwordPFA + $10 + word @_ecsPFA + $10 + word @boundsPFA + $10 + word (@a_exit - @a_base)/4 + + word @_doneNFA + $10 +_dtwoNFA byte $83,"_d2" +_dtwoPFA word @crPFA + $10 + word @dotwordPFA + $10 + word @_ecsPFA + $10 + word (@a_exit - @a_base)/4 + + word @_dtwoNFA + $10 +_dthreeNFA byte $83,"_d3" +_dthreePFA word @mcTPFA + $10 + word (@a_litw - @a_base)/4 + word $0010 + word @boundsPFA + $10 + word (@a_twogtr - @a_base)/4 + word @iPFA + $10 + word @catPFA + $10 + word @dotbytePFA + $10 + word @spacePFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFF6 + word (@a_litw - @a_base)/4 + word $0002 + word @spacesPFA + $10 + word @mcTPFA + $10 + word (@a_litw - @a_base)/4 + word $0010 + word @dotstrPFA + $10 + word (@a_exit - @a_base)/4 + + word @_dthreeNFA + $10 +dumpNFA byte $84,"dump" +dumpPFA word @_donePFA + $10 + word (@a_twogtr - @a_base)/4 + word @iPFA + $10 + word @_dtwoPFA + $10 + word @iPFA + $10 + word @mcTPFA + $10 + word (@a_litw - @a_base)/4 + word $0010 + word @cmovePFA + $10 + word @_dthreePFA + $10 + word (@a_litw - @a_base)/4 + word $0010 + word (@a_lparenpluslooprparen - @a_base)/4 + word $FFEA + word @crPFA + $10 + word (@a_exit - @a_base)/4 + + word @dumpNFA + $10 +rdumpNFA byte $85,"rdump" +rdumpPFA word @_donePFA + $10 + word (@a_twogtr - @a_base)/4 + word @iPFA + $10 + word @_dtwoPFA + $10 + word @iPFA + $10 + word @mcTPFA + $10 + word (@a_litw - @a_base)/4 + word $0010 + word @eeReadPagePFA + $10 + word (@a_zbranch - @a_base)/4 + word $000C + word @mcTPFA + $10 + word (@a_litw - @a_base)/4 + word $0010 + word @zPFA + $10 + word @fillPFA + $10 + word @_dthreePFA + $10 + word (@a_litw - @a_base)/4 + word $0010 + word (@a_lparenpluslooprparen - @a_base)/4 + word $FFDC + word @crPFA + $10 + word (@a_exit - @a_base)/4 + + word @rdumpNFA + $10 +adumpNFA byte $85,"adump" +adumpPFA word @crPFA + $10 + word (@a_over - @a_base)/4 + word @dotwordPFA + $10 + word @spacePFA + $10 + word (@a_dup - @a_base)/4 + word @dotwordPFA + $10 + word @_ecsPFA + $10 + word @boundsPFA + $10 + word (@a_twogtr - @a_base)/4 + word @crPFA + $10 + word @iPFA + $10 + word @dotwordPFA + $10 + word @_ecsPFA + $10 + word @iPFA + $10 + word (@a_litw - @a_base)/4 + word $0004 + word @boundsPFA + $10 + word (@a_twogtr - @a_base)/4 + word @iPFA + $10 + word (@a_at - @a_base)/4 + word @dotlongPFA + $10 + word @spacePFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFF6 + word (@a_litw - @a_base)/4 + word $0004 + word (@a_lparenpluslooprparen - @a_base)/4 + word $FFDC + word @crPFA + $10 + word (@a_exit - @a_base)/4 + + word @adumpNFA + $10 +bsNFA byte $E1,"\" +bsPFA word @padsizePFA + $10 + word @mcwgtinPFA + $10 + word @wbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @bsNFA + $10 +tickNFA byte $81,"'" +tickPFA word @parseblPFA + $10 + word (@a_zbranch - @a_base)/4 + word $001A + word @padgtinPFA + $10 + word @nextwordPFA + $10 + word @findPFA + $10 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000A + word @_udfPFA + $10 + word @crPFA + $10 + word (@a_drop - @a_base)/4 + word @zPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word @zPFA + $10 + word (@a_exit - @a_base)/4 + + word @tickNFA + $10 +cqNFA byte $82,"cq" +cqPFA word (@a_rgt - @a_base)/4 + word (@a_dup - @a_base)/4 + word @catplusplusPFA + $10 + word @plusPFA + $10 + word @alignwPFA + $10 + word (@a_gtr - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @cqNFA + $10 +cquoteNFA byte $E2,"c",$22 +cquotePFA word @compileqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0034 + word @cm_cqPFA + $10 + word @wcommaPFA + $10 + word (@a_litw - @a_base)/4 + word $0001 + word @mcwgtinPFA + $10 + word @wplusbangPFA + $10 + word (@a_litw - @a_base)/4 + word $0022 + word @parsePFA + $10 + word (@a_dup - @a_base)/4 + word @ccommaPFA + $10 + word (@a_dup - @a_base)/4 + word @padgtinPFA + $10 + word @mswHerePFA + $10 + word @watPFA + $10 + word (@a_rot - @a_base)/4 + word @cmovePFA + $10 + word (@a_dup - @a_base)/4 + word @allotPFA + $10 + word @oneplusPFA + $10 + word @mcwgtinPFA + $10 + word @wplusbangPFA + $10 + word @herewalPFA + $10 + word (@a_branch - @a_base)/4 + word $0018 + word (@a_litw - @a_base)/4 + word $0022 + word @parsePFA + $10 + word @oneminusPFA + $10 + word @padgtinPFA + $10 + word @twodupPFA + $10 + word @cbangPFA + $10 + word (@a_swap - @a_base)/4 + word @twoplusPFA + $10 + word @mcwgtinPFA + $10 + word @wplusbangPFA + $10 + word (@a_exit - @a_base)/4 + + word @cquoteNFA + $10 +fl_baseNFA byte $87,"fl_base" +fl_basePFA word (@a_dovarw - @a_base)/4 + word $0000 + + word @fl_baseNFA + $10 +fl_countNFA byte $88,"fl_count" +fl_countPFA word (@a_dovarw - @a_base)/4 + word $0000 + + word @fl_countNFA + $10 +fl_topNFA byte $86,"fl_top" +fl_topPFA word (@a_dovarw - @a_base)/4 + word $0000 + + word @fl_topNFA + $10 +fl_inNFA byte $85,"fl_in" +fl_inPFA word (@a_dovarw - @a_base)/4 + word $0000 + + word @fl_inNFA + $10 +fl_lockNFA byte $87,"fl_lock" +fl_lockPFA word (@a_dovarw - @a_base)/4 + word $0000 + + word @fl_lockNFA + $10 +fl_bufNFA byte $86,"fl_buf" +fl_bufPFA word @mswDictendPFA + $10 + word @watPFA + $10 + word @mswHerePFA + $10 + word @watPFA + $10 + word @minusPFA + $10 + word (@a_litw - @a_base)/4 + word $0300 + word @minusPFA + $10 + word @zPFA + $10 + word @fl_countPFA + $10 + word @wbangPFA + $10 + word @lockdictPFA + $10 + word @fl_lockPFA + $10 + word @watPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000C + word @freedictPFA + $10 + word @crPFA + $10 + word @zPFA + $10 + word (@a_branch - @a_base)/4 + word $000C + word @minusonePFA + $10 + word @fl_lockPFA + $10 + word @wbangPFA + $10 + word @freedictPFA + $10 + word @minusonePFA + $10 + word (@a_zbranch - @a_base)/4 + word $00EE + word @mswDictendPFA + $10 + word @watPFA + $10 + word (@a_dup - @a_base)/4 + word @fl_topPFA + $10 + word @wbangPFA + $10 + word (@a_swap - @a_base)/4 + word @minusPFA + $10 + word (@a_dup - @a_base)/4 + word @fl_basePFA + $10 + word @wbangPFA + $10 + word (@a_dup - @a_base)/4 + word @fl_inPFA + $10 + word @wbangPFA + $10 + word @oneminusPFA + $10 + word @mswDictendPFA + $10 + word @wbangPFA + $10 + word @zPFA + $10 + word (@a_dup - @a_base)/4 + word @mswKeyTOPFA + $10 + word @watPFA + $10 + word @zPFA + $10 + word (@a_twogtr - @a_base)/4 + word @fkeyqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $008E + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $005C + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $001E + word (@a_drop - @a_base)/4 + word @keytoPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000C + word (@a_litw - @a_base)/4 + word $000D + word (@a_eq - @a_base)/4 + word (@a_branch - @a_base)/4 + word $0004 + word @minusonePFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFEC + word (@a_branch - @a_base)/4 + word $0060 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $007B + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $001E + word (@a_drop - @a_base)/4 + word @keytoPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000C + word (@a_litw - @a_base)/4 + word $007D + word (@a_eq - @a_base)/4 + word (@a_branch - @a_base)/4 + word $0004 + word @minusonePFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFEC + word (@a_branch - @a_base)/4 + word $0038 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0005 + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0008 + word (@a_drop - @a_base)/4 + word (@a_litw - @a_base)/4 + word $005C + word @fl_inPFA + $10 + word @watPFA + $10 + word @cbangPFA + $10 + word @oneplusPFA + $10 + word @fl_inPFA + $10 + word @watPFA + $10 + word @oneplusPFA + $10 + word (@a_dup - @a_base)/4 + word @fl_topPFA + $10 + word @watPFA + $10 + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0008 + word @_eoomPFA + $10 + word @clearkeysPFA + $10 + word @resetPFA + $10 + word @fl_inPFA + $10 + word @wbangPFA + $10 + word @zPFA + $10 + word (@a_branch - @a_base)/4 + word $0006 + word (@a_drop - @a_base)/4 + word @minusonePFA + $10 + word (@a_zbranch - @a_base)/4 + word $FF68 + word (@a_lparenlooprparen - @a_base)/4 + word $FF64 + word (@a_swap - @a_base)/4 + word (@a_over - @a_base)/4 + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $FF50 + word (@a_dup - @a_base)/4 + word @dotPFA + $10 + word @dqPFA + $10 + byte $05,"chars" + word @crPFA + $10 + word @fl_countPFA + $10 + word @wbangPFA + $10 + word @minusonePFA + $10 + word (@a_branch - @a_base)/4 + word $0006 + word (@a_drop - @a_base)/4 + word @zPFA + $10 + word (@a_exit - @a_base)/4 + + word @fl_bufNFA + $10 +fl_skeysNFA byte $88,"fl_skeys" +fl_skeysPFA word @fl_lockPFA + $10 + word @watPFA + $10 + word @fl_countPFA + $10 + word @watPFA + $10 + word @zltgtPFA + $10 + word @andPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0036 + word @fl_basePFA + $10 + word @watPFA + $10 + word @fl_countPFA + $10 + word @watPFA + $10 + word @boundsPFA + $10 + word (@a_twogtr - @a_base)/4 + word @iPFA + $10 + word (@a_dup - @a_base)/4 + word @catPFA + $10 + word @emitPFA + $10 + word @mswDictendPFA + $10 + word @wbangPFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFF2 + word @fl_topPFA + $10 + word @watPFA + $10 + word @mswDictendPFA + $10 + word @wbangPFA + $10 + word @zPFA + $10 + word @fl_countPFA + $10 + word @wbangPFA + $10 + word @lockdictPFA + $10 + word @zPFA + $10 + word @fl_lockPFA + $10 + word @wbangPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @fl_skeysNFA + $10 +loadeeNFA byte $86,"loadee" +loadeePFA word @twodupPFA + $10 + word (@a_litw - @a_base)/4 + word $000F + word @andnPFA + $10 + word @boundsPFA + $10 + word (@a_twogtr - @a_base)/4 + word @iPFA + $10 + word @mcTPFA + $10 + word (@a_litw - @a_base)/4 + word $0010 + word @eeReadPagePFA + $10 + word (@a_drop - @a_base)/4 + word @mcTPFA + $10 + word (@a_litw - @a_base)/4 + word $0010 + word @boundsPFA + $10 + word (@a_twogtr - @a_base)/4 + word @iPFA + $10 + word @catPFA + $10 + word @emitPFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFF8 + word (@a_litw - @a_base)/4 + word $0010 + word (@a_lparenpluslooprparen - @a_base)/4 + word $FFDA + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $000F + word @andnPFA + $10 + word (@a_rot - @a_base)/4 + word @plusPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_litw - @a_base)/4 + word $000F + word @andPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0014 + word @boundsPFA + $10 + word (@a_twogtr - @a_base)/4 + word @iPFA + $10 + word @eeReadBytePFA + $10 + word @emitPFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFF8 + word (@a_branch - @a_base)/4 + word $0004 + word @twodropPFA + $10 + word (@a_exit - @a_base)/4 + + word @loadeeNFA + $10 +_caendNFA byte $86,"_caend" +_caendPFA word @cqPFA + $10 + byte $04," cr " + word (@a_over - @a_base)/4 + word @cappendPFA + $10 + word @cogidPFA + $10 + word (@a_over - @a_base)/4 + word @cappendncPFA + $10 + word @cqPFA + $10 + byte $14,"0 mcwEmitptr w! >cog" + word (@a_swap - @a_base)/4 + word @cappendPFA + $10 + word (@a_exit - @a_base)/4 + + word @_caendNFA + $10 +FLNFA byte $82,"FL" +FLPFA word @fl_bufPFA + $10 + word (@a_zbranch - @a_base)/4 + word $001A + word @cqPFA + $10 + byte $08,"fl_skeys" + word @mcTPFA + $10 + word @ccopyPFA + $10 + word @mcTPFA + $10 + word @_caendPFA + $10 + word @mcTPFA + $10 + word @cogXOPFA + $10 + word (@a_exit - @a_base)/4 + + word @FLNFA + $10 +eeBotNFA byte $85,"eeBot" +eeBotPFA word (@a_docon - @a_base)/4 + long $00008000 + + word @eeBotNFA + $10 +eeTopNFA byte $85,"eeTop" +eeTopPFA word (@a_docon - @a_base)/4 + long $00010000 + + word @eeTopNFA + $10 +f_fillNFA byte $86,"f_fill" +f_fillPFA word @mcPadPFA + $10 + word (@a_litw - @a_base)/4 + word $0080 + word (@a_rot - @a_base)/4 + word @fillPFA + $10 + word @eeTopPFA + $10 + word @eeBotPFA + $10 + word (@a_twogtr - @a_base)/4 + word @iPFA + $10 + word @mcPadPFA + $10 + word (@a_litw - @a_base)/4 + word $0080 + word @eeWritePagePFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word @eeErrPFA + $10 + word @crPFA + $10 + word @leavePFA + $10 + word (@a_litw - @a_base)/4 + word $0080 + word (@a_lparenpluslooprparen - @a_base)/4 + word $FFE6 + word @mcPadPFA + $10 + word (@a_litw - @a_base)/4 + word $0080 + word @blPFA + $10 + word @fillPFA + $10 + word (@a_exit - @a_base)/4 + + word @f_fillNFA + $10 +f_clearNFA byte $87,"f_clear" +f_clearPFA word @eeTopPFA + $10 + word @eeBotPFA + $10 + word (@a_twogtr - @a_base)/4 + word (@a_litw - @a_base)/4 + word $FFFF + word @iPFA + $10 + word @eeWriteWordPFA + $10 + word (@a_litw - @a_base)/4 + word $0080 + word (@a_lparenpluslooprparen - @a_base)/4 + word $FFF2 + word (@a_exit - @a_base)/4 + + word @f_clearNFA + $10 +_fiNFA byte $83,"_fi" +_fiPFA word @mcNumpadPFA + $10 + word (@a_dup - @a_base)/4 + word @watPFA + $10 + word (@a_swap - @a_base)/4 + word @twoplusPFA + $10 + word @catPFA + $10 + word @plusPFA + $10 + word @twoplusPFA + $10 + word @oneplusPFA + $10 + word (@a_litw - @a_base)/4 + word $0080 + word @uslashmodPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0004 + word @oneplusPFA + $10 + word (@a_litw - @a_base)/4 + word $0080 + word @ustarPFA + $10 + word (@a_exit - @a_base)/4 + + word @_fiNFA + $10 +listNFA byte $84,"list" +listPFA word @eeTopPFA + $10 + word @eeBotPFA + $10 + word (@a_twogtr - @a_base)/4 + word @iPFA + $10 + word @mcNumpadPFA + $10 + word @numpadsizePFA + $10 + word @namemaxPFA + $10 + word @oneplusPFA + $10 + word @twoplusPFA + $10 + word @minPFA + $10 + word @eeReadPagePFA + $10 + word (@a_zbranch - @a_base)/4 + word $0006 + word @eeErrPFA + $10 + word @leavePFA + $10 + word @mcNumpadPFA + $10 + word @watPFA + $10 + word (@a_litw - @a_base)/4 + word $FFFF + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0012 + word @iPFA + $10 + word @dotPFA + $10 + word @crPFA + $10 + word (@a_litw - @a_base)/4 + word $0080 + word @leavePFA + $10 + word (@a_branch - @a_base)/4 + word $0016 + word @iPFA + $10 + word @dotPFA + $10 + word @mcNumpadPFA + $10 + word (@a_dup - @a_base)/4 + word @watPFA + $10 + word @dotPFA + $10 + word @twoplusPFA + $10 + word @dotcstrPFA + $10 + word @crPFA + $10 + word @_fiPFA + $10 + word (@a_lparenpluslooprparen - @a_base)/4 + word $FFB4 + word (@a_exit - @a_base)/4 + + word @listNFA + $10 +f_findNFA byte $86,"f_find" +f_findPFA word @zPFA + $10 + word @eeTopPFA + $10 + word @eeBotPFA + $10 + word (@a_twogtr - @a_base)/4 + word @iPFA + $10 + word @mcNumpadPFA + $10 + word @numpadsizePFA + $10 + word @namemaxPFA + $10 + word @oneplusPFA + $10 + word @twoplusPFA + $10 + word @minPFA + $10 + word @eeReadPagePFA + $10 + word (@a_zbranch - @a_base)/4 + word $0006 + word @eeErrPFA + $10 + word @leavePFA + $10 + word @mcNumpadPFA + $10 + word @watPFA + $10 + word (@a_litw - @a_base)/4 + word $FFFF + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $000E + word @nipPFA + $10 + word (@a_litw - @a_base)/4 + word $0080 + word @leavePFA + $10 + word (@a_branch - @a_base)/4 + word $0014 + word (@a_over - @a_base)/4 + word @mcNumpadPFA + $10 + word @twoplusPFA + $10 + word (@a_cstreq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0006 + word (@a_drop - @a_base)/4 + word @iPFA + $10 + word @_fiPFA + $10 + word (@a_lparenpluslooprparen - @a_base)/4 + word $FFBA + word (@a_exit - @a_base)/4 + + word @f_findNFA + $10 +f_freeNFA byte $86,"f_free" +f_freePFA word @zPFA + $10 + word @eeTopPFA + $10 + word @eeBotPFA + $10 + word (@a_twogtr - @a_base)/4 + word @iPFA + $10 + word @mcNumpadPFA + $10 + word (@a_litw - @a_base)/4 + word $0004 + word @eeReadPagePFA + $10 + word (@a_zbranch - @a_base)/4 + word $0006 + word @eeErrPFA + $10 + word @leavePFA + $10 + word @mcNumpadPFA + $10 + word @watPFA + $10 + word (@a_litw - @a_base)/4 + word $FFFF + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0010 + word (@a_drop - @a_base)/4 + word @iPFA + $10 + word (@a_litw - @a_base)/4 + word $0080 + word @leavePFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word @_fiPFA + $10 + word (@a_lparenpluslooprparen - @a_base)/4 + word $FFCE + word (@a_exit - @a_base)/4 + + word @f_freeNFA + $10 +f_wfileNFA byte $87,"f_wfile" +f_wfilePFA word @f_freePFA + $10 + word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $005E + word (@a_dup - @a_base)/4 + word @fl_countPFA + $10 + word @watPFA + $10 + word @plusPFA + $10 + word @eeTopPFA + $10 + word (@a_lt - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0046 + word @fl_basePFA + $10 + word @watPFA + $10 + word @fl_countPFA + $10 + word @watPFA + $10 + word @boundsPFA + $10 + word (@a_twogtr - @a_base)/4 + word (@a_dup - @a_base)/4 + word @iPFA + $10 + word @fl_countPFA + $10 + word @watPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0080 + word @minPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_over - @a_base)/4 + word @minusPFA + $10 + word @fl_countPFA + $10 + word @wbangPFA + $10 + word @eeWritePagePFA + $10 + word (@a_zbranch - @a_base)/4 + word $0006 + word @eeErrPFA + $10 + word @leavePFA + $10 + word (@a_litw - @a_base)/4 + word $0080 + word @plusPFA + $10 + word (@a_litw - @a_base)/4 + word $0080 + word (@a_lparenpluslooprparen - @a_base)/4 + word $FFD0 + word (@a_drop - @a_base)/4 + word (@a_branch - @a_base)/4 + word $0006 + word (@a_drop - @a_base)/4 + word @_eoomPFA + $10 + word (@a_branch - @a_base)/4 + word $0008 + word (@a_drop - @a_base)/4 + word @eeErrPFA + $10 + word @crPFA + $10 + word (@a_exit - @a_base)/4 + + word @f_wfileNFA + $10 +FWNFA byte $82,"FW" +FWPFA word @fl_bufPFA + $10 + word (@a_zbranch - @a_base)/4 + word $00B0 + word @fl_countPFA + $10 + word @watPFA + $10 + word @zPFA + $10 + word (@a_twogtr - @a_base)/4 + word @fl_basePFA + $10 + word @watPFA + $10 + word @catPFA + $10 + word (@a_litw - @a_base)/4 + word $002E + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0008 + word @leavePFA + $10 + word (@a_branch - @a_base)/4 + word $0016 + word @fl_basePFA + $10 + word @watPFA + $10 + word @oneplusPFA + $10 + word @fl_basePFA + $10 + word @wbangPFA + $10 + word @fl_countPFA + $10 + word @watPFA + $10 + word @oneminusPFA + $10 + word @fl_countPFA + $10 + word @wbangPFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFD4 + word @fl_basePFA + $10 + word @watPFA + $10 + word (@a_litw - @a_base)/4 + word $0003 + word @plusPFA + $10 + word (@a_litw - @a_base)/4 + word $0020 + word @boundsPFA + $10 + word (@a_twogtr - @a_base)/4 + word @iPFA + $10 + word @catPFA + $10 + word @blPFA + $10 + word @lteqPFA + $10 + word @lastiqPFA + $10 + word @orPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0006 + word @iPFA + $10 + word @leavePFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFEA + word @fl_basePFA + $10 + word @watPFA + $10 + word @minusPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0003 + word @minusPFA + $10 + word @fl_basePFA + $10 + word @watPFA + $10 + word @twoplusPFA + $10 + word @cbangPFA + $10 + word @fl_countPFA + $10 + word @watPFA + $10 + word (@a_swap - @a_base)/4 + word @minusPFA + $10 + word (@a_dup - @a_base)/4 + word @fl_basePFA + $10 + word @watPFA + $10 + word @cbangPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0008 + word @rshiftPFA + $10 + word @fl_basePFA + $10 + word @watPFA + $10 + word @oneplusPFA + $10 + word @cbangPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0004 + word @f_wfilePFA + $10 + word @fl_topPFA + $10 + word @watPFA + $10 + word @mswDictendPFA + $10 + word @wbangPFA + $10 + word @lockdictPFA + $10 + word @zPFA + $10 + word @fl_lockPFA + $10 + word @wbangPFA + $10 + word @freedictPFA + $10 + word (@a_exit - @a_base)/4 + + word @FWNFA + $10 +f_alNFA byte $84,"f_al" +f_alPFA word (@a_dup - @a_base)/4 + word @eeReadWordPFA + $10 + word (@a_over - @a_base)/4 + word @twoplusPFA + $10 + word @eeReadBytePFA + $10 + word (@a_rot - @a_base)/4 + word @plusPFA + $10 + word @twoplusPFA + $10 + word @oneplusPFA + $10 + word (@a_exit - @a_base)/4 + + word @f_alNFA + $10 +f_loadNFA byte $86,"f_load" +f_loadPFA word @f_findPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $002C + word @f_alPFA + $10 + word @zPFA + $10 + word @mcTPFA + $10 + word @cbangPFA + $10 + word @mcTPFA + $10 + word @cappendncPFA + $10 + word @mcTPFA + $10 + word @cappendncPFA + $10 + word @cqPFA + $10 + byte $06,"loadee" + word @mcTPFA + $10 + word @cappendPFA + $10 + word @mcTPFA + $10 + word @_caendPFA + $10 + word @mcTPFA + $10 + word @cogXOPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @f_loadNFA + $10 +loadNFA byte $84,"load" +loadPFA word @parsenwPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0008 + word @f_loadPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @loadNFA + $10 +versionNFA byte $87,"version" +versionPFA word @cqPFA + $10 + byte $20,"PropForth v2.5 2009OCT24 17:15 0" + word (@a_exit - @a_base)/4 + + word @versionNFA + $10 +freeNFA byte $84,"free" +freePFA word @mswDictendPFA + $10 + word @watPFA + $10 + word @mswHerePFA + $10 + word @watPFA + $10 + word @minusPFA + $10 + word @dotPFA + $10 + word @dqPFA + $10 + byte $0D,"bytes free - " + word @parPFA + $10 + word @mcwAherePFA + $10 + word @watPFA + $10 + word @minusPFA + $10 + word @dotPFA + $10 + word @dqPFA + $10 + byte $0E,"cog longs free" + word @crPFA + $10 + word (@a_exit - @a_base)/4 + + word @freeNFA + $10 +saveforthNFA byte $89,"saveforth" +saveforthPFA word @cqPFA + $10 + byte $07,"mswHere" + word @findPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0060 + word @versionPFA + $10 + word (@a_dup - @a_base)/4 + word @catPFA + $10 + word @plusPFA + $10 + word (@a_dup - @a_base)/4 + word @catPFA + $10 + word @oneplusPFA + $10 + word (@a_swap - @a_base)/4 + word @cbangPFA + $10 + word @pfagtnfaPFA + $10 + word @mswHerePFA + $10 + word @watPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_dup - @a_base)/4 + word @watPFA + $10 + word (@a_over - @a_base)/4 + word @eeWriteWordPFA + $10 + word @twoplusPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $007F + word @andPFA + $10 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFEA + word (@a_twogtr - @a_base)/4 + word @iboundPFA + $10 + word @iPFA + $10 + word @minusPFA + $10 + word (@a_litw - @a_base)/4 + word $0080 + word @minPFA + $10 + word (@a_dup - @a_base)/4 + word @iPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_rot - @a_base)/4 + word @eeWritePagePFA + $10 + word (@a_zbranch - @a_base)/4 + word $0004 + word @leavePFA + $10 + word (@a_litw - @a_base)/4 + word $002E + word @emitPFA + $10 + word (@a_lparenpluslooprparen - @a_base)/4 + word $FFDC + word (@a_branch - @a_base)/4 + word $0004 + word (@a_drop - @a_base)/4 + word @crPFA + $10 + word (@a_exit - @a_base)/4 + + word @saveforthNFA + $10 +_forgetNFA byte $87,"_forget" +_forgetPFA word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0026 + word @findPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0016 + word @pfagtnfaPFA + $10 + word @nfagtlfaPFA + $10 + word (@a_dup - @a_base)/4 + word @mswHerePFA + $10 + word @wbangPFA + $10 + word @watPFA + $10 + word @mswlastnfaPFA + $10 + word @wbangPFA + $10 + word (@a_branch - @a_base)/4 + word $0008 + word @dotcstrPFA + $10 + word @qqqPFA + $10 + word @crPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @_forgetNFA + $10 +forgetNFA byte $86,"forget" +forgetPFA word @parsenwPFA + $10 + word @_forgetPFA + $10 + word (@a_exit - @a_base)/4 + + word @forgetNFA + $10 +cm_fstartNFA byte $89,"cm_fstart" +cm_fstartPFA word (@a_doconw - @a_base)/4 + word @fstartPFA + $10 + + word @cm_fstartNFA + $10 +fstartNFA byte $86,"fstart" +fstartPFA word @cogidPFA + $10 + word (@a_dup - @a_base)/4 + word @cogInbytePFA + $10 + word (@a_litw - @a_base)/4 + word $0010 + word @lshiftPFA + $10 + word @cm_entryPFA + $10 + word (@a_litw - @a_base)/4 + word $0002 + word @lshiftPFA + $10 + word @orPFA + $10 + word (@a_swap - @a_base)/4 + word @orPFA + $10 + word @resetDregPFA + $10 + word (@a_bang - @a_base)/4 + word @mcwInbytePFA + $10 + word @matPFA + $10 + word @lgtwPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0100 + word @mcwInbytePFA + $10 + word @wbangPFA + $10 + word @zPFA + $10 + word @mcwEmitptrPFA + $10 + word @wbangPFA + $10 + word @fMaskPFA + $10 + word (@a_at - @a_base)/4 + word @mcwDebugcmdPFA + $10 + word @wbangPFA + $10 + word @parPFA + $10 + word (@a_at - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0008 + word @plusPFA + $10 + word (@a_litw - @a_base)/4 + word $00F8 + word @zPFA + $10 + word @fillPFA + $10 + word @hexPFA + $10 + word @ca_varEndPFA + $10 + word @mcwAherePFA + $10 + word @wbangPFA + $10 + word @lockdictPFA + $10 + word @mswHerePFA + $10 + word @watPFA + $10 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0024 + word @zPFA + $10 + word @fl_lockPFA + $10 + word @wbangPFA + $10 + word @lastnfaPFA + $10 + word @nfagtpfaPFA + $10 + word @twoplusPFA + $10 + word @alignlPFA + $10 + word @fourplusPFA + $10 + word @mswHerePFA + $10 + word @wbangPFA + $10 + word (@a_litw - @a_base)/4 + word $7FFF + word (@a_dup - @a_base)/4 + word @mswMemendPFA + $10 + word @wbangPFA + $10 + word @mswDictendPFA + $10 + word @wbangPFA + $10 + word @freedictPFA + $10 + word @rsTopPFA + $10 + word @oneminusPFA + $10 + word @rsPtrPFA + $10 + word (@a_bang - @a_base)/4 + word (@a_litw - @a_base)/4 + word $FFFF + word (@a_eq - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0014 + word (@a_litw - @a_base)/4 + word $0008 + word @lshiftPFA + $10 + word @cogidPFA + $10 + word @plusPFA + $10 + word @vxcogPFA + $10 + word @wbangPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word (@a_drop - @a_base)/4 + word @cqPFA + $10 + byte $04,"boot" + word @mcTPFA + $10 + word @ccopyPFA + $10 + word @cogidPFA + $10 + word @mcTPFA + $10 + word @cappendnPFA + $10 + word @mcTPFA + $10 + word @findPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word @executePFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word (@a_drop - @a_base)/4 + word @minusonePFA + $10 + word @compileqPFA + $10 + word @zeqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0014 + word @dqPFA + $10 + byte $03,"Cog" + word @cogidPFA + $10 + word @dotPFA + $10 + word @dqPFA + $10 + byte $02,"ok" + word @crPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0008 + word @minusonePFA + $10 + word @mcwDebugvaluePFA + $10 + word @mbangPFA + $10 + word @interpretPFA + $10 + word @zPFA + $10 + word @zPFA + $10 + word (@a_zbranch - @a_base)/4 + word $FFD4 + word (@a_exit - @a_base)/4 + + word @fstartNFA + $10 +boot6NFA byte $85,"boot6" +boot6PFA word @cogidPFA + $10 + word @gtcogPFA + $10 + word @cogplusPFA + $10 + word (@a_exit - @a_base)/4 + + word @boot6NFA + $10 +cogqNFA byte $84,"cog?" +cogqPFA word @dqPFA + $10 + byte $0C,"Forth cogs: " + word @ffcogPFA + $10 + word @watPFA + $10 + word @dotPFA + $10 + word (@a_litw - @a_base)/4 + word $002D + word @emitPFA + $10 + word @spacePFA + $10 + word @lfcogPFA + $10 + word @watPFA + $10 + word @dotPFA + $10 + word @crPFA + $10 + word (@a_exit - @a_base)/4 + + word @cogqNFA + $10 +cogplusNFA byte $84,"cog+" +cogplusPFA word @ffcogPFA + $10 + word @watPFA + $10 + word @oneminusPFA + $10 + word (@a_dup - @a_base)/4 + word @zgteqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000E + word (@a_dup - @a_base)/4 + word @ffcogPFA + $10 + word @wbangPFA + $10 + word @cogresetPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word (@a_drop - @a_base)/4 + word @cogqPFA + $10 + word (@a_exit - @a_base)/4 + + word @cogplusNFA + $10 +cogminusNFA byte $84,"cog-" +cogminusPFA word @ffcogPFA + $10 + word @watPFA + $10 + word (@a_dup - @a_base)/4 + word @cogidPFA + $10 + word @ltgtPFA + $10 + word (@a_swap - @a_base)/4 + word @oneplusPFA + $10 + word (@a_dup - @a_base)/4 + word @lfcogPFA + $10 + word @watPFA + $10 + word @lteqPFA + $10 + word (@a_rot - @a_base)/4 + word @andPFA + $10 + word (@a_zbranch - @a_base)/4 + word $0010 + word (@a_dup - @a_base)/4 + word @oneminusPFA + $10 + word @cogstopPFA + $10 + word @ffcogPFA + $10 + word @wbangPFA + $10 + word (@a_branch - @a_base)/4 + word $0004 + word (@a_drop - @a_base)/4 + word @cogqPFA + $10 + word (@a_exit - @a_base)/4 + + word @cogminusNFA + $10 +stqNFA byte $83,"st?" +stqPFA word @dqPFA + $10 + byte $04,"ST: " + word @stPtrPFA + $10 + word (@a_at - @a_base)/4 + word @twoplusPFA + $10 + word (@a_dup - @a_base)/4 + word @stTopPFA + $10 + word (@a_lt - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0022 + word @stTopPFA + $10 + word (@a_swap - @a_base)/4 + word @minusPFA + $10 + word @zPFA + $10 + word (@a_twogtr - @a_base)/4 + word @stTopPFA + $10 + word @twominusPFA + $10 + word @iPFA + $10 + word @minusPFA + $10 + word (@a_at - @a_base)/4 + word @dotlongPFA + $10 + word @spacePFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFF0 + word (@a_branch - @a_base)/4 + word $0004 + word (@a_drop - @a_base)/4 + word @crPFA + $10 + word (@a_exit - @a_base)/4 + + word @stqNFA + $10 +scNFA byte $82,"sc" +scPFA word @stTopPFA + $10 + word @stPtrPFA + $10 + word (@a_at - @a_base)/4 + word @minusPFA + $10 + word (@a_litw - @a_base)/4 + word $0003 + word @minusPFA + $10 + word (@a_dup - @a_base)/4 + word @dotPFA + $10 + word @dqPFA + $10 + byte $0D,"items cleared" + word @crPFA + $10 + word (@a_dup - @a_base)/4 + word @zgtPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000C + word @zPFA + $10 + word (@a_twogtr - @a_base)/4 + word (@a_drop - @a_base)/4 + word (@a_lparenlooprparen - @a_base)/4 + word $FFFC + word (@a_exit - @a_base)/4 + + word @scNFA + $10 +_pnaNFA byte $84,"_pna" +_pnaPFA word (@a_dup - @a_base)/4 + word @dotwordPFA + $10 + word (@a_litw - @a_base)/4 + word $003A + word @emitPFA + $10 + word @watPFA + $10 + word (@a_dup - @a_base)/4 + word @dotwordPFA + $10 + word @spacePFA + $10 + word @pfagtnfaPFA + $10 + word @dotstrnamePFA + $10 + word @spacePFA + $10 + word (@a_exit - @a_base)/4 + + word @_pnaNFA + $10 +pfaqNFA byte $84,"pfa?" +pfaqPFA word (@a_dup - @a_base)/4 + word @pfagtnfaPFA + $10 + word (@a_dup - @a_base)/4 + word @catPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_litw - @a_base)/4 + word $0080 + word @andPFA + $10 + word @zeqPFA + $10 + word (@a_swap - @a_base)/4 + word @namemaxPFA + $10 + word @andPFA + $10 + word @zltgtPFA + $10 + word (@a_rot - @a_base)/4 + word @nfagtpfaPFA + $10 + word (@a_rot - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $0004 + word @watPFA + $10 + word (@a_rot - @a_base)/4 + word (@a_eq - @a_base)/4 + word @andPFA + $10 + word (@a_exit - @a_base)/4 + + word @pfaqNFA + $10 +rsqNFA byte $83,"rs?" +rsqPFA word @dqPFA + $10 + byte $04,"RS: " + word @rsTopPFA + $10 + word @rsPtrPFA + $10 + word (@a_at - @a_base)/4 + word @oneplusPFA + $10 + word @minusPFA + $10 + word @zPFA + $10 + word (@a_twogtr - @a_base)/4 + word @rsTopPFA + $10 + word @oneminusPFA + $10 + word @iPFA + $10 + word @minusPFA + $10 + word (@a_at - @a_base)/4 + word (@a_dup - @a_base)/4 + word @twominusPFA + $10 + word @watPFA + $10 + word @pfaqPFA + $10 + word (@a_zbranch - @a_base)/4 + word $000A + word @twominusPFA + $10 + word @_pnaPFA + $10 + word (@a_branch - @a_base)/4 + word $0006 + word @dotlongPFA + $10 + word @spacePFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFDC + word @crPFA + $10 + word (@a_exit - @a_base)/4 + + word @rsqNFA + $10 +lasmNFA byte $84,"lasm" +lasmPFA word @fourplusPFA + $10 + word (@a_dup - @a_base)/4 + word @matPFA + $10 + word (@a_swap - @a_base)/4 + word @fourplusPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_over - @a_base)/4 + word @matPFA + $10 + word (@a_dup - @a_base)/4 + word @mcwAherePFA + $10 + word @wbangPFA + $10 + word (@a_twogtr - @a_base)/4 + word @fourplusPFA + $10 + word (@a_dup - @a_base)/4 + word @matPFA + $10 + word @acommaPFA + $10 + word (@a_lparenlooprparen - @a_base)/4 + word $FFF6 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @lasmNFA + $10 +f_eraseNFA byte $87,"f_erase" +f_erasePFA word @parsenwPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $002A + word @f_findPFA + $10 + word (@a_dup - @a_base)/4 + word (@a_zbranch - @a_base)/4 + word $001C + word @eeTopPFA + $10 + word (@a_swap - @a_base)/4 + word (@a_twogtr - @a_base)/4 + word (@a_litw - @a_base)/4 + word $FFFF + word @iPFA + $10 + word @eeWriteWordPFA + $10 + word (@a_litw - @a_base)/4 + word $0080 + word (@a_lparenpluslooprparen - @a_base)/4 + word $FFF2 + word (@a_branch - @a_base)/4 + word $0004 + word (@a_drop - @a_base)/4 + word (@a_branch - @a_base)/4 + word $0004 + word (@a_drop - @a_base)/4 + word (@a_exit - @a_base)/4 + + word @f_eraseNFA + $10 +mswlastnfaNFA byte $8A,"mswlastnfa" +mswlastnfaPFA word (@a_dovarw - @a_base) /4 + word @mswlastnfaNFA + $10 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + long 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 + +ForthDictEnd +ForthMemoryEnd + diff --git a/zubehör/PropForth/PropForthPart1.f b/zubehör/PropForth/PropForthPart1.f new file mode 100644 index 0000000..176ab69 --- /dev/null +++ b/zubehör/PropForth/PropForthPart1.f @@ -0,0 +1,1132 @@ + + +FL + + + + +\ these variables are the current dictionary limits +\ cannot really easily redefine these variable on a running forth system, it really screws things up +\ to redefine requires multiple steps and caution, not worth the bother usually + +\ mswMemend w@ wvariable mswMemend mswMemend w! +\ mswHere w@ wvariable mswHere mswHere w! +\ mswDictend w@ wvariable mswDictend mswDictend w! + +\ constants which reference the cogdata space are effectively variables with +\ a level of indirection. refedinition of these, if the base variable is the same +\ is reasonable and can be done on a running system + +\ caution with other variables + +\ these constants are all intialized to the running values, so any following words compile correctly +\ if you add constants that are used by the base compiler, follow the practice +\ any word constant which begins with cm_xxx is compiled with the value @xxxPFA + $10 - which is the exection address +\ any word constant which begins with ca_xxx is copiled with the value (@xxx - @a_base)/4 - execution address + +\ cogid if the cog had an over/underflow +-1 wvariable vxcog vxcog w! + +\ first forth cog +ffcog w@ wvariable ffcog ffcog w! + +\ the last forth cog +lfcog w@ wvariable lfcog lfcog w! + +cm_serentry wconstant cm_serentry +cm_entry wconstant cm_entry + +\ this is a pointer to the main cogdata area +cm_cogdata wconstant cm_cogdata +\ this is ' cq - the routine which handles the word c" +cm_cq wconstant cm_cq +\ this is ' dq - the routine which handles the word ." +cm_dq wconstant cm_dq + +\ these constants are all assembler addresses +ca_a_exit wconstant ca_a_exit +ca_a_dovarw wconstant ca_a_dovarw +ca_a_doconw wconstant ca_a_doconw +ca_a_branch wconstant ca_a_branch +ca_a_litw wconstant ca_a_litw +ca_a_2>r wconstant ca_a_2>r +ca_a_(loop) wconstant ca_a_(loop) +ca_a_(+loop) wconstant ca_a_(+loop) +ca_a_0branch wconstant ca_a_0branch +ca_a_dovar wconstant ca_a_dovar +ca_a_docon wconstant ca_a_docon +ca_a_literal wconstant ca_a_literal +ca_a_debugonoff wconstant ca_a_debugonoff +ca_a_reset wconstant ca_a_reset +ca_a_ifunc wconstant ca_a_ifunc +ca_a_ifunc1 wconstant ca_a_ifunc1 +ca_a_ifunc2 wconstant ca_a_ifunc2 +ca_a_umstarlp wconstant ca_a_umstarlp +ca_a_umslashmodlp wconstant ca_a_umslashmodlp +ca_a_cstreqlp wconstant ca_a_cstreqlp +ca_a_finlp wconstant ca_a_finlp + +\ addresses for the stack routines +ca_a_stPush wconstant ca_a_stPush +ca_a_stPush_ret wconstant ca_a_stPush_ret +ca_a_rsPush wconstant ca_a_rsPush +ca_a_rsPush_ret wconstant ca_a_rsPush_ret +ca_a_stPop wconstant ca_a_stPop +ca_a_stPoptreg wconstant ca_a_stPoptreg +ca_a_stPop_ret wconstant ca_a_stPop_ret +ca_a_stPoptreg_ret wconstant ca_a_stPoptreg_ret +ca_a_rsPop wconstant ca_a_rsPop +ca_a_rsPop_ret wconstant ca_a_rsPop_ret + +\ address for the a_next routine +ca_a_next wconstant ca_a_next + +\ this group of words needs to align with the assembler code +ca_varStart wconstant ca_varStart +ca_varEnd wconstant ca_varEnd +: _cv ca_varStart + ; +\ : aCondMask 0 _cv ; +: fMask 0 _cv ; +: fAddrMask 1 _cv ; +: fLongMask 2 _cv ; +: resetDreg 3 _cv ; +: IP 4 _cv ; +: stPtr 5 _cv ; +: rsPtr 6 _cv ; +: stTOS 7 _cv ; + +: treg1 8 _cv ; +\ : treg2 9 _cv ; +\ : treg3 a _cv ; +\ : treg4 b _cv ; +\ : treg5 c _cv ; +\ : treg6 d _cv ; +: stBot e _cv ; +: stTop 2e _cv ; +: rsBot stTop ; +: rsTop 4e _cv ; + +\ this is space constant +bl wconstant bl +\ -1 or true, used frequently +-1 constant -1 +\ 0 or false, used frequently +0 wconstant 0 +\ this is the par register, always initalized to point to this cogs section of cogdata +1F0 wconstant par +\ the other cog special registers +1F1 wconstant cnt +1F2 wconstant ina +\ 1F3 wconstant inb +1F4 wconstant outa +\ 1F5 wconstant outb +1F6 wconstant dira +\ 1F7 wconstant dirb +1F8 wconstant ctra +1F9 wconstant ctrb +1FA wconstant frqa +1FB wconstant frqb +1FC wconstant phsa +1FD wconstant phsb +1FE wconstant vcfg +1FF wconstant vscl + +\ this variable define the number of loops for a key timeout +\ used by keyTO, fast_load, f_write, and after an undefined word +mswKeyTO w@ wvariable mswKeyTO mswKeyTO w! + +\ use in the ifuncs to get rid of litw word +: cnip mswHere w@ 2- dup w@ over 2- w! mswHere w! ; immediate + +\ ifunc ( n1 n2 -- n ) \ the assembler operation is specified by the literal which follows (replaces the i field) + +' ifunc asmlabel ifunc + +\ ifunc1 ( n -- n ) \ the assembler operation is specified by the literal which follows (replaces the i field) + +' ifunc1 asmlabel ifunc1 + +\ ifunc2 ( n1 n2 -- ) \ the assembler operation is specified by the literal which follows (replaces the i field) + +' ifunc2 asmlabel ifunc2 + +\ fin ( nfa cstr -- n1) the nfa match in the dictionary, or 0 if not found +' fin asmlabel fin + +\ mpx ( n -- t/f ) n is the bit mask to read in +' mpx asmlabel mpx + +\ mpxl ( n -- ) set the bits in n low +' mpxl asmlabel mpxl + +\ mpxh ( n -- ) set the bits in n hi +' mpxh asmlabel mpxh + +\ name= ( nfa cstr -- t/f) +' name= asmlabel name= + +\ cstr= ( cstr cstr -- t/f) +' cstr= asmlabel cstr= + +\ abs ( n1 -- abs_n1 ) \ absolute value of n1 +: abs ifunc1 151 cnip ; + +\ and ( n1 n2 -- n1 ) \ bitwise and n1 n2 +: and ifunc 0C1 cnip ; + +\ andn ( n1 n2 -- n1 ) \ bitwise and n1 invert n2 +: andn ifunc 0C9 cnip ; + +\ !d ( n1 n2 -- n1 ) set the d field of n1 with n2 +: !d ifunc 0A9 cnip ; + +\ !i ( n1 n2 -- n1 ) set the i field of n1 with n2 +: !i ifunc 0B1 cnip ; + +\ !s ( n1 n2 -- n1 ) set the s field of n1 with n2 +: !s ifunc 0A1 cnip ; + +\ m@ ( addr -- n1 ) \ fetch 32 bit value at main memory addr +: m@ ifunc1 011 cnip ; + +\ c@ ( addr -- c1 ) \ fetch 8 bit value at main memory addr +: c@ ifunc1 001 cnip ; + +\ w@ ( addr -- h1 ) \ fetch 16 bit value at main memory addr +: w@ ifunc1 009 cnip ; + +\ @ ( addr -- n1 ) \ fetch 32 bit value at cog addr +' @ asmlabel @ + +\ m! ( n1 addr -- ) \ store 32 bit value (n1) at main memory addr +: m! ifunc2 010 cnip ; + +\ c! ( c1 addr -- ) \ store 8 bit value (c1) main memory at addr +: c! ifunc2 000 cnip ; + +\ w! ( h1 addr -- ) \ store 16 bit value (h1) main memory at addr +: w! ifunc2 008 cnip ; + +\ ! ( n1 addr -- ) \ store 32 bit value (n1) at cog addr +' ! asmlabel ! + +\ branch \ 16 bit branch offset follows - -2 is to itself, +2 is next word +' branch asmlabel branch + +\ hubop ( n1 n2 -- n3 t/f ) n2 specifies which hubop (0 - 7), n1 is the source data, n3 is returned, +\ t/f is the 'c' flag is set from the hubop + +' hubop asmlabel hubop + +\ doconw ( -- h1 ) \ push 16 bit constant which follows on the stack - implicit a_exit +' doconw asmlabel doconw + +\ docon ( -- n1 ) \ push a 32 bit constant which follows the stack - implicit a_exit +' docon asmlabel docon + +\ dovarw ( -- addr ) \ push address of 16 bit variable which follows on the stack - implicit a_exit +' dovarw asmlabel dovarw + +\ dovar ( -- addr ) \ push address of 32 bit variable which follows the stack - implicit a_exit +' dovar asmlabel dovar + +\ drop ( n1 -- ) \ drop the value on the top of the stack +' drop asmlabel drop + +\ dup ( n1 -- n1 n1 ) +' dup asmlabel dup + +\ = ( n1 n2 -- t/f ) \ compare top 2 32 bit stack values, true if they are equal +' = asmlabel = + +\ exit \ exit the current forth word, and back to the caller +' exit asmlabel exit + +\ > ( n1 n2 -- t/f ) \ flag is true if and only if n1 is less than n2 +' > asmlabel > + +\ litw ( -- h1 ) \ push a 16 bit literal on the stack +' litw asmlabel litw + +\ literal ( -- n1 ) \ push a 32 bit literal on the stack +' literal asmlabel literal + +\ lshift (n1 n2 -- n3) \ n3 = n1 shifted left n2 bits +: lshift ifunc 059 cnip ; + +\ < ( n1 n2 -- t/f ) \ flag is true if and only if n1 is greater than n2 +' < asmlabel < + +\ max ( n1 n2 -- n1 ) \ signed max of top 2 stack values +: max ifunc 081 cnip ; + +\ min ( n1 n2 -- n1 ) \ signed min of top 2 stack values +: min ifunc 089 cnip ; + +\ - ( n1 n2 -- n1-n2 ) +: - ifunc 109 cnip ; + +\ or ( n1 n2 -- n1_or_n2 ) \ bitwise or +: or ifunc 0D1 cnip ; + +\ over ( n1 n2 -- n1 n2 n1 ) \ duplicate 2 value down on the stack to the top of the stack +' over asmlabel over + +\ + ( n1 n2 -- n1+n2 ) \ sum of n1 & n2 +: + ifunc 101 cnip ; + +\ rot ( n1 n2 n3 -- n2 n3 n1 ) \ rotate top 3 value on the stack +' rot asmlabel rot + +\ r@ ( -- n1 ) \ copy top of RS to stack +: r@ rsPtr @ 2+ @ ; + +\ rshift ( n1 n2 -- n3) \ n3 = n1 shifted right logically n2 bits +: rshift ifunc 51 cnip ; + +\ rashift ( n1 n2 -- n3) \ n3 = n1 shifted right arithmetically n2 bits +: rashift ifunc 071 cnip ; + +\ r> ( -- n1 ) \ pop top of RS to stack +' r> asmlabel r> + +\ >r ( n1 -- ) \ pop stack top to RS +' >r asmlabel >r + +\ 2>r ( n1 n2 -- ) \ pop top 2 stack top to RS +' 2>r asmlabel 2>r + +\ 0branch ( t/f -- ) \ branch it top of stack value is zero 16 bit branch offset follows, +\ -2 is to itself, +2 is next word +' 0branch asmlabel 0branch + +\ (loop) ( -- ) \ add 1 to loop counter, branch if count is below limit offset follows, +\ -2 is to itself, +2 is next word +' (loop) asmlabel (loop) + +\ (+loop) ( n1 -- ) \ add n1 to loop counter, branch if count is below limit, offset follows, +\ -2 is to itself, +2 is next word +' (+loop) asmlabel (+loop) + +\ swap ( n1 n2 -- n2 n1 ) \ swap top 2 stack values +' swap asmlabel swap + +\ um* ( u1 u2 -- u1*u2L u1*u2H ) \ unsigned 32bit * 32bit -- 64bit result +' um* asmlabel um* + +\ um/mod ( u1lo u1hi u2 -- remainder quotient ) \ unsigned divide & mod u1 divided by u2 +' um/mod asmlabel um/mod + +\ u/mod ( u1 u2 -- remainder quotient ) \ unsigned divide & mod u1 divided by u2 +: u/mod 0 swap um/mod ; + +\ xor ( n1 n2 -- n1_xor_n2 ) \ bitwise xor +: xor ifunc 0D9 cnip ; + +\ waitcnt ( n1 n2 -- n1 ) \ wait until n1, add n2 to n1 +: waitcnt ifunc 1F1 cnip ; + +\ waitpeq ( n1 n2 -- ) \ wait until state n1 is equal to ina anded with n2 +: waitpeq ifunc2 1E0 cnip ; + +\ waitpne ( n1 n2 -- ) \ wait until state n1 is not equal to ina anded with n2 +: waitpne ifunc2 1E8 cnip ; + +\ vfcog ( n -- n ) makes sure n is a valid forth cog +: vfcog dup ffcog w@ lfcog w@ between 0= if drop ffcog w@ then ; + +\ reboot ( -- ) reboot the propellor chip +: reboot FF 0 hubop ; + +\ cogstop ( n -- ) +: cogstop 3 hubop 2drop ; + +\ cogreset ( n1 -- ) reset the forth cog +: cogreset 7 and dup cogstop dup dup cogd dup 100 0 fill 10 lshift cm_entry +2 lshift or or 2 hubop 2drop +\ wait for the cog to come alive +cogDebugvalue 8000 0 do dup m@ if leave then loop drop ; + +\ reset ( -- ) reset this cog +: reset mydictlock w@ 0> if 1 mydictlock w! freedict then cogid cogreset ; + +\ disio ( n -- ) disconnect the output of cog n +: disio cogEmitptr 0 swap w! ; + +\ connio ( n1 n2 -- ) connect the output from cog n1 to the input of cog n2 +: connio 7 and cogInbyte swap 7 and cogEmitptr w! ; + +\ >cog ( n1 -- ) connect the console to the forth cog +: >cog cogCON w@ disio inCON over cogEmitptr w! dup cogInbyte outCON w! cogCON w! ; + +\ these variables need to be defined after >cog to operate properly when forth is being rebuilt + +\ the cog connected to the console +cogCON w@ wvariable cogCON cogCON w! + +\ data to the console, a cogs mcwEmitptr points to inCON when it is connected +inCON w@ wvariable inCON inCON w! + +\ data from the console, points to a cogs mcwInbyte when it is connected +outCON w@ wvariable outCON outCON w! + +\ the CTLa CTLb and CTLc input from the console +ctlCON w@ wvariable ctlCON ctlCON w! + +\ clkfreq ( -- u1 ) the system clock frequency +: clkfreq 0 m@ ; + +\ parat ( offset -- addr ) the offset is added to the contents of the par register, giving an address references +\ the cogdata +: parat par @ + ; + +\ cogd ( n -- addr) the address of the data area for cog n +: cogd 7 and 8 lshift cm_cogdata + ; + +\ mcwInbyte ( -- addr ) the address of the character input as a word, $100 means no char is ready, otherwise the +\ next char is in the lo byte, write $100 after the char is read +: mcwInbyte 0 parat ; + +: cogInbyte cogd ; + +\ mcwEmitptr ( -- addr ) address of the word for memory based emit +: mcwEmitptr 2 parat ; +: cogEmitptr cogd 2+ ; + +\ mcwState ( -- addr ) access as a word, the address of a variable which is +\ 0 - interpret mode +\ 1 - forth compile mode +: mcwState 4 parat ; + +\ compile? ( -- t/f ) true if we are in a compile +: compile? mcwState w@ 0<> ; + +\ mcwDebugcmd ( -- addr ) the address of the debugcmd as a word, used to commincate from forth cog to request a reset, +\ or for traces +: mcwDebugcmd 6 parat ; +: cogDebugcmd cogd 6 + ; + +\ mcwDebugvalue ( -- addr ) the address of the debugvalue as a long, used in conjuction with debugcmd +: mcwDebugvalue 8 parat ; +: cogDebugvalue cogd 8 + ; + +\ mcwBase ( -- addr ) access as a word, the address of the base variable +: mcwBase C parat ; + +\ mcwAhere ( -- addr ) access as a word, the first unused register address in this cog +: mcwAhere E parat ; + +\ execword ( -- addr ) a long, an area where the current word for execute is stored +: execword 10 parat ; + +\ execute ( addr -- ) execute the word - pfa address is on the stack +: execute dup fMask @ and if IP ! else execword w! ca_a_exit execword 2+ w! execword IP ! then ; + +\ mcw>out ( -- addr ) access as a word, the offset to the current output byte +: mcw>out 14 parat ; + +\ mcw>in ( -- addr ) access as a word, addr is the var the offset in characters from the start of the input buffer to +\ the parse area. +: mcw>in 16 parat ; + +\ mydictlock ( -- addr ) access as a word, the number of times dictlock has been executed in the cog minus the freedict +: mydictlock 18 parat ; + +\ mcwFsliceptr ( -- ) if this is not zero it is called in the key routine +: mcwFsliceptr 1A parat ; + +\ the negative of the last time the _fSlice routine was called +: mcLastcnt 1C parat ; + +\ the maximum count between calls of _fSlice +: mcFslicecnt 20 parat ; + +: _fSlicer cnt @ dup mcLastcnt m@ + mcFslicecnt m@ max mcFslicecnt m! negate mcLastcnt m! ; + +\ _fSlice ( -- ) if the fSLicePtr is set +: _fSlice mcwFsliceptr w@ dup if execute else drop then ; + +\ mcPad ( -- addr ) access as bytes, or words and long, the address of the pad area - used by accept for keyboard input, +\ can be used carefully by other code +: mcPad 24 parat ; +: cogPad cogd 24 + ; + +\ _pclr ( addr -- ) fill padsize / 4 longs with blanks, addr must be long aligned +: _pclr dup padsize + swap do 20202020 i m! 4 +loop ; + +\ cogPadclr ( n -- ) clear out the pad on cog n +: cogPadclr cogPad _pclr ; + +\ pad>in ( -- addr ) addr is the address to the start of the parse area. +: pad>in mcw>in w@ mcPad + ; + +\ namemax ( -- n1 ) the maximum name length allowed must be 1F +: namemax 1F ; + +\ padsize ( -- n1 ) the size of the pad area +: padsize 80 ; + +\ these are temporay variables, and by convention are only used within a word +\ caution, make sure you know what words you are calling +: mcwT0 A4 parat ; +: mcwT1 A6 parat ; +: mcT A8 parat ; \ 40 byte array overflows into mcNumpad + +\ mcNumpad ( -- addr ) the of the area used by the numeric output routines, can be used carefully by other code +: mcNumpad C0 parat ; + +\ pad>out ( -- addr ) addr is the address to the the current output byte +: pad>out mcw>out w@ mcNumpad + ; + +\ numpadsize ( -- n1 ) the size of the numpad +: numpadsize 30 ; + +\ keyto ( -- c1 true | false ) a key or a timeout +: keyto 0 mswKeyTO w@ 0 do key? if drop key -1 leave then loop ; + +\ emit? ( -- t/f) true if the output is ready for a char +: emit? _fSlice mcwEmitptr w@ dup if w@ 100 and 0<> else drop -1 then ; + +\ emit ( c1 -- ) emit the char on the stack +: emit begin emit? until FF and mcwEmitptr w@ dup if w! else 2drop then ; + +\ key? ( -- t/f) true if there is a key ready for input +: key? _fSlice mcwInbyte w@ 100 and 0= ; + +\ key ( -- c1 ) get a key +: key begin key? until mcwInbyte w@ 100 mcwInbyte w! ; + +\ fkey? ( -- c1 t/f ) fast nonblocking key routine +: fkey? mcwInbyte w@ dup 100 and if 0 else 100 mcwInbyte w! -1 then ; + +\ nip ( x1 x2 -- x1 ) +: nip swap drop ; + +\ tuck ( x1 x2 -- x2 x1 x2 ) +: tuck swap over ; + +\ 2dup ( n1 n2 -- n1 n2 n1 n2 ) copy top 2 items on the stack +: 2dup over over ; + +\ 2drop ( n1 n2 -- ) drop top 2 items on the stack +: 2drop drop drop ; + +\ 3drop ( n1 n2 n3 -- ) drop top 3 items on the stack +: 3drop drop drop drop ; + +\ u/ ( u1 u2 -- u1/u2) u1 divided by u2 +: u/ u/mod nip ; + +\ u* ( u1 u2 -- u1*u2) u1 multiplied by u2 +: u* um* drop ; + +\ invert ( n1 -- n2 ) bitwise invert n1 +: invert -1 xor ; + +\ negate ( n1 -- 0-n1 ) the negative of n1 +: negate ifunc1 149 cnip ; + +\ 0= ( n1 -- t/f ) true if n1 is zero +: 0= 0 = ; + +\ <> ( x1 x2 -- flag ) flag is true if and only if x1 is not bit-for-bit the same as x2. +: <> = invert ; + +\ 0 <> ( n1 -- t/f ) true if n1 is not zero +: 0<> 0= invert ; + +\ 0< ( n1 -- t/f ) true if n1 < 0 +: 0< 0 < ; + +\ 0> ( n1 -- t/f ) true if n1 > 0 +: 0> 0 > ; + +\ 1+ ( n1 -- n1+1 ) +: 1+ 1 + ; + +\ 1- ( n1 -- n1-1 ) +: 1- 1 - ; + +\ 2+ ( n1 -- n1+2 ) +: 2+ 2 + ; + +\ 4+ ( n1 -- n1+4 ) +: 4+ 4 + ; + +\ 2- ( n1 -- n1-2 ) +: 2- 2 - ; + +\ 2* ( n1 -- n1<<1 ) n2 is shifted logically left 1 bit +: 2* 1 lshift ; + +\ 2/ ( n1 -- n1>>1 ) n2 is shifted arithmetically right 1 bit +: 2/ 1 rashift ; + +\ rot2 ( x1 x2 x3 -- x3 x1 x2 ) +: rot2 rot rot ; + +\ >= ( n1 n2 -- t/f) true if n1 >= n2 +: >= 2dup > rot2 = or ; + +\ <= ( n1 n2 -- t/f) true if n1 <= n2 +: <= 2dup < rot2 = or ; + +\ 0>= ( n1 -- t/f ) true if n1 >= 0 +: 0>= dup 0 > swap 0= or ; + +\ w+! ( n1 addr -- ) add n1 to the word contents of address +: w+! dup w@ rot + swap w! ; + +\ orc! ( c1 addr -- ) or c1 with the contents of address +: orc! dup c@ rot or swap c! ; + +\ andc! ( c1 addr -- ) and c1 with the contents of address +: andc! dup c@ rot and swap c! ; + +\ between ( n1 n2 n3 -- t/f ) true if n2 <= n1 <= n3 +: between rot2 over <= rot2 >= and ; + +\ cr ( -- ) emits a carriage return +: cr D emit ; + +\ space ( -- ) emits a space +: space bl emit ; + +\ spaces ( n -- ) emit n spaces +: spaces dup if 0 do space loop else drop then ; + +\ .hex ( n -- ) emit a single hex digit +: .hex F and 30 + dup 39 > if 7 + then emit ; + +\ .byte ( n -- ) emit 2 hex digits +: .byte dup 4 rshift .hex .hex ; + +\ .word ( n -- ) emit 4 hex digits +: .word dup 8 rshift .byte .byte ; + +\ .long ( n -- ) emit 8 hex digits +: .long dup 10 rshift .word .word ; + +\ bounds ( x n -- x+n x ) +: bounds over + swap ; + +\ alignl ( n1 -- n1) aligns n1 to a long (32 bit) boundary +: alignl 3 + FFFFFFFC and ; + +\ alignw ( n1 -- n1) aligns n1 to a halfword (16 bit) boundary +: alignw 1+ FFFFFFFE and ; + +\ c@++ ( c-addr -- c-addr+1 c1 ) fetch the character and increment the address +: c@++ dup c@ swap 1+ swap ; + +\ ctolower ( c1 -- c1 ) if c is A-Z converts it to lower case +: ctolower dup 41 5A between if 20 or then ; + +\ ctoupper ( c1 -- c1 ) if c is a-z converts it to upper case +: ctoupper dup 61 7A between if DF and then ; + +\ todigit ( c1 -- n1 ) converts character to a number +: todigit ctoupper 30 - dup 9 > if 7 - dup A < if -1 then then ; + +\ isdigit ( c1 -- t/f ) true if is it a valid digit according to base +: isdigit todigit dup 0>= swap mcwBase w@ < and ; + +\ isunumber ( c-addr len -- t/f ) true if the string is numeric +: isunumber bounds -1 rot2 do i c@ isdigit and loop ; + +\ unumber ( c-addr len -- u1 ) convert string to an unsigned number +: unumber bounds 0 rot2 do mcwBase w@ u* i c@ todigit + loop ; + +\ number ( c-addr len -- n1 ) convert string to a signed number +: number over c@ 2D = if 1- 0 max swap 1+ swap unumber negate else unumber then ; + +\ isnumber ( c-addr len -- t/f ) true if the string is numeric +: isnumber over c@ 2D = if 1- 0 max swap 1+ swap then isunumber ; + +\ .str ( c-addr u1 -- ) emit u1 characters at c-addr +: .str dup if bounds do i c@ 20 max 7F min emit loop else 2drop then ; + +\ npfx ( c-addr1 c-addr2 -- t/f ) -1 if c-addr2 is prefix of c-addr1, 0 otherwise +: npfx namelen rot namelen rot 2dup > if min bounds do c@++ i c@ <> if drop 0 leave then loop 0<> else 2drop 2drop 0 then ; + +\ namelen ( c-addr -- c-addr+1 len ) returns c-addr+1 and the length of the name at c-addr +: namelen c@++ namemax and ; + +\ cmove ( c-addr1 c-addr2 u -- ) If u is greater than zero, copy u consecutive characters from the data space starting +\ at c-addr1 to that starting at c-addr2, proceeding character-by-character from lower addresses to higher addresses. +: cmove dup 0= if 3drop else bounds do c@++ i c! loop then drop ; + +\ namecopy ( c-addr1 c-addr2 -- ) Copy the name from c-addr1 to c-addr2 +: namecopy over namelen 1+ nip cmove ; + +\ ccopy ( c-addr1 c-addr2 -- ) Copy the cstr from c-addr1 to c-addr2 +: ccopy over c@ 1+ cmove ; + +\ cappend ( c-addr1 c-addr2 -- ) addpend the cstr from c-addr1 to c-addr2 +: cappend dup dup c@ + 1+ rot2 over c@ over c@ + swap c! dup c@ swap 1+ rot2 cmove ; + +\ cappendc ( c cstr -- ) append c the cstr +: cappendc dup c@ 1+ over c! dup c@ + c! ; + +\ cappendn ( n cstr -- ) print the number n and append to cstr +: cappendn swap <# #s #> swap cappend ; + +\ cappendnc ( n cstr -- ) print the number n and append to cstr and then append a blank +: cappendnc swap <# #s #> over cappend bl swap cappendc ; + +\ cogX ( cstr n -- ) execute cstr on cog n +: cogX vfcog dup cogInbyte begin dup w@ 100 and until rot2 dup cogPadclr cogPad 1+ swap c@++ rot swap cmove d swap w! ; + +\ cogXO ( cstr -- ) disconnect console input, execute cstr on the next available cog, directing output back to this cog +: cogXO 0 outCON w! cogid dup 1+ vfcog dup rot connio cogX ; + +\ ??? ( -- ) prints out ??? +: ??? ." ???" ; + +\ .strname ( c-addr -- ) c-addr point to a forth name field, print the name +: .strname dup if namelen .str else drop ??? then ; + +\ .cstr ( addr -- ) emit a counted string at addr +: .cstr c@++ .str ; + +\ dq ( -- ) emit a counted string at the IP, and increment the ip past it and word align it +: dq r> c@++ 2dup + alignw >r .str ; + +\ i ( -- n1 ) the most current loop counter +: i rsPtr @ 3 + @ ; + +\ j ( -- n1 ) the second most current loop counter +: j rsPtr @ 5 + @ ; + +\ ibound ( -- n1 ) the upper bound of i +: ibound rsPtr @ 2+ @ ; + +\ jbound ( -- n1 ) the upper bound of j +: jbound rsPtr @ 4+ @ ; + +\ lasti? ( -- t/f ) true if this is the last value of i in this loop +: lasti? rsPtr @ 2+ @ 1- rsPtr @ 3 + @ = ; + +\ lastj? ( -- t/f ) true if this is the last value of j in this loop +: lastj? rsPtr @ 4+ @ 1- rsPtr @ 5 + @ = ; + +\ seti ( n1 -- ) set the most current loop counter +: seti rsPtr @ 3 + ! ; + +\ setj ( n1 -- ) set the second most current loop counter +: setj rsPtr @ 5 + ! ; + +\ eol? ( c1 -- c1 t/f ) true if c1 == LF or CR +: eol? dup A = over D = or ; + +\ bs? ( c1 -- c1 t/f ) true if c1 == BS or DEL +: bs? dup 8 = over 7F = or ; + +\ fill ( c-addr u char -- ) +: fill rot2 bounds do dup i c! loop drop ; + +\ nfa>lfa ( addr -- addr ) go from the nfa (name field address) to the lfa (link field address) +: nfa>lfa 2- ; + +\ nfa>pfa ( addr -- addr ) go from the nfa (name field address) to the pfa (parameter field address) + +: nfa>pfa 7FFF and namelen + alignw ; + +\ nfa>next ( addr -- addr ) go from the current nfa to the prev nfa in the dictionary + +: nfa>next nfa>lfa w@ ; + +\ lastnfa ( -- addr ) gets the last NFA + +: lastnfa mswlastnfa w@ ; + +\ fnamechar? ( c1 -- t/f ) true if c1 is a valif name char > $20 < $7F + +: fnamechar? dup 20 > swap 7F < and ; + +\ fpfa>nfa ( addr -- addr ) pfa>nfa for a forth word + +: fpfa>nfa 7FFF and 1- begin 1- dup c@ fnamechar? 0= until ; + +\ apfa>nfa ( addr -- addr ) pfa>nfa for an asm word + +: apfa>nfa lastnfa begin 2dup nfa>pfa w@ = over c@ 80 and 0= and if -1 else nfa>next dup 0= then until nip ; + +\ pfa>nfa ( addr -- addr ) gets the name field address (nfa) for a parameter field address (pfa) + +: pfa>nfa dup fMask @ and if fpfa>nfa else apfa>nfa then ; + +\ accept ( c-addr +n1 -- +n2 ) collect n1 -2 characters or until eol, ctl characters, tab included are converted to space, +\ pad with 1 space at start & end. For parsing ease, and for the length byte when we make cstrs + +: accept 3 max 2dup bl fill 1- swap 1+ swap bounds 0 + +begin key eol? + if cr drop -1 + else bs? + if drop dup + if 8 emit bl emit 8 emit 1- swap 1- bl over c! swap then 0 + else bl max dup emit swap >r over c! 1+ 2dup 1+ = r> 1+ swap then + then +until nip nip ; + +\ parse ( c1 -- +n2 ) parse the word delimited by c1, or the end of buffer is reached, n2 is the length >in is the offset +\ in the pad of the start of the parsed word + +: parse padsize mcw>in w@ = if 0 else 0 begin 2dup pad>in + c@ = if -1 else 1+ 0 then until then nip ; + +\ skipbl ( -- ) increment >in past blanks or until it equals padsize +: skipbl begin pad>in c@ bl = if mcw>in w@ 1+ dup mcw>in w! padsize = else -1 then until ; + +\ nextword ( -- ) increment >in past current counted string +: nextword padsize mcw>in w@ > if pad>in c@ mcw>in w@ + 1+ mcw>in w! then ; + +\ parseword ( c1 -- +n2 ) skip blanks, and parse the following word delimited by c1, update to be a counted string in +\ the pad + +: parseword skipbl parse dup if mcw>in w@ 1- 2dup mcPad + c! mcw>in w! then ; + +\ parsebl ( -- t/f) parse the next word in the pad delimited by blank, true if there is a word + +: parsebl bl parseword 0<> ; + +\ padnw ( -- t/f ) move past current word and parse the next word, true if there is a next word + +: padnw nextword parsebl ; + +\ parsenw ( -- cstr ) parse and move to the next word, str ptr is zero if there is no next word +: parsenw parsebl if pad>in nextword else 0 then ; + +\ padclr ( -- ) +: padclr begin padnw 0= until ; + +\ find ( c-addr -- c-addr 0 | xt 2 | xt 1 | xt -1 ) c-addr is a counted string, 0 - not found, 2 eXecute word, +\ 1 immediate word, -1 word NOT ANSI + +: find lastnfa over fin dup +if nip dup nfa>pfa over c@ 80 and 0= if w@ then + swap c@ dup 40 and + if 20 and if 2 else 1 then + else drop -1 then +then ; + +\ <# ( -- ) initialize the output area +: <# numpadsize mcw>out w! ; + +\ #> ( -- caddr ) address of a counted string representing the output, NOT ANSI +: #> drop numpadsize mcw>out w@ - -1 mcw>out w+! pad>out c! pad>out ; + +\ tochar ( n1 -- c1 ) convert c1 to a char +: tochar 1F and 30 + dup 39 > if 7 + then ; + +\ # ( n1 -- n2 ) divide n1 by mcwBase and convert the remainder to a char and append to the output +: # mcwBase w@ u/mod swap tochar -1 mcw>out w+! pad>out c! ; + +\ #s ( n1 -- 0 ) execute # until the remainder is 0 +: #s begin # dup 0= until ; + +\ . ( n1 -- ) +: . dup 0< if 2D emit negate then <# #s #> .cstr 20 emit ; + +\ cogid ( -- n1 ) return id of the current cog ( 0 - 7 ) +: cogid -1 1 hubop drop ; + +\ locknew ( -- n2 ) allocate a lock, result is in n2, -1 if unsuccessful +: locknew -1 4 hubop -1 = if drop -1 then ; + +\ lockret ( n1 -- ) deallocate a lock, previously allocated via locknew +: lockret 5 hubop 2drop ; + +\ lockset ( n1 -- n2 ) set lock n1, result is in n2, -1 if the lock was set as per 'c' flag, lock ( n1 ) must have +\ been allocated via locknew +: lockset 6 hubop nip ; + +\ lockclr ( n1 -- n2 ) set lock n1, result is in n2, -1 if the lock was set as per 'c' flag, lock ( n1 ) must have +\ been allocated via locknew + +: lockclr 7 hubop nip ; + +\ lockdict? ( -- t/f ) attempt to lock the forth dictionary, 0 if unsuccessful -1 if successful + +: lockdict? mydictlock w@ if 1 mydictlock w+! -1 else 0 lockset 0= if 1 mydictlock w! -1 else 0 then then ; + +\ freedict ( -- ) free the forth dictionary, if I have it locked + +: freedict mydictlock w@ dup if 1- dup mydictlock w! 0= if 0 lockclr drop then else drop then ; + +\ lockdict ( -- ) lock the forth dictionary + +: lockdict begin lockdict? until ; + +: _eoom ." Out of memory" cr ; +\ checkdict ( n -- ) make sure there are at least n bytes available in the dictionary +: checkdict mswHere w@ + mswDictend w@ >= +if cr mswHere w@ . mswDictend . _eoom clearkeys reset then ; + +: _c1 lockdict + mswlastnfa w@ mswHere w@ dup 2+ mswlastnfa w! swap over w! 2+ ; + +: _c2 over namecopy namelen + alignw mswHere w! freedict ; + +\ ccreate ( cstr -- ) create a dictionary entry +: ccreate _c1 swap _c2 ; + +\ create ( -- ) skip blanks parse the next word and create a dictionary entry +: create bl parseword if _c1 pad>in _c2 nextword then ; + +\ clabel ( cstr -- ) create an assembler constant at the current cog mcwAhere +: clabel lockdict ccreate ca_a_doconw w, mcwAhere w@ w, forthentry freedict ; + +\ herelal ( -- ) align contents of here to a long boundary, 4 byte boundary +: herelal lockdict 4 checkdict mswHere w@ alignl mswHere w! freedict ; + +\ herewal ( -- ) align contents of here to a word boundary, 2 byte boundary +: herewal lockdict 2 checkdict mswHere w@ alignw mswHere w! freedict ; + +\ allot ( n1 -- ) add n1 to here, allocates space on the data dictionary or release it +: allot lockdict dup checkdict mswHere w+! freedict ; + +\ aallot ( n1 -- ) add n1 to aHere, allocates space in the cog or release it, n1 is # of longs +: aallot mcwAhere w+! mcwAhere w@ par >= if _eoom reset then ; + +\ , ( x -- ) allocate 1 long, 4 bytes in the dictionary and copy x to that location + +: , lockdict herelal mswHere w@ m! 4 allot freedict ; + +\ a, ( x -- ) allocate 1 long in the cog and copy x to that location +: a, mcwAhere w@ ! 1 aallot ; + +\ w, ( x -- ) allocate 1 halfword 2 bytes in the dictionary and copy x to that location +: w, lockdict herewal mswHere w@ w! 2 allot freedict ; + +\ c, ( x -- ) allocate 1 byte in the dictionary and copy x to that location +: c, lockdict mswHere w@ c! 1 allot freedict ; + +\ orlnfa ( c1 -- ) ors c1 with the nfa length of the last name field entered +: orlnfa lockdict lastnfa orc! freedict ; + +\ forthentry ( -- ) marks last entry as a forth word +: forthentry lockdict 80 orlnfa freedict ; + +\ immediate ( -- ) marks last entry as an immediate word +: immediate lockdict 40 orlnfa freedict ; + +\ exec ( -- ) marks last entry as an eXecute word, executes always +: exec lockdict 60 orlnfa freedict ; + +\ leave ( -- ) exits at the next loop or +loop, i is placed to the max loop value +: leave r> r> r> drop dup 2>r >r ; + +\ clearkeys ( -- ) clear the input keys +: clearkeys 0 mcwState w! +begin -1 mswKeyTO w@ 0 do key? if key drop drop 0 leave then loop until ; + +\ w>l ( n1 n2 -- n1n2 ) consider only lower 16 bits +: w>l FFFF and swap 10 lshift or ; + +\ l>w ( n1n2 -- n1 n2) break into 16 bits +: l>w dup 10 rshift swap FFFF and ; + + +: : lockdict create 3741 1 mcwState w! ; + +: _mmcs ." MISMATCHED CONTROL STRUCTURE(S)" cr clearkeys ; + +: _; w, 0 mcwState w! forthentry 3741 <> if _mmcs then freedict ; +\ to prevent ; from using itself while it is defining itself +: ;; ca_a_exit _; ; immediate + +: ; ca_a_exit _; ;; immediate + +: dothen l>w dup 1235 = swap 1239 = or if dup mswHere w@ swap - swap w! else _mmcs then ; + +: then dothen ; immediate + +: thens begin dup FFFF and dup 1235 = swap 1239 = or if dothen 0 else -1 then until ; immediate + +: if ca_a_0branch w, mswHere w@ 1235 w>l 0 w, ; immediate + +: else ca_a_branch w, 0 w, dothen mswHere w@ 2- 1239 w>l ; immediate + +: until l>w 1317 = if ca_a_0branch w, mswHere w@ - w, else _mmcs then ; immediate + +: begin mswHere w@ 1317 w>l ; immediate + +: doloop swap l>w 2329 = if swap w, mswHere w@ - w, else _mmcs then ; + +: loop ca_a_(loop) doloop ; immediate + +: +loop ca_a_(+loop) doloop ; immediate + +: do ca_a_2>r w, mswHere w@ 2329 w>l ; immediate + +: _ecs 3A emit space ; +: _udf ." UNDEFINED WORD " ; + +: ." cm_dq w, 1 mcw>in w+! 22 parse dup c, dup pad>in mswHere w@ rot cmove dup allot 1+ mcw>in w+! herewal ; immediate + +\ fisnumber ( -- ) dummy routine s for indirection when float package is loaded +: fisnumber isnumber ; +: fnumber number ; + +\ interpretpad ( -- ) interpret the contents of the pad +: interpretpad 0 mcw>in w! +begin bl parseword + if pad>in nextword find dup + if dup -1 = + if drop compile? if w, else execute then 0 + else 2 = + if execute 0 else + compile? if execute 0 else pfa>nfa ." IMMEDIATE WORD " .strname clearkeys cr -1 then + then + then + else drop dup c@++ fisnumber + if + c@++ fnumber compile? if dup 0 FFFF between if ca_a_litw w, w, else ca_a_literal w, , then then 0 + else + 0 mcwState w! freedict _udf .strname cr clearkeys -1 + then + then + else -1 then until ; + +\ [0m ( -- ) a dummy word, fast load echos this so... +: [0m ; + +\ interpret ( -- ) the main interpreter loop +: interpret +\ ansi red +1b emit 5b emit 33 emit 31 emit 6d emit +mcPad padsize accept drop +\ ansi normal +1b emit 5b emit 30 emit 6d emit +interpretpad ; + + +\ variable ( -- ) skip blanks parse the next word and create a variable, allocate a long, 4 bytes +: variable lockdict create ca_a_dovar w, 0 , forthentry freedict ; + +\ _wc1 ( x -- nfa ) skip blanks parse the next word and create a constant, allocate a word, 2 bytes +: _wc1 lockdict create ca_a_doconw w, w, forthentry lastnfa freedict ; + +\ wconstant ( x -- ) skip blanks parse the next word and create a constant, allocate a word, 2 bytes +: wconstant _wc1 drop ; + +\ avariable ( -- ) skip blanks parse the next word and create a cog variable, allocate a long +: avariable mcwAhere w@ _wc1 1 aallot ; + +\ wvariable ( -- ) skip blanks parse the next word and create a variable, allocate a word, 2 bytes +: wvariable lockdict create ca_a_dovarw w, 0 w, forthentry freedict ; + +\ constant ( x -- ) skip blanks parse the next word and create a constant, allocate a long, 4 bytes +: constant lockdict create ca_a_docon w, , forthentry freedict ; + +\ asmlabel ( x -- ) skip blanks parse the next word and create an assembler entry +: asmlabel lockdict create w, freedict ; + +\ hex ( -- ) set the base for hexadecimal +: hex 10 mcwBase w! ; + +\ decimal ( -- ) set the mcwBase for decimal +: decimal A mcwBase w! ; + + +\ words ( cstr -- ) prints the words in the forth dictionary starting with cstr, 0 prints all + +: _words 0 >r lastnfa ." NFA (Forth/Asm Immediate eXecute) Name" +begin + 2dup swap dup if npfx else 2drop -1 then + if + r> dup 0= if cr then 1+ 3 and >r + dup .word space dup c@ dup 80 and + if 46 else 41 then emit dup 40 and + if 49 else 20 then emit 20 and + if 58 else 20 then emit + space dup .strname dup c@ namemax and 15 swap - 0 max spaces + then nfa>next dup 0= +until r> 3drop cr ; + +\ words ( -- ) prints the words in the forth dictionary, if the pad has another string following, with that prefix +: words parsenw _words ; + + + +\ del_ms ( n1 -- ) for 80Mhz 68DB max +: del_ms 7FFFFFFF clkfreq 3e8 u/ u/ min 1 max clkfreq 3E8 u/ u* cnt @ + begin dup cnt @ - 0< until drop ; +: del_sec 10 u/mod dup if 0 do 3e80 del_ms loop else drop then dup if 0 do 3e8 del_ms loop else drop then ; + +\ >m ( n1 -- n2 ) produce a 1 bit mask n2 for position n +: >m 1 swap lshift ; + +\ eeprom read and write routine for the prop proto board AT24CL256 eeprom on pin 28 sclk, 29 sda +\ pxi ( n1 -- ) set pin # n1 to an input +: pxi >m invert dira @ and dira ! ; + +\ pxo ( n1 -- ) set pin # n1 to an input +: pxo >m dira @ or dira ! ; + +\ pxl ( n1 -- ) set pin # n1 to lo +: pxl >m mpxl ; + +\ pxh ( n1 -- ) set pin # n1 to hi +: pxh >m mpxh ; + +\ px ( t/f n1 -- ) set pin # n1 to h - true or l false +: px swap if pxh else pxl then ; + +\ px? ( n1 -- t/f) true if pin n1 is hi +: px? >m mpx ; + +1C wconstant _scl \ SCL +1D wconstant _sda \ SDA + +1 _scl lshift constant _sclm +1 _sda lshift constant _sdam + +: _sdai _sda pxi ; +: _sdao _sda pxo ; +: _scli _scl pxi ; +: _sclo _scl pxo ; + +: _sdal _sdam mpxl ; +: _sdah _sdam mpxh ; +: _scll _sclm mpxl ; +: _sclh _sclm mpxh ; +: _sda? _sdam mpx ; + +\ _eeInit ( -- ) initialize the eeprom in case it is in a weird state +: _eeInit _sclh _sclo _sdai 9 0 do _scll _sclh _sda? if leave then loop ; + +\ _eeStart ( -- ) start the data transfer +: _eeStart _sclh _sclo _sdah _sdao _sdal _scll ; + +\ _eeStop ( -- ) stop the data transfer +: _eeStop _sclh _sdah _scli _sdai ; + +\ _eeWrite ( c1 -- t/f ) write a byte to the eeprom, returns ack bit +: _eeWrite 80 8 0 +do 2dup and if _sdah else _sdal then _sclh _scll 1 rshift loop +2drop _sdai _sclh _sda? _scll _sdal _sdao ; + +\ _eeRead ( t/f -- c1 ) read a byte from the eeprom, ackbit in, byte out +: _eeRead _sdai 0 8 0 +do 1 lshift _sclh _sda? _scll if 1 or then loop +swap _sda px _sdao _sclh _scll _sdal ; + +\ the eeReadPage and eeWritePage words assume the eeprom are 64kx8 and will address up to +\ 8 sequential eeproms +\ eeReadPage ( eeAddr addr u -- t/f ) return true if there was an error, use lock 1 +: eeReadPage begin 1 lockset 0= until +1 max rot dup ff and swap dup 8 rshift ff and swap 10 rshift 7 and 1 lshift dup >r +_eeStart A0 or _eeWrite swap _eeWrite or swap _eeWrite or +_eeStart r> A1 or _eeWrite or +rot2 bounds +do lasti? _eeRead i c! loop _eeStop 1 lockclr drop ; + +\ eeWritePage ( eeAddr addr u -- t/f ) return true if there was an error, use lock 1 +: eeWritePage begin 1 lockset 0= until +1 max rot dup ff and swap dup 8 rshift ff and swap 10 rshift 7 and 1 lshift +_eeStart A0 or _eeWrite swap _eeWrite or swap _eeWrite or +rot2 bounds +do i c@ _eeWrite or loop _eeStop 10 del_ms 1 lockclr drop ; +: eeErr ." eeProm error" ; + diff --git a/zubehör/PropForth/PropForthPart2.f b/zubehör/PropForth/PropForthPart2.f new file mode 100644 index 0000000..dd089e3 --- /dev/null +++ b/zubehör/PropForth/PropForthPart2.f @@ -0,0 +1,311 @@ +FL + + + + + + +\ eeReadWord ( eeAddr -- n1 ) +: eeReadWord mcwT0 2 eeReadPage if eeErr cr then mcwT0 w@ ; + +\ eeWriteWord ( n1 eeAddr -- ) +: eeWriteWord swap mcwT0 w! mcwT0 2 eeWritePage if eeErr cr then ; + +\ eeReadByte ( eeAddr -- c1 ) +: eeReadByte eeReadWord FF and ; + +\ eeCopy ( addr1 addr2 u -- ) copy u bytes from addr1 to addr2, addr1 and addr2 must be on a 0x80 byte page boundary +\ clears the pad, so make sure no commands follow +\ and u must be a multiple of 0x80 and should not overlap +: eeCopy 7F invert and rot 7f invert and rot 7f invert and rot +0 do over i + dup . mcPad 80 eeReadPage if eeErr leave then +dup i + dup . mcPad 80 eeWritePage if eeErr leave then +i 3FF and 0= if cr then 80 +loop 2drop cogid cogPadclr ; + +: _d1 cr over .word space dup .word _ecs bounds ; +: _d2 cr .word _ecs ; +: _d3 mcT 10 bounds do i c@ .byte space loop 2 spaces mcT 10 .str ; + +\ dump ( adr cnt -- ) uses mcT +: dump _d1 do i _d2 i mcT 10 cmove _d3 10 +loop cr ; + +\ rdump ( adr cnt -- ) uses mcwT1 - mcwT8 +: rdump _d1 do i _d2 i mcT 10 eeReadPage if mcT 10 0 fill then _d3 10 +loop cr ; + +\ adump ( adr cnt -- ) +: adump cr over .word space dup .word _ecs bounds +do + cr i .word _ecs i 4 bounds + do i @ .long space loop +4 +loop cr ; + +\ \ ( -- ) moves the parse pointer >in to the end of the line, tricky to redefine +\ CTL-E gets traslated to \ by fast_load +:  \ +padsize mcw>in w! ; immediate exec + +\ ' ( -- addr ) returns the execution token for the next name, if not found it returns 0 +: ' parsebl if pad>in nextword find 0= if _udf cr drop 0 then else 0 then ; + +\ cq ( -- addr ) returns the address of the counted string following this word and increments the IP past it + +: cq r> dup c@++ + alignw >r ; + +\ c" ( -- c-addr ) compiles the string delimited by ", runtime return the addr of the counted string ** valid only in that line +: c" compile? +if + cm_cq w, 1 mcw>in w+! 22 parse dup c, dup pad>in mswHere w@ rot cmove dup allot 1+ mcw>in w+! herewal +else + 22 parse 1- pad>in 2dup c! swap 2+ mcw>in w+! +then ; immediate exec + +\ the base address for the input buffer +wvariable fl_base + +\ the number of buffered characters +wvariable fl_count + +\ the old mswDictend +wvariable fl_top + +\ the offset of the next byte in +wvariable fl_in + +\ one fast load at a time +wvariable fl_lock + +\ fl_buf ( -- t/f ) allocate all but 300 chars and load keys load true if successful +: fl_buf mswDictend w@ mswHere w@ - 300 - 0 fl_count w! lockdict fl_lock w@ +if freedict cr 0 else -1 fl_lock w! freedict -1 then +\ ( u t/f -- ) true if successful so far +if +\ save the old mswDictend and initialize variables + mswDictend w@ dup fl_top w! swap - dup fl_base w! dup fl_in w! 1- mswDictend w! + 0 + begin dup mswKeyTO w@ 0 + do + begin fkey? + if dup 5C = \ if a backslash, throw away keys + if drop begin keyto if D = else -1 then until else +\ drop all characters between { } + dup 7B = if drop begin keyto if 7D = else -1 then until else +\ translate CTL-E 05 to backspace 5C + dup 5 = if drop 5C then + fl_in w@ c! 1+ fl_in w@ 1+ dup fl_top w@ = + if _eoom clearkeys reset then fl_in w! + then + then 0 +\ stay in begin until + else drop -1 then +\ no key, exit begin until + until + loop + swap over = +\ until count is the same + until + dup . ." chars" cr fl_count w! -1 +else drop 0 then +; + +\ fl_skeys ( n -- ) emit the keys in the fast buffer +: fl_skeys +fl_lock w@ fl_count w@ 0<> and +if + fl_base w@ fl_count w@ bounds + do + i dup c@ emit mswDictend w! + loop + fl_top w@ mswDictend w! 0 fl_count w! lockdict 0 fl_lock w! freedict + +then +; + +: loadee 2dup F andn bounds + do i mcT 10 eeReadPage drop mcT 10 bounds do i c@ emit loop 10 +loop + dup F andn rot + swap F and dup if bounds do i eeReadByte emit loop else 2drop then ; +: _caend c" cr " over cappend cogid over cappendnc c" 0 mcwEmitptr w! >cog" swap cappend ; + +: FL fl_buf if c" fl_skeys" mcT ccopy mcT _caend mcT cogXO then ; + +\ file area 8000 - FFFF +\ individual files start on 128 byte boundaries, +\ the first thing is the length as a 16 bit word, then a cstr which is the file name, and then the contents +\ of the file + +8000 constant eeBot +10000 constant eeTop + +\ f_fill ( c1 -- ) fill the eeprom file area with c1 +: f_fill mcPad 80 rot fill eeTop eeBot +do i mcPad 80 eeWritePage if eeErr cr leave then 80 +loop +mcPad 80 bl fill ; + +\ f_clear ( -- ) clear the eeprom file area, only writes the length word to FFFF +: f_clear eeTop eeBot do FFFF i eeWriteWord 80 +loop ; + +: _fi mcNumpad dup w@ swap 2+ c@ + 2+ 1+ 80 u/mod swap if 1+ then 80 u* ; + +\ list ( -- ) list the files names in the eeprom +: list eeTop eeBot +do + i mcNumpad numpadsize namemax 1+ 2+ min eeReadPage if eeErr leave then mcNumpad w@ FFFF = + if i . cr 80 leave else i . mcNumpad dup w@ . 2+ .cstr cr _fi then ++loop ; + +\ f_find ( cstr -- n1 ) find the file, 0 if not found +: f_find 0 eeTop eeBot +do + i mcNumpad numpadsize namemax 1+ 2+ min eeReadPage if eeErr leave then mcNumpad w@ FFFF = + if nip 80 leave else over mcNumpad 2+ cstr= if drop i then _fi then ++loop ; + +\ f_free ( -- n1 ) address of the first free file page, 0 if there are none +: f_free 0 eeTop eeBot +do + i mcNumpad 4 eeReadPage if eeErr leave then mcNumpad w@ FFFF = + if drop i 80 leave else _fi then ++loop ; + +\ f_wfile ( -- ) write the file at fl_base for fl_count bytes, the format must be: +\ word length the number of bytes in the content +\ bytes cstr - filename +\ bytes file contents +: f_wfile f_free dup +if + dup fl_count w@ + eeTop < + if fl_base w@ fl_count w@ bounds + do dup + i fl_count w@ dup 80 min swap over - fl_count w! eeWritePage + if eeErr leave then + 80 + 80 +loop drop + else drop _eoom then +else drop eeErr cr then ; + +\ FW ( n1 -- ) like a fast load but write to the file area, first entry after a blank lines must be 3 periods followed by the filename +: FW fl_buf +if fl_count w@ 0 + do + fl_base w@ c@ 2E = + if leave else fl_base w@ 1+ fl_base w! fl_count w@ 1- fl_count w! then + loop + fl_base w@ 3 + 20 bounds do i c@ bl <= lasti? or if i leave then loop fl_base w@ - dup + 3 - fl_base w@ 2+ c! + fl_count w@ swap - dup fl_base w@ c! dup 8 rshift fl_base w@ 1+ c! + if f_wfile then +fl_top w@ mswDictend w! lockdict 0 fl_lock w! freedict +then ; + +\ f_al ( addr1 -- n1 addr2) for file at addr1, get the length - n1, and the address of teh contents - addr2 +: f_al dup eeReadWord over 2+ eeReadByte rot + 2+ 1+ ; + +\ f_load ( cstr -- ) load the file name following from eeprom +: f_load f_find dup +if f_al 0 mcT c! mcT cappendnc mcT cappendnc c" loadee" mcT cappend mcT _caend mcT cogXO else drop then ; + +\ load ( -- ) load the file name following from eeprom +: load parsenw dup if f_load else drop then ; + +: version c" PropForth v2.5 2009OCT24 17:15 0" ; + +\ free ( -- ) display free main bytes and current cog longs +: free mswDictend w@ mswHere w@ - . ." bytes free - " par mcwAhere w@ - . ." cog longs free" cr ; + +\ saveforth( -- ) write the running image to eeprom +: saveforth +c" mswHere" find +if + version dup c@ + dup c@ 1+ swap c! + pfa>nfa mswHere w@ swap +\ 2e emit + begin dup w@ over eeWriteWord 2+ dup 7F and 0= until + do + ibound i - 80 min dup i dup rot + eeWritePage if leave then 2e emit + +loop +else drop then cr ; + +\ _forget ( cstr -- ) wind the dictionary back to the word which follows - caution +: _forget dup +if + find if + pfa>nfa nfa>lfa dup mswHere w! w@ mswlastnfa w! + else .cstr ??? cr then +else drop then ; + + +\ forget ( -- ) wind the dictionary back to the word which follows - caution +: forget parsenw _forget ; + +\ this constant is used at boot time to set the forth starting routine, if it is changed +\ it does not take effect until a reboot, a cog reset is not adequate +cm_fstart wconstant cm_fstart + +\ fstart ( -- ) the start word +: fstart +cogid dup cogInbyte 10 lshift cm_entry 2 lshift or swap or resetDreg ! + +mcwInbyte m@ l>w swap + +100 mcwInbyte w! +0 mcwEmitptr w! +fMask @ mcwDebugcmd w! +\ zero out cog data area +par @ 8 + F8 0 fill +\ initialize forth variables +hex + +ca_varEnd mcwAhere w! + +\ initiliaze the common variables +lockdict mswHere w@ 0= +if 0 fl_lock w! lastnfa nfa>pfa 2+ alignl 4+ mswHere w! 7FFF dup mswMemend w! mswDictend w! then +freedict rsTop 1- rsPtr ! +FFFF = if 8 lshift cogid + vxcog w! else drop then +c" boot" mcT ccopy cogid mcT cappendn mcT find if execute else drop then +-1 +begin + compile? 0= if ." Cog" cogid . ." ok" cr then +\ if the first time through set mcwDebugValue to -1 to let people know we are alive + if -1 mcwDebugvalue m! then + interpret +0 0 until ; + +: boot6 cogid >cog cog+ ; + +\ cog? ( -- ) display active forth cogs +: cog? ." Forth cogs: " ffcog w@ . 2D emit space lfcog w@ . cr ; + +\ cog+ ( -- ) add a forth cog +: cog+ ffcog w@ 1- dup 0>= if dup ffcog w! cogreset else drop then cog? ; + +\ cog- ( -- ) stop first forth cog, cannot be executed form the first forth cog +: cog- ffcog w@ dup cogid <> swap 1+ dup lfcog w@ <= rot and if dup 1- cogstop ffcog w! else drop then cog? ; + +\ st? ( -- ) prints out the stack +: st? ." ST: " stPtr @ 2+ dup stTop < if stTop swap - 0 do stTop 2- i - @ .long space loop else drop then cr ; + +\ sc ( -- ) clears the stack +: sc stTop stPtr @ - 3 - dup . ." items cleared" cr dup 0> if 0 do drop loop then ; + +\ _pna ( addr -- ) print the address, contents and forth name +: _pna dup .word 3a emit w@ dup .word space pfa>nfa .strname space ; + +\ pfa? ( addr -- t/f) true if addr is a pfa +: pfa? dup pfa>nfa dup c@ dup 80 and 0= swap namemax and 0<> rot nfa>pfa rot if w@ then rot = and ; + +\ rs? ( -- ) prints out the return stack +: rs? ." RS: " rsTop rsPtr @ 1+ - 0 do rsTop 1- i - @ dup 2- w@ pfa? if 2- _pna else .long space then loop cr ; + +\ lasm ( addr -- ) expects an address pointing to a structure in the following form +\ empty long, long upper address of the assembler routine, long lower address of the assembler routine +\ a series of longs which are the assembler codes +: lasm 4+ dup m@ swap 4+ swap over m@ dup mcwAhere w! do 4+ dup m@ a, loop drop ; + +\ f_erase ( -- ) erase the word following from eeprom - DANGER - should be the last word only +\ or following words may get overwritten when a new file is written to eeprom +: f_erase parsenw dup if f_find dup if eeTop swap do FFFF i eeWriteWord 80 +loop else drop then else drop then ; +\ no more symbols available + +\ mswlastnfa is generated by the forth spinmaker word + + diff --git a/zubehör/game boulderdash/musik/BONUS.SFX b/zubehör/game boulderdash/musik/BONUS.SFX new file mode 100644 index 0000000..97f538e Binary files /dev/null and b/zubehör/game boulderdash/musik/BONUS.SFX differ diff --git a/zubehör/game boulderdash/musik/BONUS.SPN b/zubehör/game boulderdash/musik/BONUS.SPN new file mode 100644 index 0000000..ada8775 --- /dev/null +++ b/zubehör/game boulderdash/musik/BONUS.SPN @@ -0,0 +1 @@ +bonus ' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel byte $03,$03,$FF,$0F,$02,$00,$05,$00,$FF,$01,$50,$11 byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 \ No newline at end of file diff --git a/zubehör/game boulderdash/musik/CRACK.SFX b/zubehör/game boulderdash/musik/CRACK.SFX new file mode 100644 index 0000000..f3de3e2 Binary files /dev/null and b/zubehör/game boulderdash/musik/CRACK.SFX differ diff --git a/zubehör/game boulderdash/musik/CRACK.SPN b/zubehör/game boulderdash/musik/CRACK.SPN new file mode 100644 index 0000000..424e89e --- /dev/null +++ b/zubehör/game boulderdash/musik/CRACK.SPN @@ -0,0 +1 @@ +crack ' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel byte $01,$22,$01,$0F,$11,$00,$05,$00,$55,$01,$50,$11 byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 \ No newline at end of file diff --git a/zubehör/game boulderdash/musik/ERROR.SFX b/zubehör/game boulderdash/musik/ERROR.SFX new file mode 100644 index 0000000..c671bc0 Binary files /dev/null and b/zubehör/game boulderdash/musik/ERROR.SFX differ diff --git a/zubehör/game boulderdash/musik/ERROR.SPN b/zubehör/game boulderdash/musik/ERROR.SPN new file mode 100644 index 0000000..131169e --- /dev/null +++ b/zubehör/game boulderdash/musik/ERROR.SPN @@ -0,0 +1 @@ +error ' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel byte $04,$01,$80,$0F,$00,$00,$00,$00,$FF,$00,$00,$80 byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 \ No newline at end of file diff --git a/zubehör/game boulderdash/musik/EXP.SFX b/zubehör/game boulderdash/musik/EXP.SFX new file mode 100644 index 0000000..feb669b Binary files /dev/null and b/zubehör/game boulderdash/musik/EXP.SFX differ diff --git a/zubehör/game boulderdash/musik/EXP.SPN b/zubehör/game boulderdash/musik/EXP.SPN new file mode 100644 index 0000000..bd1258f --- /dev/null +++ b/zubehör/game boulderdash/musik/EXP.SPN @@ -0,0 +1 @@ +exp ' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel byte $06,$04,$10,$0F,$00,$00,$00,$00,$FF,$01,$50,$11 byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 \ No newline at end of file diff --git a/zubehör/game boulderdash/musik/Mahoney - BoulderDash (Commodore 69 mix).mp3 b/zubehör/game boulderdash/musik/Mahoney - BoulderDash (Commodore 69 mix).mp3 new file mode 100644 index 0000000..5f82040 Binary files /dev/null and b/zubehör/game boulderdash/musik/Mahoney - BoulderDash (Commodore 69 mix).mp3 differ diff --git a/zubehör/game boulderdash/musik/RKO- The Def Guide to C64 MP3 remakes. I bet you can't do this on a SID..url b/zubehör/game boulderdash/musik/RKO- The Def Guide to C64 MP3 remakes. I bet you can't do this on a SID..url new file mode 100644 index 0000000..274cdb6 --- /dev/null +++ b/zubehör/game boulderdash/musik/RKO- The Def Guide to C64 MP3 remakes. I bet you can't do this on a SID..url @@ -0,0 +1,2 @@ +[InternetShortcut] +URL=http://remix.kwed.org/index.php?search=boulder diff --git a/zubehör/game boulderdash/musik/WALL.SFX b/zubehör/game boulderdash/musik/WALL.SFX new file mode 100644 index 0000000..dec7ab7 Binary files /dev/null and b/zubehör/game boulderdash/musik/WALL.SFX differ diff --git a/zubehör/game boulderdash/musik/WALL.SPN b/zubehör/game boulderdash/musik/WALL.SPN new file mode 100644 index 0000000..8465ad0 --- /dev/null +++ b/zubehör/game boulderdash/musik/WALL.SPN @@ -0,0 +1 @@ +wall ' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel byte $04,$FF,$FF,$0F,$01,$00,$01,$00,$FF,$06,$20,$00 byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 \ No newline at end of file diff --git a/zubehör/game boulderdash/musik/WavFormat.pdf b/zubehör/game boulderdash/musik/WavFormat.pdf new file mode 100644 index 0000000..f5098a4 Binary files /dev/null and b/zubehör/game boulderdash/musik/WavFormat.pdf differ diff --git a/zubehör/game boulderdash/musik/bd.wav b/zubehör/game boulderdash/musik/bd.wav new file mode 100644 index 0000000..35f20a5 Binary files /dev/null and b/zubehör/game boulderdash/musik/bd.wav differ diff --git a/zubehör/game boulderdash/readme.rtf b/zubehör/game boulderdash/readme.rtf new file mode 100644 index 0000000..625df0e Binary files /dev/null and b/zubehör/game boulderdash/readme.rtf differ diff --git a/zubehör/game boulderdash/sourcen/Bellatrix-Code/Boulderdash_095.spin b/zubehör/game boulderdash/sourcen/Bellatrix-Code/Boulderdash_095.spin new file mode 100644 index 0000000..6d331a5 --- /dev/null +++ b/zubehör/game boulderdash/sourcen/Bellatrix-Code/Boulderdash_095.spin @@ -0,0 +1,3812 @@ +'Boulderdash, for Hydra or Demo Board. +'Version 0.95 +'Released to the public domain. + +' Changes: +' 2009-11-10 - Modified for the Demo Board. +' - Added 'readkey' routine to allow playing the game from the keyboard. +' - Rockford now can be moved around and the screen scrolls automatically. +' 2009-11-12 - Halved tile horizontal resolution to eliminate redundant pixel pairs +' (and BoulderDash uses 8x16 tiles anyway). This also halves tile memory +' requirements. +' - The scroller now runs in a separate cog. +' 2009-11-13 - Changed pixel clock settings in order to display 20 tiles per line, +' as in the classic C64/Atari BoulderDash I. +' - Added code to handle boulders and diamonds. Rockford cannot push yet +' boulders or pick-up diamonds. +' 2009-11-14 - Reversed pixel order in video driver in order to avoid having to define +' mirrored tiles. +' - Added more tiles, hopefully all the characters are there. +' - The scroller cog now also handles animated characters. +' - Rockford can pick-up diamonds and the screen flashes when diamond count +' reaches the target. +' - Rockford now walks facing in the right direction and gets "bored". +' 2009-11-15 - Added an optional status line. +' - Added a character font for the status line. +' - Main game loop moved to a separate routine. +' - Boulders can be pushed around. +' - New routines to cover and uncover the screen. +' - Added an infinite loop to the main routine, pressing ESC restarts the +' game. +' 2009-11-16 - Inbox now morphs into Rockford. +' - Rockford can exit through the Outbox. +' 2009-11-17 - Added hardware detection feature (Hydra, Demo Board, etc.) Video driver +' changed accordingly. Not sure if keyboard will work on Hydra. +' - Falling boulders and diamonds now can kill Rockford. +' - Added PAL timings table to video driver, but PAL mode is not working yet. +' 2009-11-18 - Synchronized scroller to vertical sync, scrolling is totally smooth now. +' - PAL mode now works. +' 2009-11-25 - Started adding support for fireflies and butterflies. Had to split the +' case statement in the main game loop into sections due to poor performance. +' - Added code to decode raw cave data of original Atari/C64 BoulderDash I. +' You can now import your favorite caves :) +' 2009-11-26 - Fireflies and butterflies now explode in contact with Rockford. +' - Time counts down, but there is no "out of time" condition yet. +' 2009-11-27 - Implemented the "pick without moving" Rockford trick (use left CTRL key). +' - Stop cave when time runs out. +' - Do not advance to next cave until current one is successfully completed. +' Game is now playable! Use LeftCtrl + LeftShift as a "cheat" to move to +' next cave without finishing the current one. The Escape key restarts the +' current cave. Sorry, no score points yet. +' 2009-11-28 - Status line now handled by a separate cog. +' - Flashing "Out of time" message when time runs out. +' - Space bar now pauses game. +' - Score points implemented. +' - No more unlimited lifes, sorry ;))) +' - New life every 500 points. +' 2009-11-29 - Using a table of codes to reset the 'scanned' flag avoids a second case +' statement and improves performance. +' - Implemented amoebas and magic wall. Now all the original caves work! +' - Added all the original BoulderDash I caves (except the intermissions) +' - Added a Level variable. After successfully finishing the last cave the +' game starts again from the first one of the next difficulty level. +' 2009-11-30 - Fixed a bug in amoeba handling that caused cave M to crash. +' 2009-12-02 - Game controller apparently does not like to be read too fast. +' - Added intermission caves. +' 2009-12-04 - Aborting the current cave will cost you a life. +' - Restart (or exit) automatically the cave if "Out of time" has been +' flashing for more than a minute without user input. +' - Throtle down Rockford a bit in levels 1 and 2 (is running too fast!) +' 2009-12-05 - Added the title screen (had a hard time scrolling the background behind +' those big letters!). +' - Starting cave and level can be selected from the title screen. +' - Run a demo if the title screen has been inactive for about a minute. +' 2009-12-06 - Fixed boulder/diamond rolling off: they must move to the side first, +' not directly diagonally. +' - Added a preliminary sound object. Nothing there yet. +' - Bonus points at the end of the cave increase with difficulty level. +' 2009-12-07 - First steps towards SID emulation via PWM. Single voice waveform generation +' already works (well, sort of). No envelope control yet. +' 2009-12-08 - SID emulator: noise waveform, amplitude control, 3 voices. Envelope +' control using a separate cog (see the ChangeLog in the SIDemu.spin file). +' 2009-12-09 - Integrated the SID emulator into the game, running out of cogs. +' - Got the main tune working. +' - Added a few other sound/noise effects the game. +' - Boulder noise interfers with diamond pick up sound. Which one has the +' preference? +' 2009-12-12 - Added the cover/uncover screen sound. +' - Added the bonus points sound. +' - Added amoeba and magic wall sound. +' +' TODO: +' - Finish it :) +' - Add broadcast TV mode with sound carrier to use the TV antenna input (like in old times :)) +' +' +' Anpassungen für den Hive +' +' 09-01-2010 - Entfernung der Hardwareerkennung +' - Anpassung Konfiguration an Hive/Bellatrix +' - Gamecontr. entfernt +' - Auskommentierung Sound +' 12-01-2010 - Scrolltext im Titelscreen +' - Optimierung Soundobjekt + +con + + _clkmode = xtal1 + pll16x + _xinfreq = 5_000_000 + + ' The supported video modes + TV_NTSC = 0 + TV_PAL = 1 + + TV_MODE = TV_PAL ' <--- Select your TV system here -- NTSC or PAL ---<<< + + ' Game controller codes + GP_RIGHT = %00000001 '(Right arrow) Move right + GP_LEFT = %00000010 '(Left arrow) Move left + GP_DOWN = %00000100 '(Down arrow) Move down + GP_UP = %00001000 '(Up arrow) Move up + GP_START = %00010000 '(Left Shift) Start game. Together with GP_SELECT: go to next cave (cheat) + GP_SELECT = %00100000 '(Left Ctrl) Pick + GP_B = %01000000 '(Space) Pause + GP_A = %10000000 '(Escape) Abort and restart current cave + +var + long nes + long last_dir + long cave_addr + long random_ptr + long screen_height + long sx, sy + long video_params[7] + long sound_pin + long Score + long NextLife + byte temp_cave[40*22] + byte HWType + byte Cave + byte Level + byte CaveNumber + byte DiamondCount + byte DiamondsNeeded + byte DiamondValue + byte ExtraValue + byte CaveTime + byte Men + byte Alive + byte MagicWallStatus + byte MagicWallTime + byte AmoebaStatus + byte AmoebaTime + byte target + byte vsync + byte door_x, door_y + +obj + tv: "Boulderdash_Tile_TV" + kb: "Keyboard" + sc: "Scroller" + st: "Status" + rr: "RealRandom" + sn: "Sounds" + +pub main | success + + video_params[0] := %0_11_101_000 ' Set Mode for VCFG + video_params[1] := 2 ' Set Pingroup used by TV driver. + video_params[2] := %0111_0000 ' Set Pinmask for VCFG pins. + video_params[3] := %0000_0111<<20 ' Set Pinmask for output pins. + + video_params[4] := TV_MODE + video_params[5] := @screen + video_params[6] := @vsync + + if video_params[4] == TV_NTSC + screen_height := 12 + else + screen_height := 14 + + rr.start 'start the real random number generator + random_ptr := rr.random_ptr + + bytefill(@screen, $00, constant(40 * 22)) 'clear screen + + tv.start(@video_params) 'start the TV driver + sc.start(@video_params, random_ptr) 'start the scroller + st.start(@video_params) 'start the status line handler + kb.start(17, 16) 'start the keyboard driver + sn.start 'start the sound engine + + cave_addr := @screen + + repeat + + repeat + success := TitleScreen + + palette.byte[1] := $04 + palette.byte[2] := $4B + palette.byte[3] := $06 + bytefill(@screen, $3C, constant(40 * 22)) 'fill the screen with the scrolling pattern + status := 0 + + Score := 0 + Men := 3 + + if success + quit + else + Demo + + repeat + + sn.music_off + + CaveNumber := byte[@@caves[Cave]] + st.player_params(1, Men, CaveNumber, Level, Score) + st.set_mode(st#STATUS_PRE) + + CreateCave(@@caves[Cave], @temp_cave) + st.cave_params(DiamondsNeeded, DiamondValue, CaveTime) + + last_dir := -1 'last rockford direction + sc.rockford_go(0) 'rockford initially stands still + sc.milling_off + + if CaveNumber > 16 + 'intermission + sx := 0 + sy := 0 + else + 'normal cave + sx := door_x - 10 + sx <#= constant(40 - 20) + sx #>= 0 + sy := door_y - screen_height / 2 + sy <#= 22 - screen_height + sy #>= 0 + sc.scroll_to(sx * 8, sy * 16) + + Uncover 'uncover screen + success := GameLoop + + if not success + if --Men == 0 + st.set_mode(st#STATUS_GAME_OVER) + waitcnt(clkfreq + cnt) + Cover + quit + + if success or CaveNumber > 16 + 'go to next cave only if current one was completed + 'but never restart intermissions + if success and CaveNumber > 16 and Men < 9 + ++Men 'the promised bonus life + if caves[++Cave] == 0 + if Level < 4 + ++Level + Cave := 0 + + st.player_params(1, Men, CaveNumber, Level, Score) + st.set_mode(st#STATUS_PRE) + Cover 'cover screen with scrolling pattern + + +pub TitleScreen | x, y, h, t, i, j, lk, ticks, count, scr + + if TV_MODE == TV_NTSC + h := 24 + t := 2 + ticks := constant(60 * 130 / 2) 'dr235 + else + h := 28 + t := 4 + ticks := constant(50 * 130 / 2) + + scr := 0 + + bytefill(@screen, $00, constant(40 * 28)) 'clear screen + palette.byte[1] := $FC + palette.byte[2] := $FB + palette.byte[3] := $06 + st.set_mode(st#STATUS_NONE) + + Cave := 0 + Level := 0 + CaveNumber := byte[@@caves[Cave]] + + repeat x from 0 to 19 + byte[@screen + x] := $B1 + byte[@screen + x + (h - 6) * 40] := $B1 + repeat y from 1 to h - 7 + byte[@screen + y * 40] := $B5 + repeat x from 1 to 18 + byte[@screen + x + y * 40] := $B0 + byte[@screen + 19 + y * 40] := $B6 + + i := 0 + repeat y from t to t + 6 + repeat x from 1 to 18 + byte[@screen + x + y * 40] := big_boulder.byte[i++] + + i := 0 + repeat y from t + 8 to t + 14 + repeat x from 3 to 15 + byte[@screen + x + y * 40] := big_dash.byte[i++] + + status := 2 + scroll := 0 + 'st.text_out(@screen + (h - 4) * 40, @str1, 20) + scr++ + repeat i from 0 to 19 + 'j := str1.byte[i] + j := scr1.byte[i + scr] + if j == $20 + byte[@screen + (h - 4) * 40 + i] := $90 + else + byte[@screen + (h - 4) * 40 + i] := j + $A0 + st.text_out(@screen + (h - 3) * 40, @str2, 20) + st.text_out(@screen + (h - 2) * 40, @str3, 20) + st.text_out(@screen + (h - 1) * 40, @str4, 20) + + screen.byte[(h - 2) * 40] := $D1 'player(s) + screen.byte[(h - 2) * 40 + 10] := $D1 'joystick(s) + screen.byte[(h - 1) * 40 + 7] := CaveNumber + $E0 + screen.byte[(h - 1) * 40 + 17] := Level + $D1 + + lk := 0 'last key + count := ticks + + sn.music_on + + repeat while count > 0 + + 'wait for vsync, count every other tick + repeat while vsync == 0 + repeat while vsync <> 0 + repeat while vsync == 0 + repeat while vsync <> 0 + --count + + 'scrolltext + scr++ + if (scr>>2) > 318 '(scr2 - scr1) + scr := 0 + repeat i from 0 to 19 + j := scr1.byte[i + (scr>>2)] + if j == $20 + byte[@screen + (h - 4) * 40 + i] := $90 + else + byte[@screen + (h - 4) * 40 + i] := j + $A0 + + ' scrolling background + x := @tiles + constant(16 * $B0) + y := word[x] + wordmove(x, x + 2, 7) + word[x + 15] := y + + repeat i from 0 to 5 + repeat y from 0 to 14 step 2 + x := @tiles + constant(16 * $B0) + y + t := @tiles + constant(16 * $BD) + y + 16 * i + j := @tiles + constant(16 * $B3) + y + 16 * i + word[j] := word[x] | word[t] + repeat y from 0 to 14 step 2 + x := @tiles + constant(16 * $B0) + y + t := @tiles + constant(16 * $C3) + y + j := @tiles + constant(16 * $B9) + y + word[j] := (word[x] & $00FF) | word[t] + repeat y from 0 to 14 step 2 + x := @tiles + constant(16 * $B0) + y + t := @tiles + constant(16 * $C4) + y + j := @tiles + constant(16 * $BA) + y + word[j] := (word[x] & $FF00) | word[t] + repeat y from 0 to 14 step 2 + x := @tiles + constant(16 * $B0) + y + t := @tiles + constant(16 * $C5) + y + j := @tiles + constant(16 * $BB) + y + word[j] := (word[x] & $FF00) | word[t] + + i := read_input + if i <> lk + count := ticks 'reset countdown + if i & GP_START + sn.music_off + return 1 + elseif i & GP_LEFT + if Cave => 5 + Cave -= 5 + CaveNumber := byte[@@caves[Cave]] + screen.byte[(h - 1) * 40 + 7] := CaveNumber + $E0 + elseif i & GP_RIGHT + if Cave =< 10 + Cave += 5 + CaveNumber := byte[@@caves[Cave]] + screen.byte[(h - 1) * 40 + 7] := CaveNumber + $E0 + elseif i & GP_UP + if Level < 4 + ++Level + screen.byte[(h - 1) * 40 + 17] := Level + $D1 + elseif i & GP_DOWN + if Level > 0 + --Level + screen.byte[(h - 1) * 40 + 17] := Level + $D1 + lk := i + + sn.music_off + return 0 + +dat + +big_boulder + byte $B2, $B1, $B7, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0 + byte $B2, $B0, $B9, $B2, $B1, $BA, $B5, $B9, $B2, $B0, $BA, $B1, $B7, $B2, $B1, $BA, $B1, $B7 + byte $B2, $B1, $B8, $B2, $BA, $BA, $B5, $B9, $B2, $B0, $BA, $B5, $B9, $B2, $B0, $BA, $B5, $B9 + byte $B2, $B1, $B7, $B2, $BA, $BA, $B5, $B9, $B2, $B0, $BA, $B5, $B9, $B2, $B5, $BA, $B1, $B8 + byte $B2, $B0, $B9, $B2, $BA, $BA, $B5, $B9, $B2, $B0, $BA, $B5, $B9, $B2, $B0, $BA, $B1, $B7 + byte $B2, $B1, $B5, $B2, $B1, $BA, $B1, $B5, $B2, $B1, $BA, $B1, $B5, $B2, $B1, $BA, $B5, $B9 + byte $B2, $B1, $B8, $B2, $B1, $BA, $B1, $B5, $B2, $B1, $BA, $B1, $B8, $B2, $B1, $BA, $B5, $B9 + +big_dash + byte $BA, $B1, $B3, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0 + byte $BA, $B5, $BA, $B0, $B2, $B7, $B2, $B1, $BA, $B5, $BA, $BB, $BC + byte $BA, $B5, $BA, $BA, $B5, $B9, $B2, $B0, $BA, $B5, $BA, $B0, $B0 + byte $BA, $B5, $BA, $BA, $B1, $B5, $B2, $B1, $BA, $B1, $B1, $B0, $B0 + byte $BA, $B5, $BA, $BA, $B5, $B9, $B0, $B2, $BA, $B5, $BA, $B0, $B0 + byte $BA, $B1, $B1, $BA, $B5, $B9, $B2, $B1, $BA, $B5, $BA, $B0, $B0 + byte $BA, $B1, $B4, $BA, $B5, $B9, $B2, $B1, $BA, $B5, $BA, $B0, $B0 + +str1 byte " HIVE VERSION " +str2 byte "PRESS BUTTON TO PLAY" +str3 byte " PLAYER JOYSTICK" +str4 byte " CAVE: LEVEL: " + +scr1 byte " " + byte "THANKS :SPORK FROGS: :HPG: :AHLE2: AND THE OTHER PROPELLERHEADS FOR THE BASECODE" + byte " " + byte "THANKS PEX :MAHONEY: TUFVESSON FOR THE COOL MUSIC" + byte " " + byte "GRUSS AN ALLE HIVE-DROHNEN" + byte " " + byte "HIVE: WE ARE BORG - RESISTANCE IS FUTILE" + byte " " + byte "DROHNE235: HIVE-VERSION 2010" + byte " " +scr2 byte 0 + +pub Demo + + Score := 0 + Cave := 0 'demo happens on cave A + Level := 0 + CaveNumber := byte[@@caves[Cave]] + st.player_params(1, Men, CaveNumber, Level, Score) + st.set_mode(st#STATUS_PRE) + + CreateCave(@@caves[Cave], @temp_cave) + st.cave_params(DiamondsNeeded, DiamondValue, CaveTime) + + last_dir := -1 'last rockford direction + sc.rockford_go(0) 'rockford initially stands still + sc.milling_off + + sx := door_x - 10 + sx <#= constant(40 - 20) + sx #>= 0 + sy := door_y - screen_height / 2 + sy <#= 22 - screen_height + sy #>= 0 + sc.scroll_to(sx * 8, sy * 16) + + demo_ptr := @demo_data 'set demo data pointer + kcount := 0 + + Uncover 'uncover screen + GameLoop 'play the demo + Cover 'cover screen back + +var + + long demo_ptr + byte kcount, last_key + +dat + +' The low nibble of each byte is the direction of movement: +' $x0 = no movement +' $x1 = Right +' $x2 = Left +' $x3 = Down +' $x4 = Up +' bit 3 ($x8) set means GP_SELECT is pressed (not used here anyway) +' The high nibble is the number of scan frames to apply the movement. +' $00 means end of demo data. + +demo_data + byte $F0, $10, $14, $71, $23, $91, $40, $23 + byte $41, $34, $12, $40, $14, $B1, $13, $21 + byte $40, $63, $11, $43, $32, $40, $13, $12 + byte $41, $32, $40, $44, $52, $34, $52, $43 + byte $32, $50, $34, $A2, $14, $32, $13, $62 + byte $43, $11, $40, $33, $41, $43, $42, $24 + byte $21, $34, $A1, $A1, $13, $41, $13, $41 + byte $23, $50, $51, $44, $51, $60, $13, $00 + +pub readkey : key + + if demo_ptr + if kcount > 0 + --kcount + return last_key + else + key := byte[demo_ptr++] + if key == $00 + demo_ptr := 0 + else + kcount := key / 16 - 1 + case key & $07 + $0: last_key := 0 + $1: last_key := GP_RIGHT + $2: last_key := GP_LEFT + $3: last_key := GP_DOWN + $4: last_key := GP_UP + if key & $08 + last_key |= GP_SELECT + return last_key + + key := 0 + if kb.keystate($C0) + key |= GP_LEFT + if kb.keystate($C1) + key |= GP_RIGHT + if kb.keystate($C2) + key |= GP_UP + if kb.keystate($C3) + key |= GP_DOWN + if kb.keystate($F2) 'left control key + key |= GP_SELECT + if kb.keystate($CB) 'escape key + key |= GP_A + if kb.keystate($20) 'space key + key |= GP_B + if kb.keystate($F0) 'left shift + key |= GP_START + if kb.keystate($0D) 'or enter + key |= GP_START + +pub read_input + + return readkey + + +var + byte RandSeed1, RandSeed2 + +pub GetRandom | temp1, temp2, temp3, cy, r + +'' Generate a pseudo-random number, given a seed +'' The output matches the one used in the original BoulderDash I + + temp1 := (RandSeed1 & 1) << 7 + temp2 := (RandSeed2 & 1) << 7 + temp3 := (RandSeed2 >> 1) & $7F + + r := RandSeed2 + temp2 + if r > $FF + cy := 1 + r &= $FF + else + cy := 0 + + r += cy + $13 + if r > $FF + cy := 1 + r &= $FF + else + cy := 0 + + RandSeed2 := r + + r := RandSeed1 + cy + temp1 + if r > $FF + cy := 1 + r &= $FF + else + cy := 0 + + r += cy + temp3 + RandSeed1 := r & $FF + +dat + +caves long @cave_A, @cave_B, @cave_C, @cave_D, @inter_1 + long @cave_E, @cave_F, @cave_G, @cave_H, @inter_2 + long @cave_I, @cave_J, @cave_K, @cave_L, @inter_3 + long @cave_M, @cave_N, @cave_O, @cave_P, @inter_4 + long 0 + +cave_A byte 1 'cave number + byte 20 'magic wall/amoeba time + byte 10 'initial diamond value + byte 15 'extra diamond value + byte 10, 11, 12, 13, 14 'randomizer seed per level + byte 12, 12, 12, 12, 12 'diamonds needed per level + byte 150, 110, 70, 40, 30 'time per level + byte $08, $0B, $09, $D4, $20 'bg color 1, bg color 2, fg color + byte $00, $10, $14, $00 'random objects + byte $3C, $32, $09, $00 'probability of object + byte $42, $01, $09, $1E, $02 'raw cave data + byte $42, $09, $10, $1E, $02 + byte $25, $03, $04 + byte $04, $26, $12 + byte $FF + +cave_B byte 2 + byte 20 + byte 20, 50 + byte $03, $00, $01, $57, $58 + byte $0A, $0C, $09, $0D, $0A + byte $96, $6E, $46, $46, $46 + byte $0A, $04, $09, $00, $00 + byte $00, $10, $14, $08 + byte $3C, $32, $09, $02 + byte $42, $01, $08, $26, $02, $42, $01, $0F, $26, $02, $42, $08, $03, $14, $04, $42 + byte $10, $03, $14, $04, $42, $18, $03, $14, $04, $42, $20, $03, $14, $04, $40, $01 + byte $05, $26, $02, $40, $01, $0B, $26, $02, $40, $01, $12, $26, $02, $40, $14, $03 + byte $14, $04, $25, $12, $15, $04, $12, $16, $FF + +cave_C byte 3 + byte $00 + byte $0F, $00 + byte $00, $32, $36, $34, $37 + byte $18, $17, $18, $17, $15 + byte $96, $64, $5A, $50, $46 + byte $09, $08, $09, $04, $00 + byte $02, $10, $14, $00 + byte $64, $32, $09, $00 + byte $25, $03, $04, $04, $27, $14, $FF + +cave_D byte 4 + byte $14 + byte $05, $14 + byte $00, $6E, $70, $73, $77 + byte $24, $24, $24, $24, $24 + byte $78, $64, $50, $3C, $32 + byte $04, $08, $09, $00, $00 + byte $10, $00, $00, $00 + byte $14, $00, $00, $00 + byte $25, $01, $03, $04, $26, $16, $81, $08, $0A, $04, $04, $00, $30, $0A, $0B, $81 + byte $10, $0A, $04, $04, $00, $30, $12, $0B, $81, $18, $0A, $04, $04, $00, $30, $1A + byte $0B, $81, $20, $0A, $04, $04, $00, $30, $22, $0B, $FF + +cave_E byte $05, $14, $32, $5A + byte $00, $00, $00, $00, $00 + byte $04, $05, $06, $07, $08 + byte $96, $78, $5A, $3C, $1E + byte $09, $0A, $09, $00, $00 + byte $00, $00, $00, $00 + byte $00, $00, $00, $00 + byte $25, $01, $03, $04, $27, $16, $80, $08, $0A, $03, $03, $00, $80, $10, $0A, $03 + byte $03, $00, $80, $18, $0A, $03, $03, $00, $80, $20, $0A, $03, $03, $00, $14, $09 + byte $0C, $08, $0A, $0A, $14, $11, $0C, $08, $12, $0A, $14, $19, $0C, $08, $1A, $0A + byte $14, $21, $0C, $08, $22, $0A, $80, $08, $10, $03, $03, $00, $80, $10, $10, $03 + byte $03, $00, $80, $18, $10, $03, $03, $00, $80, $20, $10, $03, $03, $00, $14, $09 + byte $12, $08, $0A, $10, $14, $11, $12, $08, $12, $10, $14, $19, $12, $08, $1A, $10 + byte $14, $21, $12, $08, $22, $10, $FF + +cave_F byte $06, $14, $28, $3C + byte $00, $14, $15, $16, $17 + byte $04, $06, $07, $08, $08 + byte $96, $78, $64, $5A, $50 + byte $0E, $0A, $09, $00, $00 + byte $10, $00, $00, $00 + byte $32, $00, $00, $00 + byte $82, $01, $03, $0A, $04, $00, $82, $01, $06, $0A, $04, $00, $82, $01, $09, $0A + byte $04, $00, $82, $01, $0C, $0A, $04, $00, $41, $0A, $03, $0D, $04, $14, $03, $05 + byte $08, $04, $05, $14, $03, $08, $08, $04, $08, $14, $03, $0B, $08, $04, $0B, $14 + byte $03, $0E, $08, $04, $0E, $82, $1D, $03, $0A, $04, $00, $82, $1D, $06, $0A, $04 + byte $00, $82, $1D, $09, $0A, $04, $00, $82, $1D, $0C, $0A, $04, $00, $41, $1D, $03 + byte $0D, $04, $14, $24, $05, $08, $23, $05, $14, $24, $08, $08, $23, $08, $14, $24 + byte $0B, $08, $23, $0B, $14, $24, $0E, $08, $23, $0E, $25, $03, $14, $04, $26, $14 + byte $FF + +cave_G byte $07, $4B, $0A, $14 + byte $02, $07, $08, $0A, $09 + byte $0F, $14, $19, $19, $19 + byte $78, $78, $78, $78, $78 + byte $09, $0A, $0D, $00, $00 + byte $00, $10, $08, $00 + byte $64, $28, $02, $00 + byte $42, $01, $07, $0C, $02, $42, $1C, $05, $0B, $02, $7A, $13, $15, $02, $02, $14 + byte $04, $06, $14, $04, $0E, $14, $04, $16, $14, $22, $04, $14, $22, $0C, $14, $22 + byte $16, $25, $14, $03, $04, $27, $07, $FF + +cave_H byte $08, $14, $0A, $14 + byte $01, $03, $04, $05, $06 + byte $0A, $0F, $14, $14, $14 + byte $78, $6E, $64, $5A, $50 + byte $02, $0E, $09, $00, $00 + byte $00, $10, $08, $00 + byte $5A, $32, $02, $00 + byte $14, $04, $06, $14, $22, $04, $14, $22, $0C, $04, $00, $05, $25, $14, $03, $42 + byte $01, $07, $0C, $02, $42, $01, $0F, $0C, $02, $42, $1C, $05, $0B, $02, $42, $1C + byte $0D, $0B, $02, $43, $0E, $11, $08, $02, $14, $0C, $10, $00, $0E, $12, $14, $13 + byte $12, $41, $0E, $0F, $08, $02, $FF + +cave_I byte $09, $14, $05, $0A + byte $64, $89, $8C, $FB, $33 + byte $4B, $4B, $50, $55, $5A + byte $96, $96, $82, $82, $78 + byte $08, $04, $09, $00, $00 + byte $10, $14, $00, $00 + byte $F0, $78, $00, $00 + byte $82, $05, $0A, $0D, $0D, $00, $01, $0C, $0A, $82, $19, $0A, $0D, $0D, $00, $01 + byte $1F, $0A, $42, $11, $12, $09, $02, $40, $11, $13, $09, $02, $25, $07, $0C, $04 + byte $08, $0C, $FF + +cave_J byte $0A, $14, $19, $3C + byte $00, $00, $00, $00, $00 + byte $0C, $0C, $0C, $0C, $0C + byte $96, $82, $78, $6E, $64 + byte $06, $08, $09, $00, $00 + byte $00, $00, $00, $00 + byte $00, $00, $00, $00 + byte $25, $0D, $03, $04, $27, $16, $54, $05, $04, $11, $03, $54, $15, $04, $11, $05 + byte $80, $05, $0B, $11, $03, $08, $C2, $01, $04, $15, $11, $00, $0D, $04, $C2, $07 + byte $06, $0D, $0D, $00, $0D, $06, $C2, $09, $08, $09, $09, $00, $0D, $08, $C2, $0B + byte $0A, $05, $05, $00, $0D, $0A, $82, $03, $06, $03, $0F, $08, $00, $04, $06, $54 + byte $04, $10, $04, $04, $FF + +cave_K byte $0B, $14, $32, $00 + byte $00, $04, $66, $97, $64 + byte $06, $06, $06, $06, $06 + byte $78, $78, $96, $96, $F0 + byte $0B, $08, $09, $00, $00 + byte $00, $10, $08, $00 + byte $64, $50, $02, $00 + byte $42, $0A, $03, $09, $04, $42, $14, $03, $09, $04, $42, $1E, $03, $09, $04, $42 + byte $09, $16, $09, $00, $42, $0C, $0F, $11, $02, $42, $05, $0B, $09, $02, $42, $0F + byte $0B, $09, $02, $42, $19, $0B, $09, $02, $42, $1C, $13, $0B, $01, $14, $04, $03 + byte $14, $0E, $03, $14, $18, $03, $14, $22, $03, $14, $04, $16, $14, $23, $15, $25 + byte $14, $14, $04, $26, $11, $FF + +cave_L byte $0C, $14, $14, $00 + byte $00, $3C, $02, $3B, $66 + byte $13, $13, $0E, $10, $15 + byte $B4, $AA, $A0, $A0, $A0 + byte $0C, $0A, $09, $00, $00 + byte $00, $10, $14, $00 + byte $3C, $32, $09, $00 + byte $42, $0A, $05, $12, $04, $42, $0E, $05, $12, $04, $42, $12, $05, $12, $04, $42 + byte $16, $05, $12, $04, $42, $02, $06, $0B, $02, $42, $02, $0A, $0B, $02, $42, $02 + byte $0E, $0F, $02, $42, $02, $12, $0B, $02, $81, $1E, $04, $04, $04, $00, $08, $20 + byte $05, $81, $1E, $09, $04, $04, $00, $08, $20, $0A, $81, $1E, $0E, $04, $04, $00 + byte $08, $20, $0F, $25, $03, $14, $04, $27, $16, $FF + +cave_M byte $0D, $8C, $05, $08 + byte $00, $01, $02, $03, $04 + byte $32, $37, $3C, $46, $50 + byte $A0, $9B, $96, $91, $8C + byte $06, $08, $0D, $00, $00 + byte $10, $00, $00, $00 + byte $28, $00, $00, $00 + byte $25, $12, $03, $04, $0A, $03, $3A, $14, $03, $42, $05, $12, $1E, $02, $70, $05 + byte $13, $1E, $02, $50, $05, $14, $1E, $02, $C1, $05, $15, $1E, $02, $FF + +cave_N byte $0E, $14, $0A, $14 + byte $00, $00, $00, $00, $00 + byte $1E, $23, $28, $2A, $2D + byte $96, $91, $8C, $87, $82 + byte $0C, $08, $09, $00, $00 + byte $10, $00, $00, $00 + byte $00, $00, $00, $00 + byte $81, $0A, $0A, $0D, $0D, $00, $70, $0B, $0B, $0C, $03, $C1, $0C, $0A, $03, $0D + byte $C1, $10, $0A, $03, $0D, $C1, $14, $0A, $03, $0D, $50, $16, $08, $0C, $02, $48 + byte $16, $07, $0C, $02, $C1, $17, $06, $03, $04, $C1, $1B, $06, $03, $04, $C1, $1F + byte $06, $03, $04, $25, $03, $03, $04, $27, $14, $FF + +cave_O byte $0F, $08, $0A, $14 + byte $01, $1D, $1E, $1F, $20 + byte $0F, $14, $14, $19, $1E + byte $78, $78, $78, $78, $8C + byte $08, $0E, $09, $00, $00 + byte $00, $10, $08, $00 + byte $64, $50, $02, $00 + byte $42, $02, $04, $0A, $03, $42, $0F, $0D, $0A, $01, $41, $0C, $0E, $03, $02, $43 + byte $0C, $0F, $03, $02, $04, $14, $16, $25, $14, $03, $FF + +cave_P byte $10, $14, $0A, $14 + byte $01, $78, $81, $7E, $7B + byte $0C, $0F, $0F, $0F, $0C + byte $96, $96, $96, $96, $96 + byte $09, $0A, $09, $00, $00 + byte $10, $00, $00, $00 + byte $32, $00, $00, $00 + byte $25, $01, $03, $04, $27, $04, $81, $08, $13, $04, $04, $00, $08, $0A, $14, $C2 + byte $07, $0A, $06, $08, $43, $07, $0A, $06, $02, $81, $10, $13, $04, $04, $00, $08 + byte $12, $14, $C2, $0F, $0A, $06, $08, $43, $0F, $0A, $06, $02, $81, $18, $13, $04 + byte $04, $00, $08, $1A, $14, $81, $20, $13, $04, $04, $00, $08, $22, $14, $FF + +inter_1 byte $11, $14, $1E, $00 + byte $0A, $0B, $0C, $0D, $0E + byte $06, $06, $06, $06, $06 + byte $0A, $0A, $0A, $0A, $0A + byte $0E, $02, $09, $00, $00 + byte $00, $14, $00, $00 + byte $FF, $09, $00, $00 + byte $87, $00, $02, $28, $16, $07, $87, $00, $02, $14, $0C, $00, $32, $0A, $0C, $10 + byte $0A, $04, $01, $0A, $05, $25, $03, $05, $04, $12, $0C, $FF + +inter_2 byte $12, $14, $0A, $00 + byte $0A, $0B, $0C, $0D, $0E + byte $10, $10, $10, $10, $10 + byte $0F, $0F, $0F, $0F, $0F + byte $06, $0F, $09, $00, $00 + byte $00, $00, $00, $00 + byte $00, $00, $00, $00 + byte $87, $00, $02, $28, $16, $07, $87, $00, $02, $14, $0C, $01, $50, $01, $03, $09 + byte $03, $48, $02, $03, $08, $03, $54, $01, $05, $08, $03, $50, $01, $06, $07, $03 + byte $50, $12, $03, $09, $05, $54, $12, $05, $08, $05, $50, $12, $06, $07, $05, $25 + byte $01, $04, $04, $12, $04, $FF + +inter_3 byte $13, $04, $0A, $00 + byte $0A, $0B, $0C, $0D, $0E + byte $0E, $0E, $0E, $0E, $0E + byte $14, $14, $14, $14, $14 + byte $06, $08, $09, $00, $00 + byte $00, $00, $00, $00 + byte $00, $00, $00, $00 + byte $87, $00, $02, $28, $16, $07, $87, $00, $02, $14, $0C, $00, $54, $01, $0C, $12 + byte $02, $88, $0F, $09, $04, $04, $08, $25, $08, $03, $04, $12, $07, $FF + +inter_4 byte $14, $03, $1E, $00 + byte $00, $00, $00, $00, $00 + byte $06, $06, $06, $06, $06 + byte $14, $14, $14, $14, $14 + byte $06, $08, $09, $00, $00 + byte $00, $00, $00, $00 + byte $00, $00, $00, $00 + byte $87, $00, $02, $28, $16, $07, $87, $00, $02, $14, $0C, $01, $D0, $0B, $03, $03 + byte $02, $80, $0B, $07, $03, $06, $00, $43, $0B, $06, $03, $02, $43, $0B, $0A, $03 + byte $02, $50, $08, $07, $03, $03, $25, $03, $03, $04, $09, $0A, $FF + +dat + +' C64 color table approximation. Not the most accurate one, but gives the desired effect. + +ctable byte $02, $06, $4B, $BC, $2B, $9C, $EB, $7D + byte $4B, $4A, $4B, $04, $04, $9D, $0B, $04 + +pub CreateCave(raw_cave, dest) | i, j, k, cx, cy, ci, co, dir, len + +'' Create cave contents from the description array + + CaveNumber := byte[raw_cave] + + RandSeed1 := 0 + RandSeed2 := byte[raw_cave + 4 + Level] + + ' Set colors + palette.byte[1] := ctable.byte[byte[raw_cave + 20]] + palette.byte[2] := ctable.byte[byte[raw_cave + 19]] + palette.byte[3] := ctable.byte[byte[raw_cave + 21] - 8] + + ' Place random objects + repeat cy from 1 to 21 + repeat cx from 0 to 39 + co := $01 ' dirt + GetRandom + repeat ci from 0 to 3 + if RandSeed1 < byte[raw_cave + 28 + ci] + co := byte[raw_cave + 24 + ci] + byte[dest + cx + cy * 40] := co + + ' Steel bounds + repeat cx from 0 to 39 + byte[dest + cx] := $07 + byte[dest + cx + 21 * 40] := $07 + repeat cy from 0 to 21 + byte[dest + cy * 40] := $07 + byte[dest + 39 + cy * 40] := $07 + + 'Decode raw data + i := raw_cave + 32 + repeat + ci := byte[i++] + cx := byte[i++] + cy := byte[i++] - 2 + if ci == $FF + quit + case ci & $C0 + $00: + byte[dest + cx + cy * 40] := ci & $3F + if (ci & $3F) == $25 + door_x := cx + door_y := cy + $40: + len := byte[i++] + dir := byte[i++] + repeat + byte[dest + cx + cy * 40] := ci & $3F + case dir + 0: --cy + 1: --cy + ++cx + 2: ++cx + 3: ++cy + ++cx + 4: ++cy + 5: ++cy + --cx + 6: --cx + 7: --cy + --cx + while --len > 0 + $80: + len := byte[i++] - 1 'width + dir := byte[i++] - 1 'height + co := byte[i++] + repeat j from 0 to len + byte[dest + cx + j + cy * 40] := ci & $3F + byte[dest + cx + j + (cy + dir) * 40] := ci & $3F + repeat j from 1 to dir - 1 + byte[dest + cx + (cy + j) * 40] := ci & $3F + repeat k from 1 to len - 1 + byte[dest + cx + k + (cy + j) * 40] := co + byte[dest + cx + len + (cy + j) * 40] := ci & $3F + $C0: + len := byte[i++] - 1 'width + dir := byte[i++] - 1 'height + repeat j from 0 to len + byte[dest + cx + j + cy * 40] := ci & $3F + byte[dest + cx + j + (cy + dir) * 40] := ci & $3F + repeat j from 0 to dir + byte[dest + cx + (cy + j) * 40] := ci & $3F + byte[dest + cx + len + (cy + j) * 40] := ci & $3F + + DiamondsNeeded := byte[raw_cave + 9 + Level] + CaveTime := byte[raw_cave + 14 + Level] + MagicWallTime := byte[raw_cave + 1] + if MagicWallTime > CaveTime + AmoebaTime := CaveTime + else + AmoebaTime := CaveTime - MagicWallTime + DiamondValue := byte[raw_cave + 2] + ExtraValue := byte[raw_cave + 3] + DiamondCount := 0 + +pub Cover | n, cell + +'' Ramdomly cover the screen with a scrolling pattern + + n := 0 + repeat while n <> constant(40 * 22) + cell := ||long[random_ptr] // constant(40 * 22) + if byte[cave_addr + cell] <> $3C + byte[cave_addr + cell] := $3C + ++n + sn.cover_sound + waitcnt(clkfreq / 1000 + cnt) + +pub Uncover | n, cell + +'' Ramdomly uncover the screen + + n := 0 + repeat while n <> constant(40 * 22) + cell := ||long[random_ptr] // constant(40 * 22) + if byte[cave_addr + cell] == $3C + byte[cave_addr + cell] := temp_cave[cell] + ++n + sn.cover_sound + waitcnt(clkfreq / 1000 + cnt) + +dat + +reset byte $00, $01, $02, $03, $04, $05, $06, $07 + byte $08, $09, $0A, $0B, $08, $09, $0A, $0B + byte $10, $10, $12, $12, $14, $14, $16, $16 + byte $18, $19, $1A, $1B, $1C, $1D, $1E, $1F + byte $20, $21, $22, $23, $24, $25, $26, $27 + byte $28, $29, $2A, $2B, $2C, $2D, $2E, $2F + byte $30, $31, $32, $33, $30, $31, $32, $33 + byte $38, $38, $3A, $3B, $3C, $3D, $3E, $3F + +dirs long 1, 40, -1, -40 + +pub GameLoop | cx, cy, ca, cn, ob, o1, o2, ready, count, amoebas, enclosed + +'' Main game loop. Everything happens here. + + target := 0 + count := 0 'scans before rockford is born + ready := 0 + + NextLife := ((Score / 500) + 1) * 500 + MagicWallStatus := 0 'dormant + AmoebaStatus := 0 'growing slowly + + ' game loop + repeat + Alive := false + amoebas := 0 + enclosed := true + repeat cy from 1 to 21 + repeat cx from 0 to 39 + ca := cave_addr + cx + cy * 40 'address of current object + + 'large case statements execute rather slowly to the point + 'that the game becomes unplayable, so we have to split the + 'case into sections (too bad there is no indirect function + 'call in Spin) + + ob := byte[ca] + if ob < $10 + case ob + $04: 'out door + if target + byte[ca] := $05 + $08: 'firefly facing left + if CheckAround(ca) + ExplodeCenter(ca, $1B) + else + if byte[ca + 40] == $00 + byte[ca + 40] := $0F + byte[ca] := $00 + elseif byte[ca - 1] == $00 + byte[ca - 1] := $0C + byte[ca] := $00 + else + byte[ca] := $0D + $09: 'firefly facing up + if CheckAround(ca) + ExplodeCenter(ca, $1B) + else + if byte[ca - 1] == $00 + byte[ca - 1] := $0C + byte[ca] := $00 + elseif byte[ca - 40] == $00 + byte[ca - 40] := $0D + byte[ca] := $00 + else + byte[ca] := $0E + $0A: 'firefly facing right + if CheckAround(ca) + ExplodeCenter(ca, $1B) + else + if byte[ca - 40] == $00 + byte[ca - 40] := $0D + byte[ca] := $00 + elseif byte[ca + 1] == $00 + byte[ca + 1] := $0E + byte[ca] := $00 + else + byte[ca] := $0F + $0B: 'firefly facing down + if CheckAround(ca) + ExplodeCenter(ca, $1B) + else + if byte[ca + 1] == $00 + byte[ca + 1] := $0E + byte[ca] := $00 + elseif byte[ca + 40] == $00 + byte[ca + 40] := $0F + byte[ca] := $00 + else + byte[ca] := $0C + + elseif ob < $20 + case ob + $10: 'boulder + case byte[ca + 40] 'check object below + $00: + 'boulder can fall + byte[ca] := $00 + byte[ca + 40] := $13 'falling boulder, scanned + sn.boulder_sound + $02, $10, $14: 'wall, boulder or diamond + if byte[ca - 1] == $00 and byte[ca + constant(40 - 1)] == $00 + 'boulder can roll left + byte[ca] := $00 + byte[ca - 1] := $13 'falling boulder, scanned + sn.boulder_sound + elseif byte[ca + 1] == $00 and byte[ca + constant(40 + 1)] == $00 + 'boulder can roll right + byte[ca] := $00 + byte[ca + 1] := $13 'falling boulder, scanned + sn.boulder_sound + $12: 'falling boulder + case byte[ca + 40] 'check object below + $00: + 'boulder can continue falling + byte[ca] := $00 + byte[ca + 40] := $13 'falling boulder, scanned + $03: 'magic wall + byte[ca] := $00 + if MagicWallStatus < 2 'dormant or milling + if MagicWallStatus == 0 + MagicWallStatus := 1 + cn := st.get_time #> MagicWallTime + MagicWallTime := cn - MagicWallTime + sc.milling_on + sn.magic_wall_sound_on + if byte[ca + constant(40 * 2)] == $00 + byte[ca + constant(40 * 2)] := $17 'falling diamond, scanned + sn.diamond_sound + $02, $10, $14: 'wall, boulder or diamond + 'we hit something + sn.boulder_sound + if byte[ca - 1] == $00 and byte[ca + constant(40 - 1)] == $00 + 'boulder can roll left + byte[ca] := $00 + byte[ca - 1] := $13 'falling boulder, scanned + elseif byte[ca + 1] == $00 and byte[ca + constant(40 + 1)] == $00 + 'boulder can roll right + byte[ca] := $00 + byte[ca + 1] := $13 'falling boulder, scanned + else + 'boulder came to a stop + byte[ca] := $11 'stationary boulder, scanned + $38: 'rockford? + 'explode + ExplodeBelow(ca, $1B) + $08, $09, $0A, $0B: 'firefly? + ExplodeBelow(ca, $1B) + $30, $31, $32, $33: 'butterfly? + ExplodeBelow(ca, $20) + other: + 'boulder came to a stop + byte[ca] := $11 'stationary boulder, scanned + sn.boulder_sound + $14: 'diamond + case byte[ca + 40] 'check object below + $00: + 'diamond can fall + byte[ca] := $00 + byte[ca + 40] := $17 'falling diamond, scanned + sn.diamond_sound + $02, $10, $14: 'wall, boulder or diamond + if byte[ca - 1] == $00 and byte[ca + constant(40 - 1)] == $00 + 'diamond can roll left + byte[ca] := $00 + byte[ca - 1] := $17 'falling diamond, scanned + sn.diamond_sound + elseif byte[ca + 1] == $00 and byte[ca + constant(40 + 1)] == $00 + 'diamond can roll right + byte[ca] := $00 + byte[ca + 1] := $17 'falling diamond, scanned + sn.diamond_sound + $16: 'falling diamond + case byte[ca + 40] 'check object below + $00: + 'diamond can continue falling + byte[ca] := $00 + byte[ca + 40] := $17 'falling diamond, scanned + $03: 'magic wall + byte[ca] := $00 + if MagicWallStatus < 2 'dormant or milling + if MagicWallStatus == 0 + MagicWallStatus := 1 + cn := st.get_time #> MagicWallTime + MagicWallTime := cn - MagicWallTime + sc.milling_on + sn.magic_wall_sound_on + if byte[ca + constant(40 * 2)] == $00 + byte[ca + constant(40 * 2)] := $13 'falling boulder, scanned + sn.boulder_sound + $02, $10, $14: 'wall, boulder or diamond + 'we hit something + sn.diamond_sound + if byte[ca - 1] == $00 and byte[ca + constant(40 - 1)] == $00 + 'diamond can roll left + byte[ca] := $00 + byte[ca - 1] := $17 'falling diamond, scanned + elseif byte[ca + 1] == $00 and byte[ca + constant(40 + 1)] == $00 + 'diamond can roll right + byte[ca] := $00 + byte[ca + 1] := $17 'falling diamond, scanned + else + 'diamond came to a stop + byte[ca] := $15 'stationary diamond, scanned + $38: 'rockford? + 'explode + ExplodeBelow(ca, $1B) + $08, $09, $0A, $0B: 'firefly + ExplodeBelow(ca, $1B) + $30, $31, $32, $33: 'butterfly + ExplodeBelow(ca, $20) + other: + 'diamond came to a stop + byte[ca] := $15 'stationary diamond, scanned + sn.diamond_sound + $1B, $1C, $1D, $1E: 'explosion stages + byte[ca]++ + $1F: 'explosion to space, final stage + byte[ca] := $00 + + elseif ob < $30 + case ob + $20, $21, $22, $23: 'explosion stages + byte[ca]++ + $24: 'explosion to diamonds, final stage + byte[ca] := $15 + $25: 'inbox + Alive := true + if count++ == 20 + byte[ca] := $26 + sn.crack_sound + $26, $27: + Alive := true + byte[ca]++ + $28: + Alive := true + byte[ca] := $38 'rockford is born + sc.rockford_reset + st.set_time(CaveTime) + st.set_mode(st#STATUS_GAME) + ready := 1 + + elseif ob < $40 + case ob + $30: 'butterfly facing down + if CheckAround(ca) + ExplodeCenter(ca, $20) + else + if byte[ca - 1] == $00 + byte[ca - 1] := $35 + byte[ca] := $00 + elseif byte[ca + 40] == $00 + byte[ca + 40] := $34 + byte[ca] := $00 + else + byte[ca] := $37 + $31: 'butterfly facing left + if CheckAround(ca) + ExplodeCenter(ca, $20) + else + if byte[ca - 40] == $00 + byte[ca - 40] := $36 + byte[ca] := $00 + elseif byte[ca - 1] == $00 + byte[ca - 1] := $35 + byte[ca] := $00 + else + byte[ca] := $34 + $32: 'butterfly facing up + if CheckAround(ca) + ExplodeCenter(ca, $20) + else + if byte[ca + 1] == $00 + byte[ca + 1] := $37 + byte[ca] := $00 + elseif byte[ca - 40] == $00 + byte[ca - 40] := $36 + byte[ca] := $00 + else + byte[ca] := $35 + $33: 'butterfly facing right + if CheckAround(ca) + ExplodeCenter(ca, $20) + else + if byte[ca + 40] == $00 + byte[ca + 40] := $34 + byte[ca] := $00 + elseif byte[ca + 1] == $00 + byte[ca + 1] := $37 + byte[ca] := $00 + else + byte[ca] := $36 + + $38: 'rockford + Alive := true + nes := read_input + cn := 0 + if nes + if nes & GP_RIGHT + last_dir := 1 + sc.rockford_go(last_dir) + cn := ca + 1 + elseif nes & GP_LEFT + last_dir := -1 + sc.rockford_go(last_dir) + cn := ca - 1 + elseif nes & GP_UP + sc.rockford_go(last_dir) + cn := ca - 40 + elseif nes & GP_DOWN + sc.rockford_go(last_dir) + cn := ca + 40 + + if cn + if nes & GP_SELECT + o1 := $39 + o2 := $00 + else + o1 := $00 + o2 := $39 + case byte[cn] + $00, $01: 'empty or dirt + sn.moving_sound(byte[cn]) + byte[ca] := o1 + byte[cn] := o2 + $05: 'out door + sn.magic_wall_sound_off + sn.amoeba_sound_off + byte[ca] := o1 + byte[cn] := o2 + AddBonusPoints + waitcnt(clkfreq + cnt) '1 second delay + return true 'means cave succesfully completed + $10, $11: 'boulder, stationary + if (nes & GP_RIGHT) and (byte[cn + 1] == $00) and ((long[random_ptr] & $03) == 0) + 'boulder can be pushed + byte[cn + 1] := byte[cn] + byte[ca] := o1 + byte[cn] := o2 + sn.boulder_sound + elseif (nes & GP_LEFT) and (byte[cn - 1] == $00) and ((long[random_ptr] & $03) == 0) + 'boulder can be pushed + byte[cn - 1] := byte[cn] + byte[ca] := o1 + byte[cn] := o2 + sn.boulder_sound + $14, $15, $16, $17: 'diamond + byte[ca] := o1 + byte[cn] := o2 + sn.pick_sound + st.set_diamond_count(++DiamondCount) + IncrementScore(DiamondValue) + if DiamondCount == DiamondsNeeded and not target + 'flash screen when target is reached + sc.flash + sn.crack_sound + DiamondValue := ExtraValue + st.set_diamond_value(DiamondValue) + target := 1 + + else + sc.rockford_go(0) + + 'screen may need scrolling + if CaveNumber > 16 + 'do not scroll intermission caves + sx := 0 + sy := 0 + else + if cx - sx > constant(20 - 6) + sx += constant(10 - 5) + sx <#= constant(40 - 20) + elseif cx - sx < 5 + sx -= constant(10 - 5) + sx #>= 0 + if cy - sy > screen_height - 4 + sy += screen_height / 2 - 3 + sy <#= 22 - screen_height + elseif cy - sy < 3 + sy -= screen_height / 2 - 3 + sy #>= 0 + sc.scroll_to(sx * 8, sy * 16) + + $3A: 'amoeba + if ready + sn.amoeba_sound_on + if AmoebaStatus == 2 + 'turn into stone + byte[ca] := $10 'stationary boulder + elseif AmoebaStatus == 3 + 'turn into diamond + byte[ca] := $14 'stationary diamond + else + ++amoebas + if enclosed + enclosed := CheckEnclosed(ca) + cn := long[random_ptr] + if AmoebaStatus == 0 + cn &= $7F + else + cn &= $0F + if cn =< 3 + cn := ca + dirs[cn & $03] + ob := byte[cn] + if ob == $00 or ob == $01 + byte[cn] := $3A + + 'reset scanned flag + cn := ca - constant(40 + 1) + byte[cn] := reset.byte[byte[cn]] + + if MagicWallStatus == 1 + if st.get_time < MagicWallTime + MagicWallStatus := 2 'expired + sc.milling_off + sn.magic_wall_sound_off + + if AmoebaStatus == 0 + if st.get_time < AmoebaTime + AmoebaStatus := 1 'growing fast + if amoebas > 200 + AmoebaStatus := 2 'grew too big, turn into stones + elseif enclosed + AmoebaStatus := 3 'fully enclosed, turn into diamonds + if amoebas == 0 + sn.amoeba_sound_off + + if demo_ptr + nes := 0 + else + nes := read_input + if nes & GP_A + st.set_time(0) 'stop the time + sn.magic_wall_sound_off + sn.amoeba_sound_off + return false 'not completed, restart the same level + + elseif nes & GP_B + 'pause game + st.set_mode(st#STATUS_PAUSE) + repeat while nes & GP_B + nes := read_input + repeat while (nes & GP_B) == 0 + nes := read_input + if ready + st.set_mode(st#STATUS_GAME) + else + st.set_mode(st#STATUS_PRE) + repeat while nes & GP_B + nes := read_input + + elseif (nes & GP_SELECT) and (nes & GP_START) + st.set_time(0) + sn.magic_wall_sound_off + sn.amoeba_sound_off + return true '*cheat* go to the next level + + cn := st.get_time + if cn < 10 + sn.time_ending_sound(cn) + + if ready and (cn == 0) + 'out of time + sn.magic_wall_sound_off + sn.amoeba_sound_off + st.set_mode(st#STATUS_OUT_OF_TIME) + count := 60 * 60 'approx 1 minute + repeat while count > 0 + repeat while vsync == 0 + repeat while vsync <> 0 + --count + nes := read_input + if nes & GP_A + return false 'not completed, restart the same level + elseif (nes & GP_SELECT) and (nes & GP_START) + return true '*cheat* go to the next level + return false + + if Level < 2 + waitcnt(clkfreq / 50 + cnt) + +pub ExplodeBelow(cell, towhat) + if byte[cell - 1] <> $07 + byte[cell - 1] := towhat + 1 + if byte[cell] <> $07 + byte[cell] := towhat + 1 + if byte[cell + 1] <> $07 + byte[cell + 1] := towhat + if byte[cell + constant(40 - 1)] <> $07 + byte[cell + constant(40 - 1)] := towhat + if byte[cell + 40] <> $07 + byte[cell + 40] := towhat + if byte[cell + constant(40 + 1)] <> $07 + byte[cell + constant(40 + 1)] := towhat + if byte[cell + constant(40 * 2 - 1)] <> $07 + byte[cell + constant(40 * 2 - 1)] := towhat + if byte[cell + constant(40 * 2)] <> $07 + byte[cell + constant(40 * 2)] := towhat + if byte[cell + constant(40 * 2 + 1)] <> $07 + byte[cell + constant(40 * 2 + 1)] := towhat + sn.explosion_sound + +pub ExplodeCenter(cell, towhat) + if byte[cell - constant(40 + 1)] <> $07 + byte[cell - constant(40 + 1)] := towhat + 1 + if byte[cell - 40] <> $07 + byte[cell - 40] := towhat + 1 + if byte[cell - constant(40 - 1)] <> $07 + byte[cell - constant(40 - 1)] := towhat + 1 + if byte[cell - 1] <> $07 + byte[cell - 1] := towhat + 1 + if byte[cell] <> $07 + byte[cell] := towhat + 1 + if byte[cell + 1] <> $07 + byte[cell + 1] := towhat + if byte[cell + constant(40 - 1)] <> $07 + byte[cell + constant(40 - 1)] := towhat + if byte[cell + 40] <> $07 + byte[cell + 40] := towhat + if byte[cell + constant(40 + 1)] <> $07 + byte[cell + constant(40 + 1)] := towhat + sn.explosion_sound + +pub CheckAround(cell) | ob + ob := byte[cell - 40] + if ob => $38 and ob =< $3B 'rockford or ameba, scanned or not + return true + ob := byte[cell - 1] + if ob => $38 and ob =< $3B 'rockford or ameba, scanned or not + return true + ob := byte[cell + 1] + if ob => $38 and ob =< $3B 'rockford or ameba, scanned or not + return true + ob := byte[cell + 40] + if ob => $38 and ob =< $3B 'rockford or ameba, scanned or not + return true + return false + +pub CheckEnclosed(cell) | ob, i + repeat i from 0 to 3 + ob := byte[cell + dirs[i]] + if ob == $00 or ob == $01 + return false + return true + +pub IncrementScore(amount) + Score += amount + st.set_score(Score) + if Score => NextLife and Men < 9 + ++Men + sc.new_life + NextLife += 500 + +pub AddBonusPoints | i, j + + i := j := st.get_time + repeat while i > 0 + st.set_time(--i) + IncrementScore(Level + 1) + if i < 10 + sn.time_ending_sound(i) + waitcnt(clkfreq / 32 + cnt) + else + sn.bonus_point_sound(j - i) + +dat + + long 0 'align + + ' screen array +screen byte $00[40*28] + +' color index 3 1 2 0 +palette long $06_6B_04_02 + +' -x- -y- +scroll long $0000_0000 + +status long 1 'set this to 1 to show the status line at the top + + ' status line + byte $90[20] + + ' foreground color for status line characters + byte $06[20] + + ' tiles +tiles word %%0_0_0_0_0_0_0_0 ' $00 space + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_1_0_0_1_0_1 ' $01 dirt + word %%1_1_0_0_1_0_0_1 + word %%0_1_2_1_0_1_2_0 + word %%1_1_0_1_1_1_0_1 + word %%1_0_1_1_1_0_1_1 + word %%0_2_1_0_1_2_1_0 + word %%2_1_1_2_2_0_1_1 + word %%1_0_1_1_1_1_2_0 + word %%0_1_1_1_2_1_1_1 + word %%1_2_0_1_1_1_2_0 + word %%1_2_1_0_2_1_0_1 + word %%0_2_1_1_0_1_2_1 + word %%1_0_1_0_1_0_1_0 + word %%1_1_0_0_1_1_0_1 + word %%1_0_1_2_0_1_0_0 + word %%0_1_0_0_1_0_1_0 + + word %%0_3_3_3_0_3_3_3 ' $02 brick wall + word %%0_2_3_3_0_2_3_3 + word %%0_2_2_2_0_2_2_2 + word %%0_0_0_0_0_0_0_0 + word %%3_3_0_3_3_3_0_3 + word %%3_3_0_2_3_3_0_2 + word %%2_2_0_2_2_2_0_2 + word %%0_0_0_0_0_0_0_0 + word %%0_3_3_3_0_3_3_3 + word %%0_2_3_3_0_2_3_3 + word %%0_2_2_2_0_2_2_2 + word %%0_0_0_0_0_0_0_0 + word %%3_3_0_3_3_3_0_3 + word %%3_3_0_2_3_3_0_2 + word %%2_2_0_2_2_2_0_2 + word %%0_0_0_0_0_0_0_0 + + word %%0_3_3_3_0_3_3_3 ' $03 magic wall + word %%0_2_3_3_0_2_2_2 + word %%0_2_2_2_0_2_2_2 + word %%0_0_0_0_0_0_0_0 + word %%3_3_0_3_3_3_0_3 + word %%3_3_0_2_3_3_0_3 + word %%2_2_0_2_2_2_0_2 + word %%0_0_0_0_0_0_0_0 + word %%0_3_3_3_0_3_3_3 + word %%0_2_3_3_0_2_3_3 + word %%0_2_2_2_0_2_2_2 + word %%0_0_0_0_0_0_0_0 + word %%3_3_0_3_3_3_0_3 + word %%3_3_0_2_3_3_0_2 + word %%2_2_0_2_2_2_0_2 + word %%0_0_0_0_0_0_0_0 + + word %%2_2_2_2_2_2_2_2 ' $04 out door (invisible) + word %%2_2_2_2_2_2_2_2 + word %%2_0_0_2_2_0_0_2 + word %%2_2_0_2_2_2_0_2 + word %%2_3_0_2_2_3_0_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_0_0_2_2_0_0_2 + word %%2_2_0_2_2_2_0_2 + word %%2_3_0_2_2_3_0_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + + word %%0_0_0_0_0_0_0_0 ' $05 out door (flashing) + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $06 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%2_2_2_2_2_2_2_2 ' $07 steel wall + word %%2_2_2_2_2_2_2_2 + word %%2_0_0_2_2_0_0_2 + word %%2_2_0_2_2_2_0_2 + word %%2_3_0_2_2_3_0_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_0_0_2_2_0_0_2 + word %%2_2_0_2_2_2_0_2 + word %%2_3_0_2_2_3_0_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + + word %%0_0_0_0_0_0_0_0 ' $08 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $09 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $0A + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $0B + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $0C + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $0D + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $0E + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $0F + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_3_3_3_0_0_0 ' $10 boulder stationary + word %%0_3_2_3_1_3_0_0 + word %%3_1_3_2_3_3_3_0 + word %%2_3_1_2_1_3_3_3 + word %%2_2_2_1_2_3_3_3 + word %%2_1_2_2_2_1_2_3 + word %%2_2_1_1_2_2_3_3 + word %%2_2_2_2_2_1_2_3 + word %%2_0_2_2_2_2_2_1 + word %%2_2_0_2_2_1_2_1 + word %%2_0_2_2_2_2_2_2 + word %%2_2_0_2_2_2_2_2 + word %%2_2_2_0_2_2_2_0 + word %%0_2_2_2_2_2_2_0 + word %%0_0_2_0_1_2_0_0 + word %%0_0_0_2_2_0_0_0 + + word %%0_0_3_3_3_0_0_0 ' $11 boulder stationary, scanned this frame + word %%0_3_2_3_1_3_0_0 + word %%3_1_3_2_3_3_3_0 + word %%2_3_1_2_1_3_3_3 + word %%2_2_2_1_2_3_3_3 + word %%2_1_2_2_2_1_2_3 + word %%2_2_1_1_2_2_3_3 + word %%2_2_2_2_2_1_2_3 + word %%2_0_2_2_2_2_2_1 + word %%2_2_0_2_2_1_2_1 + word %%2_0_2_2_2_2_2_2 + word %%2_2_0_2_2_2_2_2 + word %%2_2_2_0_2_2_2_0 + word %%0_2_2_2_2_2_2_0 + word %%0_0_2_0_1_2_0_0 + word %%0_0_0_2_2_0_0_0 + + word %%0_0_3_3_3_0_0_0 ' $12 boulder falling + word %%0_3_2_3_1_3_0_0 + word %%3_1_3_2_3_3_3_0 + word %%2_3_1_2_1_3_3_3 + word %%2_2_2_1_2_3_3_3 + word %%2_1_2_2_2_1_2_3 + word %%2_2_1_1_2_2_3_3 + word %%2_2_2_2_2_1_2_3 + word %%2_0_2_2_2_2_2_1 + word %%2_2_0_2_2_1_2_1 + word %%2_0_2_2_2_2_2_2 + word %%2_2_0_2_2_2_2_2 + word %%2_2_2_0_2_2_2_0 + word %%0_2_2_2_2_2_2_0 + word %%0_0_2_0_1_2_0_0 + word %%0_0_0_2_2_0_0_0 + + word %%0_0_3_3_3_0_0_0 ' $13 boulder falling, scanned this frame + word %%0_3_2_3_1_3_0_0 + word %%3_1_3_2_3_3_3_0 + word %%2_3_1_2_1_3_3_3 + word %%2_2_2_1_2_3_3_3 + word %%2_1_2_2_2_1_2_3 + word %%2_2_1_1_2_2_3_3 + word %%2_2_2_2_2_1_2_3 + word %%2_0_2_2_2_2_2_1 + word %%2_2_0_2_2_1_2_1 + word %%2_0_2_2_2_2_2_2 + word %%2_2_0_2_2_2_2_2 + word %%2_2_2_0_2_2_2_0 + word %%0_2_2_2_2_2_2_0 + word %%0_0_2_0_1_2_0_0 + word %%0_0_0_2_2_0_0_0 + + word %%0_0_0_2_3_0_0_0 ' $14 diamond stationary + word %%0_0_0_1_2_0_0_0 + word %%0_0_2_3_3_3_0_0 + word %%0_0_1_3_3_2_0_0 + word %%0_2_2_2_2_2_3_0 + word %%0_1_1_1_1_1_2_0 + word %%2_0_0_0_0_0_0_3 + word %%1_0_0_0_0_0_0_2 + word %%2_1_1_1_1_1_1_3 + word %%1_2_2_2_2_2_2_2 + word %%0_2_3_3_3_3_3_0 + word %%0_1_3_3_3_3_2_0 + word %%0_0_2_1_1_3_0_0 + word %%0_0_1_1_1_2_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_0_1_1_0_0_0 + + word %%0_0_0_2_3_0_0_0 ' $15 diamond stationary, scanned + word %%0_0_0_1_2_0_0_0 + word %%0_0_2_3_3_3_0_0 + word %%0_0_1_3_3_2_0_0 + word %%0_2_2_2_2_2_3_0 + word %%0_1_1_1_1_1_2_0 + word %%2_0_0_0_0_0_0_3 + word %%1_0_0_0_0_0_0_2 + word %%2_1_1_1_1_1_1_3 + word %%1_2_2_2_2_2_2_2 + word %%0_2_3_3_3_3_3_0 + word %%0_1_3_3_3_3_2_0 + word %%0_0_2_1_1_3_0_0 + word %%0_0_1_1_1_2_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_0_1_1_0_0_0 + + word %%0_0_0_2_3_0_0_0 ' $16 diamond falling + word %%0_0_0_1_2_0_0_0 + word %%0_0_2_3_3_3_0_0 + word %%0_0_1_3_3_2_0_0 + word %%0_2_2_2_2_2_3_0 + word %%0_1_1_1_1_1_2_0 + word %%2_0_0_0_0_0_0_3 + word %%1_0_0_0_0_0_0_2 + word %%2_1_1_1_1_1_1_3 + word %%1_2_2_2_2_2_2_2 + word %%0_2_3_3_3_3_3_0 + word %%0_1_3_3_3_3_2_0 + word %%0_0_2_1_1_3_0_0 + word %%0_0_1_1_1_2_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_0_1_1_0_0_0 + + word %%0_0_0_2_3_0_0_0 ' $17 diamond falling, scanned + word %%0_0_0_1_2_0_0_0 + word %%0_0_2_3_3_3_0_0 + word %%0_0_1_3_3_2_0_0 + word %%0_2_2_2_2_2_3_0 + word %%0_1_1_1_1_1_2_0 + word %%2_0_0_0_0_0_0_3 + word %%1_0_0_0_0_0_0_2 + word %%2_1_1_1_1_1_1_3 + word %%1_2_2_2_2_2_2_2 + word %%0_2_3_3_3_3_3_0 + word %%0_1_3_3_3_3_2_0 + word %%0_0_2_1_1_3_0_0 + word %%0_0_1_1_1_2_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_0_1_1_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $18 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $19 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $1A + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $1B explode to space frame 1 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_3_0_0 + word %%0_0_3_0_0_0_0_0 + word %%0_3_0_0_3_0_0_0 + word %%0_0_0_3_0_0_3_0 + word %%0_0_0_0_3_0_0_0 + word %%0_0_3_0_0_0_0_0 + word %%0_3_0_0_0_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $1C explode to space frame 2 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_3_0_0 + word %%0_0_0_3_0_1_0_0 + word %%0_3_1_0_0_0_3_0 + word %%0_1_0_0_1_3_1_0 + word %%0_3_0_1_0_0_1_0 + word %%0_0_0_0_1_3_0_0 + word %%0_3_1_0_1_0_0_0 + word %%0_1_0_1_0_1_0_0 + word %%0_0_3_1_1_0_3_0 + word %%0_0_3_0_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $1D explode to space frame 3 + word %%0_0_0_0_0_0_0_0 + word %%0_3_0_0_3_0_3_0 + word %%0_0_0_3_0_2_0_0 + word %%0_3_0_1_0_1_3_0 + word %%0_1_2_0_0_0_1_0 + word %%0_2_0_0_2_1_2_0 + word %%3_1_0_2_0_0_2_0 + word %%0_0_0_0_1_1_0_0 + word %%3_1_2_0_1_0_3_0 + word %%0_2_0_2_0_1_0_0 + word %%0_0_1_2_1_0_1_0 + word %%3_0_1_0_1_0_3_0 + word %%0_0_0_3_3_0_0_0 + word %%0_3_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $1E explode to space frame 4, same as frame 2 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_3_0_0 + word %%0_0_0_3_0_1_0_0 + word %%0_3_1_0_0_0_3_0 + word %%0_1_0_0_1_3_1_0 + word %%0_3_0_1_0_0_1_0 + word %%0_0_0_0_1_3_0_0 + word %%0_3_1_0_1_0_0_0 + word %%0_1_0_1_0_1_0_0 + word %%0_0_3_1_1_0_3_0 + word %%0_0_3_0_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $1F explode to space frame 5, same as frame 1 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_3_0_0 + word %%0_0_3_0_0_0_0_0 + word %%0_3_0_0_3_0_0_0 + word %%0_0_0_3_0_0_3_0 + word %%0_0_0_0_3_0_0_0 + word %%0_0_3_0_0_0_0_0 + word %%0_3_0_0_0_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $20 explode to diamond frame 1 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_3_0_0 + word %%0_0_3_0_0_0_0_0 + word %%0_3_0_0_3_0_0_0 + word %%0_0_0_3_0_0_3_0 + word %%0_0_0_0_3_0_0_0 + word %%0_0_3_0_0_0_0_0 + word %%0_3_0_0_0_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_3_0_0_0 ' $21 explode to diamond frame 2 + word %%3_0_3_0_0_0_3_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_3_0_3_0_3_0 + word %%0_3_0_0_0_0_0_0 + word %%0_0_0_0_0_3_0_0 + word %%3_0_0_0_0_0_0_3 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%3_0_0_0_0_0_3_0 + word %%0_0_0_0_0_0_0_0 + word %%0_3_0_0_3_0_0_3 + word %%0_0_0_3_0_0_0_0 + word %%3_0_0_0_0_0_3_0 + word %%0_0_3_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_1_1_0_0_0 ' $22 explode to diamond frame 3 + word %%0_3_0_3_0_0_0_0 + word %%0_0_1_0_0_1_0_3 + word %%0_0_3_0_2_3_0_0 + word %%0_0_0_2_0_0_1_0 + word %%0_0_0_0_0_0_3_0 + word %%1_0_2_0_0_2_0_1 + word %%3_0_0_0_0_0_0_3 + word %%1_0_0_0_0_0_0_2 + word %%3_0_2_0_0_0_0_3 + word %%0_0_0_0_0_2_2_0 + word %%0_3_0_2_0_0_3_0 + word %%0_0_1_0_1_2_0_0 + word %%0_0_3_0_0_0_0_3 + word %%0_3_0_1_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + + word %%0_0_0_1_1_0_0_0 ' $23 explode to diamond frame 4 + word %%0_0_0_3_3_0_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_0_3_0_2_3_0_0 + word %%0_1_0_2_0_0_1_0 + word %%0_3_0_0_3_0_3_0 + word %%1_0_2_3_1_2_0_1 + word %%3_1_0_2_2_0_2_3 + word %%1_0_0_3_0_1_1_2 + word %%3_0_2_0_2_0_0_3 + word %%0_1_1_0_0_3_2_0 + word %%0_3_0_2_2_0_3_0 + word %%0_0_1_3_0_2_0_0 + word %%0_0_3_0_1_3_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + + word %%0_0_0_1_1_0_0_0 ' $24 explode to diamond frame 5 + word %%0_0_0_3_3_0_0_0 + word %%0_0_1_2_1_1_0_0 + word %%0_0_3_2_2_3_0_0 + word %%0_1_1_3_3_2_1_0 + word %%0_3_2_3_2_2_3_0 + word %%1_2_3_1_1_3_3_1 + word %%3_3_2_3_3_2_1_3 + word %%1_2_2_3_2_3_1_2 + word %%3_2_3_1_3_1_1_3 + word %%0_1_2_3_1_3_2_0 + word %%0_3_2_1_2_1_3_0 + word %%0_0_1_3_3_2_0_0 + word %%0_0_3_2_1_3_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + + word %%2_2_2_2_2_2_2_2 ' $25 inbox, flashing + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_2_2_2_2_2_2_2 + + word %%0_0_0_0_0_0_0_0 ' $26 inbox morphing into rockford, same as explode to space frame 1 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_3_0_0 + word %%0_0_3_0_0_0_0_0 + word %%0_3_0_0_3_0_0_0 + word %%0_0_0_3_0_0_3_0 + word %%0_0_0_0_3_0_0_0 + word %%0_0_3_0_0_0_0_0 + word %%0_3_0_0_0_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $27 inbox morphing into rockford, same as explode to space frame 2 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_3_0_0 + word %%0_0_0_3_0_1_0_0 + word %%0_3_1_0_0_0_3_0 + word %%0_1_0_0_1_3_1_0 + word %%0_3_0_1_0_0_1_0 + word %%0_0_0_0_1_3_0_0 + word %%0_3_1_0_1_0_0_0 + word %%0_1_0_1_0_1_0_0 + word %%0_0_3_1_1_0_3_0 + word %%0_0_3_0_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $28 inbox morphing into rockford, same as explode to space frame 3 + word %%0_0_0_0_0_0_0_0 + word %%0_3_0_0_3_0_3_0 + word %%0_0_0_3_0_2_0_0 + word %%0_3_0_1_0_1_3_0 + word %%0_1_2_0_0_0_1_0 + word %%0_2_0_0_2_1_2_0 + word %%3_1_0_2_0_0_2_0 + word %%0_0_0_0_1_1_0_0 + word %%3_1_2_0_1_0_3_0 + word %%0_2_0_2_0_1_0_0 + word %%0_0_1_2_1_0_1_0 + word %%3_0_1_0_1_0_3_0 + word %%0_0_0_3_3_0_0_0 + word %%0_3_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $29 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $2A + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $2B + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $2C + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $2D + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $2E + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $2F + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $30 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $31 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $32 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $33 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $34 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $35 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $36 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $37 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $38 rockford + word %%0_0_2_0_0_2_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_2_2_0_2_0 + word %%0_2_0_2_2_0_2_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_3_3_0_2_0 + word %%0_0_3_2_2_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_1_3_3_1_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_3_3_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $39 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $3A + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $3B + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%2_2_2_2_2_2_2_2 ' $3C + word %%2_2_2_2_2_2_2_2 + word %%2_0_0_2_2_0_0_2 + word %%2_2_0_2_2_2_0_2 + word %%2_3_0_2_2_3_0_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_0_0_2_2_0_0_2 + word %%2_2_0_2_2_2_0_2 + word %%2_3_0_2_2_3_0_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + + word %%0_0_0_0_0_0_0_0 ' $3D + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $3E + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $3F + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + +' chargen + + word %%0_0_0_0_0_0_0_0 ' $80 '0' + word %%0_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $81 '1' + word %%0_0_0_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $82 '2' + word %%0_3_3_3_3_3_0_0 + word %%3_3_0_0_3_3_3_0 + word %%0_0_0_3_3_3_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_3_3_3_0_0_0_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $83 + word %%0_3_3_3_3_3_3_0 + word %%0_0_0_0_3_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_0_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $84 + word %%3_3_0_0_0_0_0_0 + word %%3_3_0_0_0_0_0_0 + word %%3_3_0_3_3_3_0_0 + word %%3_3_3_3_3_3_3_0 + word %%0_0_0_3_3_3_0_0 + word %%0_0_0_3_3_3_0_0 + word %%0_0_0_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $85 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_3_3_3_0_0 + word %%0_0_0_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $86 + word %%0_3_3_3_3_3_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $87 + word %%3_3_3_3_3_3_3_0 + word %%3_0_0_0_3_3_3_0 + word %%0_0_0_3_3_3_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_3_3_3_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $88 + word %%0_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%0_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $89 + word %%0_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%0_3_3_3_3_3_3_0 + word %%0_0_0_3_3_3_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_3_3_3_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $8A ':' + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $8B ';' + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_3_3_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $8C '/' + word %%0_0_0_0_0_0_3_0 + word %%0_0_0_0_0_3_3_0 + word %%0_0_0_0_3_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_3_3_0_0_0_0 + word %%0_3_3_0_0_0_0_0 + word %%3_3_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $8D + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $8E + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $8F + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $90 space + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $91 'A' + word %%0_0_3_3_3_0_0_0 + word %%0_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $92 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $93 + word %%0_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $94 + word %%3_3_3_3_3_0_0_0 + word %%3_3_3_0_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_3_3_0_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_3_3_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $95 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $96 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $97 + word %%0_3_3_3_3_3_3_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_3_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $98 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $99 + word %%0_3_3_3_3_3_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_3_3_3_3_3_0_0 + word %%0_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $9A + word %%0_0_0_0_0_3_3_0 + word %%0_0_0_0_0_3_3_0 + word %%0_0_0_0_0_3_3_0 + word %%0_0_0_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%0_3_3_3_3_3_3_0 + word %%0_0_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $9B + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_3_3_0_0 + word %%3_3_3_3_3_0_0_0 + word %%3_3_3_3_3_0_0_0 + word %%3_3_3_0_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $9C + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $9D + word %%3_3_0_0_0_3_3_0 + word %%3_3_3_0_3_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_0_3_0_3_3_0 + word %%3_3_0_0_0_3_3_0 + word %%3_3_0_0_0_3_3_0 + word %%3_3_0_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $9E + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_0_3_3_3_0 + word %%3_3_3_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $9F + word %%0_3_3_3_3_3_0_0 + word %%3_3_0_0_0_3_3_0 + word %%3_3_0_0_0_3_3_0 + word %%3_3_0_0_0_3_3_0 + word %%3_3_0_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $A0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $A1 + word %%0_0_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_3_3_0_0 + word %%0_3_3_3_3_3_3_0 + word %%0_0_3_3_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $A2 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $A3 + word %%0_3_3_3_3_3_0_0 + word %%3_3_3_0_0_0_0_0 + word %%0_3_3_3_3_3_0_0 + word %%0_0_0_0_0_3_3_0 + word %%0_0_0_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $A4 + word %%3_3_3_3_3_3_3_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $A5 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $A6 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_0_0 + word %%0_0_3_3_3_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $A7 + word %%3_3_0_0_0_3_3_0 + word %%3_3_0_0_0_3_3_0 + word %%3_3_0_3_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_0_3_3_3_0 + word %%3_3_0_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $A8 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%0_0_3_3_3_3_0_0 + word %%0_0_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $A9 + word %%3_3_0_0_0_3_3_0 + word %%3_3_0_0_0_3_3_0 + word %%0_3_3_3_3_3_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $AA + word %%3_3_3_3_3_3_3_0 + word %%0_0_0_3_3_3_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_3_3_3_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $AB '(' + word %%0_0_0_0_3_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_0_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $AC diamond + word %%0_0_0_3_0_0_0_0 + word %%0_0_3_0_3_0_0_0 + word %%0_3_3_3_3_3_0_0 + word %%3_0_0_0_0_0_3_0 + word %%0_3_3_3_3_3_0_0 + word %%0_0_3_0_3_0_0_0 + word %%0_0_0_3_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $AD ')' + word %%0_0_3_3_0_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_3_3_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $AE + word %%0_0_3_0_0_3_0_0 + word %%0_0_3_3_3_3_0_0 + word %%0_3_0_3_3_0_3_0 + word %%0_3_0_3_3_0_3_0 + word %%0_0_3_3_3_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $AF ',' + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_3_3_0_0_0_0 + + word %%1_3_2_2_1_3_2_2 ' $B0 scrolling bgnd of the title screen + word %%1_2_2_2_1_2_2_2 + word %%0_1_2_2_0_1_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_1_3_2_2_1_3 + word %%2_2_1_2_2_2_1_2 + word %%2_2_0_1_2_2_0_1 + word %%2_2_2_2_2_2_2_2 + + word %%3_3_3_3_3_3_3_3 ' $B1 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + + word %%1_2_3_3_3_3_3_3 ' $B2 + word %%1_2_3_3_3_3_3_3 + word %%1_2_3_3_3_3_3_3 + word %%1_2_3_3_3_3_3_3 + word %%1_2_3_3_3_3_3_3 + word %%1_2_3_3_3_3_3_3 + word %%1_2_3_3_3_3_3_3 + word %%1_2_3_3_3_3_3_3 + + word %%3_3_3_3_0_0_0_0 ' $B3 + word %%3_3_3_3_3_0_0_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + + word %%3_3_3_3_3_3_3_3 ' $B4 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_3_3_0_0_0 + + word %%3_3_3_3_0_0_0_0 ' $B5 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + + word %%0_0_0_0_3_3_3_3 ' $B6 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + + word %%0_0_0_0_0_0_0_0 ' $B7 + word %%3_0_0_0_0_0_0_0 + word %%3_3_0_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + + word %%3_3_3_3_0_0_0_0 ' $B8 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_0_0_0_0_0_0 + word %%3_0_0_0_0_0_0_0 + + word %%1_2_3_3_0_0_0_0 ' $B9 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + + word %%0_0_0_0_1_2_3_3 ' $BA + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + + word %%0_0_0_0_1_2_3_3 ' $BB + word %%0_0_0_0_1_2_2_2 + word %%0_0_0_0_1_2_2_2 + word %%0_0_0_0_1_2_3_2 + word %%0_0_0_0_1_2_3_2 + word %%0_0_0_0_1_2_3_2 + word %%0_0_0_0_1_2_3_2 + word %%0_0_0_0_1_2_3_3 + + word %%3_3_3_3_3_3_3_3 ' $BC + word %%2_3_2_3_3_3_2_3 + word %%2_3_2_2_3_2_2_3 + word %%3_3_2_2_2_2_2_3 + word %%3_3_2_3_2_3_2_3 + word %%3_3_2_3_3_3_2_3 + word %%3_3_2_3_3_3_2_3 + word %%3_3_3_3_3_3_3_3 + + word %%3_3_3_3_0_0_0_0 ' $BD + word %%3_3_3_3_3_0_0_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + + word %%3_3_3_3_3_3_3_3 ' $BE + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_3_3_0_0_0 + + word %%3_3_3_3_0_0_0_0 ' $BF + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + + word %%0_0_0_0_3_3_3_3 ' $C0 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + + word %%0_0_0_0_0_0_0_0 ' $C1 + word %%3_0_0_0_0_0_0_0 + word %%3_3_0_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + + word %%3_3_3_3_0_0_0_0 ' $C2 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_0_0_0_0_0_0 + word %%3_0_0_0_0_0_0_0 + + word %%1_2_3_3_0_0_0_0 ' $C3 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + + word %%0_0_0_0_1_2_3_3 ' $C4 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + + word %%0_0_0_0_1_2_3_3 ' $C5 + word %%0_0_0_0_1_2_2_2 + word %%0_0_0_0_1_2_2_2 + word %%0_0_0_0_1_2_3_2 + word %%0_0_0_0_1_2_3_2 + word %%0_0_0_0_1_2_3_2 + word %%0_0_0_0_1_2_3_2 + word %%0_0_0_0_1_2_3_3 + + word %%0_0_0_0_0_0_0_0 ' $C6 unused... padding for second chargen (see below) + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $C7 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $C8 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $C9 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $CA + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $CB + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $CC + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $CD + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $CE + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $CF + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + +' this is basically the same character generator, but using +' a different color (I need this for the title screen). Either +' this, or separate color attributes for each cell of the +' screen. We have still some space here, so... + + word %%0_0_0_0_0_0_0_0 ' $D0 '0' + word %%0_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $D1 '1' + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $D2 '2' + word %%0_2_2_2_2_2_0_0 + word %%2_2_0_0_2_2_2_0 + word %%0_0_0_2_2_2_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_2_2_2_0_0_0_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $D3 + word %%0_2_2_2_2_2_2_0 + word %%0_0_0_0_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_0_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $D4 + word %%2_2_0_0_0_0_0_0 + word %%2_2_0_0_0_0_0_0 + word %%2_2_0_2_2_2_0_0 + word %%2_2_2_2_2_2_2_0 + word %%0_0_0_2_2_2_0_0 + word %%0_0_0_2_2_2_0_0 + word %%0_0_0_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $D5 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_2_2_2_0_0 + word %%0_0_0_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $D6 + word %%0_2_2_2_2_2_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $D7 + word %%2_2_2_2_2_2_2_0 + word %%2_0_0_0_2_2_2_0 + word %%0_0_0_2_2_2_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_2_2_2_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $D8 + word %%0_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%0_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $D9 + word %%0_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%0_2_2_2_2_2_2_0 + word %%0_0_0_2_2_2_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_2_2_2_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $DA ':' + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $DB ';' + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $DC '/' + word %%0_0_0_0_0_0_2_0 + word %%0_0_0_0_0_2_2_0 + word %%0_0_0_0_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_0_0_0_0 + word %%0_2_2_0_0_0_0_0 + word %%2_2_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $DD + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $DE + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $DF + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $E0 space + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $E1 'A' + word %%0_0_2_2_2_0_0_0 + word %%0_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $E2 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $E3 + word %%0_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $E4 + word %%2_2_2_2_2_0_0_0 + word %%2_2_2_0_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_2_2_0_0 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_2_2_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $E5 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $E6 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $E7 + word %%0_2_2_2_2_2_2_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_2_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $E8 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $E9 + word %%0_2_2_2_2_2_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_2_2_2_2_2_0_0 + word %%0_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $EA + word %%0_0_0_0_0_2_2_0 + word %%0_0_0_0_0_2_2_0 + word %%0_0_0_0_0_2_2_0 + word %%0_0_0_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%0_2_2_2_2_2_2_0 + word %%0_0_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $EB + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_2_2_0_0 + word %%2_2_2_2_2_0_0_0 + word %%2_2_2_2_2_0_0_0 + word %%2_2_2_0_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $EC + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $ED + word %%2_2_0_0_0_2_2_0 + word %%2_2_2_0_2_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_0_2_0_2_2_0 + word %%2_2_0_0_0_2_2_0 + word %%2_2_0_0_0_2_2_0 + word %%2_2_0_0_0_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $EE + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_0_2_2_2_0 + word %%2_2_2_0_0_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $EF + word %%0_2_2_2_2_2_0_0 + word %%2_2_0_0_0_2_2_0 + word %%2_2_0_0_0_2_2_0 + word %%2_2_0_0_0_2_2_0 + word %%2_2_0_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $F0 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $F1 + word %%0_0_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_2_2_0_0 + word %%0_2_2_2_2_2_2_0 + word %%0_0_2_2_0_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $F2 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $F3 + word %%0_2_2_2_2_2_0_0 + word %%2_2_2_0_0_0_0_0 + word %%0_2_2_2_2_2_0_0 + word %%0_0_0_0_0_2_2_0 + word %%0_0_0_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $F4 + word %%2_2_2_2_2_2_2_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $F5 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $F6 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_0_0 + word %%0_0_2_2_2_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $F7 + word %%2_2_0_0_0_2_2_0 + word %%2_2_0_0_0_2_2_0 + word %%2_2_0_2_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_0_2_2_2_0 + word %%2_2_0_0_0_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $F8 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $F9 + word %%2_2_0_0_0_2_2_0 + word %%2_2_0_0_0_2_2_0 + word %%0_2_2_2_2_2_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $FA + word %%2_2_2_2_2_2_2_0 + word %%0_0_0_2_2_2_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_2_2_2_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $FB '(' + word %%0_0_0_0_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_0_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $FC diamond + word %%0_0_0_2_0_0_0_0 + word %%0_0_2_0_2_0_0_0 + word %%0_2_2_2_2_2_0_0 + word %%2_0_0_0_0_0_2_0 + word %%0_2_2_2_2_2_0_0 + word %%0_0_2_0_2_0_0_0 + word %%0_0_0_2_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $FD ')' + word %%0_0_2_2_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $FE + word %%0_0_2_0_0_2_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_2_2_0_2_0 + word %%0_2_0_2_2_0_2_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $FF ',' + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_0_0_0_0 + \ No newline at end of file diff --git a/zubehör/game boulderdash/sourcen/Bellatrix-Code/Boulderdash_Tile_TV.spin b/zubehör/game boulderdash/sourcen/Bellatrix-Code/Boulderdash_Tile_TV.spin new file mode 100644 index 0000000..a7a35dd Binary files /dev/null and b/zubehör/game boulderdash/sourcen/Bellatrix-Code/Boulderdash_Tile_TV.spin differ diff --git a/zubehör/game boulderdash/sourcen/Bellatrix-Code/Game_controller.spin b/zubehör/game boulderdash/sourcen/Bellatrix-Code/Game_controller.spin new file mode 100644 index 0000000..dc4ed28 --- /dev/null +++ b/zubehör/game boulderdash/sourcen/Bellatrix-Code/Game_controller.spin @@ -0,0 +1 @@ +con GP_RIGHT = %00000001 GP_LEFT = %00000010 GP_DOWN = %00000100 GP_UP = %00001000 GP_START = %00010000 GP_SELECT = %00100000 GP_B = %01000000 GP_A = %10000000 var long stack[6] long nes_bits pub start nes_bits := 0 'cognew(process, @stack) pub read 'return nes_bits return process pub process | i, bits ' set I/O ports to proper direction ' P3 = JOY_CLK (4) ' P4 = JOY_SH/LDn (5) ' P5 = JOY_DATAOUT0 (6) ' P6 = JOY_DATAOUT1 (7) ' NES Bit Encoding ' step 1: set I/Os DIRA[3] := 1 ' output DIRA[4] := 1 ' output DIRA[5] := 0 ' input DIRA[6] := 0 ' input repeat ' step 2: set clock and latch to 0 OUTA[3] := 0 ' JOY_CLK = 0 OUTA[4] := 0 ' JOY_SH/LDn = 0 'Delay(1) ' step 3: set latch to 1 OUTA[4] := 1 ' JOY_SH/LDn = 1 'Delay(1) ' step 4: set latch to 0 OUTA[4] := 0 ' JOY_SH/LDn = 0 ' step 5: read first bit of each game pad ' data is now ready to shift out ' first bit is ready ' left controller bits := INA[5] | (INA[6] << 8) ' step 7: read next 7 bits repeat i from 0 to 6 OUTA[3] := 1 ' JOY_CLK = 1 'Delay(1) OUTA[3] := 0 ' JOY_CLK = 0 bits := (bits << 1) bits := bits | INA[5] | (INA[6] << 8) 'Delay(1) ' invert bits to make positive logic and store result nes_bits := (!bits & $FFFF) return nes_bits \ No newline at end of file diff --git a/zubehör/game boulderdash/sourcen/Bellatrix-Code/Keyboard.spin b/zubehör/game boulderdash/sourcen/Bellatrix-Code/Keyboard.spin new file mode 100644 index 0000000..8eabe22 Binary files /dev/null and b/zubehör/game boulderdash/sourcen/Bellatrix-Code/Keyboard.spin differ diff --git a/zubehör/game boulderdash/sourcen/Bellatrix-Code/RealRandom.spin b/zubehör/game boulderdash/sourcen/Bellatrix-Code/RealRandom.spin new file mode 100644 index 0000000..53dd07f Binary files /dev/null and b/zubehör/game boulderdash/sourcen/Bellatrix-Code/RealRandom.spin differ diff --git a/zubehör/game boulderdash/sourcen/Bellatrix-Code/SIDemu.spin b/zubehör/game boulderdash/sourcen/Bellatrix-Code/SIDemu.spin new file mode 100644 index 0000000..a7811be Binary files /dev/null and b/zubehör/game boulderdash/sourcen/Bellatrix-Code/SIDemu.spin differ diff --git a/zubehör/game boulderdash/sourcen/Bellatrix-Code/Scroller.spin b/zubehör/game boulderdash/sourcen/Bellatrix-Code/Scroller.spin new file mode 100644 index 0000000..b67cdf8 --- /dev/null +++ b/zubehör/game boulderdash/sourcen/Bellatrix-Code/Scroller.spin @@ -0,0 +1 @@ +' This cog takes care of the smooth scrolling and animates animated objects. ' Also: ' - flashes the screen when the game target is reached ' - signals about new life with random background pattern var long x, y, nx, ny long scroll_addr long tile_addr long palette_addr long stack[12] long rockford_dir long random_addr long vsync_addr byte flash_cnt byte new_life_cnt byte tapping byte blinking byte wall_milling pub start(video_params, rnd_addr) x := 0 y := 0 vsync_addr := long[video_params + constant(6 * 4)] random_addr := rnd_addr palette_addr := long[video_params + constant(5 * 4)] + constant(40 * 28) scroll_addr := palette_addr + 4 tile_addr := scroll_addr + constant(4 + 4 + 20 * 2) rockford_dir := 0 flash_cnt := 0 new_life_cnt := 0 blinking := 0 tapping := 0 wall_milling := 0 cognew(process, @stack) pub scroll_to(sx, sy) nx := sx ny := sy pub rockford_reset blinking := 0 tapping := 0 pub rockford_go(dir) rockford_dir := dir if rockford_dir <> 0 blinking := 0 tapping := 0 pub flash flash_cnt := 6 pub new_life new_life_cnt := 400 pub milling_on wall_milling := 1 pub milling_off wall_milling := 0 pub process | i, n, cp, temp n := 0 i := 0 repeat 'wait for vsync repeat while byte[vsync_addr] == 0 repeat while byte[vsync_addr] <> 0 if x <> nx or y <> ny if x > nx x := x - 1 elseif x < nx x := x + 1 if y > ny y := y - 2 elseif y < ny y := y + 2 long[scroll_addr] := (x << 16) + y if i == 0 'rockford if rockford_dir > 0 cp := @rockford_right + n elseif rockford_dir < 0 cp := @rockford_left + n else cp := @rockford if n == 0 if (byte[random_addr] & $03) == 0 blinking := 1 else blinking := 0 if (byte[random_addr] & $0F) == 0 tapping ^= 1 ifnot blinking or tapping wordmove(tile_addr + constant(32 * $38), cp, 16) wordmove(tile_addr + constant(32 * $39), cp, 16) else if blinking cp := @rockford_bored + n wordmove(tile_addr + constant(32 * $38), cp, 8) ' top part only wordmove(tile_addr + constant(32 * $39), cp, 8) if tapping cp := @rockford_bored + 16 + n wordmove(tile_addr + constant(32 * $38 + 16), cp, 8) ' bottom part only wordmove(tile_addr + constant(32 * $39 + 16), cp, 8) ' diamonds cp := @diamonds + n wordmove(tile_addr + constant(32 * $14), cp, 16) ' update all 4 variants wordmove(tile_addr + constant(32 * $15), cp, 16) wordmove(tile_addr + constant(32 * $16), cp, 16) wordmove(tile_addr + constant(32 * $17), cp, 16) ' fireflies cp := @firefly + n wordmove(tile_addr + constant(32 * $08), cp, 16) ' update all 8 variants wordmove(tile_addr + constant(32 * $09), cp, 16) wordmove(tile_addr + constant(32 * $0A), cp, 16) wordmove(tile_addr + constant(32 * $0B), cp, 16) wordmove(tile_addr + constant(32 * $0C), cp, 16) wordmove(tile_addr + constant(32 * $0D), cp, 16) wordmove(tile_addr + constant(32 * $0E), cp, 16) wordmove(tile_addr + constant(32 * $0F), cp, 16) ' butterflies cp := @butterfly + n wordmove(tile_addr + constant(32 * $30), cp, 16) ' update all 8 variants wordmove(tile_addr + constant(32 * $31), cp, 16) wordmove(tile_addr + constant(32 * $32), cp, 16) wordmove(tile_addr + constant(32 * $33), cp, 16) wordmove(tile_addr + constant(32 * $34), cp, 16) wordmove(tile_addr + constant(32 * $35), cp, 16) wordmove(tile_addr + constant(32 * $36), cp, 16) wordmove(tile_addr + constant(32 * $37), cp, 16) ' amoeba cp := @amoeba + n wordmove(tile_addr + constant(32 * $3A), cp, 16) wordmove(tile_addr + constant(32 * $3B), cp, 16) ' magic wall if wall_milling wordmove(tile_addr + constant(32 * $03), @magic_wall + (n & $60), 16) else wordmove(tile_addr + constant(32 * $03), @wall, 16) ' flashing door if n & 128 wordmove(tile_addr + constant(32 * $05), @door_frame, 16) wordmove(tile_addr + constant(32 * $25), @door_frame, 16) else wordmove(tile_addr + constant(32 * $05), tile_addr + constant(32 * $07), 16) wordmove(tile_addr + constant(32 * $25), tile_addr + constant(32 * $07), 16) n += 32 if n => constant(32 * 8) n := 0 i ^= 1 ' scrolling steel wall cp := tile_addr + constant(32 * $3C) temp := word[cp] wordmove(cp, cp + 2, 15) word[cp + 31] := temp if flash_cnt > 0 if --flash_cnt > 0 byte[palette_addr + 0] := $07 else byte[palette_addr + 0] := $02 if i == 0 and new_life_cnt > 0 if new_life_cnt-- == 1 wordfill(tile_addr, $00, 16) else cp := byte[random_addr] byte[tile_addr] := cp byte[tile_addr + 9] := cp cp := byte[random_addr] byte[tile_addr + 8] := cp byte[tile_addr + 1] := cp cp := byte[random_addr] byte[tile_addr + 16] := cp byte[tile_addr + 25] := cp cp := byte[random_addr] byte[tile_addr + 24] := cp byte[tile_addr + 17] := cp dat ' animated creatures, 8 frames per each ' -- amoeba amoeba word %%3_3_3_3_2_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_3_3_3_3_3_3_3 word %%0_2_3_3_3_3_3_2 word %%0_2_3_3_3_3_3_2 word %%0_2_3_3_3_3_3_2 word %%2_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_3_3_3_3_3_3_2 word %%0_2_3_3_3_3_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_3_3_3_3_2_0 word %%2_3_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_3_3_3_3_3_3_3 word %%0_2_3_3_3_3_3_2 word %%0_2_3_3_3_3_3_2 word %%0_2_3_3_3_3_3_2 word %%2_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_3_3_3_3_3_3_2 word %%0_2_3_3_3_3_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_3_3_3_3_2_0 word %%2_3_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_2_0_2_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_3_3_3_3_2 word %%2_3_3_3_3_3_2_0 word %%0_2_3_3_3_2_2_0 word %%2_3_3_3_3_3_2_0 word %%3_3_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_3_3_3_3_3_3_2 word %%0_2_3_3_3_3_2_0 word %%2_3_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_2_0_2_3_3 word %%3_3_3_2_0_2_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_3_3_3_3_2 word %%2_3_3_3_3_3_2_0 word %%0_2_3_3_3_2_2_0 word %%2_3_3_3_3_3_2_0 word %%3_3_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_3_3_3_3_3_3_2 word %%0_2_3_3_3_3_2_0 word %%2_3_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_2_0_2_3_3 word %%3_3_2_0_0_0_2_3 word %%3_3_3_2_0_2_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_3_3_3_3_2 word %%2_3_3_3_3_3_2_0 word %%3_3_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_2_0_2_3_3 word %%3_3_2_0_0_0_2_3 word %%3_3_2_0_0_0_2_3 word %%3_3_3_2_0_2_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_3_3_3_3_2 word %%2_3_3_3_3_3_2_0 word %%3_3_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_2_0_2_3_3 word %%3_3_2_0_0_0_2_3 word %%3_3_3_2_0_2_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_3_3_3_3_3_3_3 word %%0_2_3_3_3_3_3_2 word %%2_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_2_3_3_3_3_3_2 word %%0_2_3_3_3_3_2_0 word %%2_2_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_2_0_2_3_3 word %%3_3_3_2_0_2_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_3_3_3_3_3_3_3 word %%0_2_3_3_3_3_3_2 word %%2_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_2_3_3_3_3_3_2 word %%0_2_3_3_3_3_2_0 word %%2_2_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_2_0_2_3_3 ' -- fireflies firefly word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_2_2_2_2_0_2 word %%2_0_2_2_2_2_0_2 word %%2_0_2_3_3_2_0_2 word %%2_0_2_3_3_2_0_2 word %%2_0_2_3_3_2_0_2 word %%2_0_2_3_3_2_0_2 word %%2_0_2_2_2_2_0_2 word %%2_0_2_2_2_2_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_2_2_2_2_0_2 word %%2_0_2_2_2_2_0_2 word %%2_0_2_3_3_2_0_2 word %%2_0_2_3_3_2_0_2 word %%2_0_2_3_3_2_0_2 word %%2_0_2_3_3_2_0_2 word %%2_0_2_2_2_2_0_2 word %%2_0_2_2_2_2_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_2_2_2_2_2_2_0 word %%0_2_2_2_2_2_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_3_2_2_3_2_0 word %%0_2_3_2_2_3_2_0 word %%0_2_3_2_2_3_2_0 word %%0_2_3_2_2_3_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_2_2_2_2_2_0 word %%0_2_2_2_2_2_2_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_2_2_2_2_2_2_0 word %%0_2_2_2_2_2_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_3_2_2_3_2_0 word %%0_2_3_2_2_3_2_0 word %%0_2_3_2_2_3_2_0 word %%0_2_3_2_2_3_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_2_2_2_2_2_0 word %%0_2_2_2_2_2_2_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%2_3_3_3_3_3_3_2 word %%2_3_3_3_3_3_3_2 word %%2_3_2_2_2_2_3_2 word %%2_3_2_2_2_2_3_2 word %%2_3_2_0_0_2_3_2 word %%2_3_2_0_0_2_3_2 word %%2_3_2_0_0_2_3_2 word %%2_3_2_0_0_2_3_2 word %%2_3_2_2_2_2_3_2 word %%2_3_2_2_2_2_3_2 word %%2_3_3_3_3_3_3_2 word %%2_3_3_3_3_3_3_2 word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%2_3_3_3_3_3_3_2 word %%2_3_3_3_3_3_3_2 word %%2_3_2_2_2_2_3_2 word %%2_3_2_2_2_2_3_2 word %%2_3_2_0_0_2_3_2 word %%2_3_2_0_0_2_3_2 word %%2_3_2_0_0_2_3_2 word %%2_3_2_0_0_2_3_2 word %%2_3_2_2_2_2_3_2 word %%2_3_2_2_2_2_3_2 word %%2_3_3_3_3_3_3_2 word %%2_3_3_3_3_3_3_2 word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_2_2_2_2_2_2_3 word %%3_2_2_2_2_2_2_3 word %%3_2_0_0_0_0_2_3 word %%3_2_0_0_0_0_2_3 word %%3_2_0_2_2_0_2_3 word %%3_2_0_2_2_0_2_3 word %%3_2_0_2_2_0_2_3 word %%3_2_0_2_2_0_2_3 word %%3_2_0_0_0_0_2_3 word %%3_2_0_0_0_0_2_3 word %%3_2_2_2_2_2_2_3 word %%3_2_2_2_2_2_2_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_2_2_2_2_2_2_3 word %%3_2_2_2_2_2_2_3 word %%3_2_0_0_0_0_2_3 word %%3_2_0_0_0_0_2_3 word %%3_2_0_2_2_0_2_3 word %%3_2_0_2_2_0_2_3 word %%3_2_0_2_2_0_2_3 word %%3_2_0_2_2_0_2_3 word %%3_2_0_0_0_0_2_3 word %%3_2_0_0_0_0_2_3 word %%3_2_2_2_2_2_2_3 word %%3_2_2_2_2_2_2_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 ' -- diamonds diamonds word %%0_0_0_2_3_0_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_2_3_3_3_0_0 word %%0_0_1_3_3_2_0_0 word %%0_2_2_2_2_2_3_0 word %%0_1_1_1_1_1_2_0 word %%2_0_0_0_0_0_0_3 word %%1_0_0_0_0_0_0_2 word %%2_1_1_1_1_1_1_3 word %%1_2_2_2_2_2_2_2 word %%0_2_3_3_3_3_3_0 word %%0_1_3_3_3_3_2_0 word %%0_0_2_2_2_3_0_0 word %%0_0_1_1_1_2_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_0_1_1_0_0_0 word %%0_0_0_2_3_0_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_2_3_3_3_0_0 word %%0_0_1_2_2_2_0_0 word %%0_2_1_1_1_1_3_0 word %%0_1_0_0_0_0_2_0 word %%2_0_0_0_0_0_0_3 word %%1_1_1_1_1_1_1_2 word %%2_2_2_2_2_2_2_3 word %%1_3_3_3_3_3_3_2 word %%0_2_3_3_3_3_3_0 word %%0_1_2_2_2_2_2_0 word %%0_0_2_1_1_3_0_0 word %%0_0_1_0_0_2_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_0_1_1_0_0_0 word %%0_0_0_2_3_0_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_2_2_2_3_0_0 word %%0_0_1_1_1_2_0_0 word %%0_2_0_0_0_0_3_0 word %%0_1_0_0_0_0_2_0 word %%2_1_1_1_1_1_1_3 word %%1_2_2_2_2_2_2_2 word %%2_3_3_3_3_3_3_3 word %%1_3_3_3_3_3_3_2 word %%0_2_2_2_2_2_3_0 word %%0_1_1_1_1_1_2_0 word %%0_0_2_0_0_3_0_0 word %%0_0_1_0_0_2_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_0_1_1_0_0_0 word %%0_0_0_2_3_0_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_2_1_1_3_0_0 word %%0_0_1_0_0_2_0_0 word %%0_2_0_0_0_0_3_0 word %%0_1_1_1_1_1_2_0 word %%2_2_2_2_2_2_2_3 word %%1_3_3_3_3_3_3_2 word %%2_3_3_3_3_3_3_3 word %%1_2_2_2_2_2_2_2 word %%0_2_1_1_1_1_3_0 word %%0_1_0_0_0_0_2_0 word %%0_0_2_0_0_3_0_0 word %%0_0_1_1_1_2_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_0_1_1_0_0_0 word %%0_0_0_2_3_0_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_2_0_0_3_0_0 word %%0_0_1_0_0_2_0_0 word %%0_2_1_1_1_1_3_0 word %%0_1_2_2_2_2_2_0 word %%2_3_3_3_3_3_3_3 word %%1_3_3_3_3_3_3_2 word %%2_2_2_2_2_2_2_3 word %%1_1_1_1_1_1_1_2 word %%0_2_0_0_0_0_3_0 word %%0_1_0_0_0_0_2_0 word %%0_0_2_1_1_3_0_0 word %%0_0_1_2_2_2_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_0_1_1_0_0_0 word %%0_0_0_2_3_0_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_2_0_0_3_0_0 word %%0_0_1_1_1_2_0_0 word %%0_2_2_2_2_2_3_0 word %%0_1_3_3_3_3_2_0 word %%2_3_3_3_3_3_3_3 word %%1_2_2_2_2_2_2_2 word %%2_1_1_1_1_1_1_3 word %%1_0_0_0_0_0_0_2 word %%0_2_0_0_0_0_3_0 word %%0_1_1_1_1_1_2_0 word %%0_0_2_2_2_3_0_0 word %%0_0_1_3_3_2_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_0_1_1_0_0_0 word %%0_0_0_2_3_0_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_2_1_1_3_0_0 word %%0_0_1_2_2_2_0_0 word %%0_2_3_3_3_3_3_0 word %%0_1_3_3_3_3_2_0 word %%2_2_2_2_2_2_2_3 word %%1_1_1_1_1_1_1_2 word %%2_0_0_0_0_0_0_3 word %%1_0_0_0_0_0_0_2 word %%0_2_1_1_1_1_3_0 word %%0_1_2_2_2_2_2_0 word %%0_0_2_3_3_3_0_0 word %%0_0_1_3_3_2_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_0_1_1_0_0_0 word %%0_0_0_2_3_0_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_2_2_2_3_0_0 word %%0_0_1_3_3_2_0_0 word %%0_2_3_3_3_3_3_0 word %%0_1_2_2_2_2_2_0 word %%2_1_1_1_1_1_1_3 word %%1_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_3 word %%1_1_1_1_1_1_1_2 word %%0_2_2_2_2_2_3_0 word %%0_1_3_3_3_3_2_0 word %%0_0_2_3_3_3_0_0 word %%0_0_1_2_2_2_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_0_1_1_0_0_0 ' -- butterflies butterfly word %%3_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_1 word %%3_3_0_0_0_0_2_3 word %%3_2_0_0_0_0_1_3 word %%2_2_3_0_0_2_2_2 word %%1_1_2_0_0_1_1_1 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%1_1_1_3_2_1_1_1 word %%2_2_2_2_1_2_2_2 word %%3_3_3_0_0_2_3_3 word %%3_3_2_0_0_1_3_3 word %%2_3_0_0_0_0_2_2 word %%1_2_0_0_0_0_1_1 word %%2_0_0_0_0_0_0_1 word %%1_0_0_0_0_0_0_1 word %%3_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_1 word %%3_3_0_0_0_0_2_3 word %%3_2_0_0_0_0_1_3 word %%2_2_3_0_0_2_2_2 word %%1_1_2_0_0_1_1_1 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%1_1_1_3_2_1_1_1 word %%2_2_2_2_1_2_2_2 word %%3_3_3_0_0_2_3_3 word %%3_3_2_0_0_1_3_3 word %%2_3_0_0_0_0_2_2 word %%1_2_0_0_0_0_1_1 word %%2_0_0_0_0_0_0_1 word %%1_0_0_0_0_0_0_1 word %%0_3_0_0_0_0_2_0 word %%0_3_0_0_0_0_2_0 word %%0_2_0_0_0_0_1_0 word %%0_2_0_0_0_0_1_0 word %%0_2_3_0_0_2_2_0 word %%0_1_2_0_0_1_1_0 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%0_1_1_3_2_1_1_0 word %%0_2_2_2_1_2_2_0 word %%0_3_3_0_0_2_3_0 word %%0_3_2_0_0_1_3_0 word %%0_3_0_0_0_0_2_0 word %%0_2_0_0_0_0_1_0 word %%0_2_0_0_0_0_2_0 word %%0_1_0_0_0_0_1_0 word %%0_0_3_0_0_2_0_0 word %%0_0_2_0_0_1_0_0 word %%0_0_3_0_0_2_0_0 word %%0_0_2_0_0_1_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_3_0_0_2_0_0 word %%0_0_2_0_0_1_0_0 word %%0_0_3_0_0_2_0_0 word %%0_0_2_0_0_1_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_0_0_0_0_2_0 word %%0_3_0_0_0_0_2_0 word %%0_2_0_0_0_0_1_0 word %%0_2_0_0_0_0_1_0 word %%0_2_3_0_0_2_2_0 word %%0_1_2_0_0_1_1_0 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%0_1_1_3_2_1_1_0 word %%0_2_2_2_1_2_2_0 word %%0_3_3_0_0_2_3_0 word %%0_3_2_0_0_1_3_0 word %%0_3_0_0_0_0_2_0 word %%0_2_0_0_0_0_1_0 word %%0_2_0_0_0_0_2_0 word %%0_1_0_0_0_0_1_0 word %%3_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_1 word %%3_3_0_0_0_0_2_3 word %%3_2_0_0_0_0_1_3 word %%2_2_3_0_0_2_2_2 word %%1_1_2_0_0_1_1_1 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%1_1_1_3_2_1_1_1 word %%2_2_2_2_1_2_2_2 word %%3_3_3_0_0_2_3_3 word %%3_3_2_0_0_1_3_3 word %%2_3_0_0_0_0_2_2 word %%1_2_0_0_0_0_1_1 word %%2_0_0_0_0_0_0_1 word %%1_0_0_0_0_0_0_1 word %%3_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_1 word %%3_3_0_0_0_0_2_3 word %%3_2_0_0_0_0_1_3 word %%2_2_3_0_0_2_2_2 word %%1_1_2_0_0_1_1_1 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%1_1_1_3_2_1_1_1 word %%2_2_2_2_1_2_2_2 word %%3_3_3_0_0_2_3_3 word %%3_3_2_0_0_1_3_3 word %%2_3_0_0_0_0_2_2 word %%1_2_0_0_0_0_1_1 word %%2_0_0_0_0_0_0_1 word %%1_0_0_0_0_0_0_1 ' rockford ' walking left rockford_left word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_3_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_1_0 word %%0_1_0_0_0_0_0_3 word %%0_1_0_0_0_0_0_3 word %%3_3_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_3_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_1_0 word %%0_1_0_0_0_0_0_3 word %%0_1_0_0_0_0_0_3 word %%3_3_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_3_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_1_3 word %%0_0_1_0_0_0_0_3 word %%0_3_3_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_3_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_0_0_0 word %%0_0_1_0_1_1_1_0 word %%0_0_1_0_0_1_3_0 word %%0_3_3_0_0_0_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_3_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_1_1_0_0_0 word %%0_0_0_1_1_3_0_0 word %%0_0_3_3_0_3_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_3_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_1_1_1_0_0_0 word %%0_0_1_1_1_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_3_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_1_1_1_0_0_0 word %%0_0_1_1_1_0_0_0 word %%0_0_3_3_3_3_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_3_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_0_0_0 word %%0_0_1_0_1_1_1_0 word %%0_0_1_0_0_1_3_0 word %%0_3_3_0_0_0_3_0 ' walking right rockford_right word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_1_1_3_3_1_0_0 word %%3_0_0_0_0_0_1_0 word %%3_0_0_0_0_0_1_0 word %%0_0_0_0_0_0_3_3 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_1_1_3_3_1_0_0 word %%3_0_0_0_0_0_1_0 word %%3_0_0_0_0_0_1_0 word %%0_0_0_0_0_0_3_3 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%3_1_1_1_0_1_0_0 word %%3_0_0_0_0_1_0_0 word %%0_0_0_0_0_3_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_1_0_0 word %%0_1_1_1_0_1_0_0 word %%0_3_1_0_0_1_0_0 word %%0_3_0_0_0_3_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_1_1_0_0_0 word %%0_0_3_1_1_0_0_0 word %%0_0_3_0_3_3_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_1_1_1_0_0 word %%0_0_0_1_1_1_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_1_1_1_0_0 word %%0_0_0_1_1_1_0_0 word %%0_0_3_3_3_3_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_1_0_0 word %%0_1_1_1_0_1_0_0 word %%0_3_1_0_0_1_0_0 word %%0_3_0_0_0_3_3_0 ' blinking eyes / tapping foot rockford_bored word %%0_0_0_0_0_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_2_2_2_2_2_0 word %%0_2_0_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_3_3_0_2_0 word %%0_0_3_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_3_0_0_1_0_0 word %%0_0_0_0_0_3_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_2_2_2_2_2_0 word %%0_2_2_2_2_2_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_3_3_0_2_0 word %%0_0_3_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_3_0_0_1_0_0 word %%0_0_0_0_0_3_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_2_2_2_2_2_0 word %%0_2_2_2_2_2_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_3_3_0_2_0 word %%0_0_3_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_3_0_0_1_0_0 word %%0_0_0_0_0_3_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_2_2_2_2_2_0 word %%0_2_0_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_3_3_0_2_0 word %%0_0_3_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_3_0_0_1_0_0 word %%0_0_0_0_0_3_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_0_2_0 word %%0_2_0_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_3_3_0_2_0 word %%0_0_3_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_3_0_0_3_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_0_2_0 word %%0_2_0_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_3_3_0_2_0 word %%0_0_3_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_3_0_0_3_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_0_2_0 word %%0_2_0_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_3_3_0_2_0 word %%0_0_3_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_3_0_0_3_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_0_2_0 word %%0_2_0_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_3_3_0_2_0 word %%0_0_3_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_3_0_0_3_3_0 ' rockford, standing rockford word %%0_0_0_0_0_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_0_2_0 word %%0_2_0_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_3_3_0_2_0 word %%0_3_0_2_2_0_3_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_3_0_0_3_3_0 ' diamond frame word %%0_0_0_1_1_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_3_0_0_3_0_0 word %%0_1_0_0_0_0_1_0 word %%0_3_0_0_0_0_3_0 word %%1_0_0_0_0_0_0_1 word %%3_0_0_0_0_0_0_3 word %%1_0_0_0_0_0_0_2 word %%3_0_0_0_0_0_0_3 word %%0_1_0_0_0_0_2_0 word %%0_3_0_0_0_0_3_0 word %%0_0_1_0_0_2_0_0 word %%0_0_3_0_0_3_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_0_3_3_0_0_0 ' dummy word %%3_3_0_0_0_0_3_3 word %%0_3_3_3_3_3_3_0 word %%3_3_2_3_3_2_3_3 word %%3_3_2_3_3_2_3_3 word %%3_3_3_3_3_3_3_3 word %%0_3_3_0_0_3_3_0 word %%0_0_3_3_0_3_0_0 word %%0_0_2_2_2_2_0_0 word %%1_1_2_2_2_2_1_0 word %%1_0_2_2_2_2_0_1 word %%0_0_2_2_2_2_1_0 word %%0_3_3_3_3_3_3_0 word %%0_3_3_0_0_3_3_0 word %%0_3_0_0_0_0_3_0 word %%3_3_0_0_0_0_3_0 word %%0_0_0_0_0_0_3_3 ' wall wall word %%0_3_3_3_0_3_3_3 word %%0_2_3_3_0_2_3_3 word %%0_2_2_2_0_2_2_2 word %%0_0_0_0_0_0_0_0 word %%3_3_0_3_3_3_0_3 word %%3_3_0_2_3_3_0_2 word %%2_2_0_2_2_2_0_2 word %%0_0_0_0_0_0_0_0 word %%0_3_3_3_0_3_3_3 word %%0_2_3_3_0_2_3_3 word %%0_2_2_2_0_2_2_2 word %%0_0_0_0_0_0_0_0 word %%3_3_0_3_3_3_0_3 word %%3_3_0_2_3_3_0_2 word %%2_2_0_2_2_2_0_2 word %%0_0_0_0_0_0_0_0 ' door frame door_frame word %%2_2_2_2_2_2_2_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_2_2_2_2_2_2_2 ' magic wall magic_wall word %%3_3_3_3_3_3_3_3 word %%3_2_3_3_3_2_3_3 word %%3_2_2_2_3_2_2_2 word %%3_0_0_0_3_0_0_0 word %%3_3_0_3_3_3_0_3 word %%3_3_0_3_3_3_0_3 word %%2_2_0_3_2_2_0_3 word %%0_0_0_3_0_0_0_3 word %%3_3_3_3_3_3_3_3 word %%3_2_3_3_3_2_3_3 word %%3_2_2_2_3_2_2_2 word %%3_0_0_0_3_0_0_0 word %%3_3_0_3_3_3_0_3 word %%3_3_0_3_3_3_0_3 word %%2_2_0_3_2_2_0_3 word %%0_0_0_3_0_0_0_3 word %%0_3_3_3_0_3_3_3 word %%0_3_3_3_0_3_3_3 word %%0_3_2_2_0_3_2_2 word %%0_3_0_0_0_3_0_0 word %%3_3_3_3_3_3_3_3 word %%3_3_3_2_3_3_3_2 word %%2_2_3_2_2_2_3_2 word %%0_0_3_0_0_0_3_0 word %%0_3_3_3_0_3_3_3 word %%0_3_3_3_0_3_3_3 word %%0_3_2_2_0_3_2_2 word %%0_3_0_0_0_3_0_0 word %%3_3_3_3_3_3_3_3 word %%3_3_3_2_3_3_3_2 word %%2_2_3_2_2_2_3_2 word %%0_0_3_0_0_0_3_0 word %%0_3_3_3_0_3_3_3 word %%0_2_3_3_0_2_3_3 word %%0_2_3_2_0_2_3_2 word %%0_0_3_0_0_0_3_0 word %%3_3_0_3_3_3_0_3 word %%3_3_0_2_3_3_0_2 word %%2_3_0_2_2_3_0_2 word %%0_3_0_0_0_3_0_0 word %%0_3_3_3_0_3_3_3 word %%0_2_3_3_0_2_3_3 word %%0_2_3_2_0_2_3_2 word %%0_0_3_0_0_0_3_0 word %%3_3_0_3_3_3_0_3 word %%3_3_0_2_3_3_0_2 word %%2_3_0_2_2_3_0_2 word %%0_3_0_0_0_3_0_0 word %%0_3_3_3_0_3_3_3 word %%0_2_3_3_0_2_3_3 word %%0_2_2_3_0_2_2_3 word %%0_0_0_3_0_0_0_3 word %%3_3_0_3_3_3_0_3 word %%3_3_0_2_3_3_0_2 word %%3_2_0_2_3_2_0_2 word %%3_0_0_0_3_0_0_0 word %%0_3_3_3_0_3_3_3 word %%0_2_3_3_0_2_3_3 word %%0_2_2_3_0_2_2_3 word %%0_0_0_3_0_0_0_3 word %%3_3_0_3_3_3_0_3 word %%3_3_0_2_3_3_0_2 word %%3_2_0_2_3_2_0_2 word %%3_0_0_0_3_0_0_0 \ No newline at end of file diff --git a/zubehör/game boulderdash/sourcen/Bellatrix-Code/Sounds.spin b/zubehör/game boulderdash/sourcen/Bellatrix-Code/Sounds.spin new file mode 100644 index 0000000..9d8cdc3 --- /dev/null +++ b/zubehör/game boulderdash/sourcen/Bellatrix-Code/Sounds.spin @@ -0,0 +1,168 @@ +{ Hive-Soundobjekt für Boulderdash + +} + +'signaldefinitionen bellatrix + +#0, D0,D1,D2,D3,D4,D5,D6,D7 'datenbus +#8, BEL_VGABASE 'vga-signale (8pin) +#16, BEL_KEYBC,BEL_KEYBD 'keyboard-signale +#18, BEL_MOUSEC,BEL_MOUSED 'maus-signale +#20, BEL_VIDBASE 'video-signale(3pin) +#23, BEL_SELECT 'belatrix-auswahlsignal +#24, HBEAT 'front-led + BUSCLK 'bustakt + BUS_WR '/wr - schreibsignal + BUS_HS ' '/hs - quittungssignal + +var + +byte sndfx ' Kommando für Administra +byte fcCog ' Flag ob cCog gestartet +long cStack[32] ' Stack für cCog + + +pub Start: Pass + + Pass := (fcCog := cognew(cCog, @cStack)+1) > 0 + +pub cCog | cmd + + bus_init + repeat + repeat until sndfx > 0 'warte bis fx gesendet werden soll + bus_putchar(sndfx~) 'sndfx-Kommando senden + + +CON +' +' hbeat --------+ +' clk -------+| +' /wr ------+|| +' /hs -----+||| +------------------------- /cs +' |||| | -------- d0..d7 +DB_IN = %00001001_00000000_00000000_00000000 'maske: dbus-eingabe +DB_OUT = %00001001_00000000_00000000_11111111 'maske: dbus-ausgabe + +M1 = %00000010_00000000_00000000_00000000 +M2 = %00000010_10000000_00000000_00000000 'busclk=1? & /cs=0? + +M3 = %00000000_00000000_00000000_00000000 +M4 = %00000010_00000000_00000000_00000000 'busclk=0? + + +PUB bus_putchar(zeichen) 'BUS: Ein Byte über BUS ausgeben +{{ein byte über bus ausgeben Belltrix --> Regnatix}} + waitpeq(M1,M2,0) 'busclk=1? & prop2=0? + dira := db_out 'datenbus auf ausgabe stellen + outa[7..0] := zeichen 'daten ausgeben + outa[bus_hs] := 0 'daten gültig + waitpeq(M3,M4,0) 'busclk=0? + dira := db_in 'bus freigeben + outa[bus_hs] := 1 'daten ungültig + +PUB bus_getchar : zeichen 'BUS: Ein Byte über BUS empfangen +{{ein byte über bus empfangen Regnatix --> Bellatrix}} + waitpeq(M1,M2,0) 'busclk=1? & prop2=0? + zeichen := ina[7..0] 'daten einlesen + outa[bus_hs] := 0 'daten quittieren + outa[bus_hs] := 1 + waitpeq(M3,M4,0) 'busclk=0? + +PUB bus_init +{{initialisierung des bussystems}} + dira := db_in 'datenbus auf eingabe schalten + outa[bus_hs] := 1 'handshake inaktiv + + +dat 'soundadapter + +con + +_music_on = 1 +_music_off = 2 +_moving_sound1 = 3 +_moving_sound2 = 4 +_boulder_sound = 5 +_diamond_sound = 6 +_pick_sound = 7 +_explosion_sound = 8 +_crack_sound = 9 +_magic_wall_sound_on = 10 +_magic_wall_sound_off = 11 +_amoeba_sound_on = 12 +_amoeba_sound_off = 13 +_time_ending_sound = 14 +_bonus_point_sound = 15 +_cover_sound = 16 + +pub music_on + sndfx := _music_on + +pub music_off + sndfx := _music_off + +pub moving_sound(surface) + repeat until sndfx == 0 + if surface == $00 + sndfx := _moving_sound1 + else ' $01 + sndfx := _moving_sound2 + repeat until sndfx == 0 + +pub boulder_sound + sndfx := _boulder_sound + +pub diamond_sound + repeat until sndfx == 0 + sndfx := _diamond_sound + repeat until sndfx == 0 + +pub pick_sound + repeat until sndfx == 0 + sndfx := _pick_sound + repeat until sndfx == 0 + +pub explosion_sound + repeat until sndfx == 0 + sndfx := _explosion_sound + repeat until sndfx == 0 + +pub crack_sound + repeat until sndfx == 0 + sndfx := _crack_sound + repeat until sndfx == 0 + +pub magic_wall_sound_on + repeat until sndfx == 0 + sndfx := _magic_wall_sound_on + repeat until sndfx == 0 + +pub magic_wall_sound_off + repeat until sndfx == 0 + sndfx := _magic_wall_sound_off + repeat until sndfx == 0 + +pub amoeba_sound_on + repeat until sndfx == 0 + sndfx := _amoeba_sound_on + repeat until sndfx == 0 + +pub amoeba_sound_off + 'sndfx := _amoeba_sound_off + +pub time_ending_sound(sec_left) + repeat until sndfx == 0 + sndfx := _time_ending_sound + repeat until sndfx == 0 + +pub bonus_point_sound(pts) + repeat until sndfx == 0 + sndfx := _bonus_point_sound + repeat until sndfx == 0 + +pub cover_sound + sndfx := _cover_sound + + + \ No newline at end of file diff --git a/zubehör/game boulderdash/sourcen/Bellatrix-Code/Sounds_old.spin b/zubehör/game boulderdash/sourcen/Bellatrix-Code/Sounds_old.spin new file mode 100644 index 0000000..acd30a8 --- /dev/null +++ b/zubehör/game boulderdash/sourcen/Bellatrix-Code/Sounds_old.spin @@ -0,0 +1,358 @@ +var + + long vsync_addr + long random_addr + long stack[40] + + byte music + byte mute + byte amoeba + byte magic_wall + byte v1cnt, v1ctl + byte v2cnt, v2ctl + byte v3cnt, v3ctl + +obj + + sd : "SIDemu" + +pub start(video_params, pin, rnd_addr) + + vsync_addr := long[video_params + constant(6 * 4)] + random_addr := rnd_addr + + v1cnt := 0 + v2cnt := 0 + v3cnt := 0 + + mute := false + music := false + amoeba := false + magic_wall := false + + cognew(process, @stack) + + sd.start(pin) + + sd.set_register(23, $07) 'turn main volume half-up + +pub music_on + + v1cnt := 0 + v2cnt := 0 + v3cnt := 0 + + music_init + + music := true + +pub music_off + + sd.set_register(4, sd#CREG_TRIANGLE) 'gate off + sd.set_register(11, sd#CREG_TRIANGLE) 'gate off + + music := false + +pub moving_sound(surface) + + if mute + return + + if surface == $00 + sd.set_register(7, $00) 'freq + sd.set_register(8, $35) + else ' $01 + sd.set_register(7, $00) 'freq + sd.set_register(8, $A5) + sd.set_register(12, $30) 'attack/decay + sd.set_register(13, $C0) 'sustain/release + sd.set_register(11, sd#CREG_NOISE | sd#CREG_GATE) + + v2ctl := sd#CREG_NOISE + v2cnt := 2 + +pub boulder_sound + + if mute + return + + if v1cnt + return + + sd.set_register(0, $32) 'freq + sd.set_register(1, $09) + sd.set_register(5, $00) 'attack/decay + sd.set_register(6, $F9) 'sustain/release + sd.set_register(4, sd#CREG_NOISE | sd#CREG_GATE) + + v1ctl := sd#CREG_NOISE + v1cnt := 1 + +pub diamond_sound + + if mute + return + + if v1cnt + return + + sd.set_register(0, byte[random_addr]) 'freq + sd.set_register(1, $86 + byte[random_addr] & $07) + sd.set_register(5, $00) 'attack/decay + sd.set_register(6, $F0) 'sustain/release + sd.set_register(4, sd#CREG_TRIANGLE | sd#CREG_GATE) + + v1ctl := sd#CREG_TRIANGLE + v1cnt := 2 + +pub pick_sound + + if mute + return + + if v1cnt + return + + sd.set_register(0, $78) 'freq + sd.set_register(1, $14) + sd.set_register(5, $00) 'attack/decay + sd.set_register(6, $F9) 'sustain/release + sd.set_register(4, sd#CREG_TRIANGLE | sd#CREG_GATE) + + v1ctl := sd#CREG_TRIANGLE + v1cnt := 1 + +pub explosion_sound + + if mute + return + + if v1cnt + return + + sd.set_register(0, $32) 'freq + sd.set_register(1, $14) + sd.set_register(5, $19) '$1D 'attack/decay + sd.set_register(6, $00) 'sustain/release + sd.set_register(4, sd#CREG_NOISE | sd#CREG_GATE) + + v1ctl := sd#CREG_NOISE + v1cnt := 200 + +pub crack_sound + + if mute + return + + if v3cnt + return + + sd.set_register(19, $19) 'attack/decay + sd.set_register(20, $01) 'sustain/release + sd.set_register(14, $32) 'freq + sd.set_register(15, $2F) + sd.set_register(18, sd#CREG_NOISE | sd#CREG_GATE) + + v3ctl := sd#CREG_NOISE + v3cnt := 80 + +pub magic_wall_sound_on + + if not magic_wall + magic_wall := true + sd.set_register(18, sd#CREG_TRIANGLE) + +pub magic_wall_sound_off + + if magic_wall + magic_wall := false + v3ctl := sd#CREG_TRIANGLE + v3cnt := 1 + +pub amoeba_sound_on + + if not amoeba + amoeba := true + sd.set_register(18, sd#CREG_TRIANGLE) + +pub amoeba_sound_off + + if amoeba + amoeba := false + v3ctl := sd#CREG_TRIANGLE + v3cnt := 1 + +var + + byte last_val + +pub time_ending_sound(sec_left) + + mute := true + + if sec_left == last_val + return + + last_val := sec_left + + if sec_left == 0 + mute := false + + sd.set_register(4, sd#CREG_TRIANGLE) + waitcnt(clkfreq / 1000 + cnt) + + sd.set_register(0, $00) + sd.set_register(1, $27 - sec_left) + sd.set_register(5, $0A) 'attack/decay + sd.set_register(6, $00) 'sustain/release + sd.set_register(4, sd#CREG_TRIANGLE | sd#CREG_GATE) + + v1cnt := 0 + +pub bonus_point_sound(pts) | i + + sd.set_register(5, $00) 'attack/decay + sd.set_register(6, $A0) 'sustain/release + sd.set_register(4, sd#CREG_TRIANGLE | sd#CREG_GATE) + repeat i from 2 to 30 step 2 + sd.set_register(0, $00) + sd.set_register(1, $B0 - pts + i) + waitcnt(clkfreq / 500 + cnt) + sd.set_register(4, sd#CREG_TRIANGLE) + +pub cover_sound + + if v2cnt + return + + sd.set_register(12, $05) 'attack/decay + sd.set_register(13, $00) 'sustain/release + sd.set_register(7, $00) + sd.set_register(8, $64 + byte[random_addr] & $7F) 'freq + sd.set_register(11, sd#CREG_TRIANGLE | sd#CREG_GATE) + + v2ctl := sd#CREG_TRIANGLE + v2cnt := 1 + +pub process | r + + repeat + + 'wait for vsync + repeat while byte[vsync_addr] == 0 + repeat while byte[vsync_addr] <> 0 + + if music + play_note + + if v1cnt + if --v1cnt == 0 + sd.set_register(4, v1ctl) + + if v2cnt + if --v2cnt == 0 + sd.set_register(11, v2ctl) + + if v3cnt + if --v3cnt == 0 + sd.set_register(18, v3ctl) + + if amoeba + if mute + sd.set_register(18, sd#CREG_TRIANGLE) + else + sd.set_register(19, $00) 'attack/decay + sd.set_register(20, $40) 'sustain/release + repeat + r := byte[random_addr] & $1F + while r < $07 + sd.set_register(14, $00) 'freq + sd.set_register(15, r) + sd.set_register(18, sd#CREG_TRIANGLE | sd#CREG_GATE) + v3cnt := 2 + + elseif magic_wall + if mute + sd.set_register(18, sd#CREG_TRIANGLE) + else + sd.set_register(19, $00) 'attack/decay + sd.set_register(20, $A0) 'sustain/release + r := byte[random_addr] & $03 + sd.set_register(14, $00) 'freq + sd.set_register(15, $86 + (r << 3)) + sd.set_register(18, sd#CREG_TRIANGLE | sd#CREG_GATE) + v3cnt := 2 + +dat + +notes + byte $16, $22, $1D, $26, $22, $29, $25, $2E, $14, $24, $1F, $27, $20, $29, $27, $30 + byte $12, $2A, $12, $2C, $1E, $2E, $12, $31, $20, $2C, $33, $37, $21, $2D, $31, $35 + byte $16, $22, $16, $2E, $16, $1D, $16, $24, $14, $20, $14, $30, $14, $24, $14, $20 + byte $16, $22, $16, $2E, $16, $1D, $16, $24, $1E, $2A, $1E, $3A, $1E, $2E, $1E, $2A + byte $14, $20, $14, $2C, $14, $1B, $14, $22, $1C, $28, $1C, $38, $1C, $2C, $1C, $28 + byte $11, $1D, $29, $2D, $11, $1F, $29, $2E, $0F, $27, $0F, $27, $16, $33, $16, $27 + byte $16, $2E, $16, $2E, $16, $2E, $16, $2E, $22, $2E, $22, $2E, $16, $2E, $16, $2E + byte $14, $2E, $14, $2E, $14, $2E, $14, $2E, $20, $2E, $20, $2E, $14, $2E, $14, $2E + byte $16, $2E, $32, $2E, $16, $2E, $33, $2E, $22, $2E, $32, $2E, $16, $2E, $33, $2E + byte $14, $2E, $32, $2E, $14, $2E, $33, $2E, $20, $2C, $30, $2C, $14, $2C, $31, $2C + byte $16, $2E, $16, $3A, $16, $2E, $35, $38, $22, $2E, $22, $37, $16, $2E, $31, $35 + byte $14, $2C, $14, $38, $14, $2C, $14, $38, $20, $2C, $20, $33, $14, $2C, $14, $38 + byte $16, $2E, $32, $2E, $16, $2E, $33, $2E, $22, $2E, $32, $2E, $16, $2E, $33, $2E + byte $14, $2E, $32, $2E, $14, $2E, $33, $2E, $20, $2C, $30, $2C, $14, $2C, $31, $2C + byte $2E, $32, $29, $2E, $26, $29, $22, $26, $2C, $30, $27, $2C, $24, $27, $14, $20 + byte $35, $32, $32, $2E, $2E, $29, $29, $26, $27, $30, $24, $2C, $20, $27, $14, $20 + +freqs + word $02DC, $030A, $033A, $036C, $03A0, $03D2, $0412, $044C + word $0492, $04D6, $0520, $056E, $05B8, $0614, $0674, $06D8 + word $0740, $07A4, $0824, $0898, $0924, $09AC, $0A40, $0ADC + word $0B70, $0C28, $0CE8, $0DB0, $0E80, $0F48, $1048, $1130 + word $1248, $1358, $1480, $15B8, $16E0, $1850, $19D0, $1B60 + word $1D00, $1E90, $2090, $2260, $2490, $26B0, $2900, $2B70 + word $2DC0, $0100, $0200, $0101, $0105, $0100, $0101, $0306 + word $0101, $0102, $0101 + +var + + long note + byte v1sr + +pri music_init + + note := 0 + v1sr := $B0 + + sd.set_register(4, sd#CREG_TRIANGLE) + sd.set_register(5, $4F) + sd.set_register(6, $00) + + sd.set_register(11, sd#CREG_TRIANGLE) + sd.set_register(12, $24) '$78) + sd.set_register(13, $75) '$78) + +pub play_note | n, f + + if v1sr == $B0 + sd.set_register(4, sd#CREG_TRIANGLE) + sd.set_register(11, sd#CREG_TRIANGLE) + n := notes.byte[note++] + f := word[@freqs + 2*n - $14] + sd.set_register(0, f & $FF) + sd.set_register(1, f >> 8) + n := notes.byte[note++] + f := word[@freqs + 2*n - $14] + sd.set_register(7, f & $FF) + sd.set_register(8, f >> 8) + v1sr := $A0 + return + + if note == 256 + note := 0 + sd.set_register(6, v1sr | $01) + sd.set_register(4, sd#CREG_TRIANGLE | sd#CREG_GATE) + sd.set_register(11, sd#CREG_TRIANGLE | sd#CREG_GATE) + v1sr -= $10 + if v1sr < $40 + v1sr := $B0 + \ No newline at end of file diff --git a/zubehör/game boulderdash/sourcen/Bellatrix-Code/Status.spin b/zubehör/game boulderdash/sourcen/Bellatrix-Code/Status.spin new file mode 100644 index 0000000..dc6d536 --- /dev/null +++ b/zubehör/game boulderdash/sourcen/Bellatrix-Code/Status.spin @@ -0,0 +1 @@ +' This cog handles the status line. ' Also keeps the real-time counter con STATUS_NONE, STATUS_PRE, STATUS_GAME, STATUS_PAUSE, STATUS_OUT_OF_TIME, STATUS_GAME_OVER var long status_addr long stack[20] long vsync_addr long score byte ticks_per_sec byte tick_count byte time byte diamond_count byte diamond_value byte diamonds_needed byte player byte men byte cave byte level byte status_mode byte update byte status_temp[20*2] byte toggle byte decbuf[6] pub start(video_params) vsync_addr := long[video_params + constant(6 * 4)] status_addr := long[video_params + constant(5 * 4)] + constant(40 * 28 + 4 + 4) time := 0 status_mode := STATUS_NONE update := true toggle := 0 if long[video_params + constant(4 * 4)] == 0 ticks_per_sec := 60 'NTSC else ticks_per_sec := 50 'PAL cognew(process, @stack) pub player_params(p, m, c, l, s) player := p men := m cave := c level := l score := s pub cave_params(dn, dv, t) diamonds_needed := dn diamond_value := dv diamond_count := 0 time := t tick_count := ticks_per_sec pub set_time(t) tick_count := ticks_per_sec time := t update := true pub get_time return time pub set_mode(m) status_mode := m update := true pub set_score(s) score := s update := true pub set_diamond_value(dv) diamond_value := dv update := true pub set_diamond_count(n) diamond_count := n update := true pub process repeat 'wait for vsync repeat while byte[vsync_addr] == 0 repeat while byte[vsync_addr] <> 0 if update update := false if status_mode == STATUS_NONE long[status_addr] &= !1 else long[status_addr] |= 1 if toggle longmove(status_addr, @status_temp, 10) toggle := 0 if status_mode == STATUS_PRE bytefill(status_addr + constant(4 + 20), $06, 20) if cave > 16 text_out(status_addr + 4, @bonus_life, 20) else text_out(status_addr + 4, @pre, 20) byte[status_addr + constant(4 + 8)] := player + $80 byte[status_addr + constant(4 + 11)] := men + $80 byte[status_addr + constant(4 + 17)] := cave + $90 byte[status_addr + constant(4 + 19)] := level + $81 elseif status_mode == STATUS_GAME byte[status_addr + constant(4 + 0)] := $90 if diamond_count => diamonds_needed byte[status_addr + constant(4 + 1)] := $AC byte[status_addr + constant(4 + 2)] := $AC byte[status_addr + constant(4 + 21)] := $06 byte[status_addr + constant(4 + 22)] := $06 else convert_to_dec(diamonds_needed, 2) byte[status_addr + constant(4 + 1)] := decbuf[1] byte[status_addr + constant(4 + 2)] := decbuf[0] byte[status_addr + constant(4 + 21)] := $9D byte[status_addr + constant(4 + 22)] := $9D byte[status_addr + constant(4 + 3)] := $AC convert_to_dec(diamond_value, 2) byte[status_addr + constant(4 + 4)] := decbuf[1] byte[status_addr + constant(4 + 5)] := decbuf[0] byte[status_addr + constant(4 + 6)] := $90 convert_to_dec(diamond_count, 2) byte[status_addr + constant(4 + 7)] := decbuf[1] byte[status_addr + constant(4 + 8)] := decbuf[0] byte[status_addr + constant(4 + 9)] := $90 convert_to_dec(time, 3) byte[status_addr + constant(4 + 10)] := decbuf[2] byte[status_addr + constant(4 + 11)] := decbuf[1] byte[status_addr + constant(4 + 12)] := decbuf[0] byte[status_addr + constant(4 + 13)] := $90 convert_to_dec(score, 6) byte[status_addr + constant(4 + 14)] := decbuf[5] byte[status_addr + constant(4 + 15)] := decbuf[4] byte[status_addr + constant(4 + 16)] := decbuf[3] byte[status_addr + constant(4 + 17)] := decbuf[2] byte[status_addr + constant(4 + 18)] := decbuf[1] byte[status_addr + constant(4 + 19)] := decbuf[0] byte[status_addr + constant(4 + 27)] := $9D byte[status_addr + constant(4 + 28)] := $9D elseif status_mode == STATUS_GAME_OVER bytefill(status_addr + constant(4 + 20), $06, 20) text_out(status_addr + 4, @game_over, 20) if --tick_count == 0 tick_count := ticks_per_sec if status_mode == STATUS_GAME if time > 0 convert_to_dec(--time, 3) byte[status_addr + constant(4 + 10)] := decbuf[2] byte[status_addr + constant(4 + 11)] := decbuf[1] byte[status_addr + constant(4 + 12)] := decbuf[0] elseif status_mode == STATUS_PAUSE if toggle longmove(status_addr, @status_temp, 10) toggle := 0 else longmove(@status_temp, status_addr, 10) bytefill(status_addr + constant(4 + 20), $06, 20) text_out(status_addr + 4, @pause, 20) toggle := 1 elseif status_mode == STATUS_OUT_OF_TIME 'out of time if toggle longmove(status_addr, @status_temp, 10) toggle := 0 else longmove(@status_temp, status_addr, 10) bytefill(status_addr + constant(4 + 20), $06, 20) text_out(status_addr + 4, @out_of_time, 20) toggle := 1 pub convert_to_dec(val, len) | i repeat i from 0 to len-1 decbuf[i] := val // 10 + $80 val /= 10 pub text_out(addr, str, len) | i, c repeat i from 0 to len-1 c := byte[str + i] if c == $20 byte[addr + i] := $90 elseif c == $2C byte[addr + i] := $AF elseif c == $2F byte[addr + i] := $8C else byte[addr + i] := c + $50 dat pre byte " PLAYER , MEN / " out_of_time byte " OUT OF TIME " pause byte " SPACEBAR TO RESUME " bonus_life byte " B O N U S L I F E " game_over byte " G A M E O V E R " \ No newline at end of file diff --git a/zubehör/game boulderdash/sourcen/Bellatrix-Code/_README_.txt b/zubehör/game boulderdash/sourcen/Bellatrix-Code/_README_.txt new file mode 100644 index 0000000..91191d0 Binary files /dev/null and b/zubehör/game boulderdash/sourcen/Bellatrix-Code/_README_.txt differ diff --git a/zubehör/game boulderdash/sourcen/Regnatix-Code/bd.spin b/zubehör/game boulderdash/sourcen/Regnatix-Code/bd.spin new file mode 100644 index 0000000..b85a654 --- /dev/null +++ b/zubehör/game boulderdash/sourcen/Regnatix-Code/bd.spin @@ -0,0 +1,304 @@ +{{ --------------------------------------------------------------------------------------------------------- + +Hive-Computer-Projekt: Boulder Dash - Hive-Version + + http://hive-project.de + +Basierend auf dem Fanprojekt diverser Propellerköpfe: + + http://forums.parallax.com/forums/default.aspx?f=33&m=263404 + +Besonderer Dank an Pex "Mahoney" Tufvesson für die coole Musik!: + + http://mahoney.c64.org + http://www.livet.se/visa + + +Tasten: + +ESC Stop Button A +Space Pause Button B +LShift Start +LCTRL Select +Cursor + +Anpassungen für den Hive + +09-01-2010 - Entfernung der Hardwareerkennung + - Anpassung Konfiguration an Hive/Bellatrix + - Gamecontr. entfernt + - Auskommentierung Sound +12-01-2010 - Soundadapter optimiert + - Scrolltext im Titelbildschirm eingefügt +19-04-2010 - Anpassung an TriOS: Boulder läuft jetzt auch aus dem Verzeichnis. Bedingt durch das + neue, etwas trägere WAV-Soundsystem, habe ich einige Effekte durch HSS/SFX ersetzt. + +Zur Hive-Version: Das Game an sich - also der ursprüngliche Basiscode aus dem Parallax-Forum - läuft +auf einem einzigen Propellerchip! Was war zu tun um diese Version an den Hive anzupassen: + +1. Der Code kann im wesentlichen fast ausschließlich auf Bellatrix laufen. Dafür müssen die entsprechenden +Belegungen der IO-Pins für Video und Keyboard angepasst werden. +2. Da Bellatrix keinen Sound ausgeben kann, sondern diese Aufgabe im Hive Administra übernimmt, muß die +Soundausgabe angepasst werden. Im Originalcode übernimmt das Objekt "sound.spin" diese Aufgabe - welches +wieder den SIDemu in einer getrennten Cog startet. Hier zeigt sich die Stärke der SPIN-Objekte: Für die +Anpassung brauchte ich einfach nur ein neues Objekt gleicher Struktur definieren, ohne das Hauptprogramm +zu ändern. Dieses neue Soundobjekt startet ebenfalls eine Cog, welche einzig die Aufgabe hat die Kommunikation +zu Regnatix/Administra zu realisieren. +3. Regnatix-Code: Tja, die Königin kann bei der ganzen Sache Däumchen drehen, denn sie hat nur folgend Aufgaben +in einer einzigen Cog zu bewältigen: + - Bellatrix-Code laden + - SFX-Slots in Administra initialisieren + - Warten bis Bellatrix einen Ton von sich geben möchte und Übermittlung dieser + Tonesequenz an Administra + +Damit werden natürlich auf der einen Seite massig Ressourcen in Bellatrix gegenüber dem ursprünglichen Code frei +und es sind durch die Verwendung von HSS/SFX + Waveplayer + SDCard mehr Möglichkeiten gegeben. + +Bellatrix-Code : 20,5 KByte +Regnatix-Code : 3,2 KByte + +Bei diesen Werten ist zu beachten, dass der Regnatix das blanke IOS mit 2,6 KByte eingebunden hat - ohne Optimierung, +denn ein Großteil der IOS-Routinen sind in diesem Fall ungenutzt. + +Zeitaufwand : ca. 3 nette Abende ;) + +drohne235 + + --------------------------------------------------------------------------------------------------------- }} + + +OBJ + ios : "ios" +' debugx : "pterm" 'debug + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + +CON + +_music_on = 1 +_music_off = 2 +_moving_sound1 = 3 +_moving_sound2 = 4 +_boulder_sound = 5 +_diamond_sound = 6 +_pick_sound = 7 +_explosion_sound = 8 +_crack_sound = 9 +_magic_wall_sound_on = 10 +_magic_wall_sound_off = 11 +_amoeba_sound_on = 12 +_amoeba_sound_off = 13 +_time_ending_sound = 14 +_bonus_point_sound = 15 +_cover_sound = 16 + +VAR + +byte parastr[64] +byte fl_musicon + +PUB main | a,b,c,i,n,stradr + +'initialisierung + ios.start 'ios initialisieren +' ios.startram 'code für test im ram, sollte bei bin-datei auskommentiert werden + +' debugx.start(115200) + + ios.admsetsyssnd(0) 'systemsounds abschalten + ios.sddmact(ios#DM_USER) 'wieder in userverzeichnis wechseln + ios.print(string("Boulder Dash - Loading...")) + +'bellatrix-code laden + ios.parastart + parastr[0] := 0 + ios.paranext(@parastr) + + case parastr[0] + "n": + ios.belload(@beln) 'grafiktreiber ntsc laden + other: + ios.belload(@belp) 'grafiktreiber pal laden + + ios.sddmact(ios#DM_USER) '??? + +'sfx-slots setzen + ios.sfx_setslot(@fx_moving_sound1, 0) + ios.sfx_setslot(@fx_moving_sound2, 1) + ios.sfx_setslot(@fx_boulder_sound,2) + ios.sfx_setslot(@fx_diamond_sound,3) + ios.sfx_setslot(@fx_pick_sound,4) + ios.sfx_setslot(@fx_amoeba_sound,5) + ios.sfx_setslot(@fx_time_sound,6) + ios.sfx_setslot(@fx_cover_sound,7) + ios.sfx_setslot(@fx_bonus,8) + ios.sfx_setslot(@fx_crack,9) + ios.sfx_setslot(@fx_explosion,10) + ios.sfx_setslot(@fx_wall,11) + + +'soundadapter + repeat + case ios.bus_getchar2 + + _music_on: 'titelmusik + ios.admsetsound(ios#SND_HSSOFF) 'hss ausschalten + ios.admsetsound(ios#SND_WAVON) 'wav einschalten + n := ios.wav_play(@wav1) + fl_musicon := 1 + + _music_off: + if fl_musicon + ios.wav_stop + ios.admsetsound(ios#SND_WAVOFF) 'wav ausschalten + ios.admsetsound(ios#SND_HSSON) 'hss anschalten + fl_musicon := 0 + + _moving_sound1: + ios.sfx_fire(0,1) + + _moving_sound2: + ios.sfx_fire(1,1) + + _boulder_sound: + ios.sfx_fire(2,1) + waitcnt(clkfreq / 30 + cnt) + + _diamond_sound: + b? + b := b & $FF + byte[@fx_diamond_sound+2] := b + ios.sfx_setslot(@fx_diamond_sound,3) + ios.sfx_fire(3,1) + waitcnt(clkfreq / 30 + cnt) + + _pick_sound: + ios.sfx_fire(4,2) + waitcnt(clkfreq / 3 + cnt) + + _explosion_sound: 'explosion + ios.sfx_fire(10,1) + waitcnt(clkfreq * 3 + cnt) + + _crack_sound: 'eingang + ios.sfx_fire(9,1) + waitcnt(clkfreq / 3 + cnt) + + _magic_wall_sound_on: + ios.sfx_fire(11,2) + + _magic_wall_sound_off: + + _amoeba_sound_on: + ios.sfx_fire(5,2) + + _amoeba_sound_off: + + _time_ending_sound: + ios.sfx_fire(6,2) + + _bonus_point_sound: 'bonus + ios.sfx_fire(8,2) + waitcnt(clkfreq * 4 + cnt) + + _cover_sound: + b? + b := b & $FF + byte[@fx_cover_sound+2] := b + ios.sfx_setslot(@fx_cover_sound,7) + ios.sfx_fire(7,1) + waitcnt(clkfreq / 30 + cnt) + + + +DAT + +wav1 byte "bd.wav",0 ' titelmusik + +beln byte "bd_ntsc.bel",0 ' bella-code, ntsc-version +belp byte "bd_pal.bel",0 + + 'basisschwingung modulation hüllkurve + 'Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel +fx_moving_sound1 byte $06, $02, $01, $08, $00, $00, $00, $00, $FF, $00, $00, $D0 +fx_moving_sound2 byte $06, $02, $01, $0F, $00, $00, $00, $00, $FF, $00, $00, $D0 +fx_boulder_sound byte $06, $01, $FF, $0F, $01, $03, $01, $00, $FF, $00, $00, $80 +fx_diamond_sound byte $01, $01, $E0, $0F, $00, $00, $00, $00, $FF, $00, $00, $80 +fx_pick_sound byte $01, $01, $E0, $0F, $00, $00, $00, $00, $FF, $00, $00, $80 +fx_explosion_sound byte $01, $01, $E0, $0F, $00, $00, $00, $00, $FF, $00, $00, $80 +fx_crack_sound byte $06, $02, $10, $0F, $00, $00, $00, $00, $FF, $00, $00, $D0 +fx_magic_sound byte $01, $01, $80, $0F, $00, $00, $00, $00, $FF, $00, $00, $80 +fx_amoeba_sound byte $01, $01, $80, $0F, $00, $00, $00, $00, $FF, $00, $00, $80 +fx_time_sound byte $02, $05, $FF, $0F, $10, $00, $01, $00, $FF, $00, $00, $40 +fx_bonus_sound byte $01, $01, $80, $0F, $00, $00, $00, $00, $FF, $00, $00, $80 +fx_cover_sound byte $01, $01, $80, $0F, $00, $00, $00, $00, $FF, $00, $00, $80 + +fx_bonus +' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel +byte $03,$03,$FF,$0F,$02,$00,$05,$00,$FF,$01,$50,$11 +byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 + +fx_crack +' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel +byte $01,$22,$01,$0F,$11,$00,$05,$00,$55,$01,$50,$11 +byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 + +fx_explosion +' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel +byte $06,$04,$10,$0F,$00,$00,$00,$00,$FF,$01,$50,$11 +byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 + +fx_wall +' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel +byte $04,$FF,$FF,$0F,$01,$00,$01,$00,$FF,$06,$20,$00 +byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 + + +DAT +{ + +sfx-struktur: + +wav len freq vol grundschwingung +lfo lfw fma ama modulation +att dec sus rel hüllkurve +seq (optional) + +wav wellenform + 0 sinus (0..500hz) + 1 schneller sinus (0..1khz) + 2 dreieck (0..500hz) + 3 rechteck (0..1khz) + 4 schnelles rechteck (0..4khz) + 5 impulse (0..1,333hz) + 6 rauschen +len tonlänge $0..$fe, $ff endlos +freq frequenz $00..$ff +vol lautstärke $00..$0f + +lfo low frequency oscillator $ff..$01 +lfw low frequency waveform + $00 sinus (0..8hz) + $01 fast sine (0..16hz) + $02 ramp up (0..8hz) + $03 ramp down (0..8hz) + $04 square (0..32hz) + $05 random + $ff sequencer data +fma frequency modulation amount + $00 no modulation + $01..$ff +ama amplitude modulation amount + $00 no modulation + $01..$ff +att attack $00..$ff +dec decay $00..$ff +sus sustain $00..$ff +rel release $00..$ff + + + +} \ No newline at end of file diff --git a/zubehör/game boulderdash/sourcen/Regnatix-Code/ios.spin b/zubehör/game boulderdash/sourcen/Regnatix-Code/ios.spin new file mode 100644 index 0000000..68781f5 Binary files /dev/null and b/zubehör/game boulderdash/sourcen/Regnatix-Code/ios.spin differ diff --git a/zubehör/game boulderdash/sourcen/Regnatix-Code/pterm.spin b/zubehör/game boulderdash/sourcen/Regnatix-Code/pterm.spin new file mode 100644 index 0000000..a525a4b Binary files /dev/null and b/zubehör/game boulderdash/sourcen/Regnatix-Code/pterm.spin differ diff --git a/zubehör/shoot/bellatrix-code/Graphics.spin b/zubehör/shoot/bellatrix-code/Graphics.spin new file mode 100644 index 0000000..dbe7e03 Binary files /dev/null and b/zubehör/shoot/bellatrix-code/Graphics.spin differ diff --git a/zubehör/shoot/bellatrix-code/Mouse.spin b/zubehör/shoot/bellatrix-code/Mouse.spin new file mode 100644 index 0000000..c37ad5c Binary files /dev/null and b/zubehör/shoot/bellatrix-code/Mouse.spin differ diff --git a/zubehör/shoot/bellatrix-code/TV.spin b/zubehör/shoot/bellatrix-code/TV.spin new file mode 100644 index 0000000..b58adcf Binary files /dev/null and b/zubehör/shoot/bellatrix-code/TV.spin differ diff --git a/zubehör/shoot/bellatrix-code/_readme_.txt b/zubehör/shoot/bellatrix-code/_readme_.txt new file mode 100644 index 0000000..39520ed --- /dev/null +++ b/zubehör/shoot/bellatrix-code/_readme_.txt @@ -0,0 +1,23 @@ +BST Propeller Archive +Created by Brads Spin Tool Compiler v0.15.4-pre5 - Copyright 2008,2009,2010 All rights reserved +Compiled for i386 Win32 at 14:24:31 on 2010/03/10 + +Archive Created at 15:34:27 On 01/05/10 +Included Objects : +shoot1 + | + +--tv + | + +--graphics + | + +--mouse + | + +--yma_hss_v1.2 + +, + - shoot1.spin + - TV.spin + - Graphics.spin + - Mouse.spin + - yma_hss_v1.2.spin +, diff --git a/zubehör/shoot/bellatrix-code/shoot-bel.spin b/zubehör/shoot/bellatrix-code/shoot-bel.spin new file mode 100644 index 0000000..6ddca2c Binary files /dev/null and b/zubehör/shoot/bellatrix-code/shoot-bel.spin differ diff --git a/zubehör/shoot/bellatrix-code/yma_hss_hive.spin b/zubehör/shoot/bellatrix-code/yma_hss_hive.spin new file mode 100644 index 0000000..fd9f4e0 Binary files /dev/null and b/zubehör/shoot/bellatrix-code/yma_hss_hive.spin differ diff --git a/zubehör/shoot/bellatrix-code/yma_hss_v1.2.spin b/zubehör/shoot/bellatrix-code/yma_hss_v1.2.spin new file mode 100644 index 0000000..f72ae4b --- /dev/null +++ b/zubehör/shoot/bellatrix-code/yma_hss_v1.2.spin @@ -0,0 +1,694 @@ +''***************************** +''* Hydra Sound System v1.2 * +''* (C)2007 Andrew Arsenault * +''***************************** +''http://www.andrewarsenault.com/hss/ +''e-mail: ym2413a@yahoo.com +'' +'' Cogs used: 2 +'' HUB-RAM: ~2.7k + +'' Please visit the website for the latest version, documentation, examples and media files. +'' Thank you! --Ym2413a + +VAR + +'Sound Engine Stack + long hsnd_stack[18] + long cog1, cog2 + +'WavSynth Parameters + long snd_regs[48] 'Regs for Sound Hardware (8x6)+5dpcm + long dpcm_regs[5] + +'DPCM Command Variables + word dpcmreg_ptr + +'Global Hmus Player Vars + word tempo + word song_pc + word song_div + word song_ptr + word chfre[4] + byte chfx[4] + byte chvol[4] + byte hmus_state + byte hmvol + byte fxphs + +'Sound FX Variables + word runlen[2] + word envamp[2] + word sfx_ptr[2] + byte envphs[2] + byte fmcnt[2], fmfreq[2] + byte loadsfx[2] + +CON + +'' Hss Master Control + +PUB start : okay + + stop + okay := cog1 := cognew(@entry, @snd_regs) + 1 + okay := cog2 := cognew(hsound, @hsnd_stack) + 1 + +PUB stop + + if cog1 + cogstop(cog1~ - 1) + if cog2 + cogstop(cog2~ - 1) + +PUB peek(addrptr) : var1 + + var1 := LONG[@snd_regs][addrptr] + +CON + +'' Hydra Music Commands + +PUB hmus_load(songptr) | z + + hmvol := 15 + song_div := 0 + song_ptr := songptr + song_pc := WORD[songptr][8] + tempo := WORD[songptr][12] + repeat z from 0 to 3 + chfx[z] := 0 + +PUB hmus_play + + hmus_state := 1 + +PUB hmus_stop | z + + hmus_state := 0 + repeat z from 0 to 3 + chvol[z] := 0 + +PUB hmus_pause + + hmus_state := 0 + +PUB hmus_tempo(var1) + + tempo := var1 + +PUB get_hmus_tempo : var1 + + var1 := tempo + +PUB hmus_vol(var1) + + hmvol := var1 <# 15 #> 0 + +PUB get_hmus_vol : var1 + + var1 := hmvol + +CON + +'' FXsynth Commands + +PUB sfx_play(chan, soundptr) + + if(chan == 1) + sfx_ptr[0] := soundptr + loadsfx[0] := 0 + if(chan == 2) + sfx_ptr[1] := soundptr + loadsfx[1] := 0 + +PUB sfx_stop(chan) + + if(chan == 1) + sfx_ptr[0] := 0 + if(chan == 2) + sfx_ptr[1] := 0 + +PUB sfx_keyoff(chan) + + if(chan == 1) + envphs[0] := 3 + if(chan == 2) + envphs[1] := 3 + +CON + +'' Hydra DPCM Commands + +PUB dpcm_play(soundptr) + + dpcmreg_ptr := soundptr + +PUB dpcm_stop + + dpcmreg_ptr := 1 + +CON +''***************************** +''* Hss Sound Engine * +''***************************** +PRI Hsound +repeat + 'Update Music Engine + UpdateMus(song_ptr, Hmus_state) 'Update Music Player + VolumeInterpol 'Delay and Interpolate Volume to Remove Pops and Clicks. + + 'Update DPCM Engine + if(dpcmreg_ptr) + DpcmUpdate 'Update the DPCM registers + + 'Update SoundFX Engine + + 'FX channel A + FXSynth(0,32) + 'FX channel B + FXSynth(1, 40) + +PRI VolumeInterpol | z, channelmul, musvar, freqval + + fxphs += 5 + +'Volume Interpolation + repeat z from 0 to 3 step 1 + channelmul := 4+(8*z) + musvar := (chvol[z]*(hmvol+1))&$F0 + snd_regs[channelmul] := (snd_regs[channelmul] & 15)+musvar + + 'Freq Interpolation + channelmul -= 1 'Jump down a REG to Freq + musvar := chfre[z]<<16 + + if(chfx[z] == 0) 'None + snd_regs[channelmul] := musvar + + elseif(chfx[z] < 3) 'Vibrato (light/hard) + if(fxphs < 128) + snd_regs[channelmul] := musvar+(chfre[z]<<(7+chfx[z])) + else + snd_regs[channelmul] := musvar-(chfre[z]<<(7+chfx[z])) + + elseif(chfx[z] == 3) 'Tremolo + if(fxphs < 128) + snd_regs[channelmul] := musvar + else + snd_regs[channelmul] := musvar<<1 + + else 'Portamento + freqval := snd_regs[channelmul]>>16 + if(freqval & $F000 == chfre[z] & $F000) + snd_regs[channelmul] := musvar + elseif(freqval < chfre[z]) + snd_regs[channelmul] := snd_regs[channelmul]+(chfx[z]<<22) + else + snd_regs[channelmul] := snd_regs[channelmul]-(chfx[z]<<22) + +PRI UpdateMus(songptr, state) | channel, channelmul, scrdat, freq, freqoct, flag + + if(state == 0) + return ''Song is not playing. + + song_div++ + + if(song_div => tempo) 'Tempo Divider + song_div := 0 + flag := 0 + + repeat 'Score Decoder and Processor + scrdat := BYTE[song_ptr][song_pc] + channel := scrdat & 3 + channelmul := channel<<3 + song_pc++ + + ''Base Commands + if(scrdat == 0) 'End Row + quit + + if(scrdat == 1) 'Repeat Song + song_pc := WORD[songptr][9] + quit + + if(scrdat == 2) 'End Song + hmus_stop + quit + + if(scrdat == 3) 'Set Flag + flag := 1 + next + + if((scrdat & $3C) == $20) 'Patch HI Note + flag := 2 + scrdat := scrdat>>3 + scrdat += 64+channel + + if(scrdat & 4) 'Change Note + freq := scrdat>>3 + freqoct := freq/12 + freq -= freqoct*12 + case flag + 1 : freqoct += 2 + 2 : freqoct += 6 + other : freqoct += 4 + flag := 0 + snd_regs[4+channelmul] := snd_regs[4+channelmul] & $FE + chfre[channel] := NoteFreqs[freq]>>(6-freqoct) + snd_regs[4+channelmul] := (snd_regs[4+channelmul] & $FE)+1 + next 'Repeat To Next Datum + + if(scrdat & 8) 'Change Evelope / Channel Effect + if(flag) + chfx[channel] := scrdat>>4 + flag := 0 + else + chvol[channel] := scrdat>>4 + next 'Repeat To Next Datum + + if(scrdat & 16) 'Change Instrument + freq := (scrdat & $E0)>>3 + freq += flag<<5 + flag := 0 + snd_regs[0+channelmul] := songptr+WORD[songptr+32][freq] + snd_regs[1+channelmul] := WORD[songptr+32][freq+1] + snd_regs[2+channelmul] := WORD[songptr+32][freq+2] + snd_regs[4+channelmul] := WORD[songptr+32][freq+3] & $0F + next 'Repeat To Next Datum + + if(scrdat & 64) 'Detune + chfre[channel] := chfre[channel]+(chfre[channel]>>8) + + + +PRI DpcmUpdate + + if(dpcmreg_ptr > 15) 'Play Sample. + dpcm_regs[2] := 65535 'End sample if one was playing + dpcm_regs[0] := dpcmreg_ptr+8 + dpcm_regs[4] := 128 + dpcm_regs[3] := LONG[dpcmreg_ptr][1] 'Get sampling rate + dpcm_regs[1] := WORD[dpcmreg_ptr][1] 'Get length + dpcm_regs[2] := 0 'Reset play counter + elseif(dpcmreg_ptr == 1) 'Stop Sample + dpcm_regs[2] := 65535 'End sample + dpcm_regs[4] := 128 + + dpcmreg_ptr := 0 + +PRI FXSynth(SoundVars, ChannelFX) | TimeCnt, SoundFX, Modwav, FMwav, AMwav + TimeCnt := Cnt + SoundFX := sfx_ptr[SoundVars] + + if(loadsfx[SoundVars] == 0) + 'Setup OSC WaveForm + case BYTE[SoundFX][0] + $00: 'Sine + snd_regs[ChannelFX] := @SineTable + snd_regs[1+ChannelFX] := 64 + $01: 'Fast Sine + snd_regs[ChannelFX] := @FastSine + snd_regs[1+ChannelFX] := 32 + $02: 'Sawtooth + snd_regs[ChannelFX] := @Sawtooth + snd_regs[1+ChannelFX] := 64 + $03: 'Square + snd_regs[ChannelFX] := @SqrTable + snd_regs[1+ChannelFX] := 32 + $04: 'Fast Square + snd_regs[ChannelFX] := @FastSqr + snd_regs[1+ChannelFX] := 8 + $05: 'Buzz + snd_regs[ChannelFX] := @NoteFreqs + snd_regs[1+ChannelFX] := 24 + $06: 'Noise + snd_regs[ChannelFX] := $F002 + snd_regs[1+ChannelFX] := 3000 + + snd_regs[2+ChannelFX] := 0 + snd_regs[4+ChannelFX] := $01 + + loadsfx[SoundVars] := 1 + runlen[SoundVars] := 0 + fmcnt[SoundVars] := 0 + fmfreq[SoundVars] := 0 + envamp[SoundVars] := 0 + envphs[SoundVars] := 0 + +''Modulation Code + fmfreq[SoundVars]++ + if(fmfreq[SoundVars] => BYTE[SoundFX][4]) + fmfreq[SoundVars] := 0 + fmcnt[SoundVars]++ + fmcnt[SoundVars] := fmcnt[SoundVars] & $3F + + case BYTE[SoundFX][5] + $00: + Modwav := BYTE[@SineTable][fmcnt[SoundVars]] + $01: + Modwav := BYTE[@FastSine][fmcnt[SoundVars] & 31] + $02: + Modwav := fmcnt[SoundVars]<<2 + $03: + Modwav := !fmcnt[SoundVars]<<2 + $04: + if(fmcnt[SoundVars] & 8) + Modwav := $ff + else + Modwav := $00 + $05: + Modwav := BYTE[$F002][fmcnt[SoundVars]] + $FF: + Modwav := BYTE[SoundFX+12][fmcnt[SoundVars] & 15] + + fmwav := Modwav/(BYTE[SoundFX][6]) 'FM amount + amwav := 256-(Modwav/(BYTE[SoundFX][7])) 'AM amount + amwav := (BYTE[SoundFX][3]*amwav)>>8 + +''Envelope Generator + if(envphs[SoundVars] == 0) 'Attack + envamp[SoundVars] += BYTE[SoundFX][8] + if(envamp[SoundVars] > 8191) + envamp[SoundVars] := 8191 + envphs[SoundVars] := 1 + if(BYTE[SoundFX][8] == $ff) + envamp[SoundVars] := 8191 + if(envphs[SoundVars] == 1) 'Decay + envamp[SoundVars] -= BYTE[SoundFX][9] + if(envamp[SoundVars] & $8000) + envphs[SoundVars] := 2 + if(envamp[SoundVars] =< (BYTE[SoundFX][10]<<5)) + envphs[SoundVars] := 2 + if(envphs[SoundVars] == 2) 'Sustain + envamp[SoundVars] := (BYTE[SoundFX][10]<<5) + if(envphs[SoundVars] == 3) 'Release + envamp[SoundVars] -= BYTE[SoundFX][11] + if(envamp[SoundVars] & $8000) + envamp[SoundVars] := 4 + + amwav := ((envamp[SoundVars]>>9)*(amwav+1))>>4 + +''Run Length and Outputing + if(SoundFX > 15) + runlen[SoundVars]++ + snd_regs[3+ChannelFX] := (BYTE[SoundFX][2]+fmwav)<<24 'Update Frequency + snd_regs[4+ChannelFX] := (amwav<<4)+(snd_regs[4+ChannelFX] & $0F) 'Update Amplitude + else + snd_regs[4+ChannelFX] := $00 'Mute + + if(BYTE[SoundFX][1] == $ff) '$ff = never stop + runlen[SoundVars] := 0 + + if(runlen[SoundVars] > (BYTE[SoundFX][1]<<5)) 'Duration KeyOff + envphs[SoundVars] := 3 + +WaitCnt(TimeCnt + 52_000) ''Delay for Synth Engine Update. + +DAT + +SineTable byte $80, $8c, $98, $a5, $b0, $bc, $c6, $d0 + byte $da, $e2, $ea, $f0, $f5, $fa, $fd, $fe + byte $ff, $fe, $fd, $fa, $f5, $f0, $ea, $e2 + byte $da, $d0, $c6, $bc, $b0, $a5, $98, $8c + byte $80, $73, $67, $5a, $4f, $43, $39, $2f + byte $25, $1d, $15, $0f, $0a, $05, $02, $01 + byte $00, $01, $02, $05, $0a, $0f, $15, $1d + byte $25, $2f, $39, $43, $4f, $5a, $67, $73 + +Sawtooth byte $ff, $fb, $f7, $f3, $ef, $eb, $e7, $e3 + byte $df, $db, $d7, $d3, $cf, $cb, $c7, $c3 + byte $bf, $bb, $b7, $b3, $af, $ab, $a7, $a3 + byte $9f, $9b, $97, $93, $8f, $8b, $87, $83 + byte $80, $7c, $78, $74, $70, $6c, $68, $64 + byte $60, $5c, $58, $54, $50, $4c, $48, $44 + byte $40, $3c, $38, $34, $30, $2c, $28, $24 + byte $20, $1c, $18, $14, $10, $0c, $08, $04 + +FastSine byte $80, $98, $b0, $c6, $da, $ea, $f5, $fd + byte $ff, $fd, $f5, $ea, $da, $c6, $b0, $98 + byte $80, $67, $4f, $39, $25, $15, $0a, $02 + byte $00, $02, $0a, $15, $25, $39, $4f, $67 + +SqrTable byte $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff + byte $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff + byte $00, $00, $00, $00, $00, $00, $00, $00 + byte $00, $00, $00, $00, $00, $00, $00, $00 + +FastSqr byte $ff, $ff, $ff, $ff, $00, $00, $00, $00 + +'Note LookupTable. +NoteFreqs word $85F3, $8DEA, $965B, $9F4B, $A8C4, $B2CD, $BD6F, $C8B3, $D4A2, $E147, $EEAC, $FCDE 'Top Octave Lookup + +CON +''***************************** +''* WaveTable Synth v1.2 * +''* DPCM Synth v1.1 * +''* (C)2006 Andrew Arsenault * +''***************************** +DAT + org +entry mov dira,Port_Pins 'Setup output pins + + mov ctra,Right_ctra 'Setup Right Audio Channel + mov ctrb,Left_ctra 'Setup Left Audio Channel + + mov ChlA_wave,#256 'Set channel signals. + mov ChlA_offset,#0 'Set channel's offset. + mov ChlA_counter,#0 + + mov Time,#10 + add Time,cnt 'Prepare for asm type WAITCNT loop. + +'MAIN LOOP +update waitcnt Time,Timing_delay 'Wait for CNT = D, then add S into D + + 'Transfer Sound Registers + mov addrregs,par + mov y,NumberOfChannels + + 'Fetch Channel's Registers +transferchl rdlong ChlAp_sampptr,addrregs + add addrregs,#4 + rdlong ChlAp_sampend,addrregs + add addrregs,#4 + rdlong Ch1Ap_samplpp,addrregs + add addrregs,#4 + rdlong Ch1Ap_freq,addrregs + add addrregs,#4 + rdlong ChlAp_keyon,addrregs + + 'Fetch Channel's Static Variables + add addrregs,#8 + rdlong ChlA_offset,addrregs + add addrregs,#4 + rdlong ChlA_counter,addrregs + + 'Run Synth Engine on Channel + call #wvsynth + + 'Store Channel's Static Variables (Tucked Center X move to Wave) + wrlong ChlA_counter,addrregs + sub addrregs,#4 + sub x,#256 + wrlong ChlA_offset,addrregs + sub addrregs,#4 + mov ChlA_wave,x 'Doesn't Waste anything doing this. + wrlong ChlA_wave,addrregs + add addrregs,#12 + + 'Loop Until All Channel's Are Done. + djnz y,#transferchl + + 'Run DPCM Engine + call #dpcm + + 'Mix Channels Together + mov addrregs,par + mov ChlA_wave,#0 + add addrregs,#5*4 + mov y,NumberOfChannels + +mixchls rdlong x,addrregs + add ChlA_wave,x + add addrregs,#8*4 + djnz y,#mixchls + + mov x,DPCM_wave 'Add DPCM + shl x,#2 + add ChlA_wave,x + + shl ChlA_wave,#20 'Convert 12bit singal into a 32bit one. + + 'Update output Channels then repeat again. + mov frqa,ChlA_wave + mov frqb,ChlA_wave + + jmp #update + + + + +'-------------------------Dpcm Engine-------------------------' + +dpcm mov addrregs,par + add addrregs,#192 + + rdlong DPCM_address,addrregs 'Start Address + add addrregs,#4 + rdlong DPCM_runlen,addrregs 'File Lenght + add addrregs,#4 + rdlong DPCM_offset,addrregs 'File Offset + add addrregs,#4 + rdlong DPCM_freq,addrregs 'Playback Speed + add addrregs,#4 + rdlong DPCM_wave,addrregs 'Waveform Amp + + 'Check for if keyon/length is set. + cmp DPCM_offset,DPCM_runlen wc + if_ae jmp #mute_dpcm 'End of file + + 'Freq Timer/Divider and Increase sampling offset + add DPCM_counter,DPCM_freq wc + if_nc jmp #done_dpcm + + 'Decode DPCM + add DPCM_address,DPCM_offset + rdbyte x,DPCM_address 'Fetch Datum + + mov DPCM_delta,x + shr DPCM_delta,#6 + mov y,#1 + shl y,DPCM_delta + mov DPCM_delta,y + + mov y,#1 + shl y,DPCM_phs + test x,y wc + if_c add DPCM_wave,DPCM_delta + if_nc sub DPCM_wave,DPCM_delta + + add DPCM_phs,#1 + cmp DPCM_phs,#6 wc + if_b jmp #done_dpcm + + mov DPCM_phs,#0 + add DPCM_offset,#1 + jmp #done_dpcm + +mute_dpcm mov DPCM_wave, #128 + +done_dpcm mov addrregs,par + add addrregs,#200 + wrlong DPCM_offset,addrregs 'File Offset + add addrregs,#8 + wrlong DPCM_wave,addrregs 'Wave +dpcm_ret ret + +'-----------------------Dpcm Engine End-----------------------' + + + +'-------------------------Sound Engine-------------------------' + + 'Freq Timer/Divider and Increase sampling offset +wvsynth add ChlA_counter,Ch1Ap_freq wc + if_c add ChlA_offset,#1 + + 'Reset sample position and lock at zero if Keyoff. + test ChlAp_keyon,#%0001 wc + if_nc mov ChlA_offset,#0 + + 'Reset(loop) if needed + cmp ChlA_offset,ChlAp_sampend wc + if_ae mov ChlA_offset,Ch1Ap_samplpp + + 'Check BitRate and Set Offset + mov x,ChlA_offset + test ChlAp_keyon,#%0010 wc + if_c shr x,#1 + + 'Fetch WaveTable + mov ChlA_wave,ChlAp_sampptr + add ChlA_wave,x + rdbyte ChlA_wave,ChlA_wave + + 'Check BitRate and Skip if 8bit + test ChlAp_keyon,#%0010 wc + if_nc jmp #skip_4bitsam + + 'Convert 4bit to 8bit + test ChlA_offset,#%0001 wc + if_c shr ChlA_wave,#4 + if_nc and ChlA_wave,#%00001111 + + mov x,ChlA_wave + shl ChlA_wave,#4 + add ChlA_wave,x + + 'Center Amplitude and mute if Keyoff. +skip_4bitsam test ChlAp_keyon,#%0001 wc + if_nc mov ChlA_wave,#128 + + 'Volume Multiply + mov x,#0 + test ChlAp_keyon,#%10000000 wc + if_c add x,ChlA_wave + if_nc add x,#128 + + shr ChlA_wave,#1 + test ChlAp_keyon,#%01000000 wc + if_c add x,ChlA_wave + if_nc add x,#64 + add x,#64 + + shr ChlA_wave,#1 + test ChlAp_keyon,#%00100000 wc + if_c add x,ChlA_wave + if_nc add x,#32 + add x,#96 + + shr ChlA_wave,#1 + test ChlAp_keyon,#%00010000 wc + if_c add x,ChlA_wave + if_nc add x,#16 + add x,#112 + +'Return Audio as X. +wvsynth_ret ret + +'-----------------------Sound Engine End-----------------------' + +Port_Pins long %00000000_00000000_00001100_00000000 + + '- CTR PLL -------- BPIN --- APIN +Right_ctra long %0_00110_000_00000000_000000_000_001010 +Left_ctra long %0_00110_000_00000000_000000_000_001011 + +Timing_delay long 2500 'Sampling Rate = 32,000.00hz +NumberOfChannels long 6 + +Time res 1 +addrregs res 1 +x res 1 +y res 1 + +'WaveTable Synth Accumulators +ChlA_wave res 1 +ChlA_offset res 1 +ChlA_counter res 1 +ChlAp_sampptr res 1 +ChlAp_sampend res 1 +Ch1Ap_samplpp res 1 +Ch1Ap_freq res 1 +ChlAp_keyon res 1 + +'DPCM Accumulators +DPCM_wave res 1 +DPCM_address res 1 +DPCM_offset res 1 +DPCM_counter res 1 +DPCM_freq res 1 +DPCM_runlen res 1 +DPCM_phs res 1 +DPCM_delta res 1 \ No newline at end of file diff --git a/zubehör/shoot/bin/game.hss b/zubehör/shoot/bin/game.hss new file mode 100644 index 0000000..6f56d22 Binary files /dev/null and b/zubehör/shoot/bin/game.hss differ diff --git a/zubehör/shoot/bin/menu.hss b/zubehör/shoot/bin/menu.hss new file mode 100644 index 0000000..4c8d9d5 Binary files /dev/null and b/zubehör/shoot/bin/menu.hss differ diff --git a/zubehör/shoot/bin/shoot.bel b/zubehör/shoot/bin/shoot.bel new file mode 100644 index 0000000..7776d9b Binary files /dev/null and b/zubehör/shoot/bin/shoot.bel differ diff --git a/zubehör/shoot/bin/shoot.bin b/zubehör/shoot/bin/shoot.bin new file mode 100644 index 0000000..f42273d Binary files /dev/null and b/zubehör/shoot/bin/shoot.bin differ diff --git a/zubehör/shoot/regnatix-code/ios.spin b/zubehör/shoot/regnatix-code/ios.spin new file mode 100644 index 0000000..576ec2e Binary files /dev/null and b/zubehör/shoot/regnatix-code/ios.spin differ diff --git a/zubehör/shoot/regnatix-code/shoot.spin b/zubehör/shoot/regnatix-code/shoot.spin new file mode 100644 index 0000000..20dd1a5 Binary files /dev/null and b/zubehör/shoot/regnatix-code/shoot.spin differ diff --git a/zubehör/sphinx/hive-port/codegen/codegen.spin b/zubehör/sphinx/hive-port/codegen/codegen.spin new file mode 100644 index 0000000..33d3c4a --- /dev/null +++ b/zubehör/sphinx/hive-port/codegen/codegen.spin @@ -0,0 +1,1072 @@ +' 2010-02-25 new version number +con + _clkmode = xtal1 + pll8x + _xinfreq = 10_000_000 + + tvPin = 24 + sdPin = 16 + +obj + term: "isxtv" + kw: "kwdefs" + st: "symbols" + bt: "bintree" + fs: "sxfile" + str: "stringx" + token: "tokenrdr" + eval: "eval" + methods: "methods" + +pub Main | err, p + + err := \Try + if err + if err > 0 + term.str( err ) + else + term.str( string("Error ") ) + term.dec( err ) + term.out( 13 ) + if stackset and long[pSymbolTableSpace] <> $6666_6666 + term.str( string("Stack corrupt",13) ) + term.dec( token.LineNumber ) + term.out( "," ) + term.dec( token.Column + 1 ) + term.out( " " ) + term.out( "'" ) + term.str( token.Text ) + term.out( "'" ) + term.out( 13 ) + fs.Close + fs.Open( string("sphinx.bin"), "R" ) + else + fs.Close + if link + fs.Open( string("link.bin"), "R" ) + else + fs.Open( string("sphinx.bin"), "R" ) + bt.Stop + fs.Execute( 0 ) + +pri Try + ProcessCommandLine + if verbosity => 1 + term.str( string("codegen 100225", 13) ) + + Start + +pri ProcessCommandLine | nArgs, l + fs.Open( string("args.d8a"), "R" ) + nArgs := fs.ReadByte + ifnot nArgs-- + abort string("usage: compile spinfile [options]") + fs.ReadStringUpperCase( @tokenFilename, MAXFILENAMELENGTH ) + + l := strsize( @tokenFilename ) + if tokenFilename[l-4] == "." and tokenFilename[l-3] == "S" and tokenFilename[l-2] == "P" and tokenFilename[l-1] == "N" + tokenFilename[l-4]~ + if strsize( @tokenFilename ) > 8 + term.str( @tokenFilename ) + abort string(" -- filename too long") + str.Copy( @outputFilename, @tokenFilename ) + str.Copy( @binFilename, @tokenFilename ) + str.Append( @tokenFilename, string(".TOK") ) + str.Append( @outputFilename, string(".SOB") ) + str.Append( @binFilename, string(".BIN") ) + + ' Process command line arguments + + repeat while nArgs-- + fs.ReadStringUpperCase( @stringBuffer, MAXSTRINGBUFFERLENGTH ) + if stringBuffer[0] == "-" + stringBuffer[0] := "/" + if strcomp( @stringBuffer, string("/L") ) + link~~ + elseif strcomp( @stringBuffer, string("/V") ) + ifnot nArgs-- + abort string("/V must be followed by a number") + verbosity := fs.ReadNumber + elseif strcomp( @stringBuffer, string("/S") ) + ifnot nArgs-- + abort string("/S must be followed by a number") + STACKSPACE := fs.ReadNumber + if STACKSPACE & 3 + abort string("/S argument must be a multiple of 4") + elseif strcomp( @stringBuffer, string("/T") ) + ifnot nArgs-- + abort string("/T must be followed by a number") + TABLESPACE := fs.ReadNumber + if TABLESPACE & 3 + abort string("/T argument must be a multiple of 4") + 'else + ' ignore + + fs.Close + +con + MAXFILENAMELENGTH = 8 + 1 + 3 ' 8.3 + MAXSTRINGBUFFERLENGTH = 32 + +SXTVRENDEZVOUS = $8000 - 4 +RESERVED = SXTVRENDEZVOUS - 4 +SDSPIRENDEZVOUS = RESERVED - 3 * 4 +SXFS2RENDEZVOUS = SDSPIRENDEZVOUS - 4 * 4 ' four rendezvous variables +SXFSRENDEZVOUS = SXFS2RENDEZVOUS - 4 * 4 ' four rendezvous variables +METADATABUFFER = SXFSRENDEZVOUS - 512 + +_free = ($8000 - METADATABUFFER) / 4 + +var + byte tokenFilename[MAXFILENAMELENGTH+1] ' input .tok file + byte outputFilename[MAXFILENAMELENGTH+1] ' output .sob file + byte binFilename[MAXFILENAMELENGTH+1] ' output .bin file (just used to empty the .bin) + byte sobFilename[MAXFILENAMELENGTH+1] ' used for child .sob file(s) + byte stringBuffer[MAXSTRINGBUFFERLENGTH+1] ' temp string buffer + +dat +STACKSPACE long 575<<2 +TABLESPACE long 1500<<2 +verbosity byte 0 ' set by /V option +stackset byte 0 +link byte 0 ' set by /L; if non-zero, run link.bin automatically. + +{ + |<---STACKSPACE--->|<--------TABLESPACE---------->|<-----------OBJECTSPACE------------>|<-I/O RENDEZVOUS etc. + +-----+------------+-----------+------------------+------+----------------+------------+--+ + |stack| |symboltable| |header|dat/PASM|methods| | | + +-----+------------+-----------+------------------+------+----------------+------------+--+ + |tempstorage| ^ ^ |stringtemp| ^ + | | ^ ^ | + pObjSpace-+ pObjWork-+ | | +--$8000 + pStringWork-+ pObjTop-+ +} +var +' These next 3 vars actually live in methods.spin now. +' word pObjSpace ' points to area where the compiled object's header and bytecode will live (this pointer doesn't change) +' word pObjWork ' points to next available byte (this pointer changes as code is compiled) +' word pObjTop ' points just beyond available object workspace + + word pDatWork ' like pObjWork but for the DAT segment + word pSymbolTableSpace + +pri Start | i + pSymbolTableSpace := word[ $0a ] + STACKSPACE + + methods.set_pObjSpace( pSymbolTableSpace + TABLESPACE ) + methods.set_pObjTop( METADATABUFFER ) + + bt.Init( pSymbolTableSpace, methods.get_pObjSpace ) + st.Init + + long[ bt.Alloc(4) ] := $6666_6666 + stackset~~ + + ReadTimestamp + + if verbosity => 2 + term.str( string("stack space: ") ) + term.dec( STACKSPACE ) + term.str( string(13,"table space: ") ) + term.dec( TABLESPACE ) + term.str( string(13,"work space: ") ) + term.dec( methods.get_pObjTop - methods.get_pObjSpace ) + term.out( 13 ) + + term.str( string("Opening ") ) + term.str( @tokenFilename ) + term.out( 13 ) + token.Open( @tokenFilename ) + + bvarSize~ + wvarSize~ + lvarSize~ + nPubs := 1 ' pub indexes start at 1; 0th entry in object header is not a pub + nPris~ ' pri indexes have to be compensated later once final nPubs is known + nObjs~ + pObjList~ + pObjListEnd~ + + ParsePass1 + token.Close + + CheckStack + + varSize := (lvarSize + wvarSize + bvarSize + 3) & !3 + pDatWork := methods.get_pObjSpace + (nPubs + nPris + nObjs) << 2 ' each PUB/PRI/OBJ takes up 4 bytes in the object header + methods.set_pObjWork( pDatWork + datSize ) + bytefill( methods.get_pObjSpace, 0, pDatWork - methods.get_pObjSpace ) ' zero the header + + FixupOffsets( bt.PeekW( st.GetPSymbolTable ) ) + + token.Open( @tokenFilename ) + + ParsePass2 + token.Close + + methods.set_pObjWork( (methods.get_pObjWork + 3) & !3 ) ' Round up to multiple of 4 + + WriteSobFile + +pri CheckStack + if long[pSymbolTableSpace] <> $6666_6666 + abort string("Stack overflow") + +pri ReadTimestamp + if verbosity => 3 + term.str( string("reading timestamp: ") ) + + if fs.Open( string("timestmp.d8a"), "R" ) == 0 + timestamp := fs.ReadLong + 1 + fs.Close + else + timestamp := 1 + + if verbosity => 3 + term.dec( timestamp ) + term.out( 13 ) + + fs.Open( string("timestmp.d8a"), "W" ) + fs.WriteLong( timestamp ) + fs.Close + +pri WriteSobFile | p + + if nPubs == 1 ' recall that nPubs starts at 1 because of the 0th entry in the object header. + abort string("No PUB routines defined") + + ifnot link ' If we're not running the linker immediately after codegen, + if verbosity => 3 ' empty the .bin file if it exists(would be better to delete, + term.str( string("Zeroing ") ) ' but sxfs doesn't have that ability). If we forget to link, + term.str( @binFilename ) ' we'll get an error when we try to run the .bin. + term.out( 13 ) + + if fs.Open( @binFilename, "R" ) == 0 ' Check for existence + fs.Close + fs.Open( @binFilename, "W" ) + + fs.Close + + objBinSize := methods.get_pObjWork - methods.get_pObjSpace ' This gets stored in .sob header + word[methods.get_pObjSpace][0] := objBinSize ' This gets stored in object header + word[methods.get_pObjSpace][1] := nPubs + nPris + nObjs << 8 + + ' Compute checksum and hash + checksum~ + hash~ + p := methods.get_pObjSpace + repeat objBinSize + checksum += byte[p] + hash := (hash <- 1) ^ byte[p++] + + if verbosity => 2 + term.str( string("Writing ") ) + term.str( @outputFilename ) + term.out( 13 ) + + wordfill( @numExports, 0, 4 ) + ComputeSobInfo( bt.PeekW( st.GetPSymbolTable ) ) + + fs.Open( @outputFilename, "W" ) + fs.Write( @SobFileHeader, SIZEOFSOBHEADER ) + WriteExports( bt.PeekW( st.GetPSymbolTable ) ) + WriteImports + fs.Write( methods.get_pObjSpace, objBinSize ) + fs.Close + +pri FixupOffsets( p ) | s, t, v, size, headerSize, q +{{ + Goes through the symbol table and adjusts offsets of word VARs to put them after long VARs + and puts byte VARs after word VARs. + Also adjusts PRI method indexes so they come after PUBs, and OBJ indexes to put them after PRIs. + And now also adjusts DAT labels upward by the size of the object header. +}} + ifnot p + return + + FixupOffsets( bt.PeekW( p ) ) + + s := p + 4 + s += strsize(s) + 1 + if byte[s] == st#kVAR_SYMBOL ' var is followed by + ++s + size := byte[s++] ' 1-byte size (1, 2, 4) and 2-byte offset + t~ + if size == 2 + t := lvarSize ' word vars come after long vars + elseif size == 1 + t := lvarSize + wvarSize ' byte vars come after word vars + bt.PokeW( s, bt.PeekW(s) + t ) ' adjust var symbol's offset + elseif byte[s] == st#kPRI_SYMBOL + ++s + byte[s] += nPubs ' the PUBs are 1..nPubs-1, the PRIs are nPubs..nPubs+nPris-1 + elseif byte[s] == st#kOBJ_SYMBOL + ++s + byte[s][2] += nPubs + nPris ' the OBJs are nPubs+nPris.. + elseif byte[s] == st#kDAT_SYMBOL + headerSize := (nPubs + nPris + nObjs) << 2 + q := s ' start at global label + repeat ' and follow the linked list of local labels + bt.PokeW( q+2, bt.PeekW( q+2 ) + headerSize ) ' adjust label's dp + ifnot q := bt.PeekW( q+6 ) + quit + q += strsize(q) + 1 ' next in the list + + FixupOffsets( bt.PeekW( p + 2 ) ) + +{ +pri TraverseTable( p ) | s, t, v, q +{ + Symbol table dump. Call thusly: + TraverseTable( bt.PeekW( st.GetPSymbolTable ) ) +} + ifnot p + return + + TraverseTable( bt.PeekW( p ) ) + + s := p + 4 + term.str( s ) + s += strsize(s) + 1 + case t := byte[s++] + st#kINT_CON_SYMBOL: + v := bt.PeekL( s ) + term.out( "=" ) + term.dec( v ) + st#kPRI_SYMBOL, st#kPUB_SYMBOL: + if t == st#kPRI_SYMBOL + term.str( string(" pri: ") ) + else + term.str( string(" pub: ") ) + term.dec( byte[s++] ) ' method index + term.out( " " ) + term.dec( byte[s++] ) ' #params + st#kDAT_SYMBOL: + q := s-1 + repeat while q := bt.PeekW( q+6 ) + term.out(":") + term.str( q ) + q += strsize( q ) + 1 + term.str( string(" dat ") ) + case byte[s++] + 1: term.str( string("byte@") ) + 2: term.str( string("word@") ) + 4: term.str( string("long@") ) + term.hex( bt.PeekW(s), 4 ) + term.out(",") + term.hex( bt.PeekW(s+2), 4 ) + st#kVAR_SYMBOL: + term.str( string(" var ") ) + case byte[s++] + 1: term.str( string("byte@") ) + 2: term.str( string("word@") ) + 4: term.str( string("long@") ) + term.hex( bt.PeekW(s), 4 ) + st#kOBJ_SYMBOL: + term.out( ":" ) + term.str( bt.PeekW(s) ) + st#kSOB_SYMBOL: + term.out( ">" ) + term.hex( bt.PeekW(s), 4) + other: + term.out( "?" ) + term.hex( t, 2 ) + term.out( ";" ) + term.out( " " ) + + TraverseTable( bt.PeekW( p + 2 ) ) +} +con +SIZEOFSOBHEADER = 26 + +dat +SobFileHeader long + byte "SOB1" +timestamp long 0 +hash long 0 +numExports word 0 +exportSize word 0 +numImports word 0 +importSize word 0 +objBinSize word 0 +checksum byte 0 +{padding} byte 0 +varSize word 0 ' total size in bytes of vars (rounded up to multiple of 4) + + +pri ComputeSobInfo( p ) | pName, type +{{ + Traverses the symbol table and computes exportSize, numExports, importSize, numImports. + Initialize those variables to 0 before entering this routine. +}} + ifnot p + return + + pName := p + 4 + type := byte[pName + strsize(pName) + 1] + if type == st#kINT_CON_SYMBOL or type == st#kFLOAT_CON_SYMBOL + ++numExports + exportSize += strsize(pName) + 6 ' name + null + type + 4-byte value + elseif type == st#kPUB_SYMBOL + ++numExports + exportSize += strsize(pName) + 4 ' name + null + type + index + #args + elseif type == st#kOBJ_SYMBOL + pName := bt.PeekW( pName + strsize(pName) + 2 ) + ++numImports + importSize += strsize(pName) - 4 + 4 ' name (excluding ".SOB") + null + 2-byte count + reserved + + ComputeSobInfo( bt.PeekW( p ) ) + ComputeSobInfo( bt.PeekW( p + 2 ) ) + +pri WriteExports( p ) | pName, pData, type +{{ + Traverses the symbol table and writes exports to output file. +}} + ifnot p + return + + pName := p + 4 + pData := pName + strsize(pName) + 1 + type := byte[pData] + + if type == st#kINT_CON_SYMBOL or type == st#kFLOAT_CON_SYMBOL ' name + null + type + 4-byte value + fs.WriteString( pName ) + fs.WriteByte( type ) + fs.WriteLong( bt.PeekL( pData+1 ) ) + elseif type == st#kPUB_SYMBOL ' name + null + type + index + #args + fs.WriteString( pName ) + fs.WriteByte( type ) + fs.Write( pData+1, 2 ) ' index + #args + + WriteExports( bt.PeekW( p ) ) + WriteExports( bt.PeekW( p + 2 ) ) + +pri WriteImports | pName, pData, type +{{ + Traverses the OBJ list and writes imports to output file. + + We use a list so that the imports are written in the order they appear in the source. + This is important for OBJ symbols because we want the SOB imports to line up properly. +}} + pName := pObjList + repeat while pName + + pData := pName + strsize(pName) + 1 ' pName is name of symbol (e.g. "DEBUG") + ' pData points to symbol's data: 1-byte type + 2-byte pointer to SOB + 1-byte index + 2-byte count + 2-byte link + pName := bt.PeekW( pData + 1 ) ' pName is name of .sob file (e.g. "TV_TEXT.SOB") + fs.Write( pName, strsize(pName)-4 ) ' Write name but drop .SOB suffix. + fs.WriteByte( 0 ) ' Write null terminator + fs.WriteWord( bt.PeekW( pData + 4 ) ) ' Write count + fs.WriteByte( 0 ) ' Write reserved byte + + pName := bt.PeekW( pData + 6 ) ' link to next + +pri ParsePass1 + Eval.set_pass( 1 ) + InitDat + if verbosity => 2 + term.str( string("Pass 1") ) + term.out( 13 ) + ParseCon1 + repeat while token.Type <> kw#kEOF + ifnot token.IsBlockDesignator + abort string("Syntax error") + if token.Column + abort string("Block designator not in column 1") + if token.AdvanceIf( kw#kCON ) + ParseCon1 + elseif token.AdvanceIf( kw#kDAT ) + ParseDat1 + elseif token.AdvanceIf( kw#kOBJ ) + ParseObj1 + elseif token.AdvanceIf( kw#kPRI ) + ParseMethod1( st#kPRI_SYMBOL ) + elseif token.AdvanceIf( kw#kPUB ) + ParseMethod1( st#kPUB_SYMBOL ) + elseif token.AdvanceIf( kw#kVAR ) + ParseVar1 + else + abort string("Syntax error") + +pri ParsePass2 + Eval.set_pass( 2 ) + InitDat + if verbosity => 2 + term.str( string("Pass 2") ) + term.out( 13 ) + ParseCon2 + repeat while token.Type <> kw#kEOF + CheckStack + ifnot token.IsBlockDesignator + abort string("Syntax error") + if token.AdvanceIf( kw#kCON ) + ParseCon2 + elseif token.AdvanceIf( kw#kDAT ) + ParseDat2 + elseif token.AdvanceIf( kw#kOBJ ) + SkipBlock + elseif token.AdvanceIf( kw#kPRI ) + methods.Parse2( st#kPRI_SYMBOL ) + elseif token.AdvanceIf( kw#kPUB ) + methods.Parse2( st#kPUB_SYMBOL ) + elseif token.AdvanceIf( kw#kVAR ) + SkipBlock + else + abort string("Syntax error") + +pri SkipBlock + repeat until token.IsBlockDesignator or token.Type == kw#kEOF + token.Advance + +pri ParseCon1 | o, p, inc, v + o~ + token.AdvanceIf( kw#kEOL ) + repeat + inc := 1 + if token.AdvanceIf( kw#kOCTOTHORP ) + o := Eval.EvaluateExpression( 0 ) + elseif token.IsId ' Id +? + st.AddToTable( token.Text ) + byte[ p := bt.Alloc(1) ] := st#kINT_CON_SYMBOL ' p points to symbol type byte + ' in case we have to patch the type retroactively + token.Advance + if token.AdvanceIf( kw#kEQUAL ) ' Id = + v := Eval.TryToEvaluateExpression( 0 ) + if Eval.Succeeded + bt.PokeL( bt.Alloc(4), v ) + else ' it is undefined + byte[p] := st#kUNDEFINED_CON_SYMBOL + bt.Alloc(4) ' but we should allocate space for the eventual value. + elseif token.AdvanceIf( kw#kLBRACKET ) ' Id [ + inc := Eval.EvaluateExpression( 0 ) + token.Eat( kw#kRBRACKET ) + bt.PokeL( bt.Alloc(4), o ) + o += inc + else ' Plain Id + bt.PokeL( bt.Alloc(4), o ) + o += inc + else + quit + if token.Type == kw#kCOMMA or token.Type == kw#kEOL + token.Advance + else + abort string("Syntax error") + +pri ParseCon2 | o, p, inc + o~ + token.AdvanceIf( kw#kEOL ) + repeat + inc := 1 + if token.AdvanceIf( kw#kOCTOTHORP ) + o := Eval.EvaluateExpression( 0 ) + elseif token.IsId ' Id +? + p := st.SymbolLookup( token.Text ) + token.Advance + if token.AdvanceIf( kw#kEQUAL ) ' Id = + bt.PokeL( p+1, Eval.EvaluateExpression( 0 ) ) + byte[p] := st#kINT_CON_SYMBOL + elseif token.AdvanceIf( kw#kLBRACKET ) ' Id [ + inc := Eval.EvaluateExpression( 0 ) + token.Eat( kw#kRBRACKET ) + o += inc + else ' Plain Id + o += inc + else + quit + if token.Type == kw#kCOMMA or token.Type == kw#kEOL + token.Advance + else + abort string("Syntax error") + +var + word dp ' dp is the address in DAT space of current source line. + ' dp = pObjWork - pObjSpace + word ooo ' dp + ooo = cogx4; cogx4 / 4 = cog address of current source line. + word pGlobalLabel ' points to most-recently defined global label; used as the head of a linked list of local labels + byte alignment ' 1, 2, or 4 +{ + a DAT line consists of (in rough pseudo-bnf) one of the following: + 1) [label | :label] ORG|RES [ ] + 2) [label | :label] * (with commas between -- yeah, yeah, I said it was rough) + 3) [label | :label] [ ] , * + + As we process DAT statements and emit bytes, pDatWork increases, always pointing where the next byte will go. + dp = pDatWork - pObjSpace (i.e., dp 0 is the beginning of DAT space) + cogx4 = dp + ooo, where ooo is updated each time an ORG directive is encountered: + ooo = org_expression * 4 - dp + Example: + Let us say pObjSpace is 1000. The object header starts there. Say it takes up 100 bytes, so pDatWork is 1100. + In terms of DAT space, dp = 1100 - 1000 = 100. + Say there's an ORG 100, so ooo = 100 * 4 - 100 = 300. + A label defined at this point would have dp = 100, cogx4 = 100 + 300 = 400 (divide this by 4 to get cog address 100). + Suppose we assemble a PASM instruction and emit the four bytes. + Now pDatWork = 1104, dp = 104, and cogx4 = 104 + 300 = 404 (cog address 101). +} +pri InitDat + if Eval.get_pass == 1 + dp~ + ooo~ + else + ooo := methods.get_pObjSpace - pDatWork '= -dp + + pGlobalLabel~ + alignment := 1 + +pri ParseDat1 | pLabelData, p, v, size, count, dpInc, temp, cogx4 + Eval.EnteringDat + cogx4~ + repeat + pLabelData~ + if token.AdvanceIf( kw#kEOL ) + next + + if token.IsId ' label? + if byte[token.Text] == ":" ' local label? + ' Traverse the list of locals to check for duplicates + p := pGlobalLabel + repeat while p := bt.PeekW( p + 6 ) ' p points to string part of local label + if strcomp( p, token.Text ) + abort string("Duplicate local label") + p += strsize(p) + 1 ' Increment p past string part to data part + + p := bt.Alloc( strsize( token.Text ) + 9 ) ' p points to + str.Copy( p, token.Text ) ' local label's text followed by + pLabelData := p + strsize( token.Text ) + 1 ' 8 bytes of label data (to be filled in later) + byte[ pLabelData ] := st#kDAT_SYMBOL ' type + bt.PokeW( pLabelData+6, bt.PeekW(pGlobalLabel+6) ) ' pointer to local labels + ifnot pGlobalLabel + abort string("No preceding global label") + bt.PokeW( pGlobalLabel+6, p ) ' Insert this local label at head of list + + else ' plain old label + st.AddToTable( token.Text ) + pLabelData := bt.Alloc( 8 ) ' local label data + byte[ pLabelData ] := st#kDAT_SYMBOL ' type + bt.PokeW( pLabelData+6, 0 ) ' pointer to local labels + + pGlobalLabel := pLabelData + + token.Advance + + dpInc~ + if token.AdvanceIf( kw#kORG ) ' Case 1a: ORG [ ] + alignment := 4 + PadToAlignment + temp~ ' default ORG is 0 + if token.Type <> kw#kEOL + temp := Eval.EvaluateExpression( pGlobalLabel ) << 2 + ooo := temp - dp + cogx4 := dp + ooo + elseif token.AdvanceIf( kw#kRES ) ' Case 1b: RES [ ] + alignment := 4 + PadToAlignment + temp := 4 ' default RES is 1 long + if token.Type <> kw#kEOL + temp := Eval.EvaluateExpression( pGlobalLabel ) << 2 + cogx4 := dp + ooo + ooo += temp + elseif token.AdvanceIf( kw#kFIT ) + temp := 496 + if token.Type <> kw#kEOL + temp := Eval.EvaluateExpression( pGlobalLabel ) + if cogx4 > temp << 2 + abort string("Origin exceeds FIT limit") + elseif token.IsSize ' Case 2. BYTE/WORD/LONG * + alignment := |< (token.Type - kw#kBYTE) ' 1/2/4 + PadToAlignment + cogx4 := dp + ooo + token.Advance + if token.Type <> kw#kEOL + repeat + size := alignment + if token.IsSize + size := |< (token.Type - kw#kBYTE) ' 1/2/4 -- just size + token.Advance + v := Eval.TryToEvaluateExpression( pGlobalLabel ) + count := 1 + if token.AdvanceIf( kw#kLBRACKET ) + count := Eval.EvaluateExpression( pGlobalLabel ) + token.Eat( kw#kRBRACKET ) + dpInc += count * size + while token.AdvanceIf( kw#kCOMMA ) + elseif token.IsCond or token.IsPasm ' Case 3. [ ] + alignment := 4 + PadToAlignment + cogx4 := dp + ooo + dpInc := 4 + repeat + token.Advance + until token.Type == kw#kEOL + elseif token.Type <> kw#kEOL + abort string("Syntax error") + + if pLabelData ' Was a label defined on the current source line? + byte[pLabelData+1] := alignment ' data size + bt.PokeW( pLabelData+2, dp ) ' Address in DAT space + bt.PokeW( pLabelData+4, cogx4 ) ' Cog address x 4 + ' The local label linked list pointer was filled in previously + dp += dpInc + cogx4 += dpInc + + until token.IsBlockDesignator or token.Type == kw#kEOF + + datSize := dp + + Eval.LeavingDat + +pri ParseDat2 | pLabelData, p, v, size, count, temp, cond, pasmOp, ds, effect, oooInc + Eval.EnteringDat + oooInc~ + repeat + pLabelData~ + if token.AdvanceIf( kw#kEOL ) + next + + if token.IsId ' label? + if byte[token.Text] == ":" ' local label? + ' Traverse the list of locals to find this one. + p := pGlobalLabel + repeat while p := bt.PeekW( p + 6 ) ' p points to string part of local label + if strcomp( p, token.Text ) + quit + p += strsize(p) + 1 ' Increment p past string part to data part + pLabelData := p + strsize(p) + 1 + else ' plain old label + pLabelData := st.SymbolLookup( token.Text ) + pGlobalLabel := pLabelData + + token.Advance + + dp := pDatWork - methods.get_pObjSpace + + if token.AdvanceIf( kw#kORG ) ' Case 1: ORG + temp~ ' default ORG is 0 + alignment := 4 + PadToAlignment + if token.Type <> kw#kEOL + temp := Eval.EvaluateExpression( pGlobalLabel ) << 2 + ooo := temp - dp + elseif token.AdvanceIf( kw#kRES ) ' Case 1b: RES [ ] + alignment := 4 + PadToAlignment + oooInc := 4 ' default RES is 1 long + if token.Type <> kw#kEOL + oooInc := Eval.EvaluateExpression( pGlobalLabel ) << 2 + elseif token.AdvanceIf( kw#kFIT ) ' ignore FIT in pass 2 + if token.Type <> kw#kEOL + Eval.EvaluateExpression( pGlobalLabel ) + + elseif token.IsSize ' Case 2. BYTE/WORD/LONG * + alignment := |< (token.Type - kw#kBYTE) ' 1/2/4 + PadToAlignment + token.Advance + if token.Type == kw#kEOL + next + repeat + size := alignment + if token.IsSize + size := |< (token.Type - kw#kBYTE) ' 1/2/4 -- just size + token.Advance + v := Eval.EvaluateExpression( pGlobalLabel ) + count := 1 + if token.AdvanceIf( kw#kLBRACKET ) + count := Eval.EvaluateExpression( pGlobalLabel ) + token.Eat( kw#kRBRACKET ) + repeat count + temp := v + repeat size + EmitDat( temp ) + temp >>= 8 + while token.AdvanceIf( kw#kCOMMA ) + elseif token.IsCond or token.IsPasm + alignment := 4 + PadToAlignment + cond~~ + if token.IsCond + cond := token.GetCond + token.Advance + ifnot token.IsPasm + abort string("Expected PASM instruction") + ds := %11 + case token.Type + kw#kAND: pasmOp := $60bc0000 ' Special handling for double-duty PASM mnemonics + kw#kOR: pasmOp := $68bc0000 + kw#kWAITCNT: pasmOp := $f8bc0000 + kw#kWAITPEQ: pasmOp := $f03c0000 + kw#kWAITPNE: pasmOp := $f43c0000 + kw#kWAITVID: pasmOp := $fc3c0000 + kw#kCOGID: pasmOp := $0cfc0001 + ds := %10 + kw#kCOGINIT: pasmOp := $0c7c0002 + ds := %10 + kw#kCOGSTOP: pasmOp := $0cfc0003 + ds := %10 + kw#kCLKSET: pasmOp := $0c7c0000 + ds := %10 + other: + pasmOp := token.GetPasmOp + ds := token.GetPasmDS + + if token.Type == kw#kCALL ' special handling for CALL instruction + token.Advance + token.Eat( kw#kOCTOTHORP ) + ifnot token.IsId + abort string("Expected return label") + str.Copy( @stringBuffer, token.Text ) + str.Append( @stringBuffer, string("_RET") ) + ifnot p := st.SymbolLookup( @stringBuffer ) + abort string("Return label not found") + if byte[p] <> st#kDAT_SYMBOL + abort string("Non-DAT return label") + temp := bt.PeekW( p+4 ) + if temp & 3 + abort string("Return label is not long") + pasmOp |= ((temp >> 2 & $1ff) << 9) | (Eval.EvaluateExpression( pGlobalLabel ) & $1ff) ' combine destination and source + + else ' regular PASM instruction + token.Advance + if ds & %10 ' destination operand + pasmOp |= (Eval.EvaluateExpression( pGlobalLabel ) & $1ff) << 9 + if ds == %11 + token.Eat( kw#kCOMMA ) + if ds & %01 + if token.AdvanceIf( kw#kOCTOTHORP ) ' immediate? + pasmOp |= |< 22 ' set I + pasmOp |= Eval.EvaluateExpression( pGlobalLabel ) & $1ff ' source operand + + effect~ + if token.Type <> kw#kEOL + repeat + ifnot token.IsEffect + abort string("Expected PASM effect") + if token.GetEffect == 8 ' NR? + effect &= %110 ' clear R + else + effect |= token.GetEffect + token.Advance + while token.AdvanceIf( kw#kCOMMA ) + + if pasmOp == 0 and (cond <> -1 or effect ) + abort string("Conditions and effects not allowed on NOP") + + pasmOp |= (effect << 23) + if cond <> -1 + pasmOp := pasmOp & %111111_1111_0000_111111111_111111111 | (cond << 18) + + repeat 4 + EmitDat( pasmOp ) + pasmOp >>= 8 + + if pLabelData ' Was a label defined on the current source line? + if byte[pLabelData+1] <> alignment { data size +} or bt.PeekW( pLabelData+2 ) <> dp { Address in DAT space +} or bt.PeekW( pLabelData+4 ) <> dp + ~~ooo ' Cog address x 4 + term.dec(byte[pLabelData+1]) + term.out(" ") + term.dec(alignment) + term.out(13) + term.dec(bt.PeekW( pLabelData+2 )) + term.out(" ") + term.dec(dp) + term.out(13) + term.dec(bt.PeekW( pLabelData+4 )) + term.out(" ") + term.dec(dp+~~ooo) + abort string("Phase error") + + ooo += oooInc~ + + until token.IsBlockDesignator or token.Type == kw#kEOF + Eval.LeavingDat + +pri PadToAlignment + repeat (alignment - dp) & (alignment - 1) ' number of bytes needed to pad to new alignment + ++dp + if Eval.get_pass == 2 + EmitDat( 0 ) ' padding + +pri EmitDat( b ) + byte[pDatWork++] := b + +var + word pObjList ' OBJ symbols are linked together in a list. + word pObjListEnd ' Pointer to the last OBJ; append new OBJs at the end. + +pri ParseObj1 | i, count, pObj, pSob, pObjName +{{ + { [ ] } : +}} + token.AdvanceIf( kw#kEOL ) + repeat while token.IsId + pObjName := bt.Alloc( 0 ) + 4 ' Hacky way to get pointer to the name field of the symbol we're about to add. + st.AddToTable( token.Text ) + pObj := bt.Alloc( 8 ) ' type (1), ptr to sym table (2), index(1), count (2), ptr to next (2) + byte[pObj] := st#kOBJ_SYMBOL + + token.Advance + + count := 1 + if token.AdvanceIf( kw#kLBRACKET ) + count := Eval.EvaluateExpression( 0 ) + token.Eat( kw#kRBRACKET ) + + token.Eat( kw#kCOLON ) + + byte[pObj][3] := nObjs + nObjs += count + bt.PokeW( pObj+4, count ) + + ' Link this OBJ into the list of OBJs + if pObjListEnd ' this points to last OBJ name field + pObjListEnd += strsize(pObjListEnd)+1 ' now this points to OBJ data + bt.PokeW( pObjListEnd+6, pObjName ) ' make a link to new OBJ name field + + pObjListEnd := pObjName + bt.PokeW( pObj+6, 0 ) + + ifnot pObjList + pObjList := pObjName + + i~ + repeat + ifnot token.IsIntLiteral + abort string("Syntax error") + sobFilename[i++] := token.Value + if i > MAXFILENAMELENGTH-4 ' have to leave room for ".sob" suffix + abort string("SOB filename too long") + token.Advance + while token.AdvanceIf( kw#kCOMMA ) + + sobFilename[i]~ + str.ToUpper( @sobFilename ) + str.Append( @sobFilename, string(".SOB") ) + + ifnot pSob := st.SymbolLookup( @sobFilename ) + st.AddToTable( @sobFilename ) + byte[ pSob := bt.Alloc(3) ] := st#kSOB_SYMBOL ' type (1), ptr to sym table (2) + bt.PokeW( pSob+1, 0 ) + ReadSobFile( pSob+1 ) + bt.PokeW( pObj+1, pSob - strsize(@sobFilename) - 1 ) + + token.Eat( kw#kEOL ) + +con +SOBFILEFORMATVERSION = "S" + "O" << 8 + "B" << 16 + "1" << 24 ' "SOB1" + +pri ReadSobFile( pSobTable ) | p, t + if verbosity => 3 + term.str( string("Reading ") ) + term.str( @sobFilename ) + term.out( 13 ) + if fs.Open( @sobFilename, "R" ) <> 0 + term.str( @sobFilename ) + abort string(" -- couldn't open") + + if fs.Readlong <> SOBFILEFORMATVERSION ' SOB file format version + abort string("Unrecognized SOB file format") + fs.Readlong ' timestamp + fs.ReadLong ' hash + numExports := fs.ReadWord ' number of exports + exportSize := fs.ReadWord ' size of exports segment + fs.ReadWord ' number of imports + importSize := fs.ReadWord ' size of imports segment + fs.ReadWord ' size of bytecode segment + fs.ReadByte ' checksum + fs.ReadByte ' padding + fs.ReadWord ' size of sob's VAR space + + repeat numExports + fs.ReadStringUpperCase( @stringBuffer, MAXSTRINGBUFFERLENGTH ) + bt.AddToTable( @stringBuffer, pSobTable ) + case t := fs.ReadByte + st#kINT_CON_SYMBOL, st#kFLOAT_CON_SYMBOL: + p := bt.Alloc( 5 ) + byte[p++] := t + bt.PokeL( p, fs.ReadLong ) + st#kPUB_SYMBOL: + p := bt.Alloc( 3 ) + byte[p++] := t + byte[p++] := fs.ReadByte ' method index + byte[p++] := fs.ReadByte ' #params + + fs.Close + +pri ParseMethod1( type ) | nargs +' type = st#kPRI_SYMBOL or st#kPUB_SYMBOL + ifnot token.IsId + abort string("Expected ID") + st.AddToTable( token.Text ) + token.Advance + nargs~ + if token.AdvanceIf( kw#kLPAREN ) + repeat + ++nargs + ifnot token.IsId + abort string("Expected ID") + token.Advance + while token.AdvanceIf( kw#kCOMMA ) + token.Eat( kw#kRPAREN ) + if nargs > 255 + abort string("Too many parameters") + byte[ bt.Alloc(1) ] := type + if type == st#kPUB_SYMBOL + byte[ bt.Alloc(1) ] := nPubs++ + else + byte[ bt.Alloc(1) ] := nPris++ + byte[ bt.Alloc(1) ] := nargs + + SkipBlock + +var + word bvarSize ' size in bytes of byte var area + word wvarSize ' size in bytes of word var area + word lvarSize ' size in bytes of long var area + byte nPubs, nPris + word nObjs + word datSize ' size in bytes of DAT area + +pri ParseVar1 | s, t, dim + token.AdvanceIf( kw#kEOL ) + repeat while token.IsSize + if token.Type == kw#kBYTE + s~ + elseif token.Type == kw#kWORD + s := 1 + elseif token.Type == kw#kLONG + s := 2 + token.Advance + repeat + ifnot token.IsId + abort string("Expected ID") + st.AddToTable( token.Text ) + token.Advance + byte[ bt.Alloc(1) ] := st#kVAR_SYMBOL + byte[ bt.Alloc(1) ] := |< s + if token.AdvanceIf( kw#kLBRACKET ) + dim := Eval.EvaluateExpression( 0 ) + token.Eat( kw#kRBRACKET ) + else + dim := 1 + bt.PokeW( bt.Alloc(2), bvarSize[s] ) + bvarSize[s] += dim << s + while token.AdvanceIf( kw#kCOMMA ) + token.Eat( kw#kEOL ) + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} + \ No newline at end of file diff --git a/zubehör/sphinx/hive-port/linker/link.spin b/zubehör/sphinx/hive-port/linker/link.spin new file mode 100644 index 0000000..f5f72e2 --- /dev/null +++ b/zubehör/sphinx/hive-port/linker/link.spin @@ -0,0 +1,616 @@ +{ + .sob linker +2009 +April + 10 Successfully linked two test programs + 15 SOB1 format: + #args in exported pubs now just one byte + added byte to imports for possible future use with object "pointers" + rearranged fields in SOB file header so that longs are long-aligned in memory +June + 9 Sphinxified + timestamp comparison + 12 Removed /s and /t options + 18 Don't stop on first out-of-date error. + +To do: + removal of duplicate sobs + + +Usage: link sobname [options] +sobname is name of .sob file, with or without .sob suffix. +Options start with / or - and are case-insensitive: + /v -- Sets verbosity level. Higher values of n => more verbose. Default is 0. + + SOB file format + + 0 4 bytes: SOB file format version # + 4 4 bytes: OBJ timestamp or version + 8 4 bytes: hash of OBJ's binary code. + 12 2 bytes: NUMEXPORTS + 14 2 bytes: EXPORTSIZE + 16 2 bytes: NUMIMPORTS + 18 2 bytes: IMPORTSIZE + 20 2 bytes: OBJBINSIZE (this is always a multiple of 4) + 22 1 byte: checksum + 23 1 byte: reserved + 24 2 bytes: size of OBJ's VAR space. + 26 EXPORTSIZE bytes: exported symbols: CONs, PUBs, maybe PRIs. + IMPORTSIZE bytes: OBJ's sub-OBJs. + OBJBINSIZE bytes: the compiled OBJ: header followed by methods. + + Export record format + + name + null + 0 + 4-byte int CON int + name + null + 1 + 4-byte float CON float + name + null + 2 + index + #args PUB + name + null + 3 + index + #args PRI (not exported) + + Import record format + + name + null + 2-byte count + reserved + + Export and import names are uppercase. Import name must not include ".SOB" or other suffix. + +} +SIZEOFSOBHEADER = 26 + +obj + term: "isxtv" + fs[2]: "sxfile" + str: "stringx" + +pub Main | err + err := \Try + if err + if err > 0 + term.str( err ) + else + term.str( string("Error ") ) + term.dec( err ) + term.out( 13 ) + + fs[0].Close + fs[0].Open( string("sphinx.bin"), "R" ) + fs[0].Execute( 0 ) + +dat +STACKSPACE long 500 ' in bytes; must be multiple of 4 +TABLESPACE long 1000 ' in bytes; must be multiple of 4 +WORKSPACE long 0 +verbosity byte 0 +outOfDate byte 0 +ignoreOutOfDate byte 0 + +pri Try | nArgs, pTable, pWork, l, p, totalVarSize + + fs.Open( string("args.d8a"), "R" ) + nArgs := fs.ReadByte + ifnot nArgs-- + abort string("usage: link sobname [options]") + fs.ReadStringUpperCase( @sobName, MAXFILENAMELENGTH ) + + l := strsize( @sobName ) + if sobName[l-4] == "." and sobName[l-3] == "S" and sobName[l-2] == "O" and sobName[l-1] == "B" + sobName[l-4]~ + if strsize( @sobName ) > 8 + term.str( @sobName ) + abort string(" -- sobname too long") + str.Copy( @outputName, @sobName ) + + ' Process command line arguments + + repeat while nArgs-- + fs.ReadStringUpperCase( @stringBuffer, 20 ) + if stringBuffer[0] == "-" + stringBuffer[0] := "/" + if strcomp( @stringBuffer, string("/V") ) + ifnot nArgs-- + abort string("/V must be followed by a number") + verbosity := fs.ReadNumber + elseif strcomp( @stringBuffer, string("/I") ) + ignoreOutOfDate~~ +{ + elseif strcomp( @stringBuffer, string("/S") ) + ifnot nArgs-- + abort string("/S must be followed by a number") + STACKSPACE := fs.ReadNumber + if STACKSPACE & 3 + abort string("/S argument must be a multiple of 4") + elseif strcomp( @stringBuffer, string("/T") ) + ifnot nArgs-- + abort string("/T must be followed by a number") + TABLESPACE := fs.ReadNumber + if TABLESPACE & 3 + abort string("/T argument must be a multiple of 4") +} + 'else + 'ignore + + fs.Close + + if verbosity => 1 + term.str( string("link 090627", 13) ) + + pTable := word[$000a] + STACKSPACE + pWork := pTable + TABLESPACE + WORKSPACE := 32768-pWork + + if verbosity => 2 + term.dec( WORKSPACE ) + term.str( string(" bytes of work space", 13) ) + + if WORKSPACE =< 0 + abort string("No work space") + + SobInit( pTable, TABLESPACE ) + AddSob( @sobName ) + ProcessSob( pTable, true ) + checksum~ + totalVarSize := ComputeAddressAndTotalVarSize( pTable, $0010 ) + + word[@header][3] := $0010 + word[@header[$08]] := objBinEndAddress + word[@header[$0a]] := objBinEndAddress + totalVarSize + 8 + word[@header[$0c]] := firstPubOffset + $0010 + word[@header[$0e]] := word[@header[$0a]] + firstPubLocalsSize + (firstPubNumArgs + 1) << 2 + + AddToChecksum( @header, $10 ) + AddToChecksum( @footer, 8 ) + header[5] := -checksum + + if verbosity => 3 + p := pTable + repeat while p + term.str( word[p +_pName] ) + term.out( " " ) + term.hex( word[p +_startAddress], 4 ) + term.out( " " ) + term.dec( word[p +_totalVarSize] ) + term.out( " " ) + term.hex( byte[p +_checksum], 2 ) + term.out( 13 ) + p := word[p +_pNextSorted] + + if not outOfDate or ignoreOutOfDate + str.Append( @outputName, string(".BIN") ) + if verbosity => 2 + term.str( string("Writing ") ) + term.str( @outputName ) + term.out( 13 ) + WriteBinaryFile( @outputName, pTable, pWork, WORKSPACE ) + else + term.str( string("No .bin written", 13) ) + +pri WriteBinaryFile( pFilename, pSob, pBuff, buffsize ) | n, p, pImports, pCounts, interObjectOffset, varOffset +{{ + Go down the priority-sorted list of sobs assigning them hub addresses such that they follow one + another in memory. On the way back up the list, compute each sob's total VAR size (the sob's + own VARs plus its imported sobs' VARs.) + Also updates checksum. + Return value is the current sob's total VAR size. Only the top object's return value is looked at. +}} + fs[0].Open( pFilename, "W" ) + fs[0].Write( @header, 16 ) + + repeat while pSob + str.Copy( @stringBuffer, word[pSob +_pName] ) + str.Append( @stringBuffer, string(".SOB") ) + if verbosity => 2 + term.str( @stringBuffer ) + term.str( string(" -- copying", 13) ) + + n := word[pSob +_objBinSize] + if n > buffsize + abort string("work area too small") + + fs[1].Open( @stringBuffer, "R" ) + fs[1].SkipBytes( SIZEOFSOBHEADER + word[pSob +_exportImportSize] ) + fs[1].Read( pBuff, n ) + fs[1].Close + + p := pBuff + byte[pBuff][2] << 2 ' byte[2] is index of 1st obj entry; multiply by 4 bytes/entry + varOffset := word[pSob +_varSize] + pImports := word[pSob +_pImports] + pCounts := word[pSob +_pCounts] + repeat word[pSob +_nImports] + interObjectOffset := word[ word[pImports] +_startAddress] - word[pSob +_startAddress] + repeat word[pCounts] + word[p] := interObjectOffset + p += 2 + word[p] := varOffset + p += 2 + varOffset += word[ word[pImports] +_totalVarSize] + + pImports += 2 + pCounts += 2 + + + fs[0].Write( pBuff, n ) + pSob := word[pSob +_pNextSorted] + fs[0].Close + +{{ + objBinEndAddress := address ' end address will point just beyond the last obj in hub memory. + ' Here we're just overwriting as we go and keeping the last one. + + ComputeAddressAndTotalVarSize( word[p +_pNextSorted], address ) + + checksum += byte[p +_checksum] ' this is the partial checksum of the obj (doesn't count its sub-object table because + ' sub-object links are not known until link time (i.e., now)) + totalVarSize := word[p +_varSize] + pImports := word[p +_pImports] + pCounts := word[p +_pCounts] + repeat word[p +_nImports] ' for each import, add the import's VAR size multiplied by its count + interObjectOffset := word[ word[pImports] +_startAddress] - word[p +_startAddress] + repeat word[pCounts] + AddToChecksum( @totalVarSize, 2 ) ' checksum needs to include this half of an object table entry + AddToChecksum( @interObjectOffset, 2 ) ' and this other half of an object table entry + + totalVarSize += word[ word[pImports] +_totalVarSize] + + pImports += 2 + pCounts += 2 + + word[p +_totalVarSize] := totalVarSize +}} + +var + word firstPubLocalsSize + word firstPubOffset + word firstPubNumArgs + word objBinEndAddress + byte checksum + long clk_freq + long xin_freq + long clk_mode + long free + long stack + +pri ReadExports( numExports ) | firstPub, type, val, index, nArgs, i, p, f, frequency + f~ + firstPub~~ + stack := 16 + frequency := 12_000_000 + + repeat numExports + fs.ReadStringUpperCase( @stringBuffer, MAXEXPORTLENGTH ) + case type := fs.ReadByte + 0, 1: ' int or float CON + val := fs.ReadLong + 2, 3: ' PUB or PRI + index := fs.ReadByte + nArgs := fs.ReadByte + if firstPub~ + firstPubNumArgs := nArgs + + repeat i from 0 to 4 + if strcomp( @stringBuffer, @@ptrs[i] ) + if type + term.str( @stringBuffer ) + abort string(" -- not an int CON") + clk_freq[i] := val + f |= |< i + + f &= 7 + if clk_mode & 3 + f |= 8 + case f ' four bits: rc|clkmode|xinfreq|clkfreq + %0000: ' none of clkmode/xinfreq/clkfreq specified + %0001..%0011: abort string("_CLKMODE must be specified") + %0100: abort string("_CLKFREQ or _XINFREQ must be specified") + %0101: frequency := clk_freq + %0110: frequency := xin_freq * ((clk_mode >> 6) #> 1) + %0111: if clk_freq <> xin_freq * ((clk_mode >> 6) #> 1) + abort string("conflicting _CLKFREQ and _XINFREQ") + %1000..%1011: ' these cases shouldn't happen + %1100: ' this case is OK + %1101..%1111: abort string("RCFAST/SLOW incompatible with _CLKFREQ/_XINFREQ") + + long[@header] := frequency + + header[4] := ComputeClkmodeByte( clk_mode ) + +pri ComputeClkmodeByte( mode ) : m | b1, b2, i +{ +rcfast $001 exactly one 1 in 0000_0000_00xx incompatible with clkfreq/xinfreq +rcslow $002 + or +xinput $004 exactly one 1 in 0000_00xx_xx00 and requires clkfreq/xinfreq +xtal1 $008 up to one 1 in 0xxx_xx00_0000 +xtal2 $010 +xtal3 $020 +pll1x $040 +pll2x $080 +pll4x $100 +pll8x $200 +pll16x $400 +} + b1 := -1 ' b1 is the position of the single 1 in mode[5..0]. + repeat i from 0 to 5 + if mode & |< i + if b1 <> -1 + abort string("invalid _CLKMODE") ' only one 1 allowed + b1 := i + m := lookupz( b1: $00, $01, $22, $2a, $32, $3a ) + + b2 := -1 ' b2 is the position of single 1 in mode[10..6] (-1 if no 1 bit) + repeat i from 6 to 10 + if mode & |< i + if b2 <> -1 + abort string("invalid _CLKMODE (multiple PLL)") ' only one 1 allowed + b2 := i + + if b1 < 2 ' RCFAST/RCSLOW? + if b2 <> -1 ' b2 better not be set + abort string("invalid _CLKMODE (RC+PLL)") + else ' one of the X-modes + if b2 <> -1 + m |= $40 ' PLLENA + m += b2 - 5 + + +dat +ptrs word @s0, @s1, @s2, @s3, @s4 +s0 byte "_CLKFREQ", 0 +s1 byte "_XINFREQ", 0 +s2 byte "_CLKMODE", 0 +s3 byte "_FREE", 0 +s4 byte "_STACK", 0 + + +dat + long +header byte 0[16] +footer byte $ff, $ff, $f9, $ff + byte $ff, $ff, $f9, $ff + +con + MAXFILENAMELENGTH = 8 + 1 + 3 ' 8.3 + MAXEXPORTLENGTH = 32 + +var + byte stringBuffer[MAXEXPORTLENGTH+1] + byte sobName[MAXFILENAMELENGTH+1] + byte outputName[MAXFILENAMELENGTH+1] + +con +#0 +_pNext[2] +_pNextSorted[2] +_pName[2] +_nImports[2] +_pImports[2] +_pCounts[2] +_startAddress[2] +_objBinSize[2] +_totalVarSize[2] +_varSize[2] +_timestamp[4] +_exportImportSize[2] +_checksum[1] +_[1] ' for alignment: _SIZEOFSOBINFO must be a multiple of 4 +_SIZEOFSOBINFO + +SOBFILEFORMATVERSION = "S" + "O" << 8 + "B" << 16 + "1" << 24 ' "SOB1" + +dat +pSobSpace word 0 +SOBSSIZE word 0 +pDataSpace word 0 +pFirst word 0 +pLast word 0 +pLastSorted word 0 + +pri SobInit( p, size ) + pFirst := pSobSpace := p + SOBSSIZE := size + pDataSpace := pSobSpace + SOBSSIZE + + pLastSorted := pLast := pFirst + + word[pFirst +_pNext]~ + word[pFirst +_pNextSorted]~ + +pri ComputeAddressAndTotalVarSize( p, address ) : totalVarSize | pImports, pCounts, interObjectOffset +{{ + Go down the priority-sorted list of sobs assigning them hub addresses such that they follow one + another in memory. On the way back up the list, compute each sob's total VAR size (the sob's + own VARs plus its imported sobs' VARs.) + Also updates checksum. + Return value is the current sob's total VAR size. Only the top object's return value is looked at. +}} + ifnot p + return + + word[p +_startAddress] := address + address += word[p +_objBinSize] + + objBinEndAddress := address ' end address will point just beyond the last obj in hub memory. + ' Here we're just overwriting as we go and keeping the last one. + + ComputeAddressAndTotalVarSize( word[p +_pNextSorted], address ) + + checksum += byte[p +_checksum] ' this is the partial checksum of the obj (doesn't count its sub-object table because + ' sub-object links are not known until link time (i.e., now)) + totalVarSize := word[p +_varSize] + pImports := word[p +_pImports] + pCounts := word[p +_pCounts] + repeat word[p +_nImports] ' for each import, add the import's VAR size multiplied by its count + interObjectOffset := word[ word[pImports] +_startAddress] - word[p +_startAddress] + repeat word[pCounts] + AddToChecksum( @totalVarSize, 2 ) ' checksum needs to include this half of an object table entry + AddToChecksum( @interObjectOffset, 2 ) ' and this other half of an object table entry + + totalVarSize += word[ word[pImports] +_totalVarSize] + + pImports += 2 + pCounts += 2 + + word[p +_totalVarSize] := totalVarSize + +pri AddToChecksum( p, n ) + repeat n + checksum += byte[p++] + +pri AddSob( pName ) : p | n +{{ + Copies name to data area, appends name to the sobs list, returns pointer to new sob entry. +}} + if verbosity => 2 + term.str(string("adding ")) + term.str(pName) + term.out(13) + + p := pSobSpace + pSobSpace += _SIZEOFSOBINFO + + n := strsize(pName) + 1 + bytemove( Alloc(n), pName, n ) + + word[pLast +_pNext] := p + word[pLastSorted +_pNextSorted] := p + word[p +_pName] := pDataSpace + word[p +_pNext]~ + word[p +_pNextSorted]~ + pLast := p + pLastSorted := p + +pri Alloc( n ) + pDataSpace := (pDataSpace - n) & $fffffffc ' long-aligned + if pDataSpace < pSobSpace + abort string("Insufficient sob table space") + return pDataSpace + +pri FindSob( pName ) : p | pPrev +{{ + Search the sob list in priority order. If a sob in the list matches name, + update priority-order links to put the sob at the end and return a pointer to it. + Otherwise, return 0. +}} + p := pPrev := pFirst + repeat while p + if strcomp( word[p +_pName], pName ) + if p <> pLastSorted + word[pPrev +_pNextSorted] := word[p +_pNextSorted] + word[pLastSorted +_pNextSorted] := p + word[p +_pNextSorted]~ + pLastSorted := p + return + pPrev := p + p := word[p +_pNextSorted] + return 0 + +pri ProcessSob( p, top ) | len, numExports, exportSize, numImports, importSize, objBinSize, hash, pStart, temp, pImports, pCounts, ts0, ts1 +{{ + Reads the sob file identified by p, appends the sob's imports to the sob list, + then recursively processes the imported sobs. + top is true for the top sob, false for all other sobs. +}} + Str.Copy( @stringBuffer, word[p +_pName] ) + Str.Append( @stringBuffer, string(".SOB") ) + + if verbosity => 2 + term.str( string("Reading [") ) + term.str( @stringBuffer ) + term.out( "]" ) + term.out( 13 ) + + fs.Open( @stringBuffer, "R" ) + + if fs.Readlong <> SOBFILEFORMATVERSION ' SOB file format version + abort string("Unrecognized SOB file format") + long[p +_timestamp] := fs.Readlong ' timestamp + hash := fs.ReadLong ' hash + numExports := fs.ReadWord ' number of exports + exportSize := fs.ReadWord ' size of exports segment + numImports := fs.ReadWord ' number of imports + importSize := fs.ReadWord ' size of imports segment + word[p +_objBinSize] := fs.ReadWord ' size of bytecode segment + byte[p +_checksum] := fs.ReadByte ' checksum + fs.ReadByte ' padding + word[p +_varSize] := fs.ReadWord ' size of sob's VAR space + + ts0 := long[p +_timestamp] + + if top + ReadExports( numExports ) + else + fs.SkipBytes( exportSize ) + + word[p +_exportImportSize] := exportSize + importSize + + word[p +_nImports] := numImports + word[p +_pImports] := pImports := Alloc( numImports << 1 ) ' points to an array of sob pointers + word[p +_pCounts] := pCounts := Alloc( numImports << 1 ) ' points to an array of sob counts + + pStart := pLast + repeat numImports + fs.ReadStringUpperCase( @stringBuffer, 8 ) + ts1 := GetTimestamp( @stringBuffer ) + if ts0 and ts1 ' Only compare non-zero timestamps + if ts0 =< ts1 + term.str( word[p+_pName] ) + term.str( string(".SOB is older than ") ) + term.str( @stringBuffer ) + term.str( string(".SOB", 13) ) + outOfDate~~ + ifnot temp := FindSob( @stringBuffer ) + temp := AddSob( @stringBuffer ) + word[pImports] := temp + word[pCounts] := fs.ReadWord + fs.ReadByte ' reserved byte + if verbosity => 3 + term.str( word[ word[pImports] +_pName] ) + term.out( "*" ) + term.dec( word[pCounts] ) + term.out( 13 ) + pImports += 2 + pCounts += 2 + + if top + fs.SkipBytes( $4 ) ' look into the top sob's object header + firstPubOffset := fs.ReadWord ' and get offset to first pub + firstPubLocalsSize := fs.ReadWord ' and size of first pub's locals + + fs.Close + + ' Process the imported sobs + + pStart := word[pStart +_pNext] + repeat while pStart + ProcessSob( pStart, false ) + pStart := word[pStart +_pNext] + + if verbosity => 2 + term.str( string("done with ") ) + term.str( word[p +_pName] ) + term.out( 13 ) + +pri GetTimestamp( pFilename ) + str.Append( pFilename, string(".SOB") ) + fs[1].Open( pFilename, "R" ) + fs[1].ReadLong + result := fs[1].ReadLong + fs[1].Close + byte[pFilename][ strsize(pFilename) - 4 ]~ ' remove .SOB tail + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} + \ No newline at end of file diff --git a/zubehör/sphinx/hive-port/tokenizer/bintree.spin b/zubehör/sphinx/hive-port/tokenizer/bintree.spin new file mode 100644 index 0000000..62778ed --- /dev/null +++ b/zubehör/sphinx/hive-port/tokenizer/bintree.spin @@ -0,0 +1,238 @@ +obj + str: "stringx" + +dat +cog long 0 + +pub Init( p0, p1 ) + pFree := p0 ' leave some room for the stack, then free space. + pLimit := p1 + + Stop + sync~~ + cog := cognew( @LookerUpper, @input ) + 1 + ifnot cog + abort string("Couldn't start bintree cog") + repeat while sync + +pub Stop + if cog + cogstop( cog~ - 1 ) + +pub FindInTable( s, p ) | d +{{ + Finds string s in table pointed to by p. + Returns pointer to s's data area if s is found, 0 otherwise. +}} + input[0] := s + input[1] := p + sync~~ + repeat while sync + return output +{ + ifnot p + return 0 + d := str.Compare( s, p+4 ) + ifnot d + return p + 4 + strsize(s) + 1 + if d < 0 + return FindInTable( s, Peekw(p) ) + ' else + return FindInTable( s, Peekw(p+2) ) +} + +pub AddToTable( s, pP ) | p, d +{{ + Adds string s to table. Note: pP is a pointer-to-pointer to table. + Returns a pointer to s's data area (actually pFree, so if you add + any data, increment pFree past it). +}} + ifnot p := PeekW( pP ) + PokeW( pP, pFree ) + PokeW( pFree, 0 ) + pFree += 2 + PokeW( pFree, 0 ) + pFree += 2 + str.Copy( pFree, s ) + pFree += strsize(s) + 1 + return pFree + + d := str.Compare( s, p+4 ) +{ + term.dec(d) + term.out(13) + waitcnt( clkfreq + cnt ) +} + ifnot d + abort string("Symbol already defined") + if d < 0 + return AddToTable( s, @word[p][0] ) + ' else + return AddToTable( s, @word[p][1] ) + +pub PeekW( p ) + return byte[p++] + byte[p] << 8 + +pub PokeW( p, w ) + byte[p++] := w + byte[p] := w >> 8 + +pub PeekL( p ) : t + repeat 4 + t := (t | byte[p++]) -> 8 + +pub PokeL( p, l ) + repeat 4 + byte[p++] := l + l >>= 8 + +dat +pFree long 0 +pLimit long 0 + +pub Alloc( n ) + result := pFree + if (pFree += n) > pLimit + abort string("Out of symbol table space") + +dat +input long 0 ' rendezvous variables for LookerUpper +output long 0 +sync long 1 + +{ +This PASM routine is equivalent to the following: + +pub FindInTable( s, p ) | d +{{ + Finds string s in table pointed to by p. + Returns pointer to s's data area if s is found, 0 otherwise. +}} + ifnot p + return 0 + d := str.Compare( s, p+4 ) + ifnot d + return p + 4 + strsize(s) + 1 + if d < 0 + return FindInTable( s, Peekw(p) ) + ' else + return FindInTable( s, Peekw(p+2) ) +} + +dat org 0 +LookerUpper + mov pInput, par ' Enter with par pointing to rendezvous area, + mov pOutput, par ' sync = 1 + add pOutput, #4 + mov pSync, par + add pSync, #8 + + rdlong pTable, pInput ' Save @tableStart + ' and ack to inform Spin program that the cog is running. +Ack + wrlong retval, pOutput + mov temp, #0 + wrlong temp, pSync + +:wait ' Wait for caller to set sync to indicate that input is ready. + rdlong temp, pSync wz + if_z jmp #:wait + + rdlong pString, pInput ' input[0] points to string to look up. + rdlong ptr, pOutput ' input[1] points to table. (input[1] = output) + + mov retval, #0 +:loop + tjz ptr, #Ack + + mov pLeft, pString ' Compare string + mov pRight, ptr ' to string at current position in table + add pRight, #4 ' (bump up ptr by 4 to skip two link words). + + call #StringCompare + + if_e jmp #:equal + if_b jmp #:less +:greater ' If left > right, + add ptr, #2 ' use the 2nd link. +:less ' If left < right, use 1st link. + rdbyte temp, ptr ' Follow the link + add ptr, #1 ' It would be nice to just "rdword ptr, ptr" here + rdbyte ptr, ptr ' but ptr might be odd so we have to go through + shl ptr, #8 ' some extra gyrations. + add ptr, temp + + jmp #:loop ' and recurse (well, just iterate). + +:equal ' If left = right, return ptr + 4 + strsize(pString) + 1 + mov retval, ptr + add retval, #5 +:x + rdbyte temp, pString wz ' add strsize(pString) + if_z jmp #:y + add retval, #1 + add pString, #1 + jmp #:x +:y + jmp #Ack + +StringCompare +' Compares zero-terminated strings pointed to by pLeft and pRight. +' On return, Z and C are set appropriately. + rdbyte temp, pLeft wz + add pLeft, #1 + if_z jmp #:leftEnd + rdbyte temp1, pRight wz + add pRight, #1 + if_z jmp #:rightEnd + cmp temp, temp1 wc, wz + if_e jmp #StringCompare ' If they match, try the next pair. + jmp #StringCompare_ret ' Otherwise, we're done. + +:leftEnd rdbyte temp1, pRight wz ' If we're at the end of both strings, + if_z jmp #StringCompare_ret ' leave (with Z set). + ' Otherwise, left string is shorter than the right + ' and therefore less. + neg temp, #1 + mov temp, temp wc, wz ' Set C=1 and Z=0 for "less than" + jmp #StringCompare_ret +:rightEnd ' Here we've reached the end of the right string. + ' The left string is longer than the right + ' and therefore greater. + mov temp, #1 wc, wz ' Set C=0 and Z=0 for "greater than" + +StringCompare_ret + ret + +temp res 1 +temp1 res 1 +ptr res 1 +pLeft res 1 +pRight res 1 +pString res 1 +pTable res 1 +pInput res 1 +pOutput res 1 +pSync res 1 +retval res 1 + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} + + \ No newline at end of file diff --git a/zubehör/sphinx/hive-port/tokenizer/fltmath.spin b/zubehör/sphinx/hive-port/tokenizer/fltmath.spin new file mode 100644 index 0000000..4204f99 --- /dev/null +++ b/zubehör/sphinx/hive-port/tokenizer/fltmath.spin @@ -0,0 +1,219 @@ +''*************************************** +''* Floating-Point Math * +''* Single-precision IEEE-754 * +''* Author: Chip Gracey * +''* Copyright (c) 2006 Parallax, Inc. * +''* See end of file for terms of use. * +''*************************************** + + +PUB FFloat(integer) : single | s, x, m + +''Convert integer to float + + if m := ||integer 'absolutize mantissa, if 0, result 0 + s := integer >> 31 'get sign + x := >|m - 1 'get exponent + m <<= 31 - x 'msb-justify mantissa + m >>= 2 'bit29-justify mantissa + + return Pack(@s) 'pack result + + +PUB FRound(single) : integer + +''Convert float to rounded integer + + return FInteger(single, 1) 'use 1/2 to round + + +PUB FTrunc(single) : integer + +''Convert float to truncated integer + + return FInteger(single, 0) 'use 0 to round + + +PUB FNeg(singleA) : single + +''Negate singleA + + return singleA ^ $8000_0000 'toggle sign bit + + +PUB FAbs(singleA) : single + +''Absolute singleA + + return singleA & $7FFF_FFFF 'clear sign bit + + +PUB FSqr(singleA) : single | s, x, m, root + +''Compute square root of singleA + + if singleA > 0 'if a =< 0, result 0 + + Unpack(@s, singleA) 'unpack input + + m >>= !x & 1 'if exponent even, shift mantissa down + x ~>= 1 'get root exponent + + root := $4000_0000 'compute square root of mantissa + repeat 31 + result |= root + if result ** result > m + result ^= root + root >>= 1 + m := result >> 1 + + return Pack(@s) 'pack result + + +PUB FAdd(singleA, singleB) : single | sa, xa, ma, sb, xb, mb + +''Add singleA and singleB + + Unpack(@sa, singleA) 'unpack inputs + Unpack(@sb, singleB) + + if sa 'handle mantissa negation + -ma + if sb + -mb + + result := ||(xa - xb) <# 31 'get exponent difference + if xa > xb 'shift lower-exponent mantissa down + mb ~>= result + else + ma ~>= result + xa := xb + + ma += mb 'add mantissas + sa := ma < 0 'get sign + ||ma 'absolutize result + + return Pack(@sa) 'pack result + + +PUB FSub(singleA, singleB) : single + +''Subtract singleB from singleA + + return FAdd(singleA, FNeg(singleB)) + + +PUB FMul(singleA, singleB) : single | sa, xa, ma, sb, xb, mb + +''Multiply singleA by singleB + + Unpack(@sa, singleA) 'unpack inputs + Unpack(@sb, singleB) + + sa ^= sb 'xor signs + xa += xb 'add exponents + ma := (ma ** mb) << 3 'multiply mantissas and justify + + return Pack(@sa) 'pack result + + +PUB FDiv(singleA, singleB) : single | sa, xa, ma, sb, xb, mb + +''Divide singleA by singleB + + Unpack(@sa, singleA) 'unpack inputs + Unpack(@sb, singleB) + + sa ^= sb 'xor signs + xa -= xb 'subtract exponents + + repeat 30 'divide mantissas + result <<= 1 + if ma => mb + ma -= mb + result++ + ma <<= 1 + ma := result + + return Pack(@sa) 'pack result + + +PRI FInteger(a, r) : integer | s, x, m + +'Convert float to rounded/truncated integer + + Unpack(@s, a) 'unpack input + + if x => -1 and x =< 30 'if exponent not -1..30, result 0 + m <<= 2 'msb-justify mantissa + m >>= 30 - x 'shift down to 1/2-lsb + m += r 'round (1) or truncate (0) + m >>= 1 'shift down to lsb + if s 'handle negation + -m + return m 'return integer + + +PRI Unpack(pointer, single) | s, x, m + +'Unpack floating-point into (sign, exponent, mantissa) at pointer + + s := single >> 31 'unpack sign + x := single << 1 >> 24 'unpack exponent + m := single & $007F_FFFF 'unpack mantissa + + if x 'if exponent > 0, + m := m << 6 | $2000_0000 '..bit29-justify mantissa with leading 1 + else + result := >|m - 23 'else, determine first 1 in mantissa + x := result '..adjust exponent + m <<= 7 - result '..bit29-justify mantissa + + x -= 127 'unbias exponent + + longmove(pointer, @s, 3) 'write (s,x,m) structure from locals + + +PRI Pack(pointer) : single | s, x, m + +'Pack floating-point from (sign, exponent, mantissa) at pointer + + longmove(@s, pointer, 3) 'get (s,x,m) structure into locals + + if m 'if mantissa 0, result 0 + + result := 33 - >|m 'determine magnitude of mantissa + m <<= result 'msb-justify mantissa without leading 1 + x += 3 - result 'adjust exponent + + m += $00000100 'round up mantissa by 1/2 lsb + if not m & $FFFFFF00 'if rounding overflow, + x++ '..increment exponent + + x := x + 127 #> -23 <# 255 'bias and limit exponent + + if x < 1 'if exponent < 1, + m := $8000_0000 + m >> 1 '..replace leading 1 + m >>= -x '..shift mantissa down by exponent + x~ '..exponent is now 0 + + return s << 31 | x << 23 | m >> 9 'pack result + +{{ + ++------------------------------------------------------------------------------------------------------------------------------+ +¦ TERMS OF USE: MIT License ¦ ++------------------------------------------------------------------------------------------------------------------------------¦ +¦Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation ¦ +¦files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, ¦ +¦modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software¦ +¦is furnished to do so, subject to the following conditions: ¦ +¦ ¦ +¦The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.¦ +¦ ¦ +¦THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE ¦ +¦WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ¦ +¦COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ¦ +¦ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ¦ ++------------------------------------------------------------------------------------------------------------------------------+ +}} \ No newline at end of file diff --git a/zubehör/sphinx/hive-port/tokenizer/fltstr.spin b/zubehör/sphinx/hive-port/tokenizer/fltstr.spin new file mode 100644 index 0000000..b997b59 --- /dev/null +++ b/zubehör/sphinx/hive-port/tokenizer/fltstr.spin @@ -0,0 +1,534 @@ +''***************************************** +''* Floating-Point <-> Strings v 1.2 * +''* Single-precision IEEE-754 * +''* Authors: Chip Gracey and Cam Thompson * +''* (C) 2006 Parallax, Inc. * +''* See end of file for terms of use. * +''***************************************** + +'' v1.0 - 01 May 2006 - original version +'' v1.1 - 12 Jul 2006 - added FloatToFormat routine +'' v1.2 - 06 Mar 2009 - added StringToFloat [mpark] +VAR + + long p, digits, exponent, integer, tens, zeros, precision + long positive_chr, decimal_chr, thousands_chr, thousandths_chr + byte float_string[20] + + +OBJ + ' The F object can be FloatMath, Float32 or Float32Full depending on the application + F : "FltMath" + +PUB FloatToString(Single) : StringPtr + +''Convert floating-point number to string +'' +'' entry: +'' Single = floating-point number +'' +'' exit: +'' StringPtr = pointer to resultant z-string +'' +'' Magnitudes below 1e+12 and within 1e-12 will be expressed directly; +'' otherwise, scientific notation will be used. +'' +'' examples results +'' ----------------------------------------- +'' FloatToString(0.0) "0" +'' FloatToString(1.0) "1" +'' FloatToString(-1.0) "-1" +'' FloatToString(^^2.0) "1.414214" +'' FloatToString(2.34e-3) "0.00234" +'' FloatToString(-1.5e-5) "-0.000015" +'' FloatToString(2.7e+6) "2700000" +'' FloatToString(1e11) "100000000000" +'' FloatToString(1e12) "1.000000e+12" +'' FloatToString(1e-12) "0.000000000001" +'' FloatToString(1e-13) "1.000000e-13" + + 'perform initial setup + StringPtr := Setup(Single) + + 'eliminate trailing zeros + if integer + repeat until integer // 10 + integer /= 10 + tens /= 10 + digits-- + else + digits~ + + 'express number according to exponent + case exponent + 'in range left of decimal + 11..0: + AddDigits(exponent + 1) + 'in range right of decimal + -1..digits - 13: + zeros := -exponent + AddDigits(1) + 'out of range, do scientific notation + other: + DoScientific + + 'terminate z-string + byte[p]~ + + +PUB FloatToScientific(Single) : StringPtr + +''Convert floating-point number to scientific-notation string +'' +'' entry: +'' Single = floating-point number +'' +'' exit: +'' StringPtr = pointer to resultant z-string +'' +'' examples results +'' ------------------------------------------------- +'' FloatToScientific(1e-9) "1.000000e-9" +'' FloatToScientific(^^2.0) "1.414214e+0" +'' FloatToScientific(0.00251) "2.510000e-3" +'' FloatToScientific(-0.0000150043) "-1.500430e-5" + + 'perform initial setup + StringPtr := Setup(Single) + + 'do scientific notation + DoScientific + + 'terminate z-string + byte[p]~ + + +PUB FloatToMetric(Single, SuffixChr) : StringPtr | x, y + +''Convert floating-point number to metric string +'' +'' entry: +'' Single = floating-point number +'' SuffixChr = optional ending character (0=none) +'' +'' exit: +'' StringPtr = pointer to resultant z-string +'' +'' Magnitudes within the metric ranges will be expressed in metric +'' terms; otherwise, scientific notation will be used. +'' +'' range name symbol +'' ----------------------- +'' 1e24 yotta Y +'' 1e21 zetta Z +'' 1e18 exa E +'' 1e15 peta P +'' 1e12 tera T +'' 1e9 giga G +'' 1e6 mega M +'' 1e3 kilo k +'' 1e0 - - +'' 1e-3 milli m +'' 1e-6 micro u +'' 1e-9 nano n +'' 1e-12 pico p +'' 1e-15 femto f +'' 1e-18 atto a +'' 1e-21 zepto z +'' 1e-24 yocto y +'' +'' examples results +'' ------------------------------------ +'' metric(2000.0, "m") "2.000000km" +'' metric(-4.5e-5, "A") "-45.00000uA" +'' metric(2.7e6, 0) "2.700000M" +'' metric(39e31, "W") "3.9000e+32W" + + 'perform initial setup + StringPtr := Setup(Single) + + 'determine thousands exponent and relative tens exponent + x := (exponent + 45) / 3 - 15 + y := (exponent + 45) // 3 + + 'if in metric range, do metric + if ||x =< 8 + 'add digits with possible decimal + AddDigits(y + 1) + 'if thousands exponent not 0, add metric indicator + if x + byte[p++] := " " + byte[p++] := metric[x] + 'if out of metric range, do scientific notation + else + DoScientific + + 'if SuffixChr not 0, add SuffixChr + if SuffixChr + byte[p++] := SuffixChr + + 'terminate z-string + byte[p]~ + + +PUB FloatToFormat(single, width, dp) : stringptr | n, w2 + +''Convert floating-point number to formatted string +'' +'' entry: +'' Single = floating-point number +'' width = width of field +'' dp = number of decimal points +'' +'' exit: +'' StringPtr = pointer to resultant z-string +'' +'' asterisks are displayed for format errors +'' leading blank fill is used + + ' get string pointer + stringptr := p := @float_string + + ' width must be 1 to 9, dp must be 0 to width-1 + w2 := width := width #> 1 <# 9 + dp := dp #> 0 <# (width - 2) + if dp > 0 + w2-- + if single & $8000_0000 or positive_chr + w2-- + + ' get positive scaled integer value + n := F.FRound(F.FMul(single & $7FFF_FFFF , F.FFloat(teni[dp]))) + + if n => teni[w2] + ' if format error, display asterisks + repeat while width + if --width == dp + if decimal_chr + byte[p++] := decimal_chr + else + byte[p++] := "." + else + byte[p++] := "*" + byte[p]~ + + else + ' store formatted number + p += width + byte[p]~ + + repeat width + byte[--p] := n // 10 + "0" + n /= 10 + if --dp == 0 + if decimal_chr + byte[--p] := decimal_chr + else + byte[--p] := "." + if n == 0 and dp < 0 + quit + + ' store sign + if single & $80000000 + byte[--p] := "-" + elseif positive_chr + byte[--p] := positive_chr + ' leading blank fill + repeat while p <> stringptr + byte[--p] := " " + +PUB SetPrecision(NumberOfDigits) + +''Set precision to express floating-point numbers in +'' +'' NumberOfDigits = Number of digits to round to, limited to 1..7 (7=default) +'' +'' examples results +'' ------------------------------- +'' SetPrecision(1) "1e+0" +'' SetPrecision(4) "1.000e+0" +'' SetPrecision(7) "1.000000e+0" + + precision := NumberOfDigits + + +PUB SetPositiveChr(PositiveChr) + +''Set lead character for positive numbers +'' +'' PositiveChr = 0: no character will lead positive numbers (default) +'' non-0: PositiveChr will lead positive numbers (ie " " or "+") +'' +'' examples results +'' ---------------------------------------- +'' SetPositiveChr(0) "20.07" "-20.07" +'' SetPositiveChr(" ") " 20.07" "-20.07" +'' SetPositiveChr("+") "+20.07" "-20.07" + + positive_chr := PositiveChr + + +PUB SetDecimalChr(DecimalChr) + +''Set decimal point character +'' +'' DecimalChr = 0: "." will be used (default) +'' non-0: DecimalChr will be used (ie "," for Europe) +'' +'' examples results +'' ---------------------------- +'' SetDecimalChr(0) "20.49" +'' SetDecimalChr(",") "20,49" + + decimal_chr := DecimalChr + + +PUB SetSeparatorChrs(ThousandsChr, ThousandthsChr) + +''Set thousands and thousandths separator characters +'' +'' ThousandsChr = +'' 0: no character will separate thousands (default) +'' non-0: ThousandsChr will separate thousands +'' +'' ThousandthsChr = +'' 0: no character will separate thousandths (default) +'' non-0: ThousandthsChr will separate thousandths +'' +'' examples results +'' ----------------------------------------------------------- +'' SetSeparatorChrs(0, 0) "200000000" "0.000729345" +'' SetSeparatorChrs(0, "_") "200000000" "0.000_729_345" +'' SetSeparatorChrs(",", 0) "200,000,000" "0.000729345" +'' SetSeparatorChrs(",", "_") "200,000,000" "0.000_729_345" + + thousands_chr := ThousandsChr + thousandths_chr := ThousandthsChr + + +PUB StringToFloat(strptr) : flt | significand, ssign, places, exp, esign +{{ + Converts string to floating-point number + entry: + strptr = pointer to z-string + + exit: + flt = floating-point number + + + Assumes the following floating-point syntax: [-] [0-9]* [ . [0-9]* ] [ e|E [-|+] [0-9]* ] + +-- +----- +----------- +------------------- + ¦ ¦ ¦ ¦ +---- +----- + Optional negative sign --------------------+ ¦ ¦ ¦ ¦ ¦ + Digits ----------------------------------------+ ¦ ¦ ¦ ¦ + Optional decimal point followed by digits ------------+ ¦ ¦ ¦ + Optional exponent -------------------------------------------------+ ¦ ¦ + optional exponent sign ------------------------------------------------+ ¦ + exponent digits -------------------------------------------------------------+ + + Examples of recognized floating-point numbers: + "123", "-123", "123.456", "123.456e+09" + Conversion stops as soon as an invalid character is encountered. No error-checking. + + Based on Ariba's StrToFloat in http://forums.parallax.com/forums/default.aspx?f=25&m=280607 + Expanded by Michael Park +}} + significand~ + ssign~ + exp~ + esign~ + places~ + repeat + case byte[strptr] + "-": + ssign~~ + ".": + places := 1 + "0".."9": + significand := significand * 10 + byte[strptr] - "0" + if places + ++places 'count decimal places + "e", "E": + ++strptr ' skip over the e or E + repeat + case byte[strptr] + "+": + ' ignore + "-": + esign~~ + "0".."9": + exp := exp * 10 + byte[strptr] - "0" + other: + quit + ++strptr + quit + other: + quit + ++strptr + + if ssign + -significand + flt := f.FFloat(significand) + + ifnot esign ' tenf table is in decreasing order, so the sign of exp is reversed + -exp + + if places + exp += places - 1 + + flt := f.FMul(flt, tenf[exp]) 'adjust flt's decimal point + + +PRI Setup(single) : stringptr + + 'limit digits to 1..7 + if precision + digits := precision #> 1 <# 7 + else + digits := 7 + + 'initialize string pointer + p := @float_string + + 'add "-" if negative + if single & $80000000 + byte[p++] := "-" + 'otherwise, add any positive lead character + elseif positive_chr + byte[p++] := positive_chr + + 'clear sign and check for 0 + if single &= $7FFFFFFF + + 'not 0, estimate exponent + exponent := ((single << 1 >> 24 - 127) * 77) ~> 8 + + 'if very small, bias up + if exponent < -32 + single := F.FMul(single, 1e13) + exponent += result := 13 + + 'determine exact exponent and integer + repeat + integer := F.FRound(F.FMul(single, tenf[exponent - digits + 1])) + if integer < teni[digits - 1] + exponent-- + elseif integer => teni[digits] + exponent++ + else + exponent -= result + quit + + 'if 0, reset exponent and integer + else + exponent~ + integer~ + + 'set initial tens and clear zeros + tens := teni[digits - 1] + zeros~ + + 'return pointer to string + stringptr := @float_string + + +PRI DoScientific + + 'add digits with possible decimal + AddDigits(1) + 'add exponent indicator + byte[p++] := "e" + 'add exponent sign + if exponent => 0 + byte[p++] := "+" + else + byte[p++] := "-" + ||exponent + 'add exponent digits + if exponent => 10 + byte[p++] := exponent / 10 + "0" + exponent //= 10 + byte[p++] := exponent + "0" + + +PRI AddDigits(leading) | i + + 'add leading digits + repeat i := leading + AddDigit + 'add any thousands separator between thousands + if thousands_chr + i-- + if i and not i // 3 + byte[p++] := thousands_chr + 'if trailing digits, add decimal character + if digits + AddDecimal + 'then add trailing digits + repeat while digits + 'add any thousandths separator between thousandths + if thousandths_chr + if i and not i // 3 + byte[p++] := thousandths_chr + i++ + AddDigit + + +PRI AddDigit + + 'if leading zeros, add "0" + if zeros + byte[p++] := "0" + zeros-- + 'if more digits, add current digit and prepare next + elseif digits + byte[p++] := integer / tens + "0" + integer //= tens + tens /= 10 + digits-- + 'if no more digits, add "0" + else + byte[p++] := "0" + + +PRI AddDecimal + + if decimal_chr + byte[p++] := decimal_chr + else + byte[p++] := "." + + +DAT + long 1e+38, 1e+37, 1e+36, 1e+35, 1e+34, 1e+33, 1e+32, 1e+31 + long 1e+30, 1e+29, 1e+28, 1e+27, 1e+26, 1e+25, 1e+24, 1e+23, 1e+22, 1e+21 + long 1e+20, 1e+19, 1e+18, 1e+17, 1e+16, 1e+15, 1e+14, 1e+13, 1e+12, 1e+11 + long 1e+10, 1e+09, 1e+08, 1e+07, 1e+06, 1e+05, 1e+04, 1e+03, 1e+02, 1e+01 +tenf long 1e+00, 1e-01, 1e-02, 1e-03, 1e-04, 1e-05, 1e-06, 1e-07, 1e-08, 1e-09 + long 1e-10, 1e-11, 1e-12, 1e-13, 1e-14, 1e-15, 1e-16, 1e-17, 1e-18, 1e-19 + long 1e-20, 1e-21, 1e-22, 1e-23, 1e-24, 1e-25, 1e-26, 1e-27, 1e-28, 1e-29 + long 1e-30, 1e-31, 1e-32, 1e-33, 1e-34, 1e-35, 1e-36, 1e-37, 1e-38 + +teni long 1, 10, 100, 1_000, 10_000, 100_000, 1_000_000, 10_000_000, 100_000_000, 1_000_000_000 + + byte "yzafpnum" +metric byte 0 + byte "kMGTPEZY" + +{{ ++------------------------------------------------------------------------------------------------------------------------------+ +¦ TERMS OF USE: MIT License ¦ ++------------------------------------------------------------------------------------------------------------------------------¦ +¦Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation ¦ +¦files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, ¦ +¦modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software¦ +¦is furnished to do so, subject to the following conditions: ¦ +¦ ¦ +¦The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.¦ +¦ ¦ +¦THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE ¦ +¦WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ¦ +¦COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ¦ +¦ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ¦ ++------------------------------------------------------------------------------------------------------------------------------+ +}} \ No newline at end of file diff --git a/zubehör/sphinx/hive-port/tokenizer/keywords.spin b/zubehör/sphinx/hive-port/tokenizer/keywords.spin new file mode 100644 index 0000000..612a0e4 --- /dev/null +++ b/zubehör/sphinx/hive-port/tokenizer/keywords.spin @@ -0,0 +1,530 @@ +obj + bt: "bintree" + +pub Init + + tableStart += @tableStart + FixupTable( @tableStart + 2 ) + +pri FixupTable( p ) | q + q := bt.PeekW( p ) + if q + bt.PokeW( p, q += @tableStart ) + FixupTable( q ) + q := bt.PeekW( p + 2 ) + if q + bt.PokeW( p + 2, q += @tableStart ) + FixupTable( q ) + +pub KeywordLookup( s ) + return bt.FindInTable( s, tableStart ) + +con +{ + 31 (plain ID) + 30 (int literal) + 29 (float literal) + 28 ? + 27 unary + 26 binary/postfix + 25 pasm (TJZ, XOR) + 24 cond (IF_Z, IF_E) + 23 effect (WC, WZ) + 22 stmtfn (BYTEMOVE, WAITCNT) + 21 assignment op (-=, OR=) + 20 intrinsic + 19 prec3 + 18 prec2 + 17 d prec1 + 16 s prec0 + 15 pasmop spinop7 + 14 pasmop spinop6 + 13 pasmop spinop5 keyword + 12 pasmop spinop4 uniquifier + 11 pasmop spinop3 bits + 10 pasmop spinop2 | + 9 pasmop spinop1 | #args + 8 pasmop spinop0 V #args + 7 pasmop spinop7 id7 op + 6 pasmop spinop6 id6 op + 5 pasmop spinop5 id5 op + 4 pasmop spinop4 id4 op + 3 pasmop spinop3 cond3 id3 effect op + 2 pasmop spinop2 cond2 id2 effect op + 1 pasmop spinop1 cond1 id1 effect op + 0 pasmop spinop0 cond0 id0 effect op +} +con ' The following is auto-generated. Do not edit. + kID = $80000000 + kINTLITERAL = $40000000 + kFLOATLITERAL = $20000000 + kUNARY = $08000000 + kBINARY = $04000000 + kPOSTFIX = $04000000 + kPASM = $02000000 + kCOND = $01000000 + kEFFECT = $00800000 + kSTMTFN = $00400000 + kASSIGNMENT = $00200000 + kINTRINSIC = $00100000 + +' kBANG = $080100e7 +' kOCTOTHORPRANGLE = $040700e4 +' kAMPERSAND = $040300e8 +' kSTAR = $040500f4 +' kSTARSTAR = $040500f5 + kPLUS = $040600ec +' kPLUSPLUS = $0c002820 + kMINUS = $040600ed +' kMINUSMINUS = $0c003830 +' kMINUSRANGLE = $040200e0 +' kSLASH = $040500f6 +' kSLASHSLASH = $040500f7 +' kLANGLE = $040800f9 +' kLANGLEOCTOTHORP = $040700e5 +' kLANGLEMINUS = $040200e1 +' kLANGLELANGLE = $040200e3 +' kLANGLERANGLE = $040800fb +' kEQUALLANGLE = $040800fd +' kEQUALEQUAL = $040800fc +' kEQUALRANGLE = $040800fe +' kRANGLE = $040800fa +' kRANGLELANGLE = $040200ef +' kRANGLERANGLE = $040200e2 +' kRANGLEBAR = $080100f1 + kQUESTION = $0c000c08 + kAT = $08000000 + kATAT = $08000001 +' kCARET = $040400eb +' kCARETCARET = $080100f8 + kBAR = $040400ea +' kBARLANGLE = $080100f3 +' kBARBAR = $080100e9 + kTILDE = $0c001810 +' kTILDERANGLE = $040200ee + kTILDETILDE = $0c001c14 + kAND = $060a00f0 +' kNOT = $080900ff + kOR = $060b00f2 +' kABS = $0203a8bc +' kABSNEG = $0203acbc +' kADD = $020380bc +' kADDABS = $020388bc +' kADDS = $0203d0bc +' kADDSX = $0203d8bc +' kADDX = $0203c8bc +' kANDN = $020364bc + kCALL = $02015cfc +' kCMP = $0203843c +' kCMPS = $0203c03c +' kCMPSUB = $0203e0bc +' kCMPSX = $0203c43c +' kCMPX = $0203cc3c +' kDJNZ = $0203e4bc +' kHUBOP = $02030c3c +' kJMP = $02015c3c +' kJMPRET = $02035cbc +' kMAX = $02034cbc +' kMAXS = $020344bc +' kMIN = $020348bc +' kMINS = $020340bc +' kMOV = $0203a0bc +' kMOVD = $020354bc +' kMOVI = $020358bc +' kMOVS = $020350bc +' kMUXC = $020370bc +' kMUXNC = $020374bc +' kMUXNZ = $02037cbc +' kMUXZ = $020378bc +' kNEG = $0203a4bc +' kNEGC = $0203b0bc +' kNEGNC = $0203b4bc +' kNEGNZ = $0203bcbc +' kNEGZ = $0203b8bc +' kNOP = $02000000 +' kRCL = $020334bc +' kRCR = $020330bc +' kRDBYTE = $020300bc +' kRDLONG = $020308bc +' kRDWORD = $020304bc +' kRET = $02005c7c +' kREV = $02033cbc +' kROL = $020324bc +' kROR = $020320bc +' kSAR = $020338bc +' kSHL = $02032cbc +' kSHR = $020328bc +' kSUB = $020384bc +' kSUBABS = $02038cbc +' kSUBS = $0203d4bc +' kSUBSX = $0203dcbc +' kSUBX = $0203ccbc +' kSUMC = $020390bc +' kSUMNC = $020394bc +' kSUMNZ = $02039cbc +' kSUMZ = $020398bc +' kTEST = $0203603c +' kTJNZ = $0203e83c +' kTJZ = $0203ec3c +' kWRBYTE = $0203003c +' kWRLONG = $0203083c +' kWRWORD = $0203043c +' kXOR = $02036cbc + kPAR = $00000001 +' kCNT = $00000002 +' kINA = $00000003 +' kINB = $00000004 +' kOUTA = $00000005 +' kOUTB = $00000006 +' kDIRA = $00000007 +' kDIRB = $00000008 +' kCTRA = $00000009 +' kCTRB = $0000000a +' kFRQA = $0000000b +' kFRQB = $0000000c +' kPHSA = $0000000d +' kPHSB = $0000000e +' kVCFG = $0000000f + kVSCL = $00000010 +' kIF_A = $01000001 +' kIF_AE = $01000003 +' kIF_ALWAYS = $0100000f +' kIF_B = $0100000c +' kIF_BE = $0100000e +' kIF_C = $0100000c +' kIF_C_AND_NZ = $01000004 +' kIF_C_AND_Z = $01000008 +' kIF_C_EQ_Z = $01000009 +' kIF_C_NE_Z = $01000006 +' kIF_C_OR_NZ = $0100000d +' kIF_C_OR_Z = $0100000e +' kIF_E = $0100000a +' kIF_NC = $01000003 +' kIF_NC_AND_NZ = $01000001 +' kIF_NC_AND_Z = $01000002 +' kIF_NC_OR_NZ = $01000007 +' kIF_NC_OR_Z = $0100000b +' kIF_NE = $01000005 +' kIF_NEVER = $01000000 +' kIF_NZ = $01000005 +' kIF_NZ_AND_C = $01000004 +' kIF_NZ_AND_NC = $01000001 +' kIF_NZ_OR_C = $0100000e +' kIF_NZ_OR_NC = $0100000b +' kIF_Z = $0100000a +' kIF_Z_AND_C = $01000008 +' kIF_Z_AND_NC = $01000002 +' kIF_Z_EQ_C = $01000009 +' kIF_Z_NE_C = $01000006 +' kIF_Z_OR_C = $0100000e +' kIF_Z_OR_NC = $0100000b +' kNR = $00800008 +' kWC = $00800002 +' kWR = $00800001 +' kWZ = $00800004 + kCON = $00000011 + kDAT = $00000012 + kOBJ = $00000013 + kPRI = $00000014 + kPUB = $00000015 + kVAR = $00000016 + kBYTE = $00000017 + kWORD = $00000018 + kLONG = $00000019 +' kBYTEFILL = $00400318 +' kWORDFILL = $00400319 +' kLONGFILL = $0040031a +' kBYTEMOVE = $0040031c +' kWORDMOVE = $0040031d +' kLONGMOVE = $0040031e + kCLKSET = $02400220 + kCOGSTOP = $02400121 +' kLOCKRET = $00400122 + kWAITCNT = $02400123 + kWAITPEQ = $0240031b + kWAITPNE = $0240031f + kWAITVID = $02400227 + kOCTOTHORP = $0000001a +' kDOLLAR = $0000001b + kLPAREN = $0000001c + kRPAREN = $0000001d + kCOMMA = $0000001e + kDOT = $0000001f + kDOTDOT = $00000020 + kCOLON = $00000021 + kCOLONEQUAL = $00200022 + kEQUAL = $00000023 + kABORT = $00000024 + kCASE = $00000025 + kCHIPVER = $00100000 + kCLKFREQ = $00100010 + kCLKMODE = $00100020 + kCOGID = $02100003 + kCOGINIT = $02100004 + kCOGNEW = $00100005 + kREBOOT = $00100006 +' kSTRCOMP = $00100172 +' kSTRSIZE = $00100161 +' kLOCKCLR = $0012b2f1 +' kLOCKNEW = $001292d0 +' kLOCKSET = $0012a2e1 +' kLOOKDOWN = $00113111 +' kLOOKDOWNZ = $00113110 +' kLOOKUP = $00112101 +' kLOOKUPZ = $00112100 + kCONSTANT = $00000026 + kELSE = $00000027 + kELSEIF = $00000028 + kELSEIFNOT = $00000029 +' kFILE = $0000002a + kFIT = $0000002b +' kFLOAT = $0000002c + kFROM = $0000002d + kIF = $0000002e + kIFNOT = $0000002f + kNEXT = $00000030 + kORG = $00000031 +' kORGX = $00000032 + kOTHER = $00000033 + kQUIT = $00000034 + kREPEAT = $00000035 + kRES = $00000036 + kRESULT = $00000037 + kRETURN = $00000038 +' kROUND = $00000039 + kSPR = $0000003a + kSTEP = $0000003b + kSTRING = $0000003c + kTO = $0000003d +' kTRUNC = $0000003e + kUNTIL = $0000003f + kWHILE = $00000040 + kLBRACKET = $00000041 + kBACKSLASH = $00000042 + kRBRACKET = $00000043 + kLBRACE = $00000044 + kRBRACE = $00000045 + kEOL = $000000fd + kEOF = $000000fe + kUNKNOWN = $000000ff +dat +tableStart word $0002 + + byte $0e,$00,$63,$06,$49,$4e,$41,$00,$03,$00,$00,$00,$1c,$00,$d6,$02 + byte $43,$4d,$50,$53,$58,$00,$3c,$c4,$03,$02,$27,$00,$57,$01,$3d,$3e + byte $00,$fe,$00,$08,$04,$32,$00,$c2,$00,$2d,$3e,$00,$e0,$00,$02,$04 + byte $3c,$00,$83,$00,$2a,$00,$f4,$00,$05,$04,$46,$00,$65,$00,$24,$00 + byte $1b,$00,$00,$00,$50,$00,$5a,$00,$23,$00,$1a,$00,$00,$00,$00,$00 + byte $00,$00,$21,$00,$e7,$00,$01,$08,$00,$00,$00,$00,$23,$3e,$00,$e4 + byte $00,$07,$04,$6f,$00,$79,$00,$28,$00,$1c,$00,$00,$00,$00,$00,$00 + byte $00,$26,$00,$e8,$00,$03,$04,$00,$00,$00,$00,$29,$00,$1d,$00,$00 + byte $00,$8d,$00,$ad,$00,$2c,$00,$1e,$00,$00,$00,$97,$00,$a2,$00,$2b + byte $00,$ec,$00,$06,$04,$00,$00,$00,$00,$2a,$2a,$00,$f5,$00,$05,$04 + byte $00,$00,$00,$00,$2b,$2b,$00,$20,$28,$00,$0c,$b8,$00,$00,$00,$2d + byte $2d,$00,$30,$38,$00,$0c,$00,$00,$00,$00,$2d,$00,$ed,$00,$06,$04 + byte $cd,$00,$16,$01,$3c,$23,$00,$e5,$00,$07,$04,$d8,$00,$f7,$00,$2f + byte $2f,$00,$f7,$00,$05,$04,$e3,$00,$ed,$00,$2e,$2e,$00,$20,$00,$00 + byte $00,$00,$00,$00,$00,$2e,$00,$1f,$00,$00,$00,$00,$00,$00,$00,$2f + byte $00,$f6,$00,$05,$04,$02,$01,$0c,$01,$3a,$3d,$00,$22,$00,$20,$00 + byte $00,$00,$00,$00,$3a,$00,$21,$00,$00,$00,$00,$00,$00,$00,$3c,$00 + byte $f9,$00,$08,$04,$20,$01,$41,$01,$3d,$00,$23,$00,$00,$00,$2b,$01 + byte $36,$01,$3c,$3c,$00,$e3,$00,$02,$04,$00,$00,$00,$00,$3c,$2d,$00 + byte $e1,$00,$02,$04,$00,$00,$00,$00,$3c,$3e,$00,$fb,$00,$08,$04,$4c + byte $01,$00,$00,$3d,$3d,$00,$fc,$00,$08,$04,$00,$00,$00,$00,$3d,$3c + byte $00,$fd,$00,$08,$04,$64,$01,$0d,$02,$41,$44,$44,$58,$00,$bc,$c8 + byte $03,$02,$72,$01,$bc,$01,$41,$42,$4f,$52,$54,$00,$24,$00,$00,$00 + byte $7d,$01,$9d,$01,$3e,$7c,$00,$f1,$00,$01,$08,$88,$01,$92,$01,$3e + byte $3c,$00,$ef,$00,$02,$04,$00,$00,$00,$00,$3e,$00,$fa,$00,$08,$04 + byte $00,$00,$00,$00,$3e,$3e,$00,$e2,$00,$02,$04,$a7,$01,$b1,$01,$40 + byte $00,$00,$00,$00,$08,$00,$00,$00,$00,$3f,$00,$08,$0c,$00,$0c,$00 + byte $00,$00,$00,$40,$40,$00,$01,$00,$00,$08,$cb,$01,$f2,$01,$41,$44 + byte $44,$41,$42,$53,$00,$bc,$88,$03,$02,$da,$01,$e6,$01,$41,$42,$53 + byte $4e,$45,$47,$00,$bc,$ac,$03,$02,$00,$00,$00,$00,$41,$42,$53,$00 + byte $bc,$a8,$03,$02,$00,$00,$00,$00,$41,$44,$44,$00,$bc,$80,$03,$02 + byte $00,$02,$00,$00,$41,$44,$44,$53,$58,$00,$bc,$d8,$03,$02,$00,$00 + byte $00,$00,$41,$44,$44,$53,$00,$bc,$d0,$03,$02,$1d,$02,$7f,$02,$43 + byte $48,$49,$50,$56,$45,$52,$00,$00,$00,$10,$00,$2e,$02,$54,$02,$42 + byte $59,$54,$45,$46,$49,$4c,$4c,$00,$18,$03,$40,$00,$3b,$02,$47,$02 + byte $41,$4e,$44,$4e,$00,$bc,$64,$03,$02,$00,$00,$00,$00,$41,$4e,$44 + byte $00,$f0,$00,$0a,$06,$00,$00,$00,$00,$42,$59,$54,$45,$00,$17,$00 + byte $00,$00,$61,$02,$72,$02,$43,$41,$4c,$4c,$00,$fc,$5c,$01,$02,$00 + byte $00,$00,$00,$42,$59,$54,$45,$4d,$4f,$56,$45,$00,$1c,$03,$40,$00 + byte $00,$00,$00,$00,$43,$41,$53,$45,$00,$25,$00,$00,$00,$8b,$02,$ba + byte $02,$43,$4d,$50,$00,$3c,$84,$03,$02,$9b,$02,$ab,$02,$43,$4c,$4b + byte $4d,$4f,$44,$45,$00,$20,$00,$10,$00,$00,$00,$00,$00,$43,$4c,$4b + byte $46,$52,$45,$51,$00,$10,$00,$10,$00,$00,$00,$00,$00,$43,$4c,$4b + byte $53,$45,$54,$00,$20,$02,$40,$02,$c9,$02,$00,$00,$43,$4d,$50,$53 + byte $55,$42,$00,$bc,$e0,$03,$02,$00,$00,$00,$00,$43,$4d,$50,$53,$00 + byte $3c,$c0,$03,$02,$e3,$02,$73,$04,$49,$46,$5f,$42,$00,$0c,$00,$00 + byte $01,$f0,$02,$b0,$03,$45,$4c,$53,$45,$00,$27,$00,$00,$00,$01,$03 + byte $63,$03,$43,$4f,$4e,$53,$54,$41,$4e,$54,$00,$26,$00,$00,$00,$11 + byte $03,$38,$03,$43,$4f,$47,$49,$4e,$49,$54,$00,$04,$00,$10,$02,$1d + byte $03,$2a,$03,$43,$4e,$54,$00,$02,$00,$00,$00,$00,$00,$00,$00,$43 + byte $4d,$50,$58,$00,$3c,$cc,$03,$02,$00,$00,$00,$00,$43,$4f,$47,$49 + byte $44,$00,$03,$00,$10,$02,$48,$03,$57,$03,$43,$4f,$47,$53,$54,$4f + byte $50,$00,$21,$01,$40,$02,$00,$00,$00,$00,$43,$4f,$47,$4e,$45,$57 + byte $00,$05,$00,$10,$00,$00,$00,$00,$00,$43,$4f,$4e,$00,$11,$00,$00 + byte $00,$70,$03,$96,$03,$44,$49,$52,$41,$00,$07,$00,$00,$00,$7d,$03 + byte $8a,$03,$43,$54,$52,$42,$00,$0a,$00,$00,$00,$00,$00,$00,$00,$43 + byte $54,$52,$41,$00,$09,$00,$00,$00,$00,$00,$00,$00,$44,$41,$54,$00 + byte $12,$00,$00,$00,$a3,$03,$00,$00,$44,$4a,$4e,$5a,$00,$bc,$e4,$03 + byte $02,$00,$00,$00,$00,$44,$49,$52,$42,$00,$08,$00,$00,$00,$bd,$03 + byte $1f,$04,$46,$52,$51,$42,$00,$0c,$00,$00,$00,$c9,$03,$f7,$03,$46 + byte $49,$54,$00,$2b,$00,$00,$00,$db,$03,$ea,$03,$45,$4c,$53,$45,$49 + byte $46,$4e,$4f,$54,$00,$29,$00,$00,$00,$00,$00,$00,$00,$45,$4c,$53 + byte $45,$49,$46,$00,$28,$00,$00,$00,$00,$00,$00,$00,$46,$49,$4c,$45 + byte $00,$2a,$00,$00,$00,$04,$04,$12,$04,$46,$52,$4f,$4d,$00,$2d,$00 + byte $00,$00,$00,$00,$00,$00,$46,$4c,$4f,$41,$54,$00,$2c,$00,$00,$00 + byte $00,$00,$00,$00,$46,$52,$51,$41,$00,$0b,$00,$00,$00,$2c,$04,$53 + byte $04,$49,$46,$5f,$41,$00,$01,$00,$00,$01,$37,$04,$45,$04,$49,$46 + byte $00,$2e,$00,$00,$00,$00,$00,$00,$00,$48,$55,$42,$4f,$50,$00,$3c + byte $0c,$03,$02,$00,$00,$00,$00,$49,$46,$4e,$4f,$54,$00,$2f,$00,$00 + byte $00,$65,$04,$00,$00,$49,$46,$5f,$41,$4c,$57,$41,$59,$53,$00,$0f + byte $00,$00,$01,$00,$00,$00,$00,$49,$46,$5f,$41,$45,$00,$03,$00,$00 + byte $01,$81,$04,$77,$05,$49,$46,$5f,$4e,$45,$00,$05,$00,$00,$01,$93 + byte $04,$0c,$05,$49,$46,$5f,$43,$5f,$4f,$52,$5f,$5a,$00,$0e,$00,$00 + byte $01,$a6,$04,$d5,$04,$49,$46,$5f,$43,$5f,$41,$4e,$44,$5f,$5a,$00 + byte $08,$00,$00,$01,$b3,$04,$c1,$04,$49,$46,$5f,$43,$00,$0c,$00,$00 + byte $01,$00,$00,$00,$00,$49,$46,$5f,$42,$45,$00,$0e,$00,$00,$01,$00 + byte $00,$00,$00,$49,$46,$5f,$43,$5f,$41,$4e,$44,$5f,$4e,$5a,$00,$04 + byte $00,$00,$01,$e7,$04,$f9,$04,$49,$46,$5f,$43,$5f,$4e,$45,$5f,$5a + byte $00,$06,$00,$00,$01,$00,$00,$00,$00,$49,$46,$5f,$43,$5f,$45,$51 + byte $5f,$5a,$00,$09,$00,$00,$01,$00,$00,$00,$00,$49,$46,$5f,$43,$5f + byte $4f,$52,$5f,$4e,$5a,$00,$0d,$00,$00,$01,$20,$05,$50,$05,$49,$46 + byte $5f,$4e,$43,$5f,$41,$4e,$44,$5f,$5a,$00,$02,$00,$00,$01,$2e,$05 + byte $3b,$05,$49,$46,$5f,$4e,$43,$00,$03,$00,$00,$01,$00,$00,$00,$00 + byte $49,$46,$5f,$45,$00,$0a,$00,$00,$01,$00,$00,$00,$00,$49,$46,$5f + byte $4e,$43,$5f,$41,$4e,$44,$5f,$4e,$5a,$00,$01,$00,$00,$01,$63,$05 + byte $00,$00,$49,$46,$5f,$4e,$43,$5f,$4f,$52,$5f,$5a,$00,$0b,$00,$00 + byte $01,$00,$00,$00,$00,$49,$46,$5f,$4e,$43,$5f,$4f,$52,$5f,$4e,$5a + byte $00,$07,$00,$00,$01,$84,$05,$f3,$05,$49,$46,$5f,$5a,$00,$0a,$00 + byte $00,$01,$99,$05,$cc,$05,$49,$46,$5f,$4e,$5a,$5f,$41,$4e,$44,$5f + byte $4e,$43,$00,$01,$00,$00,$01,$a7,$05,$b8,$05,$49,$46,$5f,$4e,$5a + byte $00,$05,$00,$00,$01,$00,$00,$00,$00,$49,$46,$5f,$4e,$45,$56,$45 + byte $52,$00,$00,$00,$00,$01,$00,$00,$00,$00,$49,$46,$5f,$4e,$5a,$5f + byte $41,$4e,$44,$5f,$43,$00,$04,$00,$00,$01,$e0,$05,$00,$00,$49,$46 + byte $5f,$4e,$5a,$5f,$4f,$52,$5f,$4e,$43,$00,$0b,$00,$00,$01,$00,$00 + byte $00,$00,$49,$46,$5f,$4e,$5a,$5f,$4f,$52,$5f,$43,$00,$0e,$00,$00 + byte $01,$05,$06,$3e,$06,$49,$46,$5f,$5a,$5f,$4e,$45,$5f,$43,$00,$06 + byte $00,$00,$01,$19,$06,$2c,$06,$49,$46,$5f,$5a,$5f,$41,$4e,$44,$5f + byte $4e,$43,$00,$02,$00,$00,$01,$00,$00,$00,$00,$49,$46,$5f,$5a,$5f + byte $41,$4e,$44,$5f,$43,$00,$08,$00,$00,$01,$00,$00,$00,$00,$49,$46 + byte $5f,$5a,$5f,$45,$51,$5f,$43,$00,$09,$00,$00,$01,$51,$06,$00,$00 + byte $49,$46,$5f,$5a,$5f,$4f,$52,$5f,$4e,$43,$00,$0b,$00,$00,$01,$00 + byte $00,$00,$00,$49,$46,$5f,$5a,$5f,$4f,$52,$5f,$43,$00,$0e,$00,$00 + byte $01,$72,$06,$84,$09,$52,$45,$54,$55,$52,$4e,$00,$38,$00,$00,$00 + byte $80,$06,$1a,$08,$4e,$45,$47,$4e,$5a,$00,$bc,$bc,$03,$02,$8c,$06 + byte $64,$07,$4d,$41,$58,$00,$bc,$4c,$03,$02,$99,$06,$00,$07,$4c,$4f + byte $4e,$47,$00,$19,$00,$00,$00,$a9,$06,$d0,$06,$4c,$4f,$43,$4b,$43 + byte $4c,$52,$00,$f1,$b2,$12,$00,$b5,$06,$c1,$06,$4a,$4d,$50,$00,$3c + byte $5c,$01,$02,$00,$00,$00,$00,$49,$4e,$42,$00,$04,$00,$00,$00,$00 + byte $00,$00,$00,$4a,$4d,$50,$52,$45,$54,$00,$bc,$5c,$03,$02,$e0,$06 + byte $f0,$06,$4c,$4f,$43,$4b,$52,$45,$54,$00,$22,$01,$40,$00,$00,$00 + byte $00,$00,$4c,$4f,$43,$4b,$4e,$45,$57,$00,$d0,$92,$12,$00,$00,$00 + byte $00,$00,$4c,$4f,$43,$4b,$53,$45,$54,$00,$e1,$a2,$12,$00,$12,$07 + byte $45,$07,$4c,$4f,$4f,$4b,$44,$4f,$57,$4e,$5a,$00,$10,$31,$11,$00 + byte $23,$07,$34,$07,$4c,$4f,$4e,$47,$4d,$4f,$56,$45,$00,$1e,$03,$40 + byte $00,$00,$00,$00,$00,$4c,$4f,$4e,$47,$46,$49,$4c,$4c,$00,$1a,$03 + byte $40,$00,$00,$00,$00,$00,$4c,$4f,$4f,$4b,$44,$4f,$57,$4e,$00,$11 + byte $31,$11,$00,$55,$07,$00,$00,$4c,$4f,$4f,$4b,$55,$50,$5a,$00,$00 + byte $21,$11,$00,$00,$00,$00,$00,$4c,$4f,$4f,$4b,$55,$50,$00,$01,$21 + byte $11,$00,$71,$07,$ca,$07,$4d,$55,$58,$43,$00,$bc,$70,$03,$02,$7d + byte $07,$a3,$07,$4d,$4f,$56,$00,$bc,$a0,$03,$02,$89,$07,$96,$07,$4d + byte $49,$4e,$00,$bc,$48,$03,$02,$00,$00,$00,$00,$4d,$41,$58,$53,$00 + byte $bc,$44,$03,$02,$00,$00,$00,$00,$4d,$49,$4e,$53,$00,$bc,$40,$03 + byte $02,$b0,$07,$bd,$07,$4d,$4f,$56,$49,$00,$bc,$58,$03,$02,$00,$00 + byte $00,$00,$4d,$4f,$56,$44,$00,$bc,$54,$03,$02,$00,$00,$00,$00,$4d + byte $4f,$56,$53,$00,$bc,$50,$03,$02,$d6,$07,$ff,$07,$4e,$45,$47,$00 + byte $bc,$a4,$03,$02,$e4,$07,$f2,$07,$4d,$55,$58,$4e,$5a,$00,$bc,$7c + byte $03,$02,$00,$00,$00,$00,$4d,$55,$58,$4e,$43,$00,$bc,$74,$03,$02 + byte $00,$00,$00,$00,$4d,$55,$58,$5a,$00,$bc,$78,$03,$02,$0d,$08,$00 + byte $00,$4e,$45,$47,$4e,$43,$00,$bc,$b4,$03,$02,$00,$00,$00,$00,$4e + byte $45,$47,$43,$00,$bc,$b0,$03,$02,$27,$08,$d5,$08,$50,$48,$53,$42 + byte $00,$0e,$00,$00,$00,$33,$08,$87,$08,$4f,$52,$47,$00,$31,$00,$00 + byte $00,$3f,$08,$65,$08,$4e,$4f,$54,$00,$ff,$00,$09,$08,$4c,$08,$59 + byte $08,$4e,$45,$58,$54,$00,$30,$00,$00,$00,$00,$00,$00,$00,$4e,$45 + byte $47,$5a,$00,$bc,$b8,$03,$02,$00,$00,$00,$00,$4e,$4f,$50,$00,$00 + byte $00,$00,$02,$71,$08,$7c,$08,$4f,$42,$4a,$00,$13,$00,$00,$00,$00 + byte $00,$00,$00,$4e,$52,$00,$08,$00,$80,$00,$00,$00,$00,$00,$4f,$52 + byte $00,$f2,$00,$0b,$06,$94,$08,$bc,$08,$4f,$55,$54,$42,$00,$06,$00 + byte $00,$00,$a2,$08,$af,$08,$4f,$54,$48,$45,$52,$00,$33,$00,$00,$00 + byte $00,$00,$00,$00,$4f,$52,$47,$58,$00,$32,$00,$00,$00,$00,$00,$00 + byte $00,$4f,$55,$54,$41,$00,$05,$00,$00,$00,$c9,$08,$00,$00,$50,$48 + byte $53,$41,$00,$0d,$00,$00,$00,$00,$00,$00,$00,$50,$41,$52,$00,$01 + byte $00,$00,$00,$e4,$08,$30,$09,$52,$44,$4c,$4f,$4e,$47,$00,$bc,$08 + byte $03,$02,$f0,$08,$15,$09,$52,$43,$4c,$00,$bc,$34,$03,$02,$fc,$08 + byte $08,$09,$50,$55,$42,$00,$15,$00,$00,$00,$00,$00,$00,$00,$50,$52 + byte $49,$00,$14,$00,$00,$00,$00,$00,$00,$00,$51,$55,$49,$54,$00,$34 + byte $00,$00,$00,$24,$09,$00,$00,$52,$44,$42,$59,$54,$45,$00,$bc,$00 + byte $03,$02,$00,$00,$00,$00,$52,$43,$52,$00,$bc,$30,$03,$02,$3c,$09 + byte $69,$09,$52,$45,$53,$00,$36,$00,$00,$00,$4b,$09,$5a,$09,$52,$45 + byte $42,$4f,$4f,$54,$00,$06,$00,$10,$00,$00,$00,$00,$00,$52,$44,$57 + byte $4f,$52,$44,$00,$bc,$04,$03,$02,$00,$00,$00,$00,$52,$45,$50,$45 + byte $41,$54,$00,$35,$00,$00,$00,$75,$09,$00,$00,$52,$45,$54,$00,$7c + byte $5c,$00,$02,$00,$00,$00,$00,$52,$45,$53,$55,$4c,$54,$00,$37,$00 + byte $00,$00,$91,$09,$0e,$0b,$56,$53,$43,$4c,$00,$10,$00,$00,$00,$9e + byte $09,$57,$0a,$53,$55,$42,$53,$00,$bc,$d4,$03,$02,$aa,$09,$00,$0a + byte $53,$50,$52,$00,$3a,$00,$00,$00,$b8,$09,$dc,$09,$52,$4f,$55,$4e + byte $44,$00,$39,$00,$00,$00,$c4,$09,$d0,$09,$52,$4f,$4c,$00,$bc,$24 + byte $03,$02,$00,$00,$00,$00,$52,$45,$56,$00,$bc,$3c,$03,$02,$00,$00 + byte $00,$00,$52,$4f,$52,$00,$bc,$20,$03,$02,$e8,$09,$f4,$09,$53,$48 + byte $4c,$00,$bc,$2c,$03,$02,$00,$00,$00,$00,$53,$41,$52,$00,$bc,$38 + byte $03,$02,$00,$00,$00,$00,$53,$48,$52,$00,$bc,$28,$03,$02,$10,$0a + byte $3c,$0a,$53,$54,$52,$53,$49,$5a,$45,$00,$61,$01,$10,$00,$20,$0a + byte $2d,$0a,$53,$54,$52,$43,$4f,$4d,$50,$00,$72,$01,$10,$00,$00,$00 + byte $00,$00,$53,$54,$45,$50,$00,$3b,$00,$00,$00,$00,$00,$00,$00,$53 + byte $54,$52,$49,$4e,$47,$00,$3c,$00,$00,$00,$4b,$0a,$00,$00,$53,$55 + byte $42,$41,$42,$53,$00,$bc,$8c,$03,$02,$00,$00,$00,$00,$53,$55,$42 + byte $00,$bc,$84,$03,$02,$64,$0a,$c2,$0a,$54,$4a,$4e,$5a,$00,$3c,$e8 + byte $03,$02,$72,$0a,$9a,$0a,$53,$55,$4d,$4e,$43,$00,$bc,$94,$03,$02 + byte $7f,$0a,$8d,$0a,$53,$55,$42,$58,$00,$bc,$cc,$03,$02,$00,$00,$00 + byte $00,$53,$55,$42,$53,$58,$00,$bc,$dc,$03,$02,$00,$00,$00,$00,$53 + byte $55,$4d,$43,$00,$bc,$90,$03,$02,$a7,$0a,$b5,$0a,$53,$55,$4d,$5a + byte $00,$bc,$98,$03,$02,$00,$00,$00,$00,$53,$55,$4d,$4e,$5a,$00,$bc + byte $9c,$03,$02,$00,$00,$00,$00,$54,$45,$53,$54,$00,$3c,$60,$03,$02 + byte $d0,$0a,$f5,$0a,$55,$4e,$54,$49,$4c,$00,$3f,$00,$00,$00,$db,$0a + byte $e7,$0a,$54,$4f,$00,$3d,$00,$00,$00,$00,$00,$00,$00,$54,$4a,$5a + byte $00,$3c,$ec,$03,$02,$00,$00,$00,$00,$54,$52,$55,$4e,$43,$00,$3e + byte $00,$00,$00,$02,$0b,$00,$00,$56,$43,$46,$47,$00,$0f,$00,$00,$00 + byte $00,$00,$00,$00,$56,$41,$52,$00,$16,$00,$00,$00,$1a,$0b,$e5,$0b + byte $58,$4f,$52,$00,$bc,$6c,$03,$02,$2b,$0b,$91,$0b,$57,$4f,$52,$44 + byte $46,$49,$4c,$4c,$00,$19,$03,$40,$00,$3b,$0b,$6b,$0b,$57,$41,$49 + byte $54,$56,$49,$44,$00,$27,$02,$40,$02,$4b,$0b,$5b,$0b,$57,$41,$49 + byte $54,$50,$45,$51,$00,$1b,$03,$40,$02,$00,$00,$00,$00,$57,$41,$49 + byte $54,$43,$4e,$54,$00,$23,$01,$40,$02,$00,$00,$00,$00,$57,$41,$49 + byte $54,$50,$4e,$45,$00,$1f,$03,$40,$02,$79,$0b,$84,$0b,$57,$48,$49 + byte $4c,$45,$00,$40,$00,$00,$00,$00,$00,$00,$00,$57,$43,$00,$02,$00 + byte $80,$00,$00,$00,$00,$00,$57,$4f,$52,$44,$00,$18,$00,$00,$00,$a0 + byte $0b,$cb,$0b,$57,$52,$4c,$4f,$4e,$47,$00,$3c,$08,$03,$02,$ab,$0b + byte $bc,$0b,$57,$52,$00,$01,$00,$80,$00,$00,$00,$00,$00,$57,$4f,$52 + byte $44,$4d,$4f,$56,$45,$00,$1d,$03,$40,$00,$00,$00,$00,$00,$57,$52 + byte $42,$59,$54,$45,$00,$3c,$00,$03,$02,$d6,$0b,$00,$00,$57,$5a,$00 + byte $04,$00,$80,$00,$00,$00,$00,$00,$57,$52,$57,$4f,$52,$44,$00,$3c + byte $04,$03,$02,$ef,$0b,$2c,$0c,$7c,$00,$ea,$00,$04,$04,$f9,$0b,$17 + byte $0c,$5e,$00,$eb,$00,$04,$04,$03,$0c,$0d,$0c,$5c,$00,$42,$00,$00 + byte $00,$00,$00,$00,$00,$5b,$00,$41,$00,$00,$00,$00,$00,$00,$00,$5d + byte $00,$43,$00,$00,$00,$21,$0c,$00,$00,$7b,$00,$44,$00,$00,$00,$00 + byte $00,$00,$00,$5e,$5e,$00,$f8,$00,$01,$08,$36,$0c,$56,$0c,$7e,$00 + byte $10,$18,$00,$0c,$41,$0c,$4c,$0c,$7c,$7c,$00,$e9,$00,$01,$08,$00 + byte $00,$00,$00,$7c,$3c,$00,$f3,$00,$01,$08,$00,$00,$00,$00,$7d,$00 + byte $45,$00,$00,$00,$61,$0c,$00,$00,$7e,$7e,$00,$14,$1c,$00,$0c,$00 + byte $00,$00,$00,$7e,$3e,$00,$ee,$00,$02,$04 + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} \ No newline at end of file diff --git a/zubehör/sphinx/hive-port/tokenizer/led.spn b/zubehör/sphinx/hive-port/tokenizer/led.spn new file mode 100644 index 0000000..066b8a8 --- /dev/null +++ b/zubehör/sphinx/hive-port/tokenizer/led.spn @@ -0,0 +1,7 @@ +{{ Output.spin }} + +PUB Toggle + dira[24]~~ + repeat + !outa[24] + waitcnt(3_000_000 + cnt) \ No newline at end of file diff --git a/zubehör/sphinx/hive-port/tokenizer/lex.spin b/zubehör/sphinx/hive-port/tokenizer/lex.spin new file mode 100644 index 0000000..fe9053a --- /dev/null +++ b/zubehör/sphinx/hive-port/tokenizer/lex.spin @@ -0,0 +1,564 @@ +{{ + Lex + + usage: lex filename [options] + + Reads filename.spn on SD card, writes tokens to filename.tok. + +}} +con + +_stack = 1000 + +obj + ios: "ios" + kw: "keywords" + str: "stringx" + bt: "bintree" + floatString: "FltStr" + +var + +byte parastr[64] + +pub Main | err, p + ios.start + err := \Try + if err + if err > 0 + ios.print( err ) + ios.printnl + else + ios.print( string("Error ") ) + ios.printdec( err ) + ios.printchar( 13 ) + ios.printdec( TokLineNumber ) + ios.printchar( "," ) + ios.printdec( TokColumn + 1 ) + ios.printchar( " " ) + ios.printchar( "'" ) + ios.print( pTokenText ) + ios.printchar( "'" ) + ios.printchar( 13 ) + ios.sdclose + bt.Stop + ios.stop + +var + long pTokenText + +pri Try + bt.Init( 0, 0 ) + ProcessCommandLine + if verbosity => 1 + ios.print( string("version 100225", 13) ) + Start + +pri ProcessCommandLine | nArgs, l + + ios.parastart + repeat while ios.paranext(@parastr) 'parameter einlesen + if byte[@parastr][0] == "/" 'option? + case byte[@parastr][1] + "?": ios.print(string("help: lex /i fn.spn /o fn.tok [options]")) '/? + ios.printnl + abort + "i": ifnot ios.paranext(@spinFilename) '/i fn.spn + ios.print(string("error: input-filname")) + ios.printnl + "o": ifnot ios.paranext(@outputFilename) '/o fn.tok + ios.print(string("error: output-filname")) + ios.printnl + "c": compile~~ + "l": compile~~ + "v": if ios.paranext(@parastr) '/v n + verbosity := str2dec(@parastr) + else + ios.print(string("error: verbosity-level")) + ios.printnl + else + ios.print(string("usage: lex /i fn.spn /o fn.tok [options]")) + +pri str2dec(stradr)|buffer,counter + + buffer := byte[stradr] + counter := (strsize(stradr) <# 11) + repeat while(counter--) + result *= 10 + result += lookdownz(byte[stradr++]: "0".."9") + if(buffer == "-") + -result + +con + MAXFILENAMELENGTH = 8 + 1 + 3 ' 8.3 + MAXSTRINGBUFFERLENGTH = 32 + +var + byte spinFilename[MAXFILENAMELENGTH+1] ' input .spi file + byte outputFilename[MAXFILENAMELENGTH+1] ' output .tok file + byte stringBuffer[MAXSTRINGBUFFERLENGTH+1] ' temp string buffer + +dat +verbosity byte 0 ' set by /V option +compile byte 0 ' set by /C or /L: if non-zero, run compile.bin automatically. +type long 0 +lineNum word 0 +column word 0 + +pri Start | v + + kw.Init + pTokenText := TokGetPText + + if verbosity => 2 + ios.print( string("Reading ") ) + ios.print( @spinFilename ) + ios.printchar( 13 ) + TokOpen( @spinFilename ) + + if verbosity => 2 + ios.print( string("Writing ") ) + ios.print( @outputFilename ) + ios.printchar( 13 ) + if ios.sdnewfile( @outputFilename ) + abort string("can't open o-file") + ios.sdopen( "W", @outputFilename ) + + repeat + type := TokType + lineNum := TokLineNumber + column := Column + ios.sdputblk( 8, @type ) ' long + word + word + + if type == kw#kINTLITERAL or type == kw#kFLOATLITERAL + v := TokValue + ios.sdputblk( 4, @v ) + else + ios.sdputblk( strsize(pTokenText) + 1, pTokenText ) + + if TokType == kw#kEOF + quit + TokAdvance + ios.sdclose + +dat 'TOKENIZER + +pub TokOpen( pFilename ) + + if ios.sdopen( "R", pFilename ) <> 0 + abort string("can't open file") + + TokInitReadLine + + insideDAT~ + + TokAdvance ' prime the pump + +pub TokClose + ios.sdclose + +{ + bytes~ + InitReadLine + GetNextToken ' prime the pump + + t := cnt + repeat + case tokenType + EOL_TOKEN: + term.str( @tokenText ) + EOF_TOKEN: + quit + ID_TOKEN: + term.str( @tokenText ) + OP_TOKEN: + INT_TOKEN: + term.out( "#" ) + term.dec( tokenValue ) + FLOAT_TOKEN: + term.out( "F" ) + term.str( floatString.FloatToString( tokenValue ) ) + term.out( "\" ) + GetNextToken + term.out( 13 ) +'} +{ repeat while SkipWhitespace + term.dec( lineNo ) + term.out( "," ) + term.dec( cp+1 ) + term.out( ":" ) + if cp == lineLength + term.str( string("(eol)")) + else + term.out( lineBuffer[cp++] ) + term.out( 13 ) +'} +{ + repeat + r := sdfat.pread( @buf, BUFFERSIZE ) + if r < 0 + quit + bytes += r +'} +{ + repeat 100 + r := sdfat.pgetc + if r < 0 + quit + ++bytes + term.dec(r) + term.out( "," ) +'} + +con + MAXTOKENLENGTH = 32 + BUFFERSIZE = 200 + +var + byte tokenText[MAXTOKENLENGTH+1] + long tokenType + word tokenLineNumber + word tokenCol + long tokenValue + byte insideDAT + +pub TokGetPText + return @tokenText + +pub TokType + return tokenType + +pub TokColumn + return tokenCol + +pub TokLineNumber + return tokenLineNumber + +pub TokValue + return tokenValue + +pub TokAdvance | i, radix, fp, x, hack + if inStringLiteral + if comma + comma~ + ifnot tokenValue + abort string("Unterminated string") + if lineBuffer[cp] <> $22 ' double-quote + tokenType := kw#kCOMMA + return + ++cp + inStringLiteral~ + else + comma~~ + tokenType := kw#kINTLITERAL + tokenValue := lineBuffer[cp++] + return + + if TokSkipWhitespace + if cp == lineLength + tokenType := kw#kEOL + bytemove( @tokenText, string("(EOL)"), 6 ) + tokenLineNumber := lineNo + tokenCol := cp + elseif lineBuffer[cp] == $22 ' double-quote + tokenLineNumber := LineNo + tokenCol := cp + ++cp + if LineBuffer[cp] == $22 + abort string("Empty string") + comma~ + inStringLiteral~~ + TokAdvance + elseif lineBuffer[cp] == "%" or lineBuffer[cp] == "$" + tokenType := kw#kINTLITERAL + tokenLineNumber := lineNo + tokenCol := cp + if lineBuffer[cp] == "%" + if lineBuffer[cp+1] == "%" + radix := 4 + ++cp + else + radix := 2 + else + radix := 16 + ++cp + ifnot TokIsDigit( lineBuffer[cp], radix, false ) + abort string("Bad character in number") + tokenValue~ + repeat while TokIsDigit( lineBuffer[cp], radix, true ) + if lineBuffer[cp] <> "_" + tokenValue := tokenValue * radix + TokDigitValue( linebuffer[cp] ) + ++cp + elseif TokIsDigit( lineBuffer[cp], 10, false ) + tokenLineNumber := lineNo + tokenCol := cp + i~ + fp~ {0 => integer + 1 => have seen . + 2 => have seen e or E + 3 => have seen + or - } + repeat while TokIsDigit( lineBuffer[cp], 10, true ) { +} or ( fp < 1 and lineBuffer[cp] == "." and lineBuffer[cp+1] <> "." ) { +} or ( fp < 2 and (lineBuffer[cp] == "e" or lineBuffer[cp] == "E") ) { +} or ( (fp == 1 or fp == 2) and (lineBuffer[cp] == "+" or lineBuffer[cp] == "-") ) + if lineBuffer[cp] == "." + fp := 1 + if lineBuffer[cp] == "e" or lineBuffer[cp] == "E" + fp := 2 + if lineBuffer[cp] == "+" or lineBuffer[cp] == "-" + fp := 3 + if lineBuffer[cp] <> "_" + if i => MAXTOKENLENGTH + abort string("Token too long") + tokenText[i++] := lineBuffer[cp] + ++cp + tokenText[i]~ + if fp + tokenType := kw#kFLOATLITERAL + tokenValue := floatString.StringToFloat( @tokenText ) + else + tokenType := kw#kINTLITERAL + tokenValue~ + i~ + repeat while tokenText[i] + tokenValue := tokenValue * 10 + TokDigitValue( tokenText[i++] ) + elseif TokIsAlpha( lineBuffer[cp] ) + i~ + tokenLineNumber := lineNo + tokenCol := cp + repeat while TokIsAlpha( lineBuffer[cp] ) or TokIsDigit( lineBuffer[cp], 10, true ) + if i => MAXTOKENLENGTH + abort string("Token too long") + tokenText[i++] := TokToUpper( lineBuffer[cp++] ) + tokenText[i]~ + x := kw.KeywordLookup( @tokenText ) + if x + tokenType := bt.PeekL( x ) + if kw#kCON =< tokenType and tokenType =< kw#kVAR and tokenCol == 0 + insideDAT := tokenType == kw#kDAT + else + tokenType := kw#kID + else ' non-alphanumeric + tokenLineNumber := lineNo + tokenCol := cp + i~ + if lineBuffer[cp] < $20 or lineBuffer[cp] => $80 + abort string("Illegal character (UNICODE?)") + + if insideDat and lineBuffer[cp] == ":" and TokIsAlpha( lineBuffer[cp+1] ) + tokenText[i++] := lineBuffer[cp++] + repeat while TokIsAlpha( lineBuffer[cp] ) or TokIsDigit( lineBuffer[cp], 10, true ) + if i => MAXTOKENLENGTH + abort string("Token too long") + tokenText[i++] := TokToUpper( lineBuffer[cp++] ) + tokenText[i]~ + tokenType := kw#kID + else + repeat + if cp < lineLength + tokenText[i++] := lineBuffer[cp++] + else + tokenText[i++] := " " + ++cp + tokenText[i]~ + while x := kw.KeywordLookup( @tokenText ) + if i > 1 + tokenText[--i]~ ' shorten token by 1 + --cp + tokenType := bt.PeekL( kw.KeywordLookup( @tokenText ) ) + else + tokenType := kw#kUNKNOWN + + if TokIsBinary ' This next block is a total hack to see if a binary op + hack := blankLine ' hack is followed by "=" making it an assignment op + TokSkipWhitespace ' It parses "and ==" as "(and=) =" instead of "(and)(==)" + if lineBuffer[cp] == "=" ' PropTool does the latter. So this is wrong, but hopefully + tokenText[i++] := lineBuffer[cp++] ' not *too* wrong. + tokenText[i]~ + tokenType |= kw#kASSIGNMENT + else + blankLine := hack ' restore (this hack is necessary to reset the eol condition trigger in SkipWhitespace) + else + tokenType := kw#kEOF + bytemove( @tokenText, string("(EOF)"), 6 ) + tokenLineNumber := lineNo + tokenCol := cp + +pri TokToUpper( ch ) + if "a" =< ch and ch =< "z" + ch += constant( "A" - "a" ) + return ch + +pri TokIsAlpha( ch ) + return "a" =< ch and ch =< "z" or "A" =< ch and ch =< "Z" or ch == "_" + +pri TokIsDigit( ch, radix, u ) | upper +{{ + Returns non-zero if ch is an acceptable digit given radix (2, 4, 10, or 16), false otherwise. + Pass u = true if the underscore ("_") is an acceptable value for ch. +}} + if ch == "_" + return u + upper := constant("0"-1) + radix + if radix =< 10 + return "0" =< ch and ch =< upper + ' else radix == 16 + return "0" =< ch and ch =< "9" or "a" =< ch and ch =< "f" or "A" =< ch and ch =< "F" + +pri TokDigitValue( ch ) + if ch =< "9" + return ch - "0" + if ch =< "F" + return ch + constant( 10 - "A" ) + if ch =< "f" + return ch + constant( 10 - "a" ) + +pub TokIsBinary +{{ + Returns non-zero (not necessarily -1) if token is a binary operator. + Returns 0 otherwise. +}} + return ( tokenType & constant(kw#kUNARY|kw#kBINARY) ) == kw#kBINARY + +var + byte lineBuffer[BUFFERSIZE] + byte lineLength + byte lineRemainder + byte eolLength + word lineNo + byte cp + byte blankLine + byte inStringLiteral ' indicates we are splitting up a string literal + byte comma ' flag for returning commas when splitting up a string literal + +pri TokSkipWhitespace +'' Returns true on success, false on failure (eof). +'' lineBuffer[cp] is the next non-whitespace character +'' (comments count as whitespace). + repeat + repeat while cp => lineLength + ifnot blankLine + blankLine~~ + return true + ifnot TokReadLine + return false + if lineBuffer[cp] == 9 + abort string("Illegal TAB character") + if lineBuffer[cp] == "'" ' quote comment? + cp := lineLength ' skip to end of line + elseif lineBuffer[cp] == "}" + abort string("Unexpected '}'") + elseif lineBuffer[cp] == "{" + TokSkipComment + elseif lineBuffer[cp] == " " + ++cp + else ' non-blank character + blankLine~ + return true + +pri TokSkipComment | depth + if cp+1 < lineLength and lineBuffer[cp+1] == "{" + ++cp + repeat + repeat while cp => lineLength + ifnot TokReadLine + abort string("Unterminated comment") + if cp+1 < lineLength and lineBuffer[cp] == "}" and lineBuffer[cp+1] == "}" + cp += 2 + return + ++cp + else + ++cp + depth := 1 + repeat + repeat while cp => lineLength + ifnot TokReadLine + abort string("Unterminated comment") + if lineBuffer[cp] == "{" + ++cp + ++depth + elseif lineBuffer[cp] == "}" + ++cp + ifnot --depth + return + else + ++cp + +pri TokInitReadLine + lineLength~ + lineRemainder~ + eolLength~ + lineNo~ + cp~ + blankLine~~ + inStringLiteral~ +{ + |<--------------- BUFFERSIZE --------------->| + +--------------------------------------------+ + | | | | | + +--------------------------------------------+ + |<-lineLength ->| | | + eolLength ->| |<- | + |<- lineRemainder ->| +} +pri TokReadLine | bytes, i +'' Reads a line into lineBuff. Returns true on success, false on failure (eof) +'' The line in lineBuff is terminated with a null byte. Calling programs should +'' not modify any memory in lineBuff after the null (the "remainder" section in +'' the diagram above) because that's the following line(s). + +' First, move remainder up to start of buffer + bytemove( @lineBuffer, @lineBuffer[lineLength+eolLength], lineRemainder ) +' Fill the rest of the buffer with new data + bytes := ios.sdgetblk( BUFFERSIZE-lineRemainder, @lineBuffer[lineRemainder] ) + ' pread returns #bytes read, but after eof it returns negative numbers + if bytes > 0 + lineRemainder += bytes + + ifnot lineRemainder + ++lineNo + cp~ + return false + + repeat i from 0 to (lineRemainder-2) #> 0 + if lineBuffer[i] == 13 or lineBuffer[i] == 10 + eolLength := 1 ' cr or lf + if lineBuffer[i] == 13 and lineBuffer[i+1] == 10 + ++eolLength ' cr+lf + lineBuffer[i]~ ' set terminating null + lineLength := i + lineRemainder -= lineLength + eolLength + ++lineNo ' first line of file is line 1 + cp~ + return true + + if lineRemainder < BUFFERSIZE + lineLength := lineRemainder~ + lineBuffer[lineLength]~ + ++lineNo + cp~ + return true + + abort string("Input line too long") + + + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} + diff --git a/zubehör/sphinx/hive-port/tokenizer/stringx.spin b/zubehör/sphinx/hive-port/tokenizer/stringx.spin new file mode 100644 index 0000000..c5d8c1e --- /dev/null +++ b/zubehör/sphinx/hive-port/tokenizer/stringx.spin @@ -0,0 +1,43 @@ +pub Compare( p, q ) | lp, lq, d +{{ + Compares two strings. Returns a negative number if first string is "less than" the second, + 0 if they're identical, a positive number otherwise. +}} + lp := strsize(p) + lq := strsize(q) + repeat lp <# lq + if (d := byte[p++] - (byte[q++] & $7f)) + return ~~d + return lp-lq + +pub Copy( p, q ) + bytemove( p, q, strsize(q) + 1 ) + +pub Append( p, q ) + Copy( p + strsize(p), q ) + +pub ToUpper( p ) + repeat while byte[p] + if "a" =< byte[p] and byte[p] =< "z" + byte[p] += constant( "A" - "a" ) + ++p + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} + \ No newline at end of file diff --git a/zubehör/sphinx/hive-port/tokenizer/tokenizr.spin b/zubehör/sphinx/hive-port/tokenizer/tokenizr.spin new file mode 100644 index 0000000..652b6da --- /dev/null +++ b/zubehör/sphinx/hive-port/tokenizer/tokenizr.spin @@ -0,0 +1,430 @@ +' 2009-05-02 Modified to detect when inside DAT, handle : specially (for local labels) + +con + _clkmode = xtal1 + pll8x + _xinfreq = 10_000_000 + _stack = 1000 +obj + f: "sxfile" + floatString: "FltStr" + kw: "keywords" + bt: "bintree" + +pub Open( pFilename ) + + if f.Open( pFilename, "R") <> 0 + abort string("can't open file") + + InitReadLine + + insideDAT~ + + Advance ' prime the pump + +pub Close + f.Close + +{ + bytes~ + InitReadLine + GetNextToken ' prime the pump + + t := cnt + repeat + case tokenType + EOL_TOKEN: + term.str( @tokenText ) + EOF_TOKEN: + quit + ID_TOKEN: + term.str( @tokenText ) + OP_TOKEN: + INT_TOKEN: + term.out( "#" ) + term.dec( tokenValue ) + FLOAT_TOKEN: + term.out( "F" ) + term.str( floatString.FloatToString( tokenValue ) ) + term.out( "\" ) + GetNextToken + term.out( 13 ) +'} +{ repeat while SkipWhitespace + term.dec( lineNo ) + term.out( "," ) + term.dec( cp+1 ) + term.out( ":" ) + if cp == lineLength + term.str( string("(eol)")) + else + term.out( lineBuffer[cp++] ) + term.out( 13 ) +'} +{ + repeat + r := sdfat.pread( @buf, BUFFERSIZE ) + if r < 0 + quit + bytes += r +'} +{ + repeat 100 + r := sdfat.pgetc + if r < 0 + quit + ++bytes + term.dec(r) + term.out( "," ) +'} + +con + MAXTOKENLENGTH = 32 + BUFFERSIZE = 200 + +var + byte tokenText[MAXTOKENLENGTH+1] + long tokenType + word tokenLineNumber + word tokenCol + long tokenValue + byte insideDAT + +pub GetPText + return @tokenText + +pub Type + return tokenType + +pub Column + return tokenCol + +pub LineNumber + return tokenLineNumber + +pub Value + return tokenValue + +pub Advance | i, radix, fp, x, hack + if inStringLiteral + if comma + comma~ + ifnot tokenValue + abort string("Unterminated string") + if lineBuffer[cp] <> $22 ' double-quote + tokenType := kw#kCOMMA + return + ++cp + inStringLiteral~ + else + comma~~ + tokenType := kw#kINTLITERAL + tokenValue := lineBuffer[cp++] + return + + if SkipWhitespace + if cp == lineLength + tokenType := kw#kEOL + bytemove( @tokenText, string("(EOL)"), 6 ) + tokenLineNumber := lineNo + tokenCol := cp + elseif lineBuffer[cp] == $22 ' double-quote + tokenLineNumber := LineNo + tokenCol := cp + ++cp + if LineBuffer[cp] == $22 + abort string("Empty string") + comma~ + inStringLiteral~~ + Advance + elseif lineBuffer[cp] == "%" or lineBuffer[cp] == "$" + tokenType := kw#kINTLITERAL + tokenLineNumber := lineNo + tokenCol := cp + if lineBuffer[cp] == "%" + if lineBuffer[cp+1] == "%" + radix := 4 + ++cp + else + radix := 2 + else + radix := 16 + ++cp + ifnot IsDigit( lineBuffer[cp], radix, false ) + abort string("Bad character in number") + tokenValue~ + repeat while IsDigit( lineBuffer[cp], radix, true ) + if lineBuffer[cp] <> "_" + tokenValue := tokenValue * radix + DigitValue( linebuffer[cp] ) + ++cp + elseif IsDigit( lineBuffer[cp], 10, false ) + tokenLineNumber := lineNo + tokenCol := cp + i~ + fp~ {0 => integer + 1 => have seen . + 2 => have seen e or E + 3 => have seen + or - } + repeat while IsDigit( lineBuffer[cp], 10, true ) { +} or ( fp < 1 and lineBuffer[cp] == "." and lineBuffer[cp+1] <> "." ) { +} or ( fp < 2 and (lineBuffer[cp] == "e" or lineBuffer[cp] == "E") ) { +} or ( (fp == 1 or fp == 2) and (lineBuffer[cp] == "+" or lineBuffer[cp] == "-") ) + if lineBuffer[cp] == "." + fp := 1 + if lineBuffer[cp] == "e" or lineBuffer[cp] == "E" + fp := 2 + if lineBuffer[cp] == "+" or lineBuffer[cp] == "-" + fp := 3 + if lineBuffer[cp] <> "_" + if i => MAXTOKENLENGTH + abort string("Token too long") + tokenText[i++] := lineBuffer[cp] + ++cp + tokenText[i]~ + if fp + tokenType := kw#kFLOATLITERAL + tokenValue := floatString.StringToFloat( @tokenText ) + else + tokenType := kw#kINTLITERAL + tokenValue~ + i~ + repeat while tokenText[i] + tokenValue := tokenValue * 10 + DigitValue( tokenText[i++] ) + elseif IsAlpha( lineBuffer[cp] ) + i~ + tokenLineNumber := lineNo + tokenCol := cp + repeat while IsAlpha( lineBuffer[cp] ) or IsDigit( lineBuffer[cp], 10, true ) + if i => MAXTOKENLENGTH + abort string("Token too long") + tokenText[i++] := ToUpper( lineBuffer[cp++] ) + tokenText[i]~ + x := kw.KeywordLookup( @tokenText ) + if x + tokenType := bt.PeekL( x ) + if kw#kCON =< tokenType and tokenType =< kw#kVAR and tokenCol == 0 + insideDAT := tokenType == kw#kDAT + else + tokenType := kw#kID + else ' non-alphanumeric + tokenLineNumber := lineNo + tokenCol := cp + i~ + if lineBuffer[cp] < $20 or lineBuffer[cp] => $80 + abort string("Illegal character (UNICODE?)") + + if insideDat and lineBuffer[cp] == ":" and IsAlpha( lineBuffer[cp+1] ) + tokenText[i++] := lineBuffer[cp++] + repeat while IsAlpha( lineBuffer[cp] ) or IsDigit( lineBuffer[cp], 10, true ) + if i => MAXTOKENLENGTH + abort string("Token too long") + tokenText[i++] := ToUpper( lineBuffer[cp++] ) + tokenText[i]~ + tokenType := kw#kID + else + repeat + if cp < lineLength + tokenText[i++] := lineBuffer[cp++] + else + tokenText[i++] := " " + ++cp + tokenText[i]~ + while x := kw.KeywordLookup( @tokenText ) + if i > 1 + tokenText[--i]~ ' shorten token by 1 + --cp + tokenType := bt.PeekL( kw.KeywordLookup( @tokenText ) ) + else + tokenType := kw#kUNKNOWN + + if IsBinary ' This next block is a total hack to see if a binary op + hack := blankLine ' hack is followed by "=" making it an assignment op + SkipWhitespace ' It parses "and ==" as "(and=) =" instead of "(and)(==)" + if lineBuffer[cp] == "=" ' PropTool does the latter. So this is wrong, but hopefully + tokenText[i++] := lineBuffer[cp++] ' not *too* wrong. + tokenText[i]~ + tokenType |= kw#kASSIGNMENT + else + blankLine := hack ' restore (this hack is necessary to reset the eol condition trigger in SkipWhitespace) + else + tokenType := kw#kEOF + bytemove( @tokenText, string("(EOF)"), 6 ) + tokenLineNumber := lineNo + tokenCol := cp + +pri ToUpper( ch ) + if "a" =< ch and ch =< "z" + ch += constant( "A" - "a" ) + return ch + +pri IsAlpha( ch ) + return "a" =< ch and ch =< "z" or "A" =< ch and ch =< "Z" or ch == "_" + +pri IsDigit( ch, radix, u ) | upper +{{ + Returns non-zero if ch is an acceptable digit given radix (2, 4, 10, or 16), false otherwise. + Pass u = true if the underscore ("_") is an acceptable value for ch. +}} + if ch == "_" + return u + upper := constant("0"-1) + radix + if radix =< 10 + return "0" =< ch and ch =< upper + ' else radix == 16 + return "0" =< ch and ch =< "9" or "a" =< ch and ch =< "f" or "A" =< ch and ch =< "F" + +pri DigitValue( ch ) + if ch =< "9" + return ch - "0" + if ch =< "F" + return ch + constant( 10 - "A" ) + if ch =< "f" + return ch + constant( 10 - "a" ) + +pub IsBinary +{{ + Returns non-zero (not necessarily -1) if token is a binary operator. + Returns 0 otherwise. +}} + return ( tokenType & constant(kw#kUNARY|kw#kBINARY) ) == kw#kBINARY + +var + byte lineBuffer[BUFFERSIZE] + byte lineLength + byte lineRemainder + byte eolLength + word lineNo + byte cp + byte blankLine + byte inStringLiteral ' indicates we are splitting up a string literal + byte comma ' flag for returning commas when splitting up a string literal + +pri SkipWhitespace +'' Returns true on success, false on failure (eof). +'' lineBuffer[cp] is the next non-whitespace character +'' (comments count as whitespace). + repeat + repeat while cp => lineLength + ifnot blankLine + blankLine~~ + return true + ifnot ReadLine + return false + if lineBuffer[cp] == 9 + abort string("Illegal TAB character") + if lineBuffer[cp] == "'" ' quote comment? + cp := lineLength ' skip to end of line + elseif lineBuffer[cp] == "}" + abort string("Unexpected '}'") + elseif lineBuffer[cp] == "{" + SkipComment + elseif lineBuffer[cp] == " " + ++cp + else ' non-blank character + blankLine~ + return true + +pri SkipComment | depth + if cp+1 < lineLength and lineBuffer[cp+1] == "{" + ++cp + repeat + repeat while cp => lineLength + ifnot ReadLine + abort string("Unterminated comment") + if cp+1 < lineLength and lineBuffer[cp] == "}" and lineBuffer[cp+1] == "}" + cp += 2 + return + ++cp + else + ++cp + depth := 1 + repeat + repeat while cp => lineLength + ifnot ReadLine + abort string("Unterminated comment") + if lineBuffer[cp] == "{" + ++cp + ++depth + elseif lineBuffer[cp] == "}" + ++cp + ifnot --depth + return + else + ++cp + +pri InitReadLine + lineLength~ + lineRemainder~ + eolLength~ + lineNo~ + cp~ + blankLine~~ + inStringLiteral~ +{ + |<--------------- BUFFERSIZE --------------->| + +--------------------------------------------+ + | | | | | + +--------------------------------------------+ + |<-lineLength ->| | | + eolLength ->| |<- | + |<- lineRemainder ->| +} +pri ReadLine | bytes, i +'' Reads a line into lineBuff. Returns true on success, false on failure (eof) +'' The line in lineBuff is terminated with a null byte. Calling programs should +'' not modify any memory in lineBuff after the null (the "remainder" section in +'' the diagram above) because that's the following line(s). + +' First, move remainder up to start of buffer + bytemove( @lineBuffer, @lineBuffer[lineLength+eolLength], lineRemainder ) +' Fill the rest of the buffer with new data + bytes := f.Read( @lineBuffer[lineRemainder], BUFFERSIZE-lineRemainder ) + ' pread returns #bytes read, but after eof it returns negative numbers + if bytes > 0 + lineRemainder += bytes + + ifnot lineRemainder + ++lineNo + cp~ + return false + + repeat i from 0 to (lineRemainder-2) #> 0 + if lineBuffer[i] == 13 or lineBuffer[i] == 10 + eolLength := 1 ' cr or lf + if lineBuffer[i] == 13 and lineBuffer[i+1] == 10 + ++eolLength ' cr+lf + lineBuffer[i]~ ' set terminating null + lineLength := i + lineRemainder -= lineLength + eolLength + ++lineNo ' first line of file is line 1 + cp~ + return true + + if lineRemainder < BUFFERSIZE + lineLength := lineRemainder~ + lineBuffer[lineLength]~ + ++lineNo + cp~ + return true + + abort string("Input line too long") + + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} + \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/dokumentation/codegenbin.htm b/zubehör/sphinx/spinx100225-ori/dokumentation/codegenbin.htm new file mode 100644 index 0000000..94c23c7 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/dokumentation/codegenbin.htm @@ -0,0 +1,235 @@ + + + + + + + + + + + +codegen.bin - sphinxcompiler + + + + +
+ +
+
+
+
+
+ + + + + + + + +
+ +
+
+
+
+
+ + + + + +
+ +
+
+
+Sphinx‎ > ‎Documentation‎ > ‎Reference‎ > ‎ +
+

+codegen.bin +

+ +
+
+
Codegen.bin is the second phase of the compiler. It takes a .tok file generated by lex.bin and compiles it to a .sob file. On successful completion, codegen.bin can automatically run link.bin (of course, linking should only be done on the top object, not child objects, so don't use the /l option too freely).
 
Typically you will never run codegen.bin directly. Instead you will use the c and cl commands (provided by sphinx.bin) which run codegen.bin for you.
 
Usage:
codegen filename [options]
Options:
  • /l -- run link.bin automatically on successful completion.
  • /s n -- set stack size to n bytes (default is 2300). If codegen.bin fails because of stack overflow, run it again with a larger stack. n must be a multiple of 4.
  • /t n -- set symbol table size to n bytes (default is 6000). If codegen.bin fails because the symbol table becomes full, run it again with a larger symbol table. n must be a multiple of 4.
  • /v n -- set verbosity to 0, 1, 2, or higher (default is 0). The higher the verbosity, the more messages codegen.bin prints as it runs.
Example:
codegen howdy /v 3 /t 7000
This command compiles howdy.tok and produces howdy.sob. While running, codegen.bin prints many informative(?) messages. The symbol table size is 7,000 bytes.
Note that you do not have to add ".tok" to the input filename. Codegen.bin will add it automatically.
 
 
 
+
+
+
+
+
+
+
+
+ +
+
+
+

+ + +   + Anmelden + + +   + Site-Aktivität in letzter Zeit + + +   + Nutzungsbedingungen +   + Missbrauch melden + +   + Seite drucken + + + +  |  + + Powered by Google Sites +

+
+
+ + + + + + + + + + + + + + + + + diff --git a/zubehör/sphinx/spinx100225-ori/dokumentation/lexbin.htm b/zubehör/sphinx/spinx100225-ori/dokumentation/lexbin.htm new file mode 100644 index 0000000..5737920 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/dokumentation/lexbin.htm @@ -0,0 +1,235 @@ + + + + + + + + + + + +lex.bin - sphinxcompiler + + + + +
+ +
+
+
+
+
+ + + + + + + + +
+ +
+
+
+
+
+ + + + + +
+ +
+
+
+Sphinx‎ > ‎Documentation‎ > ‎Reference‎ > ‎ +
+

+lex.bin +

+ +
+
+
Lex.bin is the first phase of the compiler. It takes a .spn file as input, tokenizes it, and writes the result to a .tok file. On successful completion, lex.bin can automatically run codegen.bin, the next compiler phase.
 
Usage:
lex filename [options]
Options:
  • /c -- run codegen.bin automatically on successful completion.
  • /l -- run codegen.bin automatically on successful completion and tell it to run link.bin.
  • /v n -- set verbosity to 0, 1, 2, or higher (default is 0). The higher the verbosity, the more messages lex.bin prints as it runs.
Example:
lex tv_text /c
This command tokenizes tv_text.spn, producing tv_text.tok, and then runs codegen.bin. Note that you don't have to add ".spn" to the input filename. Lex.bin will add it automatically.
 
You should never have to run lex.bin directly; instead, use the convenient  c command (provided by sphinx.bin) which is equivalent to running lex with the /c option. 
 
+
+
+
+
+
+
+
+
+ +
+
+
+

+ + +   + Anmelden + + +   + Site-Aktivität in letzter Zeit + + +   + Nutzungsbedingungen +   + Missbrauch melden + +   + Seite drucken + + + +  |  + + Powered by Google Sites +

+
+
+ + + + + + + + + + + + + + + + + diff --git a/zubehör/sphinx/spinx100225-ori/dokumentation/linkbin.htm b/zubehör/sphinx/spinx100225-ori/dokumentation/linkbin.htm new file mode 100644 index 0000000..c02243b --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/dokumentation/linkbin.htm @@ -0,0 +1,235 @@ + + + + + + + + + + + +link.bin - sphinxcompiler + + + + +
+ +
+
+
+
+
+ + + + + + + + +
+ +
+
+
+
+
+ + + + + +
+ +
+
+
+Sphinx‎ > ‎Documentation‎ > ‎Reference‎ > ‎ +
+

+link.bin +

+ +
+
+
Link.bin is the linker. It takes a top object .sob file and links it together with any child .sob files it requires, producing a .bin file.
 

Usage:

link filename [options]
Options:
  • /i -- ignore out-of-date errors.
  • /v n -- set verbosity to 0, 1, 2, or higher (default is 0). The higher the verbosity, the more messages link.bin prints as it runs.
 
 
 
+
+
+
+
+
+
+
+
+ +
+
+
+

+ + +   + Anmelden + + +   + Site-Aktivität in letzter Zeit + + +   + Nutzungsbedingungen +   + Missbrauch melden + +   + Seite drucken + + + +  |  + + Powered by Google Sites +

+
+
+ + + + + + + + + + + + + + + + + diff --git a/zubehör/sphinx/spinx100225-ori/dokumentation/sobstory.htm b/zubehör/sphinx/spinx100225-ori/dokumentation/sobstory.htm new file mode 100644 index 0000000..4cedc24 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/dokumentation/sobstory.htm @@ -0,0 +1,271 @@ + + + + + + + + + + + +Compiling and linking: a SOB story - sphinxcompiler + + + + +
+ +
+
+
+
+
+ + + + + + + + +
+ +
+
+
+
+
+ + + + + +
+ +
+
+
+Sphinx‎ > ‎Documentation‎ > ‎ +
+

+Compiling and linking: a SOB story +

+ +
+
+
The process of building a program with Sphinx is divided into two steps, compiling and linking. Compiling transforms a Spin source file into a Spin Object Binary (SOB) file. Linking converts a SOB and its sub-SOBs into an executable binary image.
+
+

Compiling

+
The Sphinx "compiler" proper actually consists of two programs, lex.bin and codegen.bin, but they work so closely together that they are best considered a unit. Lex.bin reads a .spn file, tokenizes it, and produces an intermediate .tok file. Codegen.bin reads the .tok file, parses it, and generates object code which it saves in a .sob file.
+
 
+
A SOB contains the Spin bytecodes for the object's PUB and PRI methods. In addition, it contains a list of the object's imports (sub-objects) and its exports (constants and PUB method signatures). A SOB is the compiled essence of an object. As far as Sphinx is concerned, a SOB contains the same information as its corresponding Spin file, just in convenient binary form. 
+
 
+
The compiler only compiles a single .spn file at a time. If the .spn file contains a sub-object, the compiler reads the .sob file for that sub-object and retrieves its exported information. This gives the compiler enough information to compile the .spn file without having to compile additional .spn files.
+
 
+
This also means that programs have to be compiled from the bottom up. That is, sub-objects have to be compiled before any containing objects are compiled.
+
 
+
Consider a simple program that prints "Hello, world" on the screen. The top object, hello, contains a sub-object, tv_text. Tv_text in turn contains sub-object tv. When you compile hello.spn, the compiler will need to read tv_text.sob, so you have to have compiled tv_text.spn beforehand. Similarly, before compiling tv_text.spn, you must compile tv.spn to produce tv.sob. So to compile hello from a standing start you must issue these commands:
+
c tv
+
c tv_text
+
cl hello
+
 
+
Of course, subsequently you will not have to compile all three objects every time, just the objects that change.
+
+

Linking

+
You invoke the linker (link.bin) with the name of the top-level object. The linker reads the top-level SOB and goes through its list of imports (in other words, its sub-objects). The linker recursively reads the sub-SOBs and their sub-SOBs.
+
 
+
Once all the SOBs are read, the linker determines how it will lay out all the objects' bytecode in memory and adjusts the various inter-object pointers so that they all refer to one another correctly. Then it writes an executable binary image (.bin file).
+

Timestamps

+
Consider the following situation: +
    +
  1. sub.spn is compiled, producing sub.sob.
  2. +
  3. top.spn is compiled using sub.sob, producing top.sob.
  4. +
  5. sub.spn is modified and recompiled, producing a new sub.sob.
+
Now the top SOB is based on an old version of the sub-SOB. When the objects are linked, the resulting executable file may well fail because of that version mismatch.
+
 
+
In order to detect such version mismatches, Sphinx maintains a 32-bit "timestamp" in a file named timestmp.d8a. Every time you compile an object, Sphinx increments the timestamp and stores it in the .sob file. (Of course an actual timestamp could be used, but Sphinx takes this approach so as not to require a real-time clock.)
+
 
+
The linker compares timestamps and warns if any object being linked is out of date with respect to a sub-object.
+
 
+
Note that this timestamp mechanism cannot detect when a .sob file is out of date with respect to its .spn counterpart. That is, Sphinx cannot tell if a .spn file has been modified after being compiled. If you edit a source file, it is your responsibility to remember to compile it.
+
 
+
+
+
+
+
+
+
+
+
+ +
+
+
+

+ + +   + Anmelden + + +   + Site-Aktivität in letzter Zeit + + +   + Nutzungsbedingungen +   + Missbrauch melden + +   + Seite drucken + + + +  |  + + Powered by Google Sites +

+
+
+ + + + + + + + + + + + + + + + + diff --git a/zubehör/sphinx/spinx100225-ori/dokumentation/sphinxbin.htm b/zubehör/sphinx/spinx100225-ori/dokumentation/sphinxbin.htm new file mode 100644 index 0000000..54ef9fe --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/dokumentation/sphinxbin.htm @@ -0,0 +1,235 @@ + + + + + + + + + + + +sphinx.bin - sphinxcompiler + + + + +
+ +
+
+
+
+
+ + + + + + + + +
+ +
+
+
+
+
+ + + + + +
+ +
+
+
+Sphinx‎ > ‎Documentation‎ > ‎Reference‎ > ‎ +
+

+sphinx.bin +

+ +
+
+
Sphinx.bin installs the Sphinx drivers for the keyboard, TV, and SD card. It also acts as a simple command-line shell.
A command line can take any of the following forms:
  • filename arg1 arg2 ... argn
  • run filename arg1 arg2 ... argn
  • c filename arg1 arg2 ... argn
  • cl filename arg1 arg2 ... argn
The first form loads and executes the file named filename. If filename ends with ".bin" or ".eep", sphinx.bin will execute the file of that name (if it exists, of course). Otherwise, sphinx.bin will attempt to execute filename.bin and, if that fails, filename.eep.
 
The second form, the run command, also loads and runs filename. The difference between these two forms of command is that the first one leaves the Sphinx device driver cogs running, while the second stops all cogs (it effectively resets the Propeller). Use the first form to execute Sphinx-aware programs; use the run command to execute regular programs.
 
The c command compiles filename.spn and generates filename.sob (assuming no errors). This command runs lex.bin and codegen.bin, passing any command-line arguments to both programs (see below).
 
The cl command compiles and links filename.spn, generating filename.sob and filename.bin (again, assuming no errors). This command runs lex.bin, codegen.bin, and link.bin, passing its command-line arguments to all three programs.
 
Sphinx.bin should be stored in EEPROM so that the Propeller boots into Sphinx. Sphinx.bin should also exist on the SD card so that Sphinx-aware programs can, once they've finished their work, load and execute sphinx.bin. 

Command-line arguments

Sphinx.bin stores arguments as ASCII strings in a file named "args.d8a". A program launched from Sphinx can read the argument strings from that file. The first byte of the file is the number of arguments; it is followed by that number of strings, each null-terminated.
 
As noted earlier, the c and cl commands run several programs and each program receives the same arguments. This is because they do not modify args.d8a before executing the next program in the sequence. Each program pays attention to the arguments it understands and ignores any that it does not.
+
+
+
+
+
+
+
+
+ +
+
+
+

+ + +   + Anmelden + + +   + Site-Aktivität in letzter Zeit + + +   + Nutzungsbedingungen +   + Missbrauch melden + +   + Seite drucken + + + +  |  + + Powered by Google Sites +

+
+
+ + + + + + + + + + + + + + + + + diff --git a/zubehör/sphinx/spinx100225-ori/dokumentation/the-sphinx-operating-environment.htm b/zubehör/sphinx/spinx100225-ori/dokumentation/the-sphinx-operating-environment.htm new file mode 100644 index 0000000..09432c4 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/dokumentation/the-sphinx-operating-environment.htm @@ -0,0 +1,258 @@ + + + + + + + + + + + +The Sphinx operating environment - sphinxcompiler + + + + +
+ +
+
+
+
+
+ + + + + + + + +
+ +
+
+
+
+
+ + + + + +
+ +
+
+
+Sphinx‎ > ‎Documentation‎ > ‎ +
+

+The Sphinx operating environment +

+ +
+
+
+
+
Sphinx I/O is performed by device drivers that reside entirely in the Propeller's cogs, taking up almost no hub memory. For example, the video driver runs in a cog and maintains its screen buffer (13 lines of 40 characters) in its cog memory. It communicates with the rest of Sphinx through a single long memory location (known as a rendezvous, to use terminology borrowed from fsrw) at the top of hub RAM space. 
+
 
+
Similarly, the keyboard driver occupies no hub memory except for a rendezvous location.
+
 
+
The SD card driver is somewhat more complicated. It takes up three cogs. One is a low-level SD SPI driver (fsrw's sdspiqasm, lightly modified). The other two cogs implement a very barebones FAT16 file system that provides basic read, write, and execute functionality. Programs can open multiple files but must allocate some hub memory for each file. Communication with the file system is through several rendezvous locations. The file system requires a 512-byte buffer for metadata.
+
 
+
There are simple interface objects that hide the details of using the drivers.
+
 
+
+
+
Sphinx memory and cog usage
+
 
+
Sphinx.bin installs the drivers when it first boots up. From that point on, the drivers remain resident and running even as different programs execute in hub memory (as long as they are Sphinx-aware programs). For example, if you run link.bin by typing "link" at the command prompt, what happens is this:
+
+
    +
  1. Sphinx.bin uses the Sphinx file system to load link.bin into hub memory and execute it while leaving all cogs running.
  2. +
  3. Link.bin runs, using the Sphinx drivers to perform TV, keyboard, and file I/O. Note that link.bin does not install any drivers.
  4. +
  5. When link.bin terminates, it uses the file system to load and execute sphinx.bin. Sphinx.bin determines that the drivers are already running and does not re-install them. It prints a prompt and awaits the next command.
+
Sphinx-aware programs do not have to carry device driver code inside themselves; they can rely on Sphinx drivers. Sphinx-aware programs can execute other programs, typically sphinx.bin, but not necessarily (for example, lex.bin executes codegen.bin so that the two parts of the compiler run seamlessly). Running sphinx.bin puts up a command prompt immediately after a program ends, without the long delay that a reset would cause. This, coupled with the fact that the display accumulates the output from each program (rather than clearing between each program), gives the convincing illusion of a traditional command-line shell.
+
 
+
Sphinx can also execute regular (that is, non-Sphinx-aware) programs by performing the equivalent of a reset before running the program. This shuts down the driver cogs. The program must perform its own I/O. When the program finishes, a reboot will presumably occur, either programmatically or manually. At that time, Sphinx will load in from EEPROM and install the Sphinx drivers.
+
Next: Reference
+
+
+
+
+
+
+
+
+ +
+
+
+

+ + +   + Anmelden + + +   + Site-Aktivität in letzter Zeit + + +   + Nutzungsbedingungen +   + Missbrauch melden + +   + Seite drucken + + + +  |  + + Powered by Google Sites +

+
+
+ + + + + + + + + + + + + + + + + diff --git a/zubehör/sphinx/spinx100225-ori/sphinx0/fdserial.spin b/zubehör/sphinx/spinx100225-ori/sphinx0/fdserial.spin new file mode 100644 index 0000000..96d8431 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx0/fdserial.spin @@ -0,0 +1,316 @@ +''*************************************** +''* Full-Duplex Serial Driver v1.1 * +''* Author: Chip Gracey * +''* Copyright (c) 2006 Parallax, Inc. * +''* See end of file for terms of use. * +''*************************************** + + +VAR + + long cog 'cog flag/id + + long rx_head '9 contiguous longs + long rx_tail + long tx_head + long tx_tail + long rx_pin + long tx_pin + long rxtx_mode + long bit_ticks + long buffer_ptr + + byte rx_buffer[16] 'transmit and receive buffers + byte tx_buffer[16] + + +PUB start(rxpin, txpin, mode, baudrate) : okay + +'' Start serial driver - starts a cog +'' returns false if no cog available +'' +'' mode bit 0 = invert rx +'' mode bit 1 = invert tx +'' mode bit 2 = open-drain/source tx +'' mode bit 3 = ignore tx echo on rx + + stop + longfill(@rx_head, 0, 4) + longmove(@rx_pin, @rxpin, 3) + bit_ticks := clkfreq / baudrate + buffer_ptr := @rx_buffer + okay := cog := cognew(@entry, @rx_head) + 1 + + +PUB stop + +'' Stop serial driver - frees a cog + + if cog + cogstop(cog~ - 1) + longfill(@rx_head, 0, 9) + + +PUB rxflush + +'' Flush receive buffer + + repeat while rxcheck => 0 + + +PUB rxcheck : rxbyte + +'' Check if byte received (never waits) +'' returns -1 if no byte received, $00..$FF if byte + + rxbyte-- + if rx_tail <> rx_head + rxbyte := rx_buffer[rx_tail] + rx_tail := (rx_tail + 1) & $F + + +PUB rxtime(ms) : rxbyte | t + +'' Wait ms milliseconds for a byte to be received +'' returns -1 if no byte received, $00..$FF if byte + + t := cnt + repeat until (rxbyte := rxcheck) => 0 or (cnt - t) / (clkfreq / 1000) > ms + + +PUB rx : rxbyte + +'' Receive byte (may wait for byte) +'' returns $00..$FF + + repeat while (rxbyte := rxcheck) < 0 + + +PUB tx(txbyte) + +'' Send byte (may wait for room in buffer) + + repeat until (tx_tail <> (tx_head + 1) & $F) + tx_buffer[tx_head] := txbyte + tx_head := (tx_head + 1) & $F + + if rxtx_mode & %1000 + rx + + +PUB str(stringptr) + +'' Send string + + repeat strsize(stringptr) + tx(byte[stringptr++]) + + +PUB dec(value) | i + +'' Print a decimal number + + if value < 0 + -value + tx("-") + + i := 1_000_000_000 + + repeat 10 + if value => i + tx(value / i + "0") + value //= i + result~~ + elseif result or i == 1 + tx("0") + i /= 10 + + +PUB hex(value, digits) + +'' Print a hexadecimal number + + value <<= (8 - digits) << 2 + repeat digits + tx(lookupz((value <-= 4) & $F : "0".."9", "A".."F")) + + +PUB bin(value, digits) + +'' Print a binary number + + value <<= 32 - digits + repeat digits + tx((value <-= 1) & 1 + "0") + + +DAT + +'*********************************** +'* Assembly language serial driver * +'*********************************** + + org +' +' +' Entry +' +entry mov t1,par 'get structure address + add t1,#4 << 2 'skip past heads and tails + + rdlong t2,t1 'get rx_pin + mov rxmask,#1 + shl rxmask,t2 + + add t1,#4 'get tx_pin + rdlong t2,t1 + mov txmask,#1 + shl txmask,t2 + + add t1,#4 'get rxtx_mode + rdlong rxtxmode,t1 + + add t1,#4 'get bit_ticks + rdlong bitticks,t1 + + add t1,#4 'get buffer_ptr + rdlong rxbuff,t1 + mov txbuff,rxbuff + add txbuff,#16 + + test rxtxmode,#%100 wz 'init tx pin according to mode + test rxtxmode,#%010 wc + if_z_ne_c or outa,txmask + if_z or dira,txmask + + mov txcode,#transmit 'initialize ping-pong multitasking +' +' +' Receive +' +receive jmpret rxcode,txcode 'run a chunk of transmit code, then return + + test rxtxmode,#%001 wz 'wait for start bit on rx pin + test rxmask,ina wc + if_z_eq_c jmp #receive + + mov rxbits,#9 'ready to receive byte + mov rxcnt,bitticks + shr rxcnt,#1 + add rxcnt,cnt + +:bit add rxcnt,bitticks 'ready next bit period + +:wait jmpret rxcode,txcode 'run a chuck of transmit code, then return + + mov t1,rxcnt 'check if bit receive period done + sub t1,cnt + cmps t1,#0 wc + if_nc jmp #:wait + + test rxmask,ina wc 'receive bit on rx pin + rcr rxdata,#1 + djnz rxbits,#:bit + + shr rxdata,#32-9 'justify and trim received byte + and rxdata,#$FF + test rxtxmode,#%001 wz 'if rx inverted, invert byte + if_nz xor rxdata,#$FF + + rdlong t2,par 'save received byte and inc head + add t2,rxbuff + wrbyte rxdata,t2 + sub t2,rxbuff + add t2,#1 + and t2,#$0F + wrlong t2,par + + jmp #receive 'byte done, receive next byte +' +' +' Transmit +' +transmit jmpret txcode,rxcode 'run a chunk of receive code, then return + + mov t1,par 'check for head <> tail + add t1,#2 << 2 + rdlong t2,t1 + add t1,#1 << 2 + rdlong t3,t1 + cmp t2,t3 wz + if_z jmp #transmit + + add t3,txbuff 'get byte and inc tail + rdbyte txdata,t3 + sub t3,txbuff + add t3,#1 + and t3,#$0F + wrlong t3,t1 + + or txdata,#$100 'ready byte to transmit + shl txdata,#2 + or txdata,#1 + mov txbits,#11 + mov txcnt,cnt + +:bit test rxtxmode,#%100 wz 'output bit on tx pin according to mode + test rxtxmode,#%010 wc + if_z_and_c xor txdata,#1 + shr txdata,#1 wc + if_z muxc outa,txmask + if_nz muxnc dira,txmask + add txcnt,bitticks 'ready next cnt + +:wait jmpret txcode,rxcode 'run a chunk of receive code, then return + + mov t1,txcnt 'check if bit transmit period done + sub t1,cnt + cmps t1,#0 wc + if_nc jmp #:wait + + djnz txbits,#:bit 'another bit to transmit? + + jmp #transmit 'byte done, transmit next byte +' +' +' Uninitialized data +' +t1 res 1 +t2 res 1 +t3 res 1 + +rxtxmode res 1 +bitticks res 1 + +rxmask res 1 +rxbuff res 1 +rxdata res 1 +rxbits res 1 +rxcnt res 1 +rxcode res 1 + +txmask res 1 +txbuff res 1 +txdata res 1 +txbits res 1 +txcnt res 1 +txcode res 1 + +{{ + ++------------------------------------------------------------------------------------------------------------------------------+ +¦ TERMS OF USE: MIT License ¦ ++------------------------------------------------------------------------------------------------------------------------------¦ +¦Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation ¦ +¦files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, ¦ +¦modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software¦ +¦is furnished to do so, subject to the following conditions: ¦ +¦ ¦ +¦The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.¦ +¦ ¦ +¦THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE ¦ +¦WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ¦ +¦COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ¦ +¦ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ¦ ++------------------------------------------------------------------------------------------------------------------------------+ +}} \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx0/isxfs.spin b/zubehör/sphinx/spinx100225-ori/sphinx0/isxfs.spin new file mode 100644 index 0000000..661adbe --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx0/isxfs.spin @@ -0,0 +1,80 @@ +SXTVRENDEZVOUS = $8000 - 4 +SXKBRENDEZVOUS = SXTVRENDEZVOUS - 4 +SDSPIRENDEZVOUS = SXKBRENDEZVOUS - 3 * 4 +SXFS2RENDEZVOUS = SDSPIRENDEZVOUS - 4 * 4 ' four rendezvous variables +SXFSRENDEZVOUS = SXFS2RENDEZVOUS - 4 * 4 ' four rendezvous variables +METADATABUFFER = SXFSRENDEZVOUS - 512 + +_free = ($8000 - METADATABUFFER) / 4 + +SIZEOFFILESTUFF = 512 + 24 + +pCommand = SXFSRENDEZVOUS +pParam0 = pCommand+4 +pParam1 = pCommand+8 +pParam2 = pCommand+12 + +pub Open( pFilestuff, pFilename, mode ) | filenameBuffer[3], p, i +{{ + mode is either "R" or "W". + Returns 0 on success, 1 if file not found (and opening for reading). +}} + return Command( "O", pFilestuff, pFilename, mode ) + +pub Close( pFilestuff ) + Command( "C", pFilestuff, 0, 0 ) + +pub Read( pFilestuff, pBuffer, nBytes ) +{{ + Returns number of bytes actually read, -1 at EOF. +}} + long[pParam0] := pFilestuff + long[pParam1] := pBuffer + long[pParam2] := nBytes + + long[pCommand] := "R" + repeat while long[pCommand] + if long[pParam0] < -2 ' don't abort for return code -1. + abort long[pParam0] + return long[pParam0] + +pub Write( pFilestuff, pBuffer, nBytes ) + return Command( "W", pFilestuff, pBuffer, nBytes ) + +pub Execute( pFilestuff, execmode ) +{{ + If execmode is non-0, all cogs are stopped except Spin interpreter. + If execmode is 0, running cogs are left running. +}} + Command( "X", pFilestuff, execmode, cogid ) + +pub Command( cmd, param0, param1, param2 ) + long[pParam0] := param0 + long[pParam1] := param1 + long[pParam2] := param2 + + long[pCommand] := cmd + repeat while long[pCommand] + if long[pParam0] < 0 + abort long[pParam0] + return long[pParam0] + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} + \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx0/sphinx.spin b/zubehör/sphinx/spinx100225-ori/sphinx0/sphinx.spin new file mode 100644 index 0000000..d86f68c --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx0/sphinx.spin @@ -0,0 +1,370 @@ +{ + _clkfreq = 96_000_000 ' Hybrid + _clkmode = xtal1 + pll16x + + tvPins = 24 + kbPins = 12 + sdPins = 8 +} + _clkfreq = 80_000_000 ' Hydra + _clkmode = xtal1 + pll8x + + tvPins = 24 + kbPins = 13 + sdPins = 16 +{ + Simple command line + +2009 +April + 15 Adding file transfer to/from PC via serial + 16 0.02 + SendFile bugfix (while blksize == 1024) + Tries to run .bin before .eep now. +June + 4 Changing name from cl to sphinx. Converting to use sxfs, sxtv. + 15 sxkb; adding c and cl commands + 23 Corrected clock mode calculation. +2010 +Feb + 25 New version number +} + +obj + kb: "sxkb" + term: "sxtv" + sxfs: "sxfs" + f: "sxfile" + ser: "fdserial" + +con +SXTVRENDEZVOUS = $8000 - 4 +SXKBRENDEZVOUS = SXTVRENDEZVOUS - 4 +SDSPIRENDEZVOUS = SXKBRENDEZVOUS - 3 * 4 +SXFS2RENDEZVOUS = SDSPIRENDEZVOUS - 4 * 4 ' four rendezvous variables +SXFSRENDEZVOUS = SXFS2RENDEZVOUS - 4 * 4 ' four rendezvous variables +METADATABUFFER = SXFSRENDEZVOUS - 512 + +_free = ($8000 - METADATABUFFER) / 4 + +pub Main | err, p + if term.start( tvPins, SXTVRENDEZVOUS ) + term.str( string("============= Sphinx 100225 ============", 13) ) + term.str( string("video @ pin ") ) + term.dec( tvPins ) + term.str( string(13, "keyboard @ pin ") ) + term.dec( kbPins ) + term.str( string(13, "SD @ pin ") ) + term.dec( sdPins ) + term.out( 13 ) + sxfs.start( sdPins ) + kb.start( kbPins ) + + repeat + if ina[31] ' USB cable connected? + ser.start( 31, 30, %0000, 19200 ) + f.Close + err := \DoIt + if err + if err > 0 + term.str( err ) + else + term.str( string("Error ") ) + term.dec( err ) + term.out( 13 ) + else + term.str( string("Normal exit") ) ' This never happens + +pri DoIt | ch + term.out( ">" ) + term.out( "_" ) + term.out( 8 ) + repeat + if kb.peekkey + EditCmdLine + Execute + term.out( ">" ) + term.out( "_" ) + term.out( 8 ) + if (ch := ser.rxcheck) <> -1 + term.out( 8 ) + FileTransfer( ch ) + term.out( ">" ) + term.out( "_" ) + term.out( 8 ) + +con + MAXCMDLINELENGTH = 78 ' some arbitray limit. + CR = $0d + BKSP = $c8 + +var + byte cmdLine[MAXCMDLINELENGTH+1] ' +1 for null terminator + long cmdLineLength + +pri EditCmdLine | key + cmdLineLength~ ' cursor is always at end of command line + + repeat + case key := kb.key + $20..$7f: + if cmdLineLength < MAXCMDLINELENGTH + cmdLine[ cmdLineLength++ ] := key + term.out( key ) + term.out( "_" ) + term.out( 8 ) + CR: + term.out( " " ) + term.out( 13 ) + cmdLine[ cmdLineLength ]~ + return true + BKSP: + if cmdLineLength + --cmdLineLength + term.out( " " ) + term.out( 8 ) + term.out( 8 ) + term.out( "_" ) + term.out( 8 ) + +pri FileTransfer( cmd ) | ch, i + if cmd <> "G" and cmd <> "P" + term.out( cmd ) + abort string(" -- unrecognized command from PC") + i~ + repeat + ch := RxSerByte + if i => FILENAMEBUFFERSIZE + abort string("Filename too long") + filename[i++] := ch + while ch + + if cmd == "G" + term.str( string("sending ") ) + term.str( @filename ) + term.out( 13 ) + SendFileToPC + else + term.str( string("receiving ") ) + term.str( @filename ) + term.out( 13 ) + ReceiveFileFromPC + +pri SendFileToPC | blksize, i, chksum, b, n + if f.Open( @filename, "R" ) <> 0 + term.str( @filename ) + abort string(" -- can't open file for reading") + TxSerByte( "A" ) ' ack + + n~ + repeat + blksize := f.Read( @buffer, 1024 ) + if blksize == -1 + blksize~ + TxSerByte( blksize.byte[0] ) + TxSerByte( blksize.byte[1] ) + i~ + chksum~ + repeat blksize + b := buffer[i++] + chksum += b + TxSerByte( b ) + n += blksize + if chksum & $ff <> RxSerByte + abort string("Checksum error") + while blksize == 1024 + f.Close + term.dec( n ) + term.str( string(" bytes sent", 13) ) + +pri ReceiveFileFromPC | blksize, i, chksum, b, n + if f.Open( @filename, "W" ) <> 0 + term.str( @filename ) + abort string(" -- can't open file for writing") + TxSerByte( "A" ) ' ack + + n~ + repeat + blksize~ + blksize.byte[0] := RxSerByte + blksize.byte[1] := RxSerByte + if blksize > 1024 + abort string("Block size > 1024") + i~ + chksum~ + repeat blksize + b := RxSerByte + buffer[i++] := b + chksum += b + n += blksize + f.Write( @buffer, blksize ) + TxSerByte( chksum ) + while blksize == 1024 + f.Close + term.dec( n ) + term.str( string(" bytes received", 13) ) + +pri RxSerByte : b +' ser.rx with timeout + b := ser.rxtime( TIMEOUT ) + if b == -1 + abort string("RxSerByte timed out") + +pri TxSerByte( b ) +' just for symmetry with RxSerByte + ser.tx( b ) + +con +TIMEOUT = 500 + +var + byte buffer[1024] + +pri Execute | n, p, q, run, c + c~ + ifnot n := ParseCmdLine + return + p := @cmdLine + ToUpper(p) + + if run := strcomp( @cmdLine, string("RUN") ) + --n + p += strsize(p) + 1 + elseif strcomp( @cmdLine, string("C") ) + c := 1 + --n + p += strsize(p) + 1 ' command arg1 arg2... + elseif strcomp( @cmdLine, string("CL") ) ' run command arg1 arg2... + c := 2 ' c arg1 arg2... + --n ' cl arg1 arg2... + p += strsize(p) + 1 + + ifnot n + abort string("No file specified") + + f.Open( string("args.d8a"), "W" ) ' write args + if c == 0 + q := p + strsize(p) + 1 ' for run and plain command, skip first arg (command name) + --n + f.Write( @n, 1 ) + repeat n + f.Write( q, strsize(q) + 1 ) + q += strsize(q) + 1 + else ' for c and cl, + ++n ' add extra arg (/c or /l) + f.Write( @n, 1 ) + repeat n-1 + f.Write( p, strsize(p) + 1 ) + p += strsize(p) + 1 + if c == 1 + f.Write( string("/c"), 3 ) + else + f.Write( string("/l"), 3 ) + + n~ + f.Write( @n, 1 ) ' final terminating null + f.Close + + if c + if f.Open( string("lex.bin"), "R" ) <> 0 + abort string("lex.bin not found") + ser.stop + f.Execute( 0 ) + + + if EndsWith( p, string(".BIN") ) or EndsWith( p, string(".EEP") ) + if f.Open( p, "R" ) <> 0 + term.str( p ) + abort string(" -- not found") + else + if strsize(p) > MAXFILENAMELENGTH - 4 + term.str( p ) + abort string(" -- filename too long") + bytemove( @filename, p, strsize(p) + 1 ) + bytemove( @filename + strsize(p), string(".BIN"), 5 ) + if f.Open( @filename, "R" ) <> 0 + bytemove( @filename + strsize(p), string(".EEP"), 5 ) + if f.Open( @filename, "R" ) <> 0 + term.str( p ) + abort string(" -- no .bin or .eep found") + ser.stop + f.Execute( run ) + +pri ToUpper( p ) + repeat while byte[p] + if "a" =< byte[p] and byte[p] =< "z" + byte[p] += "A" - "a" + ++p + +pri EndsWith( p, s ) + if strsize(p) < strsize(s) + return false + p += strsize(p) - strsize(s) + repeat while byte[p] + if byte[p++] <> byte[s++] + return false + return true + +con + MAXFILENAMELENGTH = 12 ' 8 + . + 3 + FILENAMEBUFFERSIZE = MAXFILENAMELENGTH + 1 ' 8 + . + 3 + null + CMDNAMEBUFFERSIZE = 9 ' 8 + null + +var + byte filename[MAXFILENAMELENGTH+1] ' 8 + . + 3 + null + +pri ParseCmdLine : n | pSrc, pDst, state +{{ + Converts cmdLine from " ab de fg \" to "ab\de\fg\" ('\' = null). + Returns # of "words". +}} +{ + state whitespace null other char + 0 ++pSrc; append \0; quit append char; => 1 + 1 append \0; ++n; => 0 append \0; ++n; quit append char; +} + pSrc := @cmdLine + pDst := @cmdLine + state~ + repeat + if state == 0 + if byte[pSrc] == " " + ++pSrc + elseif byte[pSrc] == 0 + byte[pDst++]~ + quit + else + byte[pDst++] := byte[pSrc++] + state := 1 + elseif state == 1 + if byte[pSrc] == " " + ++pSrc + byte[pDst++]~ + ++n + state~ + elseif byte[pSrc] == 0 + byte[pDst++]~ + ++n + quit + else + byte[pDst++] := byte[pSrc++] + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} + \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx0/sxfile.spin b/zubehör/sphinx/spinx100225-ori/sphinx0/sxfile.spin new file mode 100644 index 0000000..921eae9 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx0/sxfile.spin @@ -0,0 +1,98 @@ +obj + isxfs: "isxfs" + +var +long filestuff[isxfs#SIZEOFFILESTUFF / 4] + +pub Open( pFilename, mode ) + return isxfs.Open( @filestuff, pFilename, mode ) + +pub Close + isxfs.Close( @filestuff ) + +pub Read( ptr, n ) + return isxfs.Read( @filestuff, ptr, n ) + +pub Write( ptr, n ) + return isxfs.Write( @filestuff, ptr, n ) + +pub Length +{{ + Only valid for files opened for reading. +}} + return long[@filestuff] + +pub Execute( mode ) + isxfs.Execute( @filestuff, mode ) + isxfs.Close( @filestuff ) ' we only get here if Execute fails for some reason. + +pub ReadString( p, MAXLENGTH ) | ch + repeat MAXLENGTH + 1 + ch := ReadByte + ifnot byte[p++] := ch + return + abort string("ReadString: string too long") + +pub ReadStringUpperCase( p, MAXLENGTH ) | ch + repeat MAXLENGTH + 1 + ch := ReadByte + if "a" =< ch and ch =< "z" + ch -= constant("a" - "A") + ifnot byte[p++] := ch + return + abort string("ReadStringUpperCase: string too long") + +pub WriteString( p ) + Write( p, strsize(p) + 1 ) + +pub ReadNumber | ch + repeat + ifnot ch := ReadByte + return + if ch < "0" or ch > "9" + abort string("ReadNumber: non-numeric character") + result := result * 10 + ch - "0" + +pub ReadByte : ch + Read( @ch, 1 ) + +pub WriteByte( b ) + Write( @b, 1 ) + +pub ReadWord + return ReadByte + (ReadByte << 8) + +pub WriteWord( w ) + Write( @w, 2 ) + +pub ReadLong + return ReadByte + (ReadByte << 8) + (ReadByte << 16) + (ReadByte << 24) + +pub WriteLong( l ) + Write( @l, 4 ) + +pub SkipBytes( n ) + repeat while n => 32768 + Read( $8000, 32768 ) + n -= 32768 + Read( $8000, n ) + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} + \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx0/sxfs.spin b/zubehör/sphinx/spinx100225-ori/sphinx0/sxfs.spin new file mode 100644 index 0000000..b290d31 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx0/sxfs.spin @@ -0,0 +1,874 @@ +' 2010-02-23 fixed duplicate file bug + +SXTVRENDEZVOUS = $8000 - 4 +SXKBRENDEZVOUS = SXTVRENDEZVOUS - 4 +SDSPIRENDEZVOUS = SXKBRENDEZVOUS - 3 * 4 +SXFS2RENDEZVOUS = SDSPIRENDEZVOUS - 4 * 4 ' four rendezvous variables +SXFSRENDEZVOUS = SXFS2RENDEZVOUS - 4 * 4 ' four rendezvous variables +METADATABUFFER = SXFSRENDEZVOUS - 512 + +_free = ($8000 - METADATABUFFER) / 4 + +{ + sxfsrendezvous sdspirendezvous +--------+ +--------+ +-------+ + | <===> command <===> | | <=====> command <=====> | | + Spin | | | | | +routines| <===> param0 <====> | SXFS | <=====> param <=====> | SDSPI | + | | cog | | cog | + | ----> param1 -----> | | ------> blockno ------> | | + | | | +-------+ + | ----> param2 -----> | | +--------+ | | sxfs2rendezvous + | | +-------+ + | | <====> command <======> | | + | | | | <==> (sxfsrendezvous) + | | <====> param0 <=======> | SXFS2 | + | | | cog | <==> (sdspirendezvous) + | | | | + +--------+ +-------+ + + +SXFS cog handles file reading: open, read, close. +SXFS2 cog, under SXFS's direction, handles execute and file writing: write, close. +SDSPI cog handles SD card sector reading and writing. + +SXFS cog communicates with main program via sxfsrendezvous and Spin interface routines. +SXFS cog communicates with SXFS2 cog via sxfs2rendezvous. +SXFS cog communicates with SDSPI cog via sdspirendezvous. + +-1: eof, general error +-100: bad command +-101: not FAT16 +-102: file not found +-104: bad mode +-106: file not closed +-107: directory full +-109: file not properly opened +-110: FAT full. +-113: bad filename + +} + +obj + sxfs2: "sxfs2" + sdspi : "sxsdspiq" + +pub Start( sdPin ) | pbrSector + + ' Determine if sxfs cog and, by association, sxfs2 and sdspi cogs, are already running. + ' If not, start them up. + ' Returns true if the cogs needed to be started, false if the cogs were already running. + + ifnot Ping + result~~ + ' start sdspi cog and initialize SD card + long[pSdspiCommand] := "I" + sdspi.start( sdPin, pSdspiCommand ) + repeat while long[pSdspiCommand] + if long[pSdspiParam] + abort long[pSdspiParam] + + pbrSector := ReadPbr + + ' start sxfs cog + long[pCommand] := "?" + if cognew( @sxfsEntry, 0 ) < 0 + abort -1 + repeat while long[pCommand] + + ' start sxfs2 cog + sxfs2.Start( pbrSector ) + +pri ReadPbr : pbrSector + repeat + sdspi.readblock( pbrSector, pMetadataBuffer ) + if bytecompare( pMetadataBuffer+$36, string("FAT16"), 5 ) + quit + if pbrSector + abort -101 ' not FAT16 + pbrSector := PeekL( pMetadataBuffer + $1c6 ) + + bytesPerSector := PeekW( pMetadataBuffer + $0b ) + sectorsPerCluster := byte[pMetadataBuffer][$0d] + clusterShift := >| sectorsPerCluster - 1 + reservedSectors := PeekW( pMetadataBuffer + $0e ) + numberOfFats := byte[pMetadataBuffer][$10] + sectorsPerFat := PeekW( pMetadataBuffer + $16 ) + RootDirEntries := PeekW( pMetadataBuffer + $11 ) + fatSector0 := pbrSector + reservedSectors + dirSector0 := fatSector0 + numberOfFats * sectorsPerFat + dataSector0 := dirSector0 + rootDirEntries >> 4 + +pri bytecompare( _p, _q, _n ) + repeat _n + if byte[_p++] <> byte[_q++] + return + return true + +pri PeekW( a ) + return byte[a++] + byte[a] << 8 + +pri PeekL( a ) + return byte[a++] + byte[a++] << 8 + byte[a++] << 16 + byte[a] << 24 + +pri Ping +{{ + returns 1 if bmfs cog is active, 0 otherwise. +}} + long[pCommand] := "?" + if long[pCommand] + return 0 + else + return 1 + +con + SECTORSIZE = 512 + SECTORSHIFT = 9 + DIRSIZE = 32 + +con +' filestuff definitions +' filestuff must be long-aligned +{ long } _length = 0 +{ long } _leftInFile = 4 +{ long } _sopDir = 8 ' sector/offset "pointer" to directory entry +{ long } _sopTail = 12 ' sector/offset "pointer" to last cluster# in FAT chain +{ word } _cluster = 16 +{ word } _sector = 18 ' sector# within cluster; ranges from 0 to sectorsPerCluster-1 +{ word } _bp = 20 ' byte pointer (actually an index into the sector buffer); range [0..511] +{ word } _mode = 22 ' 0: closed; "R": open for reading; "W": open for writing. + _buffer = 24 ' 512-byte buffer starts here + +SIZEOFFILESTUFF = SECTORSIZE + 24 + +dat +{{ + command param0 param1 param2 + "?" -- -- -- Do nothing, but acknowledge to indicate that sxfs cog is active. + "O" filestuff filename mode Open a file, populate filestuff fields. mode is "R" or "W". + "R" filestuff buffer num Reads num bytes into buffer from file specified by filestuff. + "W" filestuff buffer num Writes num bytes from buffer to file specified by filestuff. + "C" filestuff -- -- Closes file specified by filestuff. + "X" filestuff execmode cog Executes file. + +}} + org 0 +SXFSEntry + +AckNoReturnCode + mov temp, #0 ' clear return code +AckReturnCode ' enter here with temp = return code + wrlong temp, pParam0 + mov temp, #0 + wrlong temp, pCommand ' clear command to signal operation complete. + +:ready ' wait for new command + rdlong temp, pCommand wz + if_z jmp #:ready + + cmp temp, #"?" wz + if_e jmp #AckNoReturnCode + cmp temp, #"O" wz + if_e jmp #Open + cmp temp, #"R" wz + if_e jmp #Read + cmp temp, #"W" wz + if_e jmp #Write + cmp temp, #"C" wz + if_e jmp #Close + cmp temp, #"X" wz + if_e jmp #Execute + ' else + neg temp, #100 ' -100: bad command + jmp #AckReturnCode + + +'********************************************************************************************************************* +'* * +'* Open stuff * +'* * +'********************************************************************************************************************* +Open ' ( param0 = pFilestuff, param1 = pFilename, param2 = mode ) +{ + Return value: + File found File not found Error + mode = "R" 0 1 < 0 + mode = "W" 0 0 < 0 + +Mode W will either open an existing file or create a new file. +} + rdword pFilestuff, pParam0 + rdword pFilename, pParam1 + + mov p, pFilestuff + add p, #_mode + rdword temp, p wz + if_nz neg temp, #106 ' -106: file not closed + if_nz jmp #AckReturnCode + + call #MassageFilename + + rdword temp, pParam2 + cmp temp, #"R" wz + if_e jmp #:openForReading + cmp temp, #"W" wz + if_e jmp #:openForWriting + neg temp, #104 ' -104: bad mode + jmp #AckReturnCode +:openForReading + call #FindFile + + mov p, pFilestuff + add p, #_sopDir ' pFilestuff->sopDir = 0 => file not found + rdlong temp, p wz + if_z mov temp, #1 ' return 1 to indicate file not found + if_z jmp #AckReturnCode + + mov p, sop ' sop sector is still in memory + and p, #$1ff + add p, pMetadataBuffer + add p, #$1a ' point to cluster information + rdword temp, p + + mov q, pFilestuff + add q, #_cluster + wrword temp, q + + add p, #2 ' point to length information + rdlong temp, p + + sub q, #_cluster-_length ' q points to length + wrlong temp, q + add q, #_leftInFile-_length ' q points to leftInFile + wrlong temp, q + + add q, #_sector-_leftInFile ' q points to sector + mov temp, #0 + wrword temp, q + + add q, #_bp-_sector ' q points to bp + wrword k512, q + + mov p, pFilestuff + add p, #_mode + mov temp, #"R" + wrword temp, p ' save mode + + jmp #AckNoReturnCode + +:openForWriting + mov sop, dirSector0 ' sop "points" to directory entries: + shl sop, #9 ' incremented by 32 each time through the loop. + mov sopDir, #0 ' sopDir "points" to the directory entry + ' that will be used or reused for the file being opened. + mov i, rootDirEntries +:forEachDirEntry ' Loop through the directory entries, looking for a deleted entry, + ' an empty entry, or an entry that matches pFilename. + mov sector, sop + shr sector, #9 + call #ReadMetadataSector + mov p, sop + and p, #$1ff + add p, pMetadataBuffer ' p points to the current directory entry + add p, #$0b + rdbyte temp, p ' p[$0b] = attribute byte + sub p, #$0b + and temp, #$02 wz ' If hidden, + if_nz jmp #:next ' skip. Hidden dir entries include long name entries. + + rdbyte temp, p ' p[0] + cmp temp, #$e5 wz ' = $e5? (deleted directory entry?) + if_e cmp sopDir, #0 wz ' save pointer in sopDir (just the first time) + if_e mov sopDir, sop + + tjz temp, #:quit ' empty directory entry? We're done + + mov q, pFilename ' matching filename? Done. + mov n, #11 + call #ByteComp + if_e mov sopDir, sop ' 2010-02-23 duh + if_e jmp #:quit +:next + add sop, #DIRSIZE + djnz i, #:forEachDirEntry +:quit + cmp i, #0 wz ' did we go through the whole directory? + if_z neg temp, #107 ' -107: directory full + if_z jmp #AckReturnCode + + cmp sopDir, #0 wz ' if sopDir hasn't been set yet, + if_e mov sopDir, sop ' set it to sop. + + mov p, pFilestuff + add p, #_sopDir + wrlong sopDir, p ' pFilestuff->sopDir := sopDir + add p, #_sopTail-_sopDir + add sopDir, #$1a + wrlong sopDir, p ' pFilestuff->sopTail := sopDir + $1a + ' (points to directory entry's cluster field). + mov sector, sopDir + shr sector, #9 ' Get the chosen directory entry into memory + call #ReadMetadataSector ' if it isn't already. + + mov p, sopDir ' Recall that sopDir was changed + and p, #$1ff ' to point to the cluster field, + add p, pMetadataBuffer ' so p now points to the cluster field in the buffer. + + rdword cluster, p ' Save the cluster field. + mov temp, #0 + wrword temp, p ' Zero the cluster field. + sub p, #$1a ' Point to start of directory entry + + rdbyte temp, p ' Check to see if this was a deleted dir entry. + cmp temp, #$e5 wz ' If it was, we definitely do not want to zero the + if_e mov cluster, #0 ' cluster chain, so set cluster to 0. + + mov q, pFilename ' Store the filename in the directory entry. + mov n, #11 + call #ByteCopy + + mov temp, #$20 ' Set the attribute byte (immediately following name) + wrbyte temp, p + add p, #$10-$0b ' Point to creation date. + mov temp, aDate ' 2001/01/01 + wrword temp, p + add p, #$12-$10 ' Point to last access date. + wrword temp, p + add p, #$18-$12 ' Point to last update date. + wrword temp, p + + mov dirty, #1 ' We've modified metadata. + + tjz cluster, #:done +:forEachClusterInList ' Traverse the cluster list and zero each link. + + mov sector, cluster + shr sector, #8 + add sector, fatSector0 + call #ReadMetadataSector ' Read FAT sector for current cluster + + mov p, cluster + and p, #$ff + shl p, #1 + add p, pMetadataBuffer ' Point p at cluster entry in FAT + + rdword cluster, p ' Get next cluster link. + cmp cluster, #1 wc, wz ' Break if cluster <= 1 + if_be jmp #:done + + mov temp, #0 + wrword temp, p ' Zero the cluster link. + mov dirty, #1 ' We've modified metadata. + + cmp cluster, kfff0 wc, wz ' repeat unless new cluster >= $fff0 + if_b jmp #:forEachClusterInList +:done + mov p, pFilestuff + add p, #_sector + mov temp, #0 + wrword temp, p ' pFilestuff->sector := 0 + add p, #_bp-_sector + wrword temp, p ' pFilestuff->bp := 0 + + mov p, pFilestuff + mov temp, #0 + wrlong temp, p ' pFilestuff->length := 0 + add p, #_mode + mov temp, #"W" + wrword temp, p ' save mode + + jmp #AckNoReturnCode + +MassageFilename +{ + Take the null-terminated 8.3 filename pointed to by pFilename, + move it into memory starting at pFilestuff->buffer and expand it to 11 characters; + change pFilename to point to the expanded filename. +} + mov p, pFilestuff + add p, #_buffer + mov q, p + add p, #1 + mov temp, #" " + wrbyte temp, q + mov n, #10 + call #ByteCopy + + mov q, pFilename ' q is src + mov p, pFilestuff ' p is dst + add p, #_buffer + mov i, #9 ' Copy up to 8 chars (stop at . or null). +:upTo8 + rdbyte temp, q + add q, #1 + tjz temp, #:done + cmp temp, #"." wz + if_z jmp #:dot + call #ValidateChar + wrbyte temp, p + add p, #1 + djnz i, #:upTo8 + ' If we fall through, we've copied 9 characters (tsk tsk). + neg temp, #113 ' -113: bad filename + jmp #AckReturnCode +:dot + mov p, pFilestuff + add p, #_buffer+8 + mov i, #4 ' Copy up to 3 chars (stop at null). +:upTo3 + rdbyte temp, q + add q, #1 + tjz temp, #:done + call #ValidateChar + wrbyte temp, p + add p, #1 + djnz i, #:upTo3 + ' If we fall through, we've copied 4 characters (tsk tsk ). + neg temp, #113 ' -113: bad filename + jmp #AckReturnCode +:done + mov pFilename, pFilestuff + add pFilename, #_buffer + +MassageFilename_ret ret + +FindFile +{ + pFilename points to 11-character buffer (e.g. "BLAH TXT"). + pFilestuff points to a filestuff structure. + Return value: + If file is found, pFilestuff->sopDir is disk address of directory entry. + If file is not found, pFilestuff->sopDir is 0. +} + mov sop, dirSector0 ' sop starts at dirSector0<<9, counts up by DIRSIZE + shl sop, #SECTORSHIFT + mov i, rootDirEntries +:loop + mov sector, sop + shr sector, #9 + call #readMetadataSector + mov p, sop + and p, #$1ff + add p, pMetadataBuffer + rdbyte temp, p wz + if_z jmp #:notfound + + add p, #$0b + rdbyte temp, p ' p[$0b] = attribute byte + sub p, #$0b + and temp, #$02 wz ' If hidden, + if_nz jmp #:next ' skip. Hidden dir entries include long name entries. + + mov q, pFilename + mov n, #11 + call #ByteComp + if_e jmp #:found +:next + add sop, #DIRSIZE + djnz i, #:loop +:notfound + mov sop, #0 +:found + mov p, pFilestuff + add p, #_sopDir + wrlong sop, p +FindFile_ret ret + + +'********************************************************************************************************************* +'* * +'* Read stuff * +'* * +'********************************************************************************************************************* +Read ' ( param0 = pFilestuff, param1 = ptr, param2 = n ) +{ + Read n bytes from file described by pIoblock into memory starting at p. + Returns number of bytes actually read or -1 if attempting to read past EOF. +} + rdlong pFilestuff, pParam0 + rdlong destPtr, pParam1 + rdlong nBytes, pParam2 + + mov p, pFilestuff ' Verify that file was opened for reading. + add p, #_mode + rdword temp, p + cmp temp, #"R" wz + if_ne neg temp, #109 ' -109: file not properly opened + if_ne jmp #AckReturnCode + sub p, #_mode-_leftInFile + + ' Adjust nBytes depending on how much is left to read in file. + ' E.g. if we're 10 bytes from EOF and we try to read 15 bytes, + ' just read 10. If we're at EOF and try to read 15 bytes, return -1. + rdlong temp, p + max nBytes, temp ' nBytes is lesser of nBytes and leftInFile + tjnz temp, #:x + neg temp, #1 ' -1: eof + jmp #ackReturnCode +:x + mov retcode, nBytes +:while + mov leftInSector, k512 ' leftInSector = 512 - pFilestuff->bp + mov p, pFilestuff + add p, #_bp + rdword temp, p ' temp = bp + sub leftInSector, temp + cmp leftInSector, nBytes wc, wz + if_ae jmp #:endwhile + mov p, destPtr + mov q, pFilestuff + add q, #_buffer ' q points to buffer area + add q, temp ' offset by bp (= temp) + mov n, leftInSector + call #ByteCopy ' bytemove( p, q, n ) + add destPtr, leftInSector ' destPtr += leftInSector + sub nBytes, leftInSector ' nBytes -= leftInSector + mov p, pFilestuff ' long[pIoblock+_leftInFile] -= leftInSector + add p, #_leftInFile + rdlong temp, p + sub temp, leftInSector + wrlong temp, p + +' sdspi.readblock( dataSector0 + (word[pFilestuff+_cluster] - 2) << clusterShift + word[pFilestuff+_sector], pFilestuff+_buffer ) + add p, #_cluster-_leftInFile + rdword temp, p ' temp = (cluster + sub temp, #2 ' - 2) + shl temp, clusterShift ' << clusterShift + add temp, dataSector0 ' + dataSector0 + add p, #_sector-_cluster + rdword temp1, p + add temp, temp1 ' + cluster + wrlong temp, pSdspiBlockno ' Prepare to read sector + add p, #_buffer-_sector + wrlong p, pSdspiParam + mov temp, #"R" + call #SdspiCommand + +' if ++word[pFilestuff+_sector] == sectorsPerCluster + mov p, pFilestuff + add p, #_sector + rdword temp, p + add temp, #1 + wrword temp, p + cmp temp, sectorsPerCluster wz + if_ne jmp #:y + +' word[pIoblock+_sector]~ + mov temp, #0 + wrword temp, p +' word[pFilestuff+_cluster] := NextCluster( word[pFilestuff+_cluster] ) + sub p, #_sector-_cluster + rdword cluster, p + call #NextCluster '( cluster ) + mov p, pFilestuff + add p, #_cluster + wrword cluster, p +:y +' word[pFilestuff+_bp]~ + mov p, pFilestuff + add p, #_bp + mov temp, #0 + wrword temp, p + + jmp #:while +:endwhile +' bytemove( destPtr, pIoblock + word[pIoblock+_bp], n ) + mov p, destPtr + mov q, pFilestuff + add q, #_bp + rdword temp, q + add q, #_buffer-_bp + add q, temp + mov n, nBytes + call #ByteCopy + +' long[pIoblock+_leftInFile] -= n + mov p, pFilestuff + add p, #_leftInFile + rdlong temp, p + sub temp, nBytes + wrlong temp, p +' word[pIoblock+_bp] += n + add p, #_bp-_leftInFile + rdword temp, p + add temp, nBytes + wrword temp, p + + mov temp, retcode + jmp #AckReturnCode + +NextCluster ' ( cluster ) +{ + Given cluster, determines next cluster in FAT. + Result in cluster. +} + cmp cluster, #1 wc, wz + if_be jmp #NextCluster_ret + cmp cluster, kfff0 wc, wz + if_ae jmp #NextCluster_ret + + mov sector, cluster + shr sector, #8 + add sector, fatSector0 + call #ReadMetadataSector + mov p, cluster + and p, #$ff + shl p, #1 + add p, pMetadataBuffer + rdword cluster, p + +NextCluster_ret ret + +kfff0 long $fff0 + +'********************************************************************************************************************* +'* * +'* Write stuff * +'* * +'********************************************************************************************************************* +Write + rdlong p, pParam0 ' p = pFilestuff + add p, #_mode ' Verify that file was opened for writing. + rdword temp, p + cmp temp, #"W" wz + if_ne neg temp, #109 ' -109: file not properly opened + if_ne jmp #AckReturnCode + + call #FlushMetadataSector + neg currentsector, #1 ' invalidate current sector 'cuz we're about to hand the reins + ' to sxfs2 cog. + mov temp, #"W" + wrlong temp, pSxfs2Command +:wait rdlong temp, pSxfs2Command wz + if_nz jmp #:wait + + rdlong temp, pSxfs2Param + jmp #AckReturnCode + +'********************************************************************************************************************* +'* * +'* Close stuff * +'* * +'********************************************************************************************************************* +Close ' ( param0 = pFilestuff ) + rdlong pFilestuff, pParam0 + mov p, pFilestuff + add p, #_mode + rdword temp, p + + cmp temp, #"W" wz + if_e jmp #:closew + +' Files opened in mode "W" need special closing code, but for mode "R" or anything else +' (like file not even open) we can just do this: + + mov temp, #0 + wrword temp, p ' clear mode + jmp #AckNoReturnCode ' and we're done + +:closew + mov temp, #0 ' clear mode + wrword temp, p + + call #FlushMetadataSector + neg currentsector, #1 ' invalidate current sector 'cuz we're about to hand the reins + ' to sxfs2 cog. + mov temp, #"C" + wrlong temp, pSxfs2Command +:wait rdlong temp, pSxfs2Command wz + if_nz jmp #:wait + + rdlong temp, pSxfs2Param + jmp #AckReturnCode + +'********************************************************************************************************************* +'* * +'* Execute stuff * +'* * +'********************************************************************************************************************* +Execute ' ( pFilestuff, execmode, cogid ) + call #FlushMetadataSector + neg currentsector, #1 ' invalidate current sector 'cuz we're about to hand the reins + ' to sxfs2 cog. + mov temp, #"X" + wrlong temp, pSxfs2Command +:wait rdlong temp, pSxfs2Command wz + if_nz jmp #:wait + + rdlong temp, pSxfs2Param + jmp #AckReturnCode + +'********************************************************************************************************************* +'* * +'* Utility stuff * +'* * +'********************************************************************************************************************* + +ByteCopy ' ( p, q, n ) + tjz n, #ByteCopy_ret +:loop rdbyte temp, q + add q, #1 + wrbyte temp, p + add p, #1 + djnz n, #:loop + +ByteCopy_ret ret + +ByteComp ' ( p, q, n ) +{ + Compares j bytes starting at p and q. + Returns Z if they match, NZ if they differ. + Destroys p, q, and j. +} + rdbyte temp, p + add p, #1 + rdbyte temp1, q + add q, #1 + cmp temp, temp1 wz + if_z djnz n, #ByteComp + +ByteComp_ret ret + + +ValidateChar +{ + Make sure that temp is a valid filename character (for our purposes, 0-9, A-Z, _). +} + cmp temp, #"a" wc, wz + if_b jmp #:notLowerCase + cmp temp, #"z" wc, wz + if_a jmp #:notLowerCase + sub temp, #"a"-"A" ' convert to upper-case + jmp #ValidateChar_ret +:notLowerCase + cmp temp, #"A" wc, wz + if_b jmp #:notAlpha + cmp temp, #"Z" wc, wz + if_be jmp #ValidateChar_ret +:notAlpha + cmp temp, #"0" wc, wz + if_b jmp #:notNumeric + cmp temp, #"9" wc, wz + if_be jmp #ValidateChar_ret +:notNumeric + cmp temp, #"_" wz + if_e jmp #ValidateChar_ret + + mov temp, #113 ' -113: bad filename + jmp #AckReturnCode + +ValidateChar_ret ret + + + + + +ReadMetadataSector ' ( sector ) + call #FlushMetadataSector + + cmp sector, currentSector wz + if_e jmp #ReadMetadataSector_ret + wrlong pMetadataBuffer, pSdspiParam + wrlong sector, pSdspiBlockno + mov currentSector, sector + + mov temp, #"R" + call #SdspiCommand +ReadMetadataSector_ret ret + +FlushMetadataSector + tjz dirty, #FlushMetadataSector_ret + mov dirty, #0 + + ' write current sector + wrlong pMetadataBuffer, pSdspiParam + wrlong currentSector, pSdspiBlockno + mov temp, #"W" + call #SdspiCommand +FlushMetadataSector_ret ret + +SdspiCommand + wrlong temp, pSdspiCommand +:wait + rdlong temp, pSdspiCommand wz + if_nz jmp #:wait + + rdlong temp, pSdspiParam wz + if_nz jmp #AckReturnCode + +SdspiCommand_ret ret + +kFAT1 long "F" + "A"<<8 + "T"<<16 + "1"<<24 +k512 long 512 +dirty long 0 +currentSector long -1 +aDate long $2a21 + +pMetadataBuffer long METADATABUFFER + +pCommand long SXFSRENDEZVOUS+0 +pParam0 long SXFSRENDEZVOUS+4 +pParam1 long SXFSRENDEZVOUS+8 +pParam2 long SXFSRENDEZVOUS+12 + +pSdspiCommand long SDSPIRENDEZVOUS+0 +pSdspiParam long SDSPIRENDEZVOUS+4 +pSdspiBlockno long SDSPIRENDEZVOUS+8 + +pSxfs2Command long SXFS2RENDEZVOUS+0 +pSxfs2Param long SXFS2RENDEZVOUS+4 + +bytesPerSector long 0 +sectorsPerCluster long 0 +clusterShift long 0 +reservedSectors long 0 +numberOfFats long 0 +sectorsPerFat long 0 +rootDirEntries long 0 +fatSector0 long 0 +dirSector0 long 0 +dataSector0 long 0 + +temp res 1 +temp1 res 1 +i res 1 +j res 1 +n res 1 +p res 1 +q res 1 +sop res 1 +byte4 res 0 +sopDir res 1 +sector res 1 +cluster res 1 + +pFilename res 1 +pFilestuff res 1 +destPtr res 1 +nBytes res 1 +leftInFile res 1 +leftInSector res 1 +retcode res 1 + + fit + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} + \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx0/sxfs2.spin b/zubehör/sphinx/spinx100225-ori/sphinx0/sxfs2.spin new file mode 100644 index 0000000..a2aa7c1 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx0/sxfs2.spin @@ -0,0 +1,529 @@ +SXTVRENDEZVOUS = $8000 - 4 +RESERVED = SXTVRENDEZVOUS - 4 +SDSPIRENDEZVOUS = RESERVED - 3 * 4 +SXFS2RENDEZVOUS = SDSPIRENDEZVOUS - 4 * 4 ' four rendezvous variables +SXFSRENDEZVOUS = SXFS2RENDEZVOUS - 4 * 4 ' four rendezvous variables +METADATABUFFER = SXFSRENDEZVOUS - 512 + +_free = ($8000 - METADATABUFFER) / 4 + +con +SECTORSIZE = 512 + +' filestuff definitions +' filestuff must be long-aligned +{ long } _length = 0 +{ long } _leftInFile = 4 +{ long } _sopDir = 8 ' sector/offset "pointer" to directory entry +{ long } _sopTail = 12 ' sector/offset "pointer" to last cluster# in FAT chain +{ word } _cluster = 16 +{ word } _sector = 18 ' sector# within cluster; ranges from 0 to sectorsPerCluster-1 +{ word } _bp = 20 ' byte pointer (actually an index into the sector buffer); range [0..511] +{ word } _mode = 22 ' 0: closed; "R": open for reading; "W": open for writing. + _buffer = 24 ' 512-byte buffer starts here + +SIZEOFFILESTUFF = SECTORSIZE + 24 + +pub Start( pbrSector ) + + bytesPerSector := PeekW( pMetadataBuffer + $0b ) + sectorsPerCluster := byte[pMetadataBuffer][$0d] + clusterShift := >| sectorsPerCluster - 1 + reservedSectors := PeekW( pMetadataBuffer + $0e ) + numberOfFats := byte[pMetadataBuffer][$10] + sectorsPerFat := PeekW( pMetadataBuffer + $16 ) + RootDirEntries := PeekW( pMetadataBuffer + $11 ) + fatSector0 := pbrSector + reservedSectors + dirSector0 := fatSector0 + numberOfFats * sectorsPerFat + dataSector0 := dirSector0 + rootDirEntries >> 4 + + ' start sxfs2 cog + long[pCommand] := "?" + if cognew( @Sxfs2Entry, 0 ) < 0 + abort -1 + repeat while long[pCommand] + +pri PeekW( a ) + return byte[a++] + byte[a] << 8 + +pri PeekL( a ) + return byte[a++] + byte[a++] << 8 + byte[a++] << 16 + byte[a] << 24 + +dat + org 0 +Sxfs2Entry +AckNoReturnCode + mov temp, #0 ' clear return code +AckReturnCode ' enter here with temp = return code + wrlong temp, pParam + mov temp, #0 + wrlong temp, pCommand ' clear command to signal operation complete. + + mov dirty, temp ' Ensure that metatdata is flushed before coming here. + neg temp, #1 + mov currentSector, temp + +:ready ' wait for new command + rdlong temp, pCommand wz + if_z jmp #:ready + + cmp temp, #"?" wz + if_e jmp #AckNoReturnCode + cmp temp, #"W" wz + if_e jmp #Write + cmp temp, #"C" wz + if_e jmp #Close + cmp temp, #"X" wz + if_e jmp #Execute + ' else + neg temp, #100 ' return code -100 : bad command + jmp #AckReturnCode + +'********************************************************************************************************************* +'* * +'* Write stuff * +'* * +'********************************************************************************************************************* +Write ' ( pFilestuff, ptr, n ) + rdlong pFilestuff, pSxfsParam0 + rdlong srcPtr, pSxfsParam1 + rdlong nBytes, pSxfsParam2 + + mov retcode, nBytes + + mov p, pFilestuff ' long[ pFilestuff+_length ] += n + 'add p, #_length (unnecessary cuz _length = 0) + rdlong temp, p + add temp, nBytes + wrlong temp, p + + +' repeat while (leftInSector := SECTORSIZE - word[pIoblock+_bp]) < n +:while + mov p, pFilestuff + add p, #_bp ' p points to pFilestuff->bp + mov leftInSector, k512 + rdword temp, p ' temp = pFilestuff->bp + sub leftInSector, temp + cmp leftInSector, nBytes wc, wz + if_ae jmp #:done +' bytemove( pFilestuff + _buffer + word[pFilestuff+_bp], ptr, leftInSector ) + mov p, pFilestuff + add p, #_buffer + add p, temp ' p now points bp bytes into buffer. + mov q, srcPtr + mov n, leftInSector + call #ByteCopy +' ptr += leftInSector + add srcPtr, leftInSector ' advance the source pointer by #bytes written. +' n -= leftInSector + sub nBytes, leftInSector ' decrease #bytes to write by #bytes written. +' WriteNextSector( pIoblock ) + call #WriteNextSector + + jmp #:while +:done +' bytemove( pFilestuff + _buffer + word[pIoblock+_bp], ptr, n ) + mov p, pFilestuff + add p, #_buffer + add p, temp ' temp = pFilestuff->bp + mov q, srcPtr + mov n, nBytes + call #ByteCopy +' word[pFilestuff+_bp] += n + mov p, pFilestuff + add p, #_bp + rdword temp, p + add temp, nBytes ' advance bp by #bytes written. + wrword temp, p + + call #FlushMetadataSector + + mov temp, retcode + jmp #AckReturnCode + +WriteNextSector + mov p, pFilestuff + add p, #_sector + rdword temp, p wz + if_nz jmp #:writeSector ' sector# <> 0? Write that sector. + +' Writing sector 0 implies that we're starting a new cluster, so find an empty slot in the FAT + mov cluster, #0 + mov sector, fatSector0 + mov i, sectorsPerFat +:forEachFatSector + call #ReadMetadataSector + + mov p, pMetadataBuffer + mov j, #256 +:forEachSlotInSector + rdword temp, p wz ' examine current slot + if_z jmp #:foundEmptySlot + + add p, #2 + add cluster, #1 + djnz j, #:forEachSlotInSector + + add sector, #1 + djnz i, #:forEachFatSector + + neg temp, #110 ' -110: FAT full. + jmp #AckReturnCode +:foundEmptySlot + neg temp, #1 + wrword temp, p ' Claim empty slot by writing $ffff. + mov dirty, #1 ' We've modified metadata. + + mov sop, sector + shl sop, #9 + sub p, pMetadataBuffer + add sop, p ' sop "points" to slot. + + mov p, pFilestuff + add p, #_cluster + wrword cluster, p ' save cluster# in pFilestuff->cluster + + sub p, #_cluster-_sopTail ' p points to pFilestuff->sopTail + rdlong sopTail, p ' get "pointer" to end of cluster list. + + mov sector, sopTail ' Read the sector that sopTail "points" to. + shr sector, #9 + call #ReadMetadataSector + + and sopTail, #$1ff + add sopTail, pMetadataBuffer ' Use sopTail as pointer into buffer. + wrword cluster, sopTail ' Now the word pointed to by pFilestuff->sopTail + ' is updated with the new cluster#. + mov dirty, #1 + + wrlong sop, p ' p is still pointing to pFilestuff->sopTail so + ' update pFilestuff->sopTail to point to new tail. +:writeSector + mov p, pFilestuff + add p, #_cluster ' p points to pFilestuff->cluster + rdword i, p ' using i for sector# + sub i, #2 + shl i, clusterShift + add i, dataSector0 ' At this point, i is the first sector of the cluster. + + add p, #_sector-_cluster ' p points to pFilestuff->sector + rdword temp, p + add i, temp ' Now i is the correct sector of the cluster. + add temp, #1 + wrword temp, p ' Increment pFilestuff->sector + cmp temp, sectorsPerCluster wz + mov temp, #0 ' if pFilestuff->sector = sectorsPerCluster, + if_e wrword temp, p ' pFilestuff->sector := 0. + add p, #_bp-_sector ' p points to pFilestuff->bp + wrword temp, p ' pFilestuff->bp = 0. + + wrlong i, pSdspiBlockno + add p, #_buffer-_bp + wrlong p, pSdspiParam + mov temp, #"W" + call #SdspiCommand +WriteNextSector_ret ret + +'********************************************************************************************************************* +'* * +'* Close stuff * +'* * +'********************************************************************************************************************* +Close ' ( pFilestuff ) + rdlong pFilestuff, pSxfsParam0 + + mov p, pFilestuff + add p, #_bp + rdword temp, p wz ' If there's stuff waiting to be written + if_nz call #WriteNextSector ' (i.e. bp <> 0), write it. + mov p, pFilestuff + add p, #_sopDir + rdlong sop, p ' sop "points" to directory entry. + + mov sector, sop + shr sector, #9 + call #ReadMetadataSector ' We want to update metadata length info. + and sop, #$1ff + add sop, pMetadataBuffer + add sop, #$1c ' sop points to length in metadata buffer. + mov p, pFilestuff ' p points to pFilestuff->length. + rdlong temp, p + wrlong temp, sop ' store length in metadata. + mov dirty, #1 + call #FlushMetadataSector + + jmp #AckNoReturnCode + +'********************************************************************************************************************* +'* * +'* Execute stuff * +'* * +'********************************************************************************************************************* +Execute ' ( pFilestuff, execmode, cogid ) +{ + Loads 63 sectors from file and executes. Requires that the file be contiguous on the SD card, + which is generally accomplished by formatting the card with cluster size >= 32k. + This reads 63 sectors instead of 64 to avoid writing junk into the rendezvous areas. + It is conceivable that some executable files will not run because of this. + + This routine does not handle clock speed changes. + + If execmode is 0, start Spin interpreter in cog specified by cogid. + If execmode is 1, start Spin interpreter in cog specified by cogid and stop all other cogs. +} + call #FlushMetadataSector ' just in case + neg currentsector, #1 ' invalidate current sector 'cuz metadata buffer is about to be overwritten + + rdlong pFilestuff, pSxfsParam0 + + rdlong filesize, pFilestuff wz ' length of file + if_z neg temp, #1 ' if file is empty, return -1: EOF + if_z jmp #AckReturnCode ' This is a bit of a hack. The Sphinx compiler really + ' should delete outdated .bin or .eep files to force + ' (re)linking, but since sxfs doesn't know how to + ' delete files (yet(?)), the compiler just makes + ' a file empty instead of deleting it. This test + ' here catches empty executable files and bails, + ' preventing a crash. + + rdlong execmode, pSxfsParam1 + + rdbyte callingCog, pSxfsParam2 ' stop Spin interpreter + cogstop callingCog + + rdlong oldClkfreq, #0 ' save clkfreq + rdbyte oldClkmode, #4 ' save clkmode + + mov p, pFilestuff + add p, #_cluster + rdword temp, p ' temp = (cluster + sub temp, #2 ' - 2) + shl temp, clusterShift ' << clusterShift + add temp, dataSector0 ' + dataSector0 + mov p, temp ' p repurposed here as sector# + + mov i, #63 ' read 63 contiguous sectors + mov q, #0 +:loop + wrlong p, pSdspiBlockno ' Prepare to read sector p + wrlong q, pSdspiParam ' to memory pointed to by q + mov temp, #"R" + call #SdspiCommand + add p, #1 ' Next sector + add q, k512 ' Next 512-byte block of memory + djnz i, #:loop + + ' clear memory above the loaded file + mov i, #1 + shl i, #15 ' i = 32768 + sub i, filesize wz ' - file size + if_z jmp #:z + mov temp, #0 +:y + wrbyte temp, filesize ' repurpose filesize as pointer + add filesize, #1 + djnz i, #:y +:z + ' store those nutty $fff9ffff longs + rdword p, #$0a + sub p, #4 + wrlong kfff9ffff, p + sub p, #4 + wrlong kfff9ffff, p + + tjz execmode, #:dontChangeClock ' execmode = 0? skip cog-killing and clock change + + cogid temp + mov i, #0 + mov j, #8 +:cogkill + cmp i, temp wz ' kill all cogs except self + if_ne cogstop i ' (suicide comes later) + add i, #1 + djnz j, #:cogkill + + ' The following code is borrowed liberally from sdspiFemto: + rdlong temp, #0 ' new clock frequency + cmp temp, oldClkfreq wz ' compared to old + rdbyte temp, #4 ' get new clock mode in advance + if_ne jmp #:changeClock + cmp temp, oldClkmode wz ' compare new clock mode to old + if_e jmp #:dontChangeClock + +:changeClock and temp, #$f8 ' Force use of RCFAST clock while + clkset temp ' letting requested clock start + mov i, time_xtal +:startupDelay djnz i, #:startupDelay ' Allow 20ms@20MHz for xtal/pll to settle + rdbyte temp, #4 ' Then switch to selected clock + clkset temp + jmp #:x + +:dontChangeClock + wrlong oldClkfreq, #0 ' Restore old clock frequency + wrbyte oldClkmode, #4 ' and mode. + +:x + or interpreter, callingCog + coginit interpreter ' start new Spin interpreter in the same cog. + + tjz execmode, #AckNoReturnCode ' execmode = 0? Done. + + cogid temp ' kill + cogstop temp ' self + + +interpreter long ($0004 << 16) | ($F004 << 2) | %0000 ' Thanks to sdspiFemto +time_xtal long 20 * 20000 / 4 / 1 ' 20ms (@20MHz, 1 inst/loop) + +'********************************************************************************************************************* +'* * +'* Utility stuff * +'* * +'********************************************************************************************************************* +{ +Out'(outch) ''' +:w rdbyte outtemp, pTerm wz +if_nz jmp #:w +wrbyte outch, pTerm +Out_ret ret + +OutHex'(outx, outn) ''' + mov outtemp, outn + sub outtemp, #1 + shl outtemp, #2 + ror outx, outtemp +:loop + mov outch, outx + and outch, #$0f + add outch, #"0" + cmp outch, #"9" wc, wz + if_a add outch, #"a"-"0"-10 + call #out + rol outx, #4 + djnz outn, #:loop +Outhex_ret ret +pTerm long $7ffc +outch long 0 +outx long 0 +outn long 0 +outtemp long 0 ''' +} + +ByteCopy ' ( p, q, n ) + tjz n, #ByteCopy_ret +:loop rdbyte temp, q + add q, #1 + wrbyte temp, p + add p, #1 + djnz n, #:loop + +ByteCopy_ret ret + +ReadMetadataSector ' ( sector ) + call #FlushMetadataSector + + cmp sector, currentSector wz + if_e jmp #ReadMetadataSector_ret + wrlong pMetadataBuffer, pSdspiParam + wrlong sector, pSdspiBlockno + mov currentSector, sector + mov temp, #"R" + call #SdspiCommand +ReadMetadataSector_ret ret + +FlushMetadataSector + tjz dirty, #FlushMetadataSector_ret + mov dirty, #0 + + ' write current sector + wrlong pMetadataBuffer, pSdspiParam + wrlong currentSector, pSdspiBlockno + mov temp, #"W" + call #SdspiCommand +FlushMetadataSector_ret ret + +SdspiCommand + wrlong temp, pSdspiCommand +:wait + rdlong temp, pSdspiCommand wz + if_nz jmp #:wait + + rdlong temp, pSdspiParam wz + if_nz jmp #AckReturnCode + +SdspiCommand_ret ret + + +k512 long 512 +kfff9ffff long $fff9ffff +dirty long 0 +currentSector long -1 +pMetadataBuffer long METADATABUFFER + +pSxfsCommand long SXFSRENDEZVOUS+0 +pSxfsParam0 long SXFSRENDEZVOUS+4 +pSxfsParam1 long SXFSRENDEZVOUS+8 +pSxfsParam2 long SXFSRENDEZVOUS+12 + +pSdspiCommand long SDSPIRENDEZVOUS+0 +pSdspiParam long SDSPIRENDEZVOUS+4 +pSdspiBlockno long SDSPIRENDEZVOUS+8 + +pCommand long SXFS2RENDEZVOUS+0 +pParam long SXFS2RENDEZVOUS+4 + +bytesPerSector long 0 +sectorsPerCluster long 0 +clusterShift long 0 +reservedSectors long 0 +numberOfFats long 0 +sectorsPerFat long 0 +rootDirEntries long 0 +fatSector0 long 0 +dirSector0 long 0 +dataSector0 long 0 + +temp res 1 +i res 1 +j res 1 +n res 1 +p res 1 +q res 1 +pFilestuff res 1 +sop res 1 +sopTail res 1 +srcPtr res 1 +nBytes res 1 +cluster res 1 +sector res 1 +leftInSector res 1 +filesize res 1 +execmode res 1 +callingCog res 1 +oldClkfreq res 1 +oldClkmode res 1 + +retcode res 1 + + fit + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} + \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx0/sxkb.spin b/zubehör/sphinx/spinx100225-ori/sphinx0/sxkb.spin new file mode 100644 index 0000000..3bf5a33 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx0/sxkb.spin @@ -0,0 +1,728 @@ +''******************************* +''* PS/2 Keyboard Driver v2.0 * +''* (C) 2004 Parallax, Inc. * +''* Modified by Michael Green * +''* to support Hydra as well * +''******************************* +{ +Modified by Michael Park for Sphinx +2009/06/15 +} + +SXKBRENDEZVOUS = $7ff8 + +VAR + long cog + +PUB start(pingroup) : okay + +'' Start keyboard driver - starts a cog +'' returns false if no cog available +'' +'' pingroup = 1st pin number for 2-pin group for PS/2 I/O +'' (1st - data signal, 2nd - clock signal) +'' Even number selects Demo Board I/O convention +'' +'' use 100-ohm resistors between pins and jack +'' use 10K-ohm resistors to pull jack-side signals to VDD +'' connect jack-power to 5V, jack-gnd to VSS +'' +'' pingroup = 1st pin number for 4-pin group for PS/2 I/O +'' Odd number selects Hydra I/O convention +'' +'' 1st pin drives NPN base for PS/2 'data' signal pull-down +'' 2nd pin reads PS/2 'data' signal +'' 3rd pin drives NPN base for PS/2 'clock' signal pull-down +'' 4th pin reads PS/2 'clock' signal +'' +'' use 2.2K-ohm resistors between 1st/3rd pins and NPN bases +'' use 22K-ohm resistors between 2nd/4th pins and PS/2-side signals +'' use 2.2K-ohm resistors to pull PS/2-side signals to 5V +'' connect PS/2 power to 5V, PS/2 gnd to vss +'' +'' all lock-keys will be enabled, NumLock will be initially 'on', +'' and auto-repeat will be set to 15cps with a delay of .5s + + okay := startx(pingroup, %0_000_100, %01_01000) + +PUB startx(pingroup, locks, auto) | okay + +'' Like start, but allows you to specify lock settings and auto-repeat +'' +'' locks = lock setup +'' bit 6 disallows shift-alphas (case set soley by CapsLock) +'' bits 5..3 disallow toggle of NumLock/CapsLock/ScrollLock state +'' bits 2..0 specify initial state of NumLock/CapsLock/ScrollLock +'' (eg. %0_001_100 = disallow ScrollLock, NumLock initially 'on') +'' +'' auto = auto-repeat setup +'' bits 6..5 specify delay (0=.25s, 1=.5s, 2=.75s, 3=1s) +'' bits 4..0 specify repeat rate (0=30cps..31=2cps) +'' (eg %01_00000 = .5s delay, 30cps repeat) + + long[pRendezvous]~~ ' ping + if long[pRendezvous]~ == -1 ' no response + longmove(@_pingroup, @pingroup, 3) + okay := cog := cognew(@entry, 0) + 1 + +PUB peekkey + +'' Returns a 0 if the buffer is empty +'' returns next key if buffer not empty +'' but doesn't remove the key from buffer + + return long[pRendezvous] + +PUB key : keycode + +'' Get key (never waits) +'' returns key (0 if buffer empty) + + if keycode := long[pRendezvous] + long[pRendezvous]~ + +PUB getkey : keycode + +'' Get next key (may wait for keypress) +'' returns key + + repeat until (keycode := key) + +DAT +'****************************************** +'* Assembly language PS/2 keyboard driver * +'****************************************** + + org +' +' +' Entry +' +entry + mov x,_pingroup 'get mask for 1st pin + andn x,#1 + test _pingroup,#1 wz + mov dwmask,#1 + shl dwmask,x + mov drmask,dwmask + if_nz shl drmask,#1 + mov cwmask,drmask + shl cwmask,#1 + mov crmask,cwmask + if_nz shl crmask,#1 + + if_nz or dira,dwmask 'set directions + if_nz or dira,cwmask + + mov _head,#0 'reset output parameter _head + mov _tail, #0 +' +' +' Reset keyboard +' +reset test _pingroup,#1 wz + if_nz andn outa,dwmask 'let PS/2 lines float (pulled up) + if_nz andn outa,cwmask + if_z mov dira,#0 + + movd :par,#_present 'reset output parameters _present/_states[8] + mov x,#1+8 +:par mov 0,#0 + add :par,dlsb + djnz x,#:par + + mov stat,#8 'set reset flag +' +' +' Update parameters +' +update + call #Rendezvous + + test stat,#8 wc 'if reset flag, transmit reset command + if_c mov data,#$FF + if_c call #transmit +' +' +' Get scancode +' +newcode + mov stat,#0 'reset state + +:same call #receive 'receive byte from keyboard + + cmp data,#$83+1 wc 'scancode? + + if_nc cmp data,#$AA wz 'powerup/reset? + if_nc_and_z jmp #configure + + if_nc cmp data,#$E0 wz 'extended? + if_nc_and_z or stat,#1 + if_nc_and_z jmp #:same + + if_nc cmp data,#$F0 wz 'released? + if_nc_and_z or stat,#2 + if_nc_and_z jmp #:same + + if_nc jmp #newcode 'unknown, ignore +' +' +' Translate scancode and enter into buffer +' + test stat,#1 wc 'lookup code with extended flag + rcl data,#1 + call #look + + cmp data,#0 wz 'if unknown, ignore + if_z jmp #newcode + + mov t,_states+6 'remember lock keys in _states + + mov x,data 'set/clear key bit in _states + shr x,#5 + add x,#_states + movd :reg,x + mov y,#1 + shl y,data + test stat,#2 wc +:reg muxnc 0,y + + if_nc cmpsub data,#$F0 wc 'if released or shift/ctrl/alt/win, done + if_c jmp #update + + mov y,_states+7 'get shift/ctrl/alt/win bit pairs + shr y,#16 + + cmpsub data,#$E0 wc 'translate keypad, considering numlock + if_c test _locks,#%100 wz + if_c_and_z add data,#@keypad1-@table + if_c_and_nz add data,#@keypad2-@table + if_c call #look + if_c jmp #:flags + + cmpsub data,#$DD wc 'handle scrlock/capslock/numlock + if_c mov x,#%001_000 + if_c shl x,data + if_c andn x,_locks + if_c shr x,#3 + if_c shr t,#29 'ignore auto-repeat + if_c andn x,t wz + if_c xor _locks,x + if_c add data,#$DD + if_c_and_nz or stat,#4 'if change, set configure flag to update leds + + test y,#%11 wz 'get shift into nz + + if_nz cmp data,#$60+1 wc 'check shift1 + if_nz_and_c cmpsub data,#$5B wc + if_nz_and_c add data,#@shift1-@table + if_nz_and_c call #look + if_nz_and_c andn y,#%11 + + if_nz cmp data,#$3D+1 wc 'check shift2 + if_nz_and_c cmpsub data,#$27 wc + if_nz_and_c add data,#@shift2-@table + if_nz_and_c call #look + if_nz_and_c andn y,#%11 + + test _locks,#%010 wc 'check shift-alpha, considering capslock + muxnc :shift,#$20 + test _locks,#$40 wc + if_nz_and_nc xor :shift,#$20 + cmp data,#"z"+1 wc + if_c cmpsub data,#"a" wc +:shift if_c add data,#"A" + if_c andn y,#%11 + +:flags ror data,#8 'add shift/ctrl/alt/win flags + mov x,#4 '+$100 if shift +:loop test y,#%11 wz '+$200 if ctrl + shr y,#2 '+$400 if alt + if_nz or data,#1 '+$800 if win + ror data,#1 + djnz x,#:loop + rol data,#12 + + mov x, _tail 'if room in buffer and key valid, enter + sub x,#1 + and x,#$F + cmp x,_head wz + if_e jmp #:z + test data,#$FF wz + if_z jmp #:z + + mov x, #buffer + add x, _head + movd :store, x + nop +:store mov 0-0, data ' buffer[x] := data + add _head,#1 + and _head,#$F +:z + test stat,#4 wc 'if not configure flag, done + if_nc jmp #update 'else configure to update leds +' +' +' Configure keyboard +' +configure mov data,#$F3 'set keyboard auto-repeat + call #transmit + mov data,_auto + and data,#%11_11111 + call #transmit + + mov data,#$ED 'set keyboard lock-leds + call #transmit + mov data,_locks + rev data,#-3 & $1F + test data,#%100 wc + rcl data,#1 + and data,#%111 + call #transmit + + mov x,_locks 'insert locks into _states + and x,#%111 + shl _states+7,#3 + or _states+7,x + ror _states+7,#3 + + mov _present,#1 'set _present + + jmp #update 'done +' +' +' Lookup byte in table +' +look ror data,#2 'perform lookup + movs :reg,data + add :reg,#table + shr data,#27 + mov x,data +:reg mov data,0 + shr data,x + + jmp #rand 'isolate byte +' +' +' Transmit byte to keyboard +' +transmit test _pingroup,#1 wz + if_z or dira,cwmask + if_nz or outa,cwmask 'pull clock low + movs napshr,#13 'hold clock for ~128us (must be >100us) + call #nap + if_z or dira,dwmask + if_nz or outa,dwmask 'pull data low + movs napshr,#18 'hold data for ~4us + call #nap + if_z xor dira,cwmask + if_nz andn outa,cwmask 'release clock + + test data,#$0FF wc 'append parity and stop bits to byte + muxnc data,#$100 + or data,dlsb + + mov x,#10 'ready 10 bits +transmit_bit call #wait_c0 'wait until clock low + shr data,#1 wc 'output data bit + test _pingroup,#1 wz + if_z muxnc dira,dwmask + if_nz muxnc outa,dwmask + mov wcond,c1 'wait until clock high + call #wait + djnz x,#transmit_bit 'another bit? + + mov wcond,c0d0 'wait until clock and data low + call #wait + mov wcond,c1d1 'wait until clock and data high + call #wait + + call #receive_ack 'receive ack byte with timed wait + cmp data,#$FA wz 'if ack error, reset keyboard + if_nz jmp #reset +transmit_ret ret +' +' +' Receive byte from keyboard +' +receive +:waitpne + call #Rendezvous + mov x, ina 'wait indefinitely for initial clock low + and x, crmask + cmp x, crmask wz + if_e jmp #:waitpne + +receive_ack mov x,#11 'ready 11 bits +receive_bit call #wait_c0 'wait until clock low + movs napshr,#16 'pause ~16us + call #nap + test drmask,ina wc 'input data bit + rcr data,#1 + mov wcond,c1 'wait until clock high + call #wait + djnz x,#receive_bit 'another bit? + + shr data,#22 'align byte + test data,#$1FF wc 'if parity error, reset keyboard + if_nc jmp #reset +rand and data,#$FF 'isolate byte +look_ret +receive_ack_ret +receive_ret ret +' +' +' Communicate with the rest of the Propeller via "rendezvous" in hub memory. +' +Rendezvous + rdlong t, pRendezvous wz ' if rendezvous = 0 (location empty), + if_z jmp #:clearToSend ' go fill it with character in buffer. + add t, #1 wz ' if rendezvous = -1 + if_nz jmp #Rendezvous_ret ' someone is pinging to see if sxkb cog is alive; + sub t, #2 ' set rendezvous to -2 to ack. + wrlong t, pRendezvous + jmp #Rendezvous_ret +:clearToSend + cmp _head, _tail wz + if_e jmp #Rendezvous_ret + mov x, _tail + add x, #buffer + movs :read, x + nop +:read mov data, 0-0 ' data := buffer[_tail] + wrlong data, pRendezvous + add _tail, #1 + and _tail, #$0f +Rendezvous_ret ret + +' +' +' Wait for clock/data to be in required state(s) +' +wait_c0 mov wcond,c0 '(wait until clock low) + +wait mov y,tenms 'set timeout to 10ms + +wloop movs napshr,#18 'nap ~4us + call #nap + test crmask,ina wc 'check required state(s) + test drmask,ina wz 'loop until got state(s) or timeout +wcond if_never djnz y,#wloop '(replaced with c0/c1/c0d0/c1d1) + + tjz y,#reset 'if timeout, reset keyboard +wait_ret +wait_c0_ret ret + + +c0 if_c djnz y,#wloop '(if_never replacements) +c1 if_nc djnz y,#wloop +c0d0 if_c_or_nz djnz y,#wloop +c1d1 if_nc_or_z djnz y,#wloop +' +' +' Nap +' +nap rdlong t,#0 'get clkfreq +napshr shr t,#0-0 'shr scales time (set to 13/16/18) + min t,#10 'ensure waitcnt won't snag (was 3 but snagged; upped to 10 [mp]) + add t,cnt 'add cnt to time + waitcnt t,#0 'wait until time elapses (nap) + +nap_ret ret +' +' +' Initialized data +' +' +dlsb long 1 << 9 +tenms long 10_000 / 4 +' +' +' Lookup table +' ascii scan extkey regkey ()=keypad +' +table word $0000 '00 + word $00D8 '01 F9 + word $0000 '02 + word $00D4 '03 F5 + word $00D2 '04 F3 + word $00D0 '05 F1 + word $00D1 '06 F2 + word $00DB '07 F12 + word $0000 '08 + word $00D9 '09 F10 + word $00D7 '0A F8 + word $00D5 '0B F6 + word $00D3 '0C F4 + word $0009 '0D Tab + word $0060 '0E ` + word $0000 '0F + word $0000 '10 + word $F5F4 '11 Alt-R Alt-L + word $00F0 '12 Shift-L + word $0000 '13 + word $F3F2 '14 Ctrl-R Ctrl-L + word $0071 '15 q + word $0031 '16 1 + word $0000 '17 + word $0000 '18 + word $0000 '19 + word $007A '1A z + word $0073 '1B s + word $0061 '1C a + word $0077 '1D w + word $0032 '1E 2 + word $F600 '1F Win-L + word $0000 '20 + word $0063 '21 c + word $0078 '22 x + word $0064 '23 d + word $0065 '24 e + word $0034 '25 4 + word $0033 '26 3 + word $F700 '27 Win-R + word $0000 '28 + word $0020 '29 Space + word $0076 '2A v + word $0066 '2B f + word $0074 '2C t + word $0072 '2D r + word $0035 '2E 5 + word $CC00 '2F Apps + word $0000 '30 + word $006E '31 n + word $0062 '32 b + word $0068 '33 h + word $0067 '34 g + word $0079 '35 y + word $0036 '36 6 + word $CD00 '37 Power + word $0000 '38 + word $0000 '39 + word $006D '3A m + word $006A '3B j + word $0075 '3C u + word $0037 '3D 7 + word $0038 '3E 8 + word $CE00 '3F Sleep + word $0000 '40 + word $002C '41 , + word $006B '42 k + word $0069 '43 i + word $006F '44 o + word $0030 '45 0 + word $0039 '46 9 + word $0000 '47 + word $0000 '48 + word $002E '49 . + word $EF2F '4A (/) / + word $006C '4B l + word $003B '4C ; + word $0070 '4D p + word $002D '4E - + word $0000 '4F + word $0000 '50 + word $0000 '51 + word $0027 '52 ' + word $0000 '53 + word $005B '54 [ + word $003D '55 = + word $0000 '56 + word $0000 '57 + word $00DE '58 CapsLock + word $00F1 '59 Shift-R + word $EB0D '5A (Enter) Enter + word $005D '5B ] + word $0000 '5C + word $005C '5D \ + word $CF00 '5E WakeUp + word $0000 '5F + word $0000 '60 + word $0000 '61 + word $0000 '62 + word $0000 '63 + word $0000 '64 + word $0000 '65 + word $00C8 '66 BackSpace + word $0000 '67 + word $0000 '68 + word $C5E1 '69 End (1) + word $0000 '6A + word $C0E4 '6B Left (4) + word $C4E7 '6C Home (7) + word $0000 '6D + word $0000 '6E + word $0000 '6F + word $CAE0 '70 Insert (0) + word $C9EA '71 Delete (.) + word $C3E2 '72 Down (2) + word $00E5 '73 (5) + word $C1E6 '74 Right (6) + word $C2E8 '75 Up (8) + word $00CB '76 Esc + word $00DF '77 NumLock + word $00DA '78 F11 + word $00EC '79 (+) + word $C7E3 '7A PageDn (3) + word $00ED '7B (-) + word $DCEE '7C PrScr (*) + word $C6E9 '7D PageUp (9) + word $00DD '7E ScrLock + word $0000 '7F + word $0000 '80 + word $0000 '81 + word $0000 '82 + word $00D6 '83 F7 + +keypad1 byte $CA, $C5, $C3, $C7, $C0, 0, $C1, $C4, $C2, $C6, $C9, $0D, "+-*/" + +keypad2 byte "0123456789.", $0D, "+-*/" + +shift1 byte "{|}", 0, 0, "~" + +shift2 byte $22, 0, 0, 0, 0, "<_>?)!@#$%^&*(", 0, ":", 0, "+" + +_pingroup long 0 +_locks long 0 +_auto long 0 +pRendezvous long SXKBRENDEZVOUS +' +' Uninitialized data +' +buffer res 16 +dwmask res 1 'output driver mask for data +drmask res 1 'input mask for data +cwmask res 1 'output driver mask for clock +crmask res 1 'input mask for data +stat res 1 +data res 1 +x res 1 +y res 1 +t res 1 + +_tail res 1 +_head res 1 'write-only +_present res 1 'write-only +_states res 8 'write-only + + fit +'' +'' +'' _________ +'' Key Codes +'' +'' 00..DF = keypress and keystate +'' E0..FF = keystate only +'' +'' +'' 09 Tab +'' 0D Enter +'' 20 Space +'' 21 ! +'' 22 " +'' 23 # +'' 24 $ +'' 25 % +'' 26 & +'' 27 ' +'' 28 ( +'' 29 ) +'' 2A * +'' 2B + +'' 2C , +'' 2D - +'' 2E . +'' 2F / +'' 30 0..9 +'' 3A : +'' 3B ; +'' 3C < +'' 3D = +'' 3E > +'' 3F ? +'' 40 @ +'' 41..5A A..Z +'' 5B [ +'' 5C \ +'' 5D ] +'' 5E ^ +'' 5F _ +'' 60 ` +'' 61..7A a..z +'' 7B { +'' 7C | +'' 7D } +'' 7E ~ +'' +'' 80-BF (future international character support) +'' +'' C0 Left Arrow +'' C1 Right Arrow +'' C2 Up Arrow +'' C3 Down Arrow +'' C4 Home +'' C5 End +'' C6 Page Up +'' C7 Page Down +'' C8 Backspace +'' C9 Delete +'' CA Insert +'' CB Esc +'' CC Apps +'' CD Power +'' CE Sleep +'' CF Wakeup +'' +'' D0..DB F1..F12 +'' DC Print Screen +'' DD Scroll Lock +'' DE Caps Lock +'' DF Num Lock +'' +'' E0..E9 Keypad 0..9 +'' EA Keypad . +'' EB Keypad Enter +'' EC Keypad + +'' ED Keypad - +'' EE Keypad * +'' EF Keypad / +'' +'' F0 Left Shift +'' F1 Right Shift +'' F2 Left Ctrl +'' F3 Right Ctrl +'' F4 Left Alt +'' F5 Right Alt +'' F6 Left Win +'' F7 Right Win +'' +'' FD Scroll Lock State +'' FE Caps Lock State +'' FF Num Lock State +'' +'' +100 if Shift +'' +200 if Ctrl +'' +400 if Alt +'' +800 if Win +'' +'' eg. Ctrl-Alt-Delete = $6C9 +'' +'' +'' Note: Driver will buffer up to 15 keystrokes, then ignore overflow. +{{ ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx0/sxsdspiq.spin b/zubehör/sphinx/spinx100225-ori/sphinx0/sxsdspiq.spin new file mode 100644 index 0000000..26a879b --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx0/sxsdspiq.spin @@ -0,0 +1,334 @@ +' sdspi: SPI interface to a Secure Digital card. +' +' Copyright 2008 Radical Eye Software +' Modified 2009 by Michael Park: added pointer to rendezvous variables. +' +' See end of file for terms of use. +' +' You probably never want to call this; you want to use fsrw +' instead (which calls this); this is only the lowest layer. +' +' Assumes SD card is interfaced using four consecutive Propeller +' pins, as follows (assuming the base pin is pin 0): +' 3.3v +' | | | | | | +' R R R R R R 20k +' p0 --------*-+-+-+-+-+------ do +' p1 ----------*-+-+-+-+------ clk +' p2 ------------*-+-+-+------ di +' p3 --------------*-+-+------ cs (dat3) +' 150 +-+------ irq (dat1) +' +------ p9 (dat2) +' +' The 20k resistors +' are pullups, and should be there on all six lines (even +' the ones we don't drive). +' +' This code is not general-purpose SPI code; it's very specific +' to reading SD cards, although it can be used as an example. +' +' The code does not use CRC at the moment (this is the default). +' With some additional effort we can probe the card to see if it +' supports CRC, and if so, turn it on. +' +' All operations are guarded by a watchdog timer, just in case +' no card is plugged in or something else is wrong. If an +' operation does not complete in one second it is aborted. +' +con + sectorsize = 512 + sectorshift = 9 + +var + long cog + long pCommand, pParam, pBlockno ' rendezvous between spin and assembly +pub stop + if cog + cogstop(cog~ - 1) +pub start(basepin, pRendezvous) +' +' Initialize the card! Send a whole bunch of +' clocks (in case the previous program crashed +' in the middle of a read command or something), +' then a reset command, and then wait until the +' card goes idle. +' + do := basepin++ + clk := basepin++ + di := basepin++ + cs := basepin + stop + + pCommand := pRendezvous + pParam := pRendezvous + 4 + pBlockno := pRendezvous + 8 + + long[pCommand] := "I" + cog := 1 + cognew(@entry, pRendezvous) + repeat while long[pCommand] + if long[pParam] + abort long[pParam] + return 0 +pub readblock(n, b) +' +' Read a single block. The "n" passed in is the +' block number (blocks are 512 bytes); the b passed +' in is the address of 512 blocks to fill with the +' data. +' + long[pParam] := b + long[pBlockno] := n + long[pCommand] := "R" + repeat while long[pCommand] + if long[pParam] + abort long[pParam] + return 0 +pub writeblock(n, b) +' +' Write a single block. Mirrors the read above. +' + long[pParam] := b + long[pBlockno] := n + long[pCommand] := "W" + repeat while long[pCommand] + if long[pParam] + abort long[pParam] + return 0 +dat + org +entry mov comptr,par + mov parptr,par + add parptr,#4 + mov parptr2,parptr + add parptr2,#4 +' set up + mov acca,#1 + shl acca,di + or dira,acca + mov acca,#1 + shl acca,clk + or dira,acca + mov acca,#1 + shl acca,do + mov domask,acca + mov acca,#1 + shl acca,cs + or dira,acca + mov csmask,acca + neg phsb,#1 + mov frqb,#0 + mov acca,nco + add acca,clk + mov ctra,acca + mov acca,nco + add acca,di + mov ctrb,acca + mov ctr2,onek +oneloop + call #sendiohi + djnz ctr2,#oneloop + mov starttime,cnt + mov cmdo,#0 + mov cmdp,#0 + call #cmd + or outa,csmask + call #sendiohi +initloop + mov cmdo,#55 + call #cmd + mov cmdo,#41 + call #cmd + or outa,csmask + cmp accb,#1 wz + if_z jmp #initloop + wrlong accb,parptr +' reset frqa and the clock +finished + mov frqa,#0 + wrlong frqa,comptr + or outa,csmask + neg phsb,#1 + call #sendiohi +pause + mov acca,#511 + add acca,cnt + waitcnt acca,#0 +waitloop + mov starttime,cnt + rdlong acca,comptr wz + cmp acca,#"B" wz + if_z jmp #byteio + mov ctr2,sector + cmp acca,#"R" wz + if_z jmp #rblock + cmp acca,#"W" wz + if_nz jmp #pause +wblock + mov starttime,cnt + mov cmdo,#24 + rdlong cmdp,parptr2 + call #cmd + mov phsb,#$fe + call #sendio + rdlong accb,parptr + neg frqa,#1 +wbyte + rdbyte phsb,accb + shl phsb,#23 + add accb,#1 + mov ctr,#8 +wbit mov phsa,#8 + shl phsb,#1 + djnz ctr,#wbit + djnz ctr2,#wbyte + neg phsb,#1 + call #sendiohi + call #sendiohi + call #readresp + and accb,#$1f + sub accb,#5 + wrlong accb,parptr + call #busy + jmp #finished +rblock + mov starttime,cnt + mov cmdo,#17 + rdlong cmdp,parptr2 + call #cmd + call #readresp + rdlong accb,parptr + sub accb,#1 +rbyte + mov phsa,hifreq + mov frqa,freq + add accb,#1 + test domask,ina wc + addx acca,acca + test domask,ina wc + addx acca,acca + test domask,ina wc + addx acca,acca + test domask,ina wc + addx acca,acca + test domask,ina wc + addx acca,acca + test domask,ina wc + addx acca,acca + test domask,ina wc + addx acca,acca + mov frqa,#0 + test domask,ina wc + addx acca,acca + wrbyte acca,accb + djnz ctr2,#rbyte + mov frqa,#0 + neg phsb,#1 + call #sendiohi + call #sendiohi + or outa,csmask + wrlong ctr2,parptr + jmp #finished +byteio + rdlong phsb,parptr + call #sendio + wrlong accb,parptr + jmp #finished +sendio + rol phsb,#24 +sendiohi + mov ctr,#8 + neg frqa,#1 + mov accb,#0 +bit mov phsa,#8 + test domask,ina wc + addx accb,accb + rol phsb,#1 + djnz ctr,#bit +sendio_ret +sendiohi_ret + ret +checktime + mov duration,cnt + sub duration,starttime + cmp duration,clockfreq wc +checktime_ret + if_c ret + neg duration,#13 + wrlong duration,parptr + jmp #finished +cmd + andn outa,csmask + neg phsb,#1 + call #sendiohi + mov phsb,cmdo + add phsb,#$40 + call #sendio + mov phsb,cmdp + shl phsb,#9 + call #sendiohi + call #sendiohi + call #sendiohi + call #sendiohi + mov phsb,#$95 + call #sendio +readresp + neg phsb,#1 + call #sendiohi + call #checktime + cmp accb,#$ff wz + if_z jmp #readresp +cmd_ret +readresp_ret + ret +busy + neg phsb,#1 + call #sendiohi + call #checktime + cmp accb,#$0 wz + if_z jmp #busy +busy_ret + ret + +di long 0 +do long 0 +clk long 0 +cs long 0 +nco long $1000_0000 +hifreq long $e0_00_00_00 +freq long $20_00_00_00 +clockfreq long 80_000_000 +onek long 1000 +sector long 512 +domask res 1 +csmask res 1 +acca res 1 +accb res 1 +cmdo res 1 +cmdp res 1 +comptr res 1 +parptr res 1 +parptr2 res 1 +ctr res 1 +ctr2 res 1 +starttime res 1 +duration res 1 +{{ +' Permission is hereby granted, free of charge, to any person obtaining +' a copy of this software and associated documentation files +' (the "Software"), to deal in the Software without restriction, +' including without limitation the rights to use, copy, modify, merge, +' publish, distribute, sublicense, and/or sell copies of the Software, +' and to permit persons to whom the Software is furnished to do so, +' subject to the following conditions: +' +' The above copyright notice and this permission notice shall be included +' in all copies or substantial portions of the Software. +' +' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +' EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +' MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +' IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +' CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +' TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +' SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +}} \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx0/sxtv.spin b/zubehör/sphinx/spinx100225-ori/sphinx0/sxtv.spin new file mode 100644 index 0000000..43adc4e --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx0/sxtv.spin @@ -0,0 +1,916 @@ +''*************************************** +''* TV Driver v1.1 * +''* Author: Chip Gracey * +''* Copyright (c) 2004 Parallax, Inc. * +''* See end of file for terms of use. * +''*************************************** + +' v1.0 - 01 May 2006 - original version +' v1.1 - 17 May 2006 - pixel tile size can now be 16 x 32 to enable more efficient +' character displays utilizing the internal font - see 'tv_mode' +{ +2009 +May + 11 Moved blank line tasks into one-time initialization section. + Difficulty: one task was flipping the interlace bit of _mode, necessitating a reload of _mode + every superfield. Removed the flip and changed the sense of the Z tests that depended on _mode<1> + being flipped. + 12 Implemented simple scrolling terminal output in background task. + Difficulty: have to keep Z clear so that mainline interlaced code works properly. +June + 9 Added "D"isable and "E"nable commands. + 20 Changing ping response to include basepin. +} + +CON + + fntsc = 3_579_545 'NTSC color frequency + lntsc = 3640 'NTSC color cycles per line * 16 + sntsc = 624 'NTSC color cycles per sync * 16 + + fpal = 4_433_618 'PAL color frequency + lpal = 4540 'PAL color cycles per line * 16 + spal = 848 'PAL color cycles per sync * 16 + + paramcount = 14 +' colortable = $180 'start of colortable inside cog + + cols = 40 + rows = 13 + +VAR + long cog + long rendezvous + +PUB start(basepin, rv) | okay + +'' Start TV driver - starts a cog if necessary +'' returns true if it had to start a cog, false if cog was already running. +'' + _basepin := basepin + rendezvous := rv + long[rendezvous]~~ ' ping the sxtv cog (send -1) + waitcnt( clkfreq/10 + cnt ) + if long[rendezvous] <> -1 ' if the cog is alive it'll set this to _basepin<<8 + long[rendezvous]~ + return false + + _pins := (basepin & $38) << 1 | (basepin & 4 == 4) & %0101 + + if cog := cognew(@entry, rendezvous) + 1 + return true + else + abort string("Couldn't start sxtv cog") + +PUB stop + +'' Stop TV driver - frees a cog + + if cog + cogstop(cog~ - 1) + +PUB GetBasepin + repeat while long[rendezvous] + long[rendezvous]~~ ' ping the sxtv cog (send -1) + repeat while long[rendezvous] == -1 + return long[rendezvous]~ >> 8 + +PUB str(stringptr) + +'' Print a zero-terminated string + + repeat strsize(stringptr) + out(byte[stringptr++]) + + +PUB dec(value) | _i + +'' Print a decimal number + + if value < 0 + -value + out("-") + + _i := 1_000_000_000 + + repeat 10 + if value => _i + out(value / _i + "0") + value //= _i + result~~ + elseif result or _i == 1 + out("0") + _i /= 10 + + +PUB hex(value, digits) + +'' Print a hexadecimal number + + value <<= (8 - digits) << 2 + repeat digits + out(lookupz((value <-= 4) & $F : "0".."9", "A".."F")) + + +PUB bin(value, digits) + +'' Print a binary number + + value <<= 32 - digits + repeat digits + out((value <-= 1) & 1 + "0") + + +pub out( c ) + repeat while byte[rendezvous] + byte[rendezvous] := c + +DAT + +'******************************* +'* Assembly language TV driver * +'******************************* + + org +' +' +' Entry +' +entry + call #init + mov taskptr,#tasks 'reset tasks + +' +' +' Superfield +' +superfield + + test _mode,#%0001 wc 'if ntsc, set phaseflip + if_nc mov phaseflip,phasemask + + test _mode,#%0010 wz 'get interlace into nz +mov temp, #0 wz ''' I messed something up and now Z has to be set, not clear. +' +' +' Field +' +field mov x,vinv 'do invisible back porch lines +:black call #hsync 'do hsync + waitvid burst,sync_high2 'do black + jmpret taskret,taskptr 'call task section (z undisturbed) + djnz x,#:black 'another black line? + +' wrlong visible,par 'set status to visible + + mov x,vb 'do visible back porch lines + call #blank_lines + + + + + mov y,_vt 'set vertical tiles + movs :getchars4, #text '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +:line + mov vx,_vx 'set vertical expand + mov t1,#32 + mov chset, chset0 +:vert + if_z xor interlace,#1 'interlace skip? + if_z tjz interlace,#:skip + + call #hsync 'do hsync + + mov vscl,hb 'do visible back porch pixels + xor tile,colortable + waitvid tile,#0 + + mov x,_ht 'set horizontal tiles + shr x, #2 'divide by 4 + + mov vscl,hx 'set horizontal expand + +:getchars4 mov chars4, 0-0 + mov t3, #4 +:loop4 + mov char, chars4 + ror chars4, #8 + and char, #$ff + shr char, #1 wc + shl char, #7 + add char, chset + rdlong pixels16, char +' xor colors4, phaseflip + if_nc waitvid colortable, pixels16 + if_c waitvid colortable+1, pixels16 + djnz t3, #:loop4 + add :getchars4, #1 + djnz x, #:getchars4 + + mov vscl,hf 'do visible front porch pixels + mov tile,colortable'phaseflip +' xor tile,colortable + waitvid tile,#0 + sub :getchars4, #10 + +:skip + add chset, #4 + djnz t1, #:vert + + add :getchars4, #10 + djnz y,#:line 'another tile line? + + if_z xor interlace,#1 wz 'get interlace and field1 into z + + test _mode,#%0001 wc 'do visible front porch lines + mov x,vf + if_nz_and_c add x,#1 + call #blank_lines + +' if_z wrlong invisible,par 'unless interlace and field1, set status to invisible + + if_z_eq_c call #hsync 'if required, do short line + if_z_eq_c mov vscl,hrest + if_z_eq_c waitvid burst,sync_high2 + if_z_eq_c xor phaseflip,phasemask + + call #vsync_high 'do high vsync pulses + + movs vsync1,#sync_low1 'do low vsync pulses + movs vsync2,#sync_low2 + call #vsync_low + + call #vsync_high 'do high vsync pulses + + if_nz mov vscl,hhalf 'if odd frame, do half line + if_nz waitvid burst,sync_high2 + + if_z jmp #field 'if interlace and field1, display field2 + jmp #superfield 'else, new superfield +' +' +' Blank lines +' +blank_lines call #hsync 'do hsync + + xor tile,colortable 'do background + waitvid tile,#0 + + djnz x,#blank_lines + +blank_lines_ret ret +' +' +' Horizontal sync +' +hsync test _mode,#%0001 wc 'if pal, toggle phaseflip +' if_c xor phaseflip,phasemask + + mov vscl,sync_scale1 'do hsync + mov tile,burst'phaseflip +' xor tile,burst + waitvid tile,sync_normal + + mov vscl,hvis 'setup in case blank line + mov tile,#0'phaseflip + +hsync_ret ret +' +' +' Vertical sync +' +vsync_high movs vsync1,#sync_high1 'vertical sync + movs vsync2,#sync_high2 + +vsync_low mov x,vrep + +vsyncx mov vscl,sync_scale1 +vsync1 waitvid burst,sync_high1 + + mov vscl,sync_scale2 +vsync2 waitvid burst,sync_high2 + + djnz x,#vsyncx +vsync_low_ret +vsync_high_ret ret +' +' +' Tasks - performed in sections during invisible back porch lines +' +tasks + +clearscreen + mov i, #14 ' clear 13 lines + 1 extra to make scrolling easier +:lines + mov j, #40/4 ' 40 columns, 4 chars at a time +:chars +:storem mov text, x20202020 + add :storem, d0 ' inc dst + djnz j, #:chars + jmpret taskptr,taskret + djnz i, #:lines + +waitforchar + mov temp, #0 ' clear buffer: ready to accept next byte + wrlong temp, par +waitnoclear +:wait + jmpret taskptr,taskret + + rdlong ch, par + tjz ch, #:wait + ' got a byte + + mov temp, cmdPing ' roundabout comparisons to avoid changing Z. + sub temp, ch ' ch = -1 is just a ping to see if this cog is alive. + tjz temp, #ping + mov temp, cmdDisable + sub temp, ch + tjz temp, #disable + mov temp, cmdEnable + sub temp, ch + tjz temp, #enable + neg temp, #256 ' at this point, if ch is > 255, it must be _basepin<<8 + and temp, ch ' as set by a previous ping, so we just ignore it + tjnz temp, #waitnoclear ' (leave the long pointed to by par undisturbed). + +:char + mov temp, #8 + sub temp, ch + tjz temp, #:bksp + mov temp, #13 + sub temp, ch + tjnz temp, #:printchar + call #cr + jmp #waitforchar + +:bksp + sub col, #1 ' warning: no error-checking + jmp #waitforchar + +:printchar + mov temp, #40 + sub temp, col + tjnz temp, #:nocr + call #cr +:nocr + mov temp, col + shr temp, #2 + add temp, #text+12*40/4 + movs :get4chars, temp + movd :put4chars, temp + + mov i, col + and i, #3 + shl i, #3 ' col&3 => 0, 8, 16, 24 +:get4chars mov temp, 0-0 + ror temp, i + andn temp, #$ff + or temp, ch + rol temp, i +:put4chars mov 0-0, temp + + add col, #1 + + + jmp #waitforchar + +cr + movs :move4chars, #text + 40 / 4 + movd :move4chars, #text + + mov i, #13 ' copy 13 lines up. Since we have an extra blank line at the bottom + ' (see clearscreen) the last visible line is automatically cleared. +:copyline + mov j, #40/4 +:move4chars mov 0-0, 0-0 + add :move4chars, d0s0 + djnz j, #:move4chars + jmpret taskptr,taskret + djnz i, #:copyline + + mov col, #0 + +cr_ret ret + + + +ping + mov temp, _basepin + shl temp, #8 + wrlong temp, par + jmp #waitnoclear + +enable + mov dira, saveDira + mov dirb, saveDirb + jmp #waitforchar +disable + mov dira, #0 + mov dirb, #0 + jmp #waitforchar + + +' +' +' Initialized data +' +x20202020 long $20202020 +chset0 long $8000 +m8 long 8_000_000 +m128 long 128_000_000 +d0 long 1 << 9 << 0 +d6 long 1 << 9 << 6 +d0s0 long 1 << 9 << 0 + 1 << 0 +d0s1 long 1 << 9 << 0 + 1 << 1 +interlace long 0 +invisible long 1 +visible long 2 +phaseflip long $00000000 +phasemask long $F0F0F0F0 +line long $00060000 +lineinc long $10000000 +linerot long 0 +pins0 long %11110000_01110000_00001111_00000111 +pins1 long %11111111_11110111_01111111_01110111 +sync_high1 long %0101010101010101010101_101010_0101 +sync_high2 long %01010101010101010101010101010101 'used for black +sync_low1 long %1010101010101010101010101010_0101 +sync_low2 long %01_101010101010101010101010101010 +colortable +' long $07_0a_07_0a ' white on blue +' long $07_07_0a_0a +' long $bc_02_bc_02 ' green on black +' long $bc_bc_02_02 +' long $05_02_05_02 ' white on black +' long $05_05_02_02 + long $02_05_02_05 ' black on white + long $02_02_05_05 +' long $8a_8c_8a_8c ' black on yellow +' long $8a_8a_8c_8c + + +' +' +' NTSC/PAL metrics tables +' ntsc pal +' ---------------------------------------------- +wtab word lntsc - sntsc, lpal - spal 'hvis + word lntsc / 2 - sntsc, lpal / 2 - spal 'hrest + word lntsc / 2, lpal / 2 'hhalf + word 243, 286 'vvis + word 10, 18 'vinv + word 6, 5 'vrep + word $02_8A, $02_AA 'burst +wtabx +ltab long fntsc 'fcolor + long fpal + long sntsc >> 4 << 12 + sntsc 'sync_scale1 + long spal >> 4 << 12 + spal + long 67 << 12 + lntsc / 2 - sntsc 'sync_scale2 + long 79 << 12 + lpal / 2 - spal + long %0101_00000000_01_10101010101010_0101 'sync_normal + long %010101_00000000_01_101010101010_0101 +ltabx + +cmdPing long -1 +cmdEnable long "E"<<8 +cmdDisable long "D"<<8 +_basepin long 0 +' +' +' Parameter buffer +' +_enable long 1 'enable +_pins long 0 'pins +_mode long %10010 'mode +_screen long 0 'screen +_colors long 0 'colors +_ht long cols 'hc +_vt long rows 'vc +_hx long 4 'hx +_vx long 1 'vx +_ho long 0 'ho +_vo long 0 'vo +_broadcast long 0 'broadcast +_auralcog long 0 'auralcog + + +' +' +' Uninitialized data +' +i long 0 +j long 0 +col long 0 +ch long 0 +temp long 0 + +char long 0 +chset long 0 +chars4 long 0 +pixels16 long 0 +taskptr long 0 'tasks +taskret long 0 +t1 long 0 +t2 long 0 +t3 long 0 +m1 long 0 +m2 long 0 + +x long 0 'display +y long 0 +hf long 0 +hb long 0 +vf long 0 +vb long 0 +hx long 0 +vx long 0 +hc2x long 0 +screen long 0 +tile long 0 +pixels long 0 +lineadd long 0 + +hvis long 0 'loaded from word table +hrest long 0 +hhalf long 0 +vvis long 0 +vinv long 0 +vrep long 0 +burst long 0 + +fcolor long 0 'loaded from long table +sync_scale1 long 0 +sync_scale2 long 0 +sync_normal long 0 + +saveDira long 0 +saveDirb long 0 + + +text ' Cog memory from this point on will be reclaimed as text buffer. + +init + mov t1,_pins 'set video pins and directions + test t1,#$08 wc + if_nc mov t2,pins0 + if_c mov t2,pins1 + test t1,#$40 wc + shr t1,#1 + shl t1,#3 + shr t2,t1 + movs vcfg,t2 + shr t1,#6 + movd vcfg,t1 + shl t1,#3 + and t2,#$FF + shl t2,t1 + if_nc mov dira,t2 + if_nc mov saveDira, t2 + if_nc mov dirb,#0 + if_nc mov saveDirb, #0 + if_c mov dira,#0 + if_c mov saveDira, #0 + if_c mov dirb,t2 '+18 + if_c mov saveDirb, t2 + + + + movs :rd,#wtab 'load ntsc/pal metrics from word table + movd :wr,#hvis + mov t1,#wtabx - wtab + test _mode,#%0001 wc +:rd mov t2,0 + add :rd,#1 + if_nc shl t2,#16 + shr t2,#16 +:wr mov 0,t2 + add :wr,d0 + djnz t1,#:rd '+54 + + if_nc movs :ltab,#ltab 'load ntsc/pal metrics from long table + if_c movs :ltab,#ltab+1 + movd :ltab,#fcolor + mov t1,#(ltabx - ltab) >> 1 +:ltab mov 0,0 + add :ltab,d0s1 + djnz t1,#:ltab '+17 + + rdlong t1,#0 'get CLKFREQ + shr t1,#1 'if CLKFREQ < 16MHz, cancel _broadcast + cmp t1,m8 wc + if_c mov _broadcast,#0 + shr t1,#1 'if CLKFREQ < color frequency * 4, disable +' cmp t1,fcolor wc +' if_c jmp #disabled '+11 + + + mov t1,fcolor 'set ctra pll to fcolor * 16 + call #divide 'if ntsc, set vco to fcolor * 32 (114.5454 MHz) + test _mode,#%0001 wc 'if pal, set vco to fcolor * 16 (70.9379 MHz) + if_c movi ctra,#%00001_111 'select fcolor * 16 output (ntsc=/2, pal=/1) + if_nc movi ctra,#%00001_110 + if_nc shl t2,#1 + mov frqa,t2 '+147 + + mov t1,_broadcast 'set ctrb pll to _broadcast + mov t2,#0 'if 0, turn off ctrb + tjz t1,#:off + min t1,m8 'limit from 8MHz to 128MHz + max t1,m128 + mov t2,#%00001_100 'adjust _broadcast to be within 4MHz-8MHz +:scale shr t1,#1 '(vco will be within 64MHz-128MHz) + cmp m8,t1 wc + if_c add t2,#%00000_001 + if_c jmp #:scale +:off movi ctrb,t2 + call #divide + mov frqb,t2 '+165 + + mov t1,#%10100_000 'set video configuration + test _pins,#$01 wc '(swap broadcast/baseband output bits?) + if_c or t1,#%01000_000 + test _mode,#%1000 wc '(strip chroma from broadcast?) + if_nc or t1,#%00010_000 + test _mode,#%0100 wc '(strip chroma from baseband?) + if_nc or t1,#%00001_000 + and _auralcog,#%111 '(set aural cog) + or t1,_auralcog + movi vcfg,t1 '+10 + + mov hx,_hx 'compute horizontal metrics + shl hx,#8 + or hx,_hx + shl hx,#4 + + mov hc2x,_ht + shl hc2x,#1 + + mov t1,_ht + mov t2,_hx + call #multiply + mov hf,hvis + sub hf,t1 + shr hf,#1 wc + mov hb,_ho + addx hb,hf + sub hf,_ho '+52 + + mov t1,_vt 'compute vertical metrics + mov t2,_vx + call #multiply + test _mode,#%10000 wc 'consider tile size + muxc linerot,#1 + mov lineadd,lineinc + if_c shr lineadd,#1 + if_c shl t1,#1 + test _mode,#%0010 wc 'consider interlace + if_c shr t1,#1 + mov vf,vvis + sub vf,t1 + shr vf,#1 wc + neg vb,_vo + addx vb,vf + add vf,_vo '+53 + + +init_ret ret + +' +' +' Divide t1/CLKFREQ to get frqa or frqb value into t2 +' +divide rdlong m1,#0 'get CLKFREQ + + mov m2,#32+1 +:loop cmpsub t1,m1 wc + rcl t2,#1 + shl t1,#1 + djnz m2,#:loop + +divide_ret ret '+140 +' +' +' Multiply t1 * t2 * 16 (t1, t2 = bytes) +' +multiply shl t2,#8+4-1 + + mov m1,#8 +:loop shr t1,#1 wc + if_c add t1,t2 + djnz m1,#:loop + +multiply_ret ret '+37 + + +'' +''___ +''VAR 'TV parameters - 14 contiguous longs +'' +'' long tv_status '0/1/2 = off/invisible/visible read-only +'' long tv_enable '0/non-0 = off/on write-only +'' long tv_pins '%pppmmmm = pin group, pin group mode write-only +'' long tv_mode '%tccip = tile,chroma,interlace,ntsc/pal write-only +'' long tv_screen 'pointer to screen (words) write-only +'' long tv_colors 'pointer to colors (longs) write-only +'' long tv_ht 'horizontal tiles write-only +'' long tv_vt 'vertical tiles write-only +'' long tv_hx 'horizontal tile expansion write-only +'' long tv_vx 'vertical tile expansion write-only +'' long tv_ho 'horizontal offset write-only +'' long tv_vo 'vertical offset write-only +'' long tv_broadcast 'broadcast frequency (Hz) write-only +'' long tv_auralcog 'aural fm cog write-only +'' +''The preceding VAR section may be copied into your code. +''After setting variables, do start(@tv_status) to start driver. +'' +''All parameters are reloaded each superframe, allowing you to make live +''changes. To minimize flicker, correlate changes with tv_status. +'' +''Experimentation may be required to optimize some parameters. +'' +''Parameter descriptions: +'' _________ +'' tv_status +'' +'' driver sets this to indicate status: +'' 0: driver disabled (tv_enable = 0 or CLKFREQ < requirement) +'' 1: currently outputting invisible sync data +'' 2: currently outputting visible screen data +'' _________ +'' tv_enable +'' +'' 0: disable (pins will be driven low, reduces power) +'' non-0: enable +'' _______ +'' tv_pins +'' +'' bits 6..4 select pin group: +'' %000: pins 7..0 +'' %001: pins 15..8 +'' %010: pins 23..16 +'' %011: pins 31..24 +'' %100: pins 39..32 +'' %101: pins 47..40 +'' %110: pins 55..48 +'' %111: pins 63..56 +'' +'' bits 3..0 select pin group mode: +'' %0000: %0000_0111 - baseband +'' %0001: %0000_0111 - broadcast +'' %0010: %0000_1111 - baseband + chroma +'' %0011: %0000_1111 - broadcast + aural +'' %0100: %0111_0000 broadcast - +'' %0101: %0111_0000 baseband - +'' %0110: %1111_0000 broadcast + aural - +'' %0111: %1111_0000 baseband + chroma - +'' %1000: %0111_0111 broadcast baseband +'' %1001: %0111_0111 baseband broadcast +'' %1010: %0111_1111 broadcast baseband + chroma +'' %1011: %0111_1111 baseband broadcast + aural +'' %1100: %1111_0111 broadcast + aural baseband +'' %1101: %1111_0111 baseband + chroma broadcast +'' %1110: %1111_1111 broadcast + aural baseband + chroma +'' %1111: %1111_1111 baseband + chroma broadcast + aural +'' ----------------------------------------------------------- +'' active pins top nibble bottom nibble +'' +'' the baseband signal nibble is arranged as: +'' bit 3: chroma signal for s-video (attach via 560-ohm resistor) +'' bits 2..0: baseband video (sum 270/560/1100-ohm resistors to form 75-ohm 1V signal) +'' +'' the broadcast signal nibble is arranged as: +'' bit 3: aural subcarrier (sum 560-ohm resistor into network below) +'' bits 2..0: visual carrier (sum 270/560/1100-ohm resistors to form 75-ohm 1V signal) +'' _______ +'' tv_mode +'' +'' bit 4 selects between 16x16 and 16x32 pixel tiles: +'' 0: 16x16 pixel tiles (tileheight = 16) +'' 1: 16x32 pixel tiles (tileheight = 32) +'' +'' bit 3 controls chroma mixing into broadcast: +'' 0: mix chroma into broadcast (color) +'' 1: strip chroma from broadcast (black/white) +'' +'' bit 2 controls chroma mixing into baseband: +'' 0: mix chroma into baseband (composite color) +'' 1: strip chroma from baseband (black/white or s-video) +'' +'' bit 1 controls interlace: +'' 0: progressive scan (243 display lines for NTSC, 286 for PAL) +'' less flicker, good for motion +'' 1: interlaced scan (486 display lines for NTSC, 572 for PAL) +'' doubles the vertical display lines, good for text +'' +'' bit 0 selects NTSC or PAL format +'' 0: NTSC +'' 3016 horizontal display ticks +'' 243 or 486 (interlaced) vertical display lines +'' CLKFREQ must be at least 14_318_180 (4 * 3_579_545 Hz)* +'' 1: PAL +'' 3692 horizontal display ticks +'' 286 or 572 (interlaced) vertical display lines +'' CLKFREQ must be at least 17_734_472 (4 * 4_433_618 Hz)* +'' +'' * driver will disable itself while CLKFREQ is below requirement +'' _________ +'' tv_screen +'' +'' pointer to words which define screen contents (left-to-right, top-to-bottom) +'' number of words must be tv_ht * tv_vt +'' each word has two bitfields: a 6-bit colorset ptr and a 10-bit pixelgroup ptr +'' bits 15..10: select the colorset* for the associated pixel tile +'' bits 9..0: select the pixelgroup** address %ppppppppppcccc00 (p=address, c=0..15) +'' +'' * colorsets are longs which each define four 8-bit colors +'' +'' ** pixelgroups are longs which define (left-to-right, top-to-bottom) the 2-bit +'' (four color) pixels that make up a 16x16 or a 32x32 pixel tile +'' _________ +'' tv_colors +'' +'' pointer to longs which define colorsets +'' number of longs must be 1..64 +'' each long has four 8-bit fields which define colors for 2-bit (four color) pixels +'' first long's bottom color is also used as the screen background color +'' 8-bit color fields are as follows: +'' bits 7..4: chroma data (0..15 = blue..green..red..)* +'' bit 3: controls chroma modulation (0=off, 1=on) +'' bits 2..0: 3-bit luminance level: +'' values 0..1: reserved for sync - don't use +'' values 2..7: valid luminance range, modulation adds/subtracts 1 (beware of 7) +'' value 0 may be modulated to produce a saturated color toggling between levels 1 and 7 +'' +'' * because of TV's limitations, it doesn't look good when chroma changes abruptly - +'' rather, use luminance - change chroma only against a black or white background for +'' best appearance +'' _____ +'' tv_ht +'' +'' horizontal number pixel tiles - must be at least 1 +'' practical limit is 40 for NTSC, 50 for PAL +'' _____ +'' tv_vt +'' +'' vertical number of pixel tiles - must be at least 1 +'' practical limit is 13 for NTSC, 15 for PAL (26/30 max for interlaced NTSC/PAL) +'' _____ +'' tv_hx +'' +'' horizontal tile expansion factor - must be at least 3 for NTSC, 4 for PAL +'' +'' make sure 16 * tv_ht * tv_hx + ||tv_ho + 32 is less than the horizontal display ticks +'' _____ +'' tv_vx +'' +'' vertical tile expansion factor - must be at least 1 +'' +'' make sure * tv_vt * tv_vx + ||tv_vo + 1 is less than the display lines +'' _____ +'' tv_ho +'' +'' horizontal offset in ticks - pos/neg value (0 for centered image) +'' shifts the display right/left +'' _____ +'' tv_vo +'' +'' vertical offset in lines - pos/neg value (0 for centered image) +'' shifts the display up/down +'' ____________ +'' tv_broadcast +'' +'' broadcast frequency expressed in Hz (ie channel 2 is 55_250_000) +'' if 0, modulator is turned off - saves power +'' +'' broadcasting requires CLKFREQ to be at least 16_000_000 +'' while CLKFREQ is below 16_000_000, modulator will be turned off +'' ___________ +'' tv_auralcog +'' +'' selects cog to supply aural fm signal - 0..7 +'' uses ctra pll output from selected cog +'' +'' in NTSC, the offset frequency must be 4.5MHz and the max bandwidth +-25KHz +'' in PAL, the offset frequency and max bandwidth vary by PAL type + +{{ + ++------------------------------------------------------------------------------------------------------------------------------+ +¦ TERMS OF USE: MIT License ¦ ++------------------------------------------------------------------------------------------------------------------------------¦ +¦Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation ¦ +¦files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, ¦ +¦modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software¦ +¦is furnished to do so, subject to the following conditions: ¦ +¦ ¦ +¦The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.¦ +¦ ¦ +¦THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE ¦ +¦WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ¦ +¦COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ¦ +¦ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ¦ ++------------------------------------------------------------------------------------------------------------------------------+ +}} \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx1/codegen.bin b/zubehör/sphinx/spinx100225-ori/sphinx1/codegen.bin new file mode 100644 index 0000000..0ff297e Binary files /dev/null and b/zubehör/sphinx/spinx100225-ori/sphinx1/codegen.bin differ diff --git a/zubehör/sphinx/spinx100225-ori/sphinx1/cogcheck.spn b/zubehör/sphinx/spinx100225-ori/sphinx1/cogcheck.spn new file mode 100644 index 0000000..e01fcba --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx1/cogcheck.spn @@ -0,0 +1,27 @@ +_clkfreq = 80_000_000 +_clkmode = xtal1 + pll8x +obj + term: "isxtv" + f: "sxfile" + +pub CheckFreeCogs | i, x + x~ + repeat 8 + i := cognew( @nada, 0 ) + if i < 0 + quit + x |= |< i + repeat i from 0 to 7 + if x & |< i + term.str( string("free ") ) + cogstop( i ) + else + term.str( string("busy ") ) + term.out( 13 ) + f.Open( string("sphinx.bin"), "R" ) + f.Execute( 0 ) + +dat + org 0 +nada + jmp #nada \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx1/combokb.sob b/zubehör/sphinx/spinx100225-ori/sphinx1/combokb.sob new file mode 100644 index 0000000..c394cab Binary files /dev/null and b/zubehör/sphinx/spinx100225-ori/sphinx1/combokb.sob differ diff --git a/zubehör/sphinx/spinx100225-ori/sphinx1/copy.spn b/zubehör/sphinx/spinx100225-ori/sphinx1/copy.spn new file mode 100644 index 0000000..af133ec --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx1/copy.spn @@ -0,0 +1,68 @@ +SXTVRENDEZVOUS = $8000 - 4 +SXKBRENDEZVOUS = SXTVRENDEZVOUS - 4 +SDSPIRENDEZVOUS = SXKBRENDEZVOUS - 3 * 4 +SXFS2RENDEZVOUS = SDSPIRENDEZVOUS - 4 * 4 ' four rendezvous variables +SXFSRENDEZVOUS = SXFS2RENDEZVOUS - 4 * 4 ' four rendezvous variables +METADATABUFFER = SXFSRENDEZVOUS - 512 + +_free = ($8000 - METADATABUFFER) / 4 + +obj + term: "isxtv" + kb: "isxkb" + f[2]: "sxfile" + +pub main | err + err := \try + if err > 0 + term.str( err ) + term.out( 13 ) + elseif err < 0 + term.str( string("error ") ) + term.dec( err ) + term.out( 13 ) + f[0].Close + f[0].Open( string("sphinx.bin"), "R" ) + f[0].Execute( 0 ) + +con +FILENAMELENGTH = 12 ' 8 + . + 3 + +var +byte srcfilename[FILENAMELENGTH + 1] ' + null +byte dstfilename[FILENAMELENGTH + 1] ' + null +byte optionstring[3] +byte needConfirmation + +pri try | length, ch + needConfirmation~~ + f[0].Open( string("args.d8a"), "R" ) + if f[0].ReadByte <> 2 + abort string("usage: source destination") + + f[0].ReadString( @srcfilename, FILENAMELENGTH ) + f[0].ReadString( @dstfilename, FILENAMELENGTH ) + + f[0].Close + + if f[0].Open( @srcfilename, "R" ) + term.str( @srcfilename ) + abort string(" -- not found" ) + length := f[0].Length + + if f[1].Open( @dstfilename, "R" ) == 0 + term.str( @dstfilename ) + term.str( string(" -- overwrite? ") ) + ch := kb.getkey + term.out( ch ) + term.out( 13 ) + ifnot ch == "y" or ch == "Y" + return + f[1].Close + + f[1].Open( @dstfilename, "W" ) + repeat length + f[1].WriteByte( f[0].ReadByte ) ' Could probably improve on this + f[1].Close + + \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx1/del.spn b/zubehör/sphinx/spinx100225-ori/sphinx1/del.spn new file mode 100644 index 0000000..7b2bdb3 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx1/del.spn @@ -0,0 +1,246 @@ +' 2009-08-08 fixed off-by-one error in try + +SXTVRENDEZVOUS = $8000 - 4 +SXKBRENDEZVOUS = SXTVRENDEZVOUS - 4 +SDSPIRENDEZVOUS = SXKBRENDEZVOUS - 3 * 4 +SXFS2RENDEZVOUS = SDSPIRENDEZVOUS - 4 * 4 ' four rendezvous variables +SXFSRENDEZVOUS = SXFS2RENDEZVOUS - 4 * 4 ' four rendezvous variables +METADATABUFFER = SXFSRENDEZVOUS - 512 + +_free = ($8000 - METADATABUFFER) / 4 + +obj + term: "isxtv" + kb: "isxkb" + f: "sxfile" + +pub main | err + err := \try + if err > 0 + term.str( err ) + term.out( 13 ) + elseif err < 0 + term.str( string("error ") ) + term.dec( err ) + term.out( 13 ) + f.Close + f.Open( string("sphinx.bin"), "R" ) + f.Execute( 0 ) + +con +ARGSTRINGLENGTH = 12 ' 8 + . + 3 +DIRSTRINGLENGTH = 11 ' 8 + 3 + +var +byte argstring[ARGSTRINGLENGTH + 1] ' + null +byte dirstring[DIRSTRINGLENGTH + 1] ' + null (terminator not strictly necessary, but convenient for debug printing) +byte optionstring[3] +byte needConfirmation + +pri try | nArgs + needConfirmation~~ + f.Open( string("args.d8a"), "R" ) + if nArgs := f.ReadByte + f.ReadString( @argstring, ARGSTRINGLENGTH ) + if nArgs > 1 + f.ReadStringUpperCase( @optionstring, 2 ) + if strcomp( @optionstring, string("/Y") ) + needConfirmation~ + else + abort string("No files specified") + f.Close + + ExpandWildcards + MyMount + Delete + FlushMetadata + +pri ExpandWildcards | i, j + i~ + j~ + bytefill( @dirstring, " ", DIRSTRINGLENGTH ) + dirstring[DIRSTRINGLENGTH]~ + + repeat while argstring[j] + if argstring[j] == "*" + if i < 8 + repeat + dirstring[i++] := "?" + until i == 8 + elseif i < 11 + repeat + dirstring[i++] := "?" + until i == 11 + else + abort string("bad wildcard") + elseif argstring[j] == "." + if i =< 8 + i := 8 + else + abort string("filename too long") + else + if i < DIRSTRINGLENGTH + dirstring[i++] := argstring[j] + else + abort string("filename too long") + ++j + +con +pCommand = SDSPIRENDEZVOUS +pParam = pCommand + 4 +pBlockno = pCommand + 8 + +pri readblock(n, b) +' +' Read a single block. The "n" passed in is the +' block number (blocks are 512 bytes); the b passed +' in is the address of 512 blocks to fill with the +' data. +' + long[pParam] := b + long[pBlockno] := n + long[pCommand] := "R" + repeat while long[pCommand] + if long[pParam] + abort long[pParam] + return 0 +pub writeblock(n, b) +' +' Write a single block. Mirrors the read above. +' + long[pParam] := b + long[pBlockno] := n + long[pCommand] := "W" + repeat while long[pCommand] + if long[pParam] + abort long[pParam] + return 0 + +con + SECTORSIZE = 512 + SECTORSHIFT = 9 + DIRSIZE = 32 + DIRSHIFT = 5 + +con + +{ long } _length = 0 +{ long } _leftInFile = 4 +{ long } _sopDir = 8 ' sector/offset "pointer" to directory entry +{ long } _sopTail = 12 ' sector/offset "pointer" to last cluster# in FAT chain +{ word } _cluster = 16 +{ word } _sector = 18 ' sector# within cluster; ranges from 0 to sectorsPerCluster-1 +{ word } _bp = 20 ' byte pointer (actually an index into the sector buffer); range [0..511] + _buffer = 24 + +SIZEOFIOBLOCK = SECTORSIZE + 24 + +dat + long +myMetadataBuffer byte 0[512] +myMetadataSector word -1 +dirty byte 0 +clusterShift byte 0 + +pri FlushMetadata + if dirty~ + writeblock( myMetadataSector, @myMetadataBuffer ) + +pri ReadMetadataSector( s ) + if myMetadataSector == s + return + FlushMetadata + readblock( myMetadataSector := s, @myMetadataBuffer ) +var + word bytesPerSector + byte sectorsPerCluster + word reservedSectors + byte numberOfFats + word sectorsPerFat + word numberOfRootDirectoryEntries + long fat1[0] + long fatSector0 + long dirSector0 + long dataregion[0] + long dataSector0 + +pri Delete | s, p, ch + s := dirSector0 + repeat numberOfRootDirectoryEntries >> 4 + p := @myMetadataBuffer + repeat 16 + ReadMetadataSector( s ) + ifnot byte[p] + return + if byte[p] == $e5 ' already deleted? + p += 32 + next + if byte[p][$0b] & $0f == 0 and Match( p, @dirstring, 11 ) + ifnot needConfirmation + term.str( string("Deleting ") ) + repeat 11 + term.out( byte[p++] ) + p -= 11 + term.out( " " ) + term.dec( PeekL( p + $1c ) ) + if needConfirmation + term.str( string(" -- delete? ") ) + ch := kb.getkey + term.out( ch ) + else + ch := "y" + if ch == "y" or ch == "Y" + byte[p] := $e5 ' mark as deleted + dirty~~ + term.out( 13 ) + p += 32 + ++s + FlushMetadata + +pri Match( p, q, n ) | c1, c2 + repeat n + c1 := byte[p++] + c2 := byte[q++] + if "a" =< c1 and c1 =< "z" + c1 += "A" - "a" + if "a" =< c2 and c2 =< "z" + c2 += "A" - "a" + if c2 == "?" + next + if c1 <> c2 + return false + return true + +pri MyMount | pbrSector ,i + pbrSector~ + repeat + ReadMetadataSector( pbrSector ) + if bytecomp( @myMetadataBuffer+$36, string("FAT16"), 5 ) + quit + if pbrSector + abort -20 ' not FAT16 + pbrSector := PeekL( @myMetadataBuffer + $1c6 ) + + bytesPerSector := PeekW( @myMetadataBuffer + $0b ) + sectorsPerCluster := myMetadataBuffer[$0d] + clusterShift := >| sectorsPerCluster - 1 + reservedSectors := PeekW( @myMetadataBuffer + $0e ) + numberOfFats := myMetadataBuffer[$10] + sectorsPerFat := PeekW( @myMetadataBuffer + $16 ) + numberOfRootDirectoryEntries := PeekW( @myMetadataBuffer + $11 ) + fatSector0 := pbrSector + reservedSectors + dirSector0 := fatSector0 + numberOfFats * sectorsPerFat + dataSector0 := dirSector0 + numberOfRootDirectoryEntries >> 4 + +pri bytecomp( p, q, n ) + repeat n + if byte[p++] <> byte[q++] + return + return true + +pri PeekW( a ) + return byte[a++] + byte[a] << 8 + +pri PeekL( a ) + return byte[a++] + byte[a++] << 8 + byte[a++] << 16 + byte[a] << 24 + \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx1/dir.spn b/zubehör/sphinx/spinx100225-ori/sphinx1/dir.spn new file mode 100644 index 0000000..d8472b0 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx1/dir.spn @@ -0,0 +1,220 @@ +' 2009-08-08 fixed off-by-one error in try + +SXTVRENDEZVOUS = $8000 - 4 +SXKBRENDEZVOUS = SXTVRENDEZVOUS - 4 +SDSPIRENDEZVOUS = SXKBRENDEZVOUS - 3 * 4 +SXFS2RENDEZVOUS = SDSPIRENDEZVOUS - 4 * 4 ' four rendezvous variables +SXFSRENDEZVOUS = SXFS2RENDEZVOUS - 4 * 4 ' four rendezvous variables +METADATABUFFER = SXFSRENDEZVOUS - 512 + +_free = ($8000 - METADATABUFFER) / 4 + +obj + term: "isxtv" + f: "sxfile" + +pub main | err + err := \try + if err > 0 + term.str( err ) + term.out( 13 ) + elseif err < 0 + term.str( string("error ") ) + term.dec( err ) + term.out( 13 ) + f.Close + f.Open( string("sphinx.bin"), "R" ) + f.Execute( 0 ) + +con +ARGSTRINGLENGTH = 12 ' 8 + . + 3 +DIRSTRINGLENGTH = 11 ' 8 + 3 + +var +byte argstring[ARGSTRINGLENGTH + 1] ' + null +byte dirstring[DIRSTRINGLENGTH + 1] ' + null (terminator not strictly necessary, but convenient for debug printing) + +pri try + f.Open( string("args.d8a"), "R" ) + if f.ReadByte + f.ReadString( @argstring, ARGSTRINGLENGTH ) + else + bytemove( @argstring, string("*.*"), 4 ) + f.Close + + ExpandWildcards + MyMount + PrintDir + +pri ExpandWildcards | i, j + i~ + j~ + bytefill( @dirstring, " ", DIRSTRINGLENGTH ) + dirstring[DIRSTRINGLENGTH]~ + + repeat while argstring[j] + if argstring[j] == "*" + if i < 8 + repeat + dirstring[i++] := "?" + until i == 8 + elseif i < 11 + repeat + dirstring[i++] := "?" + until i == 11 + else + abort string("bad wildcard") + elseif argstring[j] == "." + if i =< 8 + i := 8 + else + abort string("filename too long") + else + if i < DIRSTRINGLENGTH + dirstring[i++] := argstring[j] + else + abort string("filename too long") + ++j + +con +pCommand = SDSPIRENDEZVOUS +pParam = pCommand + 4 +pBlockno = pCommand + 8 + +pri readblock(n, b) +' +' Read a single block. The "n" passed in is the +' block number (blocks are 512 bytes); the b passed +' in is the address of 512 blocks to fill with the +' data. +' + long[pParam] := b + long[pBlockno] := n + long[pCommand] := "R" + repeat while long[pCommand] + if long[pParam] + abort long[pParam] + return 0 +pub writeblock(n, b) +' +' Write a single block. Mirrors the read above. +' + long[pParam] := b + long[pBlockno] := n + long[pCommand] := "W" + repeat while long[pCommand] + if long[pParam] + abort long[pParam] + return 0 + +con + SECTORSIZE = 512 + SECTORSHIFT = 9 + DIRSIZE = 32 + DIRSHIFT = 5 + +con + +{ long } _length = 0 +{ long } _leftInFile = 4 +{ long } _sopDir = 8 ' sector/offset "pointer" to directory entry +{ long } _sopTail = 12 ' sector/offset "pointer" to last cluster# in FAT chain +{ word } _cluster = 16 +{ word } _sector = 18 ' sector# within cluster; ranges from 0 to sectorsPerCluster-1 +{ word } _bp = 20 ' byte pointer (actually an index into the sector buffer); range [0..511] + _buffer = 24 + +SIZEOFIOBLOCK = SECTORSIZE + 24 + +dat + long +myMetadataBuffer byte 0[512] +myMetadataSector word -1 +dirty byte 0 +clusterShift byte 0 + +pri ReadMetadataSector( s ) + if myMetadataSector == s + return + readblock( myMetadataSector := s, @myMetadataBuffer ) +var + word bytesPerSector + byte sectorsPerCluster + word reservedSectors + byte numberOfFats + word sectorsPerFat + word numberOfRootDirectoryEntries + long fat1[0] + long fatSector0 + long dirSector0 + long dataregion[0] + long dataSector0 + +pri PrintDir | s, p, c + s := dirSector0 + repeat numberOfRootDirectoryEntries >> 4 + p := @myMetadataBuffer + repeat 16 + ReadMetadataSector( s ) + ifnot byte[p] + return + if byte[p] == $e5 + p += 32 + next + if byte[p][$0b] & $0f == 0 and Match( p, @dirstring, 11 ) + repeat 11 + term.out( byte[p++] ) + p -= 11 + term.out( " " ) + term.dec( PeekL( p + $1c ) ) + term.out( 13 ) + p += 32 + ++s + +pri Match( p, q, n ) | c1, c2 + repeat n + c1 := byte[p++] + c2 := byte[q++] + if "a" =< c1 and c1 =< "z" + c1 += "A" - "a" + if "a" =< c2 and c2 =< "z" + c2 += "A" - "a" + if c2 == "?" + next + if c1 <> c2 + return false + return true + +pri MyMount | pbrSector ,i + pbrSector~ + repeat + ReadMetadataSector( pbrSector ) + if bytecomp( @myMetadataBuffer+$36, string("FAT16"), 5 ) + quit + if pbrSector + abort -20 ' not FAT16 + pbrSector := PeekL( @myMetadataBuffer + $1c6 ) + + bytesPerSector := PeekW( @myMetadataBuffer + $0b ) + sectorsPerCluster := myMetadataBuffer[$0d] + clusterShift := >| sectorsPerCluster - 1 + reservedSectors := PeekW( @myMetadataBuffer + $0e ) + numberOfFats := myMetadataBuffer[$10] + sectorsPerFat := PeekW( @myMetadataBuffer + $16 ) + numberOfRootDirectoryEntries := PeekW( @myMetadataBuffer + $11 ) + fatSector0 := pbrSector + reservedSectors + dirSector0 := fatSector0 + numberOfFats * sectorsPerFat + dataSector0 := dirSector0 + numberOfRootDirectoryEntries >> 4 + +pri bytecomp( p, q, n ) + repeat n + if byte[p++] <> byte[q++] + return + return true + +pri PeekW( a ) + return byte[a++] + byte[a] << 8 + +pri PeekL( a ) + return byte[a++] + byte[a++] << 8 + byte[a++] << 16 + byte[a] << 24 + \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx1/echo.spn b/zubehör/sphinx/spinx100225-ori/sphinx1/echo.spn new file mode 100644 index 0000000..e9e4db1 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx1/echo.spn @@ -0,0 +1,41 @@ +_clkfreq = 80_000_000 +_clkmode = xtal1 + pll8x +obj + term: "isxtv" + f: "sxfile" +pub Main | e + Err( \Echo ) + Err( \Bye ) + +pri Err( e ) + ifnot e + return + if e < 0 + term.str( string("Error ") ) + term.dec( e ) + else + term.str( e ) + term.out( 13 ) + +con MAXARGSSIZE = 40 + +pub Echo | p, n + if f.Open( string("args.d8a"), "R" ) <> 0 + return + n := f.ReadByte + term.dec( n ) + term.str( string(" args", 13) ) + f.Read( @buffer, MAXARGSSIZE ) + f.Close + + p := @buffer + repeat while byte[p] + term.str( p ) + term.out( 13 ) + p += strsize(p) + 1 + +pub Bye + f.Open( string("sphinx.bin"), "R" ) + f.Execute( 0 ) + +var byte buffer[MAXARGSSIZE] \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx1/ed.spn b/zubehör/sphinx/spinx100225-ori/sphinx1/ed.spn new file mode 100644 index 0000000..e06be23 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx1/ed.spn @@ -0,0 +1,569 @@ +{ + Simple text editor + 2009 +March + 5 started; basic screen drawing; cursor movement + 6 InsertChar, InsertCR, DeleteLeft/Right + 6 filename edit field + 6 file load, save +June + 9 Sphinxified + 30 Page up/down, minor cursor movement improvement +2010 +January + 29 Bug: Was dropping last character when reading a file that didn't end with CR/LF. Fixed. + +ENTER(CR) Carriage return +BKSP Delete to the left +DEL Delete to the right +?, ?, ?, ? Cursor movement +HOME Start of line +CTRL-HOME Start of file +END End of line +CTRL-END End of file +CTRL-O Open a file +CTRL-S Save to a file +CTRL-Q Quit to Sphinx +PGUP Page up +PGDN Page down + +to do: +block select, cut/copy/paste, find/replace, undo/redo + +} +obj + kb: "isxkb" + sxtv: "isxtv" + term: "tvtexted" + sd: "sxfile" + +var + byte x[10] + +pub Main | e + if e := \Try + if e > 0 + sxtv.str( e ) + else + sxtv.dec( e ) + sxtv.out( 13 ) + term.stop + sxtv.Enable + +pub Try | i, key, refresh, blink, t, done + sxtv.Disable + term.start( sxtv.GetBasepin ) + + Init + + Args + + done~ + blink~ + t := cnt + repeat + refresh~ + repeat while key := kb.key + refresh~~ + blink~ + case key + $20..$7f: InsertChar( key ) + CR: InsertCR + BKSP: DeleteLeft + DEL: DeleteRight + LARROW: MoveCursorLeft + RARROW: MoveCursorRight + UARROW: MoveCursorUp( false ) + DARROW: MoveCursorDown( false ) + HOME: MoveToStartOfLine + CTRL+HOME: MoveToTop + END: MoveToEndOfLine + CTRL+END: MoveToBottom + CTRL+"o": FileOp( OPEN, FALSE ) + CTRL+"s": FileOp( SAVE, FALSE ) + CTRL+"q": FileOp( SAVE, FALSE ) + done~~ + PGUP: PageCursorUp + PGDN: PageCursorDown + other: refresh~ + if cnt - t > 0 + refresh~~ + if refresh + RefreshScreen( blink ^= 1 ) + t := cnt + clkfreq/10 + until done + + term.stop + sxtv.Enable + + sd.Close + sd.Open( string("sphinx.bin"), "R" ) + sd.Execute( 0 ) + +pri Args + if sd.Open( string("args.d8a"), "R" ) == 0 + if sd.ReadByte + sd.ReadString( @filename, FILENAMEBUFFERSIZE-1 ) + sd.Close + FileOp( OPEN, true ) + sd.Close + +con + VISIBLELINES = 13 + VISIBLECOLUMNS = 40 +con + CR = $0d + LARROW = $c0 + RARROW = $c1 + UARROW = $c2 + DARROW = $c3 + HOME = $c4 + END = $c5 + PGUP = $c6 + PGDN = $c7 + BKSP = $c8 + DEL = $c9 + ESC = $cb + CTRL = $0200 + CTRL_ALT_DEL = $06c9 + +con + BUFFERSIZE = 20000 +var + long nLines + long firstVisibleLine + long firstVisibleColumn + long bytesUsed + long cursorLine + long cursorColumn + long desiredColumn + long cp + long currentLineLength + long topPtr ' points to start of first visible line + +pri InsertChar( ch ) | n + if cursorLine < nLines + if bytesUsed + 1 => BUFFERSIZE + return + else ' starting new line at end of file + if bytesUsed + 2 => BUFFERSIZE + return + buffer[bytesUsed++]~ ' terminating null for the new line + ++nLines + n := bytesUsed - (cp - @buffer) + bytemove( cp+1, cp, n ) + byte[cp] := ch + ++bytesUsed + ++currentLineLength + MoveCursorRight + +pri InsertCR | n + if cursorLine < nLines + if bytesUsed + 1 => BUFFERSIZE + return + else ' starting new line at end of file + if bytesUsed + 2 => BUFFERSIZE + return + buffer[bytesUsed++]~ ' terminating null for the new line + ++nLines + n := bytesUsed - (cp - @buffer) + bytemove( cp+1, cp, n ) + byte[cp]~ + ++bytesUsed + ++nLines + currentLineLength := cursorColumn + MoveCursorRight + +pri DeleteLeft + if cursorLine or cursorColumn + MoveCursorLeft + DeleteRight + +pri DeleteRight | n + if cursorLine == nLines ' can't delete if we're on the phantom line + return + if byte[cp] == 0 and cursorLine == nLines - 1 and cursorColumn + return ' can't delete if we're at the end of the last real line + ' unless we're at the start (start = end => empty line + ' which we can delete, making this line the new phantom line) + n := bytesUsed - (cp - @buffer) - 1 + ifnot byte[cp] + --nLines + bytemove( cp, cp+1, n ) + --bytesUsed + repeat while byte[--cp] + currentLineLength := strsize( ++cp ) + cp += cursorColumn + AdjustVisibleColumn + +pri MoveCursorLeft + if cursorColumn + desiredColumn := --cursorColumn + --cp + AdjustVisibleColumn + else + ifnot cursorLine + return + MoveCursorUp( true ) + +pri MoveCursorRight + if cursorColumn < currentLineLength + desiredColumn := ++cursorColumn + ++cp + AdjustVisibleColumn + else + if cursorLine == nLines + return + MoveCursorDown( true ) + +pri MoveCursorDown( f ) +' if f, also move cursor to start of line + if cursorLine == nLines + return + if ++cursorLine - firstVisibleLine => VISIBLELINES + ++firstVisibleLine + repeat while byte[topPtr++] + MoveCpToNextLine + if f + cursorColumn~ + desiredColumn~ + elseif cursorLine < nLines + cursorColumn := currentLineLength <# desiredColumn + else + cursorColumn~ + currentLineLength~ + cp += cursorColumn + AdjustVisibleColumn + +pri PageCursorDown + if firstVisibleLine + VISIBLELINES - 1 => nLines + return + repeat VISIBLELINES - 1 + repeat while byte[topPtr++] + ++firstVisibleLine + MoveCursorDown( false ) + +pri MoveCursorUp( f ) +' if f, also move cursor to end of line + ifnot cursorLine + return + if --cursorLine < firstVisibleLine + --firstVisibleLine + repeat while byte[--topPtr] + repeat while byte[--topPtr] + ++topPtr + MoveCpToPreviousLine + if f + cursorColumn := desiredColumn := currentLineLength + else + cursorColumn := currentLineLength <# desiredColumn + cp += cursorColumn + AdjustVisibleColumn + +pri PageCursorUp | n + n := firstVisibleLine <# VISIBLELINES - 1 + repeat n + repeat 2 + repeat while byte[--topPtr] + ++topPtr + --firstVisibleLine + MoveCursorUp( false ) + +pri MoveCpToNextLine + repeat while byte[cp++] + currentLineLength := strsize( cp ) + +pri MoveCpToPreviousLine + repeat while byte[--cp] + repeat while byte[--cp] + ++cp + currentLineLength := strsize( cp ) + +pri MoveToStartOfLine + cp -= cursorColumn + cursorColumn~ + desiredColumn~ + AdjustVisibleColumn + +pri MoveToEndOfLine + cp -= cursorColumn + cursorColumn := desiredColumn := currentLineLength + cp += currentLineLength + AdjustVisibleColumn + +pri MoveToTop + cp := topPtr := @buffer[1] + currentLineLength := strsize( cp ) + cursorLine~ + cursorColumn~ + desiredColumn~ + firstVisibleLine~ + firstVisibleColumn~ + +pri MoveToBottom ' cheesy implementation + MoveToTop + if nLines + repeat nLines-1 + MoveCursorDown( false ) + MoveToEndOfLine + +pri AdjustVisibleColumn + firstVisibleColumn~ + firstVisibleColumn #>= cursorColumn - VISIBLECOLUMNS + 1 + +var + byte buffer[BUFFERSIZE] + { buffer contains nLines null-terminated strings, with sentinel nulls at the beginning and end: + +-+---------+-+--------+-+- ---------+-+-+ + ¦0¦ line0 0¦ line1 0¦ ... lineN-1 0¦0¦ + +-+---------+-+--------+-+- ---------+-+-+ + } +pri Init + nLines~ + firstVisibleLine~ + firstVisibleColumn~ + bytesUsed := 2 + buffer[0]~ + buffer[1]~ + cursorLine~ + cursorColumn~ + desiredColumn~ + + currentLineLength~ + cp := topPtr := @buffer[1] + + eolLength := 2 + eol[0] := $0d + eol[1] := $0a + +pri RefreshScreen( drawCursor ) | p, len, m, n, l, beyondEnd + p := topPtr + beyondEnd~ + repeat l from 0 to VISIBLELINES-1 + term.setXY( 0, l ) + if firstVisibleLine + l => nLines + beyondEnd~~ + len~ + else + len := strsize( p ) + if len > firstVisibleColumn + m := (len - firstVisibleColumn) <# VISIBLECOLUMNS + p += firstVisibleColumn + repeat m-1 + term.out( byte[p++] ) + term.printNoAdvance( byte[p++] ) + term.setX( m ) + n := VISIBLECOLUMNS - m + if n + repeat n-1 + term.out( " " ) + term.printNoAdvance( " " ) + else + repeat VISIBLECOLUMNS-1 + term.out( " " ) + term.printNoAdvance( " " ) + ifnot beyondEnd + repeat while byte[p++] + if drawCursor + term.setXY( cursorColumn-firstVisibleColumn, cursorLine-firstVisibleLine ) + term.printNoAdvance( "_" ) + +con + #0, OPEN, SAVE ' File ops +' File errors + #1, FILE_TOO_BIG, CARD_FULL_MAYBE + + FILENAMEBUFFERSIZE = 13 ' 8.3 + null + +pri FileOp( op, t ) | e, i + if e := \_FileOp( op, t ) + RefreshScreen( false ) ' cursor off + term.setXY( 0, VISIBLELINES-1 ) + term.out( $0c ) ' set color + term.out( 1 ) + repeat VISIBLECOLUMNS-1 + term.out( " " ) + term.printNoAdvance( " " ) + term.setX( 0 ) + case e + FILE_TOO_BIG: term.str( string("File too large") ) + CARD_FULL_MAYBE: term.str( string("SD card full?") ) + -13: term.str( string("Unable to mount SD card") ) + other: + term.str( string("Error code ") ) + term.dec( e ) + kb.getkey + term.out( $0c ) ' set color + term.out( 0 ) + +pri _FileOp( op, t ) | r + case op + OPEN: + if t + ReadFile + elseif EditFilename + ReadFile + SAVE: + WriteFile + +pri ReadFile | r, p, pEnd + sd.Close + if r := sd.Open( @filename, "R" ) <> 0 + abort r + + Init + r := sd.Read( @buffer[1], BUFFERSIZE-2 ) + + if r < 0 + abort r + p := @buffer[1] + pEnd := @buffer[r+1] + repeat while p <> pEnd + if byte[p] == $0d or byte[p] == $0a ' change CR, LF, or CRLF + if byte[p] == $0d and byte[p+1] == $0a ' + eolLength := 2 ' + bytemove( p, p + 1, pEnd - p - 1 ) ' + --pEnd ' + else ' + eolLength := 1 ' + byte[p]~ ' to null + ++nLines + ++p + + if byte[pEnd-1] ' if byte[pEnd-1] isn't null, that means that the file didn't + byte[pEnd++]~ ' end with CR, LF, or CRLF, so we have to fake it. (fixed 2010/01/29 mp) + ++nLines + + byte[pEnd]~ ' add final null + bytesUsed := pEnd + 1 - @buffer + + currentLineLength := strsize( topPtr ) + + if r == BUFFERSIZE-2 + abort FILE_TOO_BIG ' technically we don't know that it's too big at this point, but it's a good guess. + if r := sd.Close + abort r + +pri WriteFile | p, len, r + ifnot EditFilename + return + sd.Close + if r := sd.Open( @filename, "W" ) + abort r + + p := @buffer[1] + repeat nLines + len := strsize( p ) + r := sd.Write( p, len ) + if r < 0 + abort r + if r <> len ' Does this ever happen? + abort CARD_FULL_MAYBE + + r := sd.Write( @eol, eolLength ) + if r < 0 + abort r + if r <> eolLength ' Does this ever happen? + abort CARD_FULL_MAYBE + p += len + 1 + + if (r := sd.Close) < 0 + abort r + +var + byte filename[FILENAMEBUFFERSIZE] + long filenameCursorColumn + long filenameLength + byte eolLength + byte eol[2] +con + EDITOFFSET = 10 ' filename edit field starts at column 10 + +pri EditFilename | t, key, blink, refresh + RefreshScreen( false ) ' cursor off + term.setXY( 0, VISIBLELINES-1 ) + term.out( $0c ) ' set color + term.out( 2 ) + repeat VISIBLECOLUMNS-1 + term.out( " " ) + term.printNoAdvance( " " ) + term.setX( 0 ) + term.str( string("Filename: ") ) + + filenameCursorColumn := filenameLength := strsize( @filename ) + blink~ + t := cnt + repeat + refresh~ + repeat while key := kb.key + refresh~~ + blink~ + case key + $20..$7f: FilenameInsertChar( key ) + CR: + term.out( $0c ) ' set color + term.out( 0 ) ' back to normal + return true + BKSP: + if filenameCursorColumn + filenameCursorColumn := (filenameCursorColumn - 1) #> 0 + FilenameDeleteRight + DEL: FilenameDeleteRight + LARROW: filenameCursorColumn := (filenameCursorColumn - 1) #> 0 + RARROW: filenameCursorColumn := (filenameCursorColumn + 1) <# filenameLength + ESC: + term.out( $0c ) ' set color + term.out( 0 ) ' back to normal + return false + other: refresh~ + if cnt - t > 0 + refresh~~ + if refresh + RefreshFilename( blink ^= 1 ) + t := cnt + clkfreq/10 + +pri RefreshFilename( drawCursor ) | i + term.setXY( EDITOFFSET, VISIBLELINES-1 ) + repeat i from 0 to FILENAMEBUFFERSIZE-1 + if drawCursor and i == filenameCursorColumn + term.out( "_" ) + else + if i < filenameLength + term.out( filename[i] ) + else + term.out( " " ) + +pri FilenameInsertChar( ch ) | n + if filenameLength => FILENAMEBUFFERSIZE-1 + return + n := filenameLength - filenameCursorColumn + 1 + bytemove( @filename[filenameCursorColumn+1], @filename[filenameCursorColumn], n ) + ++filenameLength + filename[filenameCursorColumn++] := ch + +pri FilenameDeleteRight | n + ifnot filenameLength + return + ifnot n := filenameLength - filenameCursorColumn + return + bytemove( @filename[filenameCursorColumn], @filename[filenameCursorColumn+1], n ) + --filenameLength + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} diff --git a/zubehör/sphinx/spinx100225-ori/sphinx1/fdserial.sob b/zubehör/sphinx/spinx100225-ori/sphinx1/fdserial.sob new file mode 100644 index 0000000..e89a53b Binary files /dev/null and b/zubehör/sphinx/spinx100225-ori/sphinx1/fdserial.sob differ diff --git a/zubehör/sphinx/spinx100225-ori/sphinx1/gr_demo.spn b/zubehör/sphinx/spinx100225-ori/sphinx1/gr_demo.spn new file mode 100644 index 0000000..0dadc8c --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx1/gr_demo.spn @@ -0,0 +1,246 @@ +''***************************** +''* Graphics Demo v1.0 * +''* (C) 2005 Parallax, Inc. * +''***************************** + +CON + + _clkmode = xtal1 + pll8x + _xinfreq = 10_000_000 + 0000 + _stack = ($3000 + $3000 + 100) >> 2 'accomodate display memory and stack + + x_tiles = 16 + y_tiles = 12 + + paramcount = 14 + bitmap_base = $2000 + display_base = $5000 + + lines = 5 + thickness = 2 + +VAR + + long mousex, mousey + + long tv_status '0/1/2 = off/visible/invisible read-only + long tv_enable '0/? = off/on write-only + long tv_pins '%ppmmm = pins write-only + long tv_mode '%ccinp = chroma,interlace,ntsc/pal,swap write-only + long tv_screen 'pointer to screen (words) write-only + long tv_colors 'pointer to colors (longs) write-only + long tv_hc 'horizontal cells write-only + long tv_vc 'vertical cells write-only + long tv_hx 'horizontal cell expansion write-only + long tv_vx 'vertical cell expansion write-only + long tv_ho 'horizontal offset write-only + long tv_vo 'vertical offset write-only + long tv_broadcast 'broadcast frequency (Hz) write-only + long tv_auralcog 'aural fm cog write-only + + word screen[x_tiles * y_tiles] + long colors[64] + + byte x[lines] + byte y[lines] + byte xs[lines] + byte ys[lines] + +OBJ + + tv : "tv" + gr : "graphics" + mouse : "mouseiso" + + +PUB start | i, j, k, kk, dx, dy, pp, pq, rr, numx, numchr + + 'start tv + longmove(@tv_status, @tvparams, paramcount) + tv_screen := @screen + tv_colors := @colors + tv.start(@tv_status) + + 'init colors + repeat i from 0 to 64 + colors[i] := $00001010 * (i+4) & $F + $2B060C02 + + 'init tile screen + repeat dx from 0 to tv_hc - 1 + repeat dy from 0 to tv_vc - 1 + screen[dy * tv_hc + dx] := display_base >> 6 + dy + dx * tv_vc + ((dy & $3F) << 10) + + 'init bouncing lines + i := 1001 + j := 123123 + k := 8776434 + repeat i from 0 to lines - 1 + x[i] := ?j // 64 + y[i] := k? // 48 + repeat until xs[i] := k? ~> 29 + repeat until ys[i] := ?j ~> 29 + + 'start and setup graphics + gr.start + gr.setup(16, 12, 128, 96, bitmap_base) + + 'start mouse + mouse.start(2) + + repeat + + 'clear bitmap + gr.clear + + 'draw falling stars + gr.colorwidth(1,0) + kk := 100000 + repeat 8 + gr.vec(?kk & $FF - 128, (kk>>8 - k<<2) & $FF - 128, kk>>16 & $3F #> 20, kk->24 + k<<7, @vecdef2) + + 'draw spinning triangles + gr.colorwidth(3,0) + repeat i from 1 to 8 + gr.vec(0, 0, (k & $7F) << 3 + i << 5, k << 6 + i << 8, @vecdef) + + 'draw expanding mouse crosshairs + gr.colorwidth(2,k>>2) + mousex := mousex + mouse.delta_x #> -128 <# 127 + mousey := mousey + mouse.delta_y #> -96 <# 95 + gr.pix(mousex, mousey, k>>4 & $7, @pixdef) + + 'if left mouse button pressed, throw snowballs + if mouse.button(0) + gr.width(pq & $F) + gr.color(2) + pp := (pq & $F)*(pq & $F) + 5 + pq++ + gr.arc(mousex, mousey, pp, pp>>1, -k * 200, $200, 8, 0) + else + pq~ + + 'if right mouse button pressed, pause + repeat while mouse.button(1) + + 'draw expanding pixel halo + gr.colorwidth(1,k) + gr.arc(0,0,80,30,-k<<5,$2000/9,9,0) + + 'step bouncing lines + repeat i from 0 to lines - 1 + if ||~x[i] > 60 + -xs[i] + if ||~y[i] > 40 + -ys[i] + x[i] += xs[i] + y[i] += ys[i] + + 'draw bouncing lines + gr.colorwidth(1,thickness) + gr.plot(~x[0], ~y[0]) + repeat i from 1 to lines - 1 + gr.line(~x[i],~y[i]) + gr.line(~x[0], ~y[0]) + + 'draw spinning stars and revolving crosshairs and dogs + gr.colorwidth(2,0) + repeat i from 0 to 7 + gr.vecarc(80,50,30,30,-(i<<10+k<<6),$40,-(k<<7),@vecdef2) + gr.pixarc(-80,-40,30,30,i<<10+k<<6,0,@pixdef2) + gr.pixarc(-80,-40,20,20,-(i<<10+k<<6),0,@pixdef) + + 'draw small box with text + gr.colorwidth(1,14) + gr.box(60,-80,60,16) + gr.textmode(1,1,6,5) + gr.colorwidth(2,0) + gr.text(90,-72,@pchip) + + 'draw incrementing digit + if not ++numx & 3 + numchr++ + if numchr < "0" or numchr > "9" + numchr := "0" + gr.textmode(8,8,6,5) + gr.colorwidth(1,8) + gr.text(-90,50,@numchr) + + 'copy bitmap to display + gr.copy(display_base) + + 'increment counter that makes everything change + k++ + +DAT + +tvparams long 0 'status + long 1 'enable + long %011_0000 'pins + long %0000 'mode + long 0 'screen + long 0 'colors + long x_tiles 'hc + long y_tiles 'vc + long 10 'hx + long 1 'vx + long 0 'ho + long 0 'vo + long 60_000_000'_xinfreq<<4 'broadcast + long 0 'auralcog + +vecdef word $4000+$2000/3*0 'triangle + word 50 + word $8000+$2000/3*1+1 + word 50 + word $8000+$2000/3*2-1 + word 50 + word $8000+$2000/3*0 + word 50 + word 0 + +vecdef2 word $4000+$2000/12*0 'star + word 50 + word $8000+$2000/12*1 + word 20 + word $8000+$2000/12*2 + word 50 + word $8000+$2000/12*3 + word 20 + word $8000+$2000/12*4 + word 50 + word $8000+$2000/12*5 + word 20 + word $8000+$2000/12*6 + word 50 + word $8000+$2000/12*7 + word 20 + word $8000+$2000/12*8 + word 50 + word $8000+$2000/12*9 + word 20 + word $8000+$2000/12*10 + word 50 + word $8000+$2000/12*11 + word 20 + word $8000+$2000/12*0 + word 50 + word 0 + +pixdef word 'crosshair + byte 2,7,3,3 + word %%00333000,%%00000000 + word %%03020300,%%00000000 + word %%30020030,%%00000000 + word %%32222230,%%00000000 + word %%30020030,%%02000000 + word %%03020300,%%22200000 + word %%00333000,%%02000000 + +pixdef2 word 'dog + byte 1,4,0,3 + word %%20000022 + word %%02222222 + word %%02222200 + word %%02000200 + +pchip byte "Propeller",0 'text \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx1/graphics.sob b/zubehör/sphinx/spinx100225-ori/sphinx1/graphics.sob new file mode 100644 index 0000000..23ef517 Binary files /dev/null and b/zubehör/sphinx/spinx100225-ori/sphinx1/graphics.sob differ diff --git a/zubehör/sphinx/spinx100225-ori/sphinx1/graphics.spn b/zubehör/sphinx/spinx100225-ori/sphinx1/graphics.spn new file mode 100644 index 0000000..31b8a04 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx1/graphics.spn @@ -0,0 +1,1669 @@ +''*************************************** +''* Graphics Driver v1.0 * +''* Author: Chip Gracey * +''* Copyright (c) 2005 Parallax, Inc. * +''* See end of file for terms of use. * +''*************************************** + +'' +'' Theory of Operation: +'' +'' A cog is launched which processes commands via the PUB routines. +'' +'' Points, lines, arcs, sprites, text, and polygons are rasterized into +'' a specified stretch of memory which serves as a generic bitmap buffer. +'' +'' The bitmap can be displayed by the TV.SRC or VGA.SRC driver. +'' +'' See GRAPHICS_DEMO.SRC for usage example. +'' + +CON + + #1, _setup, _color, _width, _plot, _line, _arc, _vec, _vecarc, _pix, _pixarc, _text, _textarc, _textmode, _fill, _loop + +VAR + + long cog + + long command + + long bitmap_base 'bitmap data + long bitmap_longs + word bases[32] + + long pixel_width 'pixel data + long slices[8] + + long text_xs, text_ys, text_sp, text_just 'text data (these 4 must be contiguous) + + +PUB start : okay + +'' Start graphics driver - starts a cog +'' returns false if no cog available + + fontptr := @font 'set font pointer (same for all instances) + + stop + okay := cog := cognew(@loop, @command) + 1 + + +PUB stop + +'' Stop graphics driver - frees a cog + + if cog + cogstop(cog~ - 1) + + command~ + + +PUB setup(x_tiles, y_tiles, x_origin, y_origin, base_ptr) | bases_ptr, slices_ptr + +'' Set bitmap parameters +'' +'' x_tiles - number of x tiles (tiles are 16x16 pixels each) +'' y_tiles - number of y tiles +'' x_origin - relative-x center pixel +'' y_origin - relative-y center pixel +'' base_ptr - base address of bitmap + + setcommand(_loop, 0) 'make sure last command finished + + repeat bases_ptr from 0 to x_tiles - 1 <# 31 'write bases + bases[bases_ptr] := base_ptr + bases_ptr * y_tiles << 6 + + y_tiles <<= 4 'adjust arguments and do setup command + y_origin := y_tiles - y_origin - 1 + bases_ptr := @bases + slices_ptr := @slices + setcommand(_setup, @x_tiles) + + bitmap_base := base_ptr 'retain high-level bitmap data + bitmap_longs := x_tiles * y_tiles + + +PUB clear + +'' Clear bitmap + + setcommand(_loop, 0) 'make sure last command finished + + longfill(bitmap_base, 0, bitmap_longs) 'clear bitmap + + +PUB copy(dest_ptr) + +'' Copy bitmap +'' use for double-buffered display (flicker-free) +'' +'' dest_ptr - base address of destination bitmap + + setcommand(_loop, 0) 'make sure last command finished + + longmove(dest_ptr, bitmap_base, bitmap_longs) 'copy bitmap + + +PUB color(c) + +'' Set pixel color to two-bit pattern +'' +'' c - color code in bits[1..0] + + setcommand(_color, @colors[c & 3]) 'set color + + +PUB width(w) | pixel_passes, r, i, p + +'' Set pixel width +'' actual width is w[3..0] + 1 +'' +'' w - 0..15 for round pixels, 16..31 for square pixels + + r := not w & $10 'determine pixel shape/width + w &= $F + pixel_width := w + pixel_passes := w >> 1 + 1 + + setcommand(_width, @w) 'do width command now to avoid updating slices when busy + + p := w ^ $F 'update slices to new shape/width + repeat i from 0 to w >> 1 + slices[i] := true >> (p << 1) << (p & $E) + if r and pixels[w] & |< i + p += 2 + if r and i == pixel_passes - 2 + p += 2 + + +PUB colorwidth(c, w) + +'' Set pixel color and width + + color(c) + width(w) + + +PUB plot(x, y) + +'' Plot point +'' +'' x,y - point + + setcommand(_plot, @x) + + +PUB line(x, y) + +'' Draw a line to point +'' +'' x,y - endpoint + + setcommand(_line, @x) + + +PUB arc(x, y, xr, yr, angle, anglestep, steps, arcmode) + +'' Draw an arc +'' +'' x,y - center of arc +'' xr,yr - radii of arc +'' angle - initial angle in bits[12..0] (0..$1FFF = 0°..359.956°) +'' anglestep - angle step in bits[12..0] +'' steps - number of steps (0 just leaves (x,y) at initial arc position) +'' arcmode - 0: plot point(s) +'' 1: line to point(s) +'' 2: line between points +'' 3: line from point(s) to center + + setcommand(_arc, @x) + + +PUB vec(x, y, vecscale, vecangle, vecdef_ptr) + +'' Draw a vector sprite +'' +'' x,y - center of vector sprite +'' vecscale - scale of vector sprite ($100 = 1x) +'' vecangle - rotation angle of vector sprite in bits[12..0] +'' vecdef_ptr - address of vector sprite definition +'' +'' +'' Vector sprite definition: +'' +'' word $8000|$4000+angle 'vector mode + 13-bit angle (mode: $4000=plot, $8000=line) +'' word length 'vector length +'' ... 'more vectors +'' ... +'' word 0 'end of definition + + setcommand(_vec, @x) + + +PUB vecarc(x, y, xr, yr, angle, vecscale, vecangle, vecdef_ptr) + +'' Draw a vector sprite at an arc position +'' +'' x,y - center of arc +'' xr,yr - radii of arc +'' angle - angle in bits[12..0] (0..$1FFF = 0°..359.956°) +'' vecscale - scale of vector sprite ($100 = 1x) +'' vecangle - rotation angle of vector sprite in bits[12..0] +'' vecdef_ptr - address of vector sprite definition + + setcommand(_vecarc, @x) + + +PUB pix(x, y, pixrot, pixdef_ptr) + +'' Draw a pixel sprite +'' +'' x,y - center of vector sprite +'' pixrot - 0: 0°, 1: 90°, 2: 180°, 3: 270°, +4: mirror +'' pixdef_ptr - address of pixel sprite definition +'' +'' +'' Pixel sprite definition: +'' +'' word 'word align, express dimensions and center, define pixels +'' byte xwords, ywords, xorigin, yorigin +'' word %%xxxxxxxx,%%xxxxxxxx +'' word %%xxxxxxxx,%%xxxxxxxx +'' word %%xxxxxxxx,%%xxxxxxxx +'' ... + + setcommand(_pix, @x) + + +PUB pixarc(x, y, xr, yr, angle, pixrot, pixdef_ptr) + +'' Draw a pixel sprite at an arc position +'' +'' x,y - center of arc +'' xr,yr - radii of arc +'' angle - angle in bits[12..0] (0..$1FFF = 0°..359.956°) +'' pixrot - 0: 0°, 1: 90°, 2: 180°, 3: 270°, +4: mirror +'' pixdef_ptr - address of pixel sprite definition + + setcommand(_pixarc, @x) + + +PUB text(x, y, string_ptr) | justx, justy + +'' Draw text +'' +'' x,y - text position (see textmode for sizing and justification) +'' string_ptr - address of zero-terminated string (it may be necessary to call .finish +'' immediately afterwards to prevent subsequent code from clobbering the +'' string as it is being drawn + + justify(string_ptr, @justx) 'justify string and draw text + setcommand(_text, @x) + + +PUB textarc(x, y, xr, yr, angle, string_ptr) | justx, justy + +'' Draw text at an arc position +'' +'' x,y - center of arc +'' xr,yr - radii of arc +'' angle - angle in bits[12..0] (0..$1FFF = 0°..359.956°) +'' string_ptr - address of zero-terminated string (it may be necessary to call .finish +'' immediately afterwards to prevent subsequent code from clobbering the +'' string as it is being drawn + + justify(string_ptr, @justx) 'justify string and draw text + setcommand(_textarc, @x) + + +PUB textmode(x_scale, y_scale, spacing, justification) + +'' Set text size and justification +'' +'' x_scale - x character scale, should be 1+ +'' y_scale - y character scale, should be 1+ +'' spacing - character spacing, 6 is normal +'' justification - bits[1..0]: 0..3 = left, center, right, left +'' bits[3..2]: 0..3 = bottom, center, top, bottom + + longmove(@text_xs, @x_scale, 4) 'retain high-level text data + + setcommand(_textmode, @x_scale) 'set text mode + + +PUB box(x, y, box_width, box_height) | x2, y2, pmin, pmax + +'' Draw a box with round/square corners, according to pixel width +'' +'' x,y - box left, box bottom + + if box_width > pixel_width and box_height > pixel_width + + pmax := pixel_width - (pmin := pixel_width >> 1) 'get pixel-half-min and pixel-half-max + + x += pmin 'adjust coordinates to accomodate width + y += pmin + x2 := x + box_width - 1 - pixel_width + y2 := y + box_height - 1 - pixel_width + + plot(x, y) 'plot round/square corners + plot(x, y2) + plot(x2, y) + plot(x2, y2) + + fill(x, y2 + pmax, 0, (x2 - x) << 16, 0, 0, pmax) 'fill gaps + fill(x, y, 0, (x2 - x) << 16, 0, 0, pmin) + fill(x - pmin, y2, 0, (x2 - x + pixel_width) << 16, 0, 0, y2 - y) + + +PUB quad(x1, y1, x2, y2, x3, y3, x4, y4) + +'' Draw a solid quadrilateral +'' vertices must be ordered clockwise or counter-clockwise + + tri(x1, y1, x2, y2, x3, y3) 'draw two triangle to make 4-sides polygon + tri(x3, y3, x4, y4, x1, y1) + + +PUB tri(x1, y1, x2, y2, x3, y3) | xy[2] + +'' Draw a solid triangle + +' reorder vertices by descending y + + case (y1 => y2) & %100 | (y2 => y3) & %010 | (y1 => y3) & %001 + %000: + longmove(@xy, @x1, 2) + longmove(@x1, @x3, 2) + longmove(@x3, @xy, 2) + %010: + longmove(@xy, @x1, 2) + longmove(@x1, @x2, 4) + longmove(@x3, @xy, 2) + %011: + longmove(@xy, @x1, 2) + longmove(@x1, @x2, 2) + longmove(@x2, @xy, 2) + %100: + longmove(@xy, @x3, 2) + longmove(@x2, @x1, 4) + longmove(@x1, @xy, 2) + %101: + longmove(@xy, @x2, 2) + longmove(@x2, @x3, 2) + longmove(@x3, @xy, 2) + +' draw triangle + + fill(x1, y1, (x3 - x1) << 16 / (y1 - y3 + 1), (x2 - x1) << 16 / (y1 - y2 + 1), (x3 - x2) << 16 / (y2 - y3 + 1), y1 - y2, y1 - y3) + + +PUB finish + +'' Wait for any current graphics command to finish +'' use this to insure that it is safe to manually manipulate the bitmap + + setcommand(_loop, 0) 'make sure last command finished + + +PRI fill(x, y, da, db, db2, linechange, lines_minus_1) + + setcommand(_fill, @x) + + +PRI justify(string_ptr, justptr) | x + + x := (strsize(string_ptr) - 1) * text_xs * text_sp + text_xs * 5 - 1 + long[justptr] := -lookupz(text_just >> 2 & 3: 0, x >> 1, x, 0) + long[justptr][1] := -lookupz(text_just & 3: 0, text_ys << 3, text_ys << 4, 0) + + +PRI setcommand(cmd, argptr) + + command := cmd << 16 + argptr 'write command and pointer + repeat while command 'wait for command to be cleared, signifying receipt + + +CON + + ' Vector font primitives + + xa0 = %000 << 0 'x line start / arc center + xa1 = %001 << 0 + xa2 = %010 << 0 + xa3 = %011 << 0 + xa4 = %100 << 0 + xa5 = %101 << 0 + xa6 = %110 << 0 + xa7 = %111 << 0 + + ya0 = %0000 << 3 'y line start / arc center + ya1 = %0001 << 3 + ya2 = %0010 << 3 + ya3 = %0011 << 3 + ya4 = %0100 << 3 + ya5 = %0101 << 3 + ya6 = %0110 << 3 + ya7 = %0111 << 3 + ya8 = %1000 << 3 + ya9 = %1001 << 3 + yaA = %1010 << 3 + yaB = %1011 << 3 + yaC = %1100 << 3 + yaD = %1101 << 3 + yaE = %1110 << 3 + yaF = %1111 << 3 + + xb0 = %000 << 7 'x line end + xb1 = %001 << 7 + xb2 = %010 << 7 + xb3 = %011 << 7 + xb4 = %100 << 7 + xb5 = %101 << 7 + xb6 = %110 << 7 + xb7 = %111 << 7 + + yb0 = %0000 << 10 'y line end + yb1 = %0001 << 10 + yb2 = %0010 << 10 + yb3 = %0011 << 10 + yb4 = %0100 << 10 + yb5 = %0101 << 10 + yb6 = %0110 << 10 + yb7 = %0111 << 10 + yb8 = %1000 << 10 + yb9 = %1001 << 10 + ybA = %1010 << 10 + ybB = %1011 << 10 + ybC = %1100 << 10 + ybD = %1101 << 10 + ybE = %1110 << 10 + ybF = %1111 << 10 + + ax1 = %0 << 7 'x arc radius + ax2 = %1 << 7 + + ay1 = %00 << 8 'y arc radius + ay2 = %01 << 8 + ay3 = %10 << 8 + ay4 = %11 << 8 + + a0 = %0000 << 10 'arc start/length + a1 = %0001 << 10 'bits[1..0] = start (0..3 = 0°, 90°, 180°, 270°) + a2 = %0010 << 10 'bits[3..2] = length (0..3 = 360°, 270°, 180°, 90°) + a3 = %0011 << 10 + a4 = %0100 << 10 + a5 = %0101 << 10 + a6 = %0110 << 10 + a7 = %0111 << 10 + a8 = %1000 << 10 + a9 = %1001 << 10 + aA = %1010 << 10 + aB = %1011 << 10 + aC = %1100 << 10 + aD = %1101 << 10 + aE = %1110 << 10 + aF = %1111 << 10 + + fline = %0 << 14 'line command + farc = %1 << 14 'arc command + + more = %1 << 15 'another arc/line + + +DAT + +' Color codes + +colors long %%0000000000000000 + long %%1111111111111111 + long %%2222222222222222 + long %%3333333333333333 + +' Round pixel recipes + +pixels byte %00000000,%00000000,%00000000,%00000000 '0,1,2,3 + byte %00000000,%00000000,%00000010,%00000101 '4,5,6,7 + byte %00001010,%00001010,%00011010,%00011010 '8,9,A,B + byte %00110100,%00111010,%01110100,%01110100 'C,D,E,F + +' Vector font - standard ascii characters ($21-$7E) + +font word fline + xa2 + yaC + xb2 + yb7 + more '! + word fline + xa2 + ya5 + xb2 + yb4 + + word fline + xa1 + yaD + xb1 + ybC + more '" + word fline + xa3 + yaD + xb3 + ybC + + word fline + xa1 + yaA + xb1 + yb6 + more '# + word fline + xa3 + yaA + xb3 + yb6 + more + word fline + xa0 + ya9 + xb4 + yb9 + more + word fline + xa0 + ya7 + xb4 + yb7 + + word farc + xa2 + ya9 + a9 + ax2 + ay1 + more '$ + word farc + xa2 + ya7 + aB + ax2 + ay1 + more + word fline + xa0 + ya6 + xb2 + yb6 + more + word fline + xa2 + yaA + xb4 + ybA + more + word fline + xa2 + yaA + xb2 + ybB + more + word fline + xa2 + ya6 + xb2 + yb5 + + word farc + xa1 + yaA + a0 + ax1 + ay1 + more '% + word farc + xa3 + ya6 + a0 + ax1 + ay1 + more + word fline + xa0 + ya6 + xb4 + ybA + + word farc + xa2 + yaA + a7 + ax1 + ay1 + more '& + word farc + xa2 + ya7 + a5 + ax2 + ay2 + more + word fline + xa1 + yaA + xb4 + yb5 + + word fline + xa2 + yaD + xb2 + ybC ' ' + + word farc + xa3 + ya9 + aD + ax1 + ay4 + more '( + word farc + xa3 + ya7 + aE + ax1 + ay4 + more + word fline + xa2 + ya7 + xb2 + yb9 + + word farc + xa1 + ya9 + aC + ax1 + ay4 + more ') + word farc + xa1 + ya7 + aF + ax1 + ay4 + more + word fline + xa2 + ya7 + xb2 + yb9 + + word fline + xa4 + ya6 + xb0 + ybA + more '* + word fline + xa0 + ya6 + xb4 + ybA + more + word fline + xa2 + yaB + xb2 + yb5 + + word fline + xa0 + ya8 + xb4 + yb8 + more '+ + word fline + xa2 + yaA + xb2 + yb6 + + word fline + xa2 + ya4 + xb1 + yb3 ', + + word fline + xa0 + ya8 + xb4 + yb8 '- + + word fline + xa2 + ya5 + xb2 + yb4 '. + + word fline + xa0 + ya4 + xb4 + ybC '/ + + word farc + xa2 + ya8 + a0 + ax2 + ay4 '0 + + word fline + xa0 + ya4 + xb4 + yb4 + more '1 + word fline + xa2 + ya4 + xb2 + ybC + more + word fline + xa0 + yaA + xb2 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more '2 + word farc + xa2 + yaA + aF + ax2 + ay3 + more + word farc + xa2 + ya4 + aD + ax2 + ay3 + more + word fline + xa0 + ya4 + xb4 + yb4 + + word farc + xa2 + yaA + a7 + ax2 + ay2 + more '3 + word farc + xa2 + ya6 + a6 + ax2 + ay2 + + word fline + xa2 + yaC + xb0 + yb7 + more '4 + word fline + xa0 + ya7 + xb4 + yb7 + more + word fline + xa3 + ya4 + xb3 + yb8 + + word farc + xa2 + ya6 + aB + ax2 + ay2 + more '5 + word fline + xa4 + yaC + xb0 + ybC + more + word fline + xa0 + yaC + xb0 + yb8 + more + word fline + xa0 + ya8 + xb2 + yb8 + more + word fline + xa0 + ya4 + xb2 + yb4 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more '6 + word farc + xa2 + ya8 + aD + ax2 + ay4 + more + word fline + xa0 + ya6 + xb0 + yb8 + more + word fline + xa2 + yaC + xb3 + ybC + + word fline + xa0 + yaC + xb4 + ybC + more '7 + word fline + xa1 + ya4 + xb4 + ybC + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more '8 + word farc + xa2 + yaA + a0 + ax2 + ay2 + + word farc + xa2 + yaA + a0 + ax2 + ay2 + more '9 + word farc + xa2 + ya8 + aF + ax2 + ay4 + more + word fline + xa4 + ya8 + xb4 + ybA + more + word fline + xa1 + ya4 + xb2 + yb4 + + word fline + xa2 + ya6 + xb2 + yb7 + more ': + word fline + xa2 + yaA + xb2 + yb9 + + word fline + xa2 + ya4 + xb1 + yb3 + more '; + word fline + xa2 + ya8 + xb2 + yb7 + + word fline + xa0 + ya8 + xb4 + ybA + more '< + word fline + xa0 + ya8 + xb4 + yb6 + + word fline + xa0 + yaA + xb4 + ybA + more '= + word fline + xa0 + ya6 + xb4 + yb6 + + word fline + xa4 + ya8 + xb0 + ybA + more '> + word fline + xa4 + ya8 + xb0 + yb6 + + word farc + xa2 + yaB + a8 + ax2 + ay1 + more '? + word farc + xa3 + yaB + aF + ax1 + ay2 + more + word farc + xa3 + ya7 + aD + ax1 + ay2 + more + word fline + xa2 + ya5 + xb2 + yb4 + + word farc + xa2 + ya8 + a0 + ax1 + ay1 + more '@ + word farc + xa2 + ya8 + a4 + ax2 + ay3 + more + word farc + xa3 + ya8 + aF + ax1 + ay1 + more + word farc + xa2 + ya6 + aF + ax2 + ay1 + more + word fline + xa3 + ya7 + xb3 + yb9 + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more 'A + word fline + xa0 + ya4 + xb0 + ybA + more + word fline + xa4 + ya4 + xb4 + ybA + more + word fline + xa0 + ya8 + xb4 + yb8 + + word farc + xa2 + yaA + aB + ax2 + ay2 + more 'B + word farc + xa2 + ya6 + aB + ax2 + ay2 + more + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa0 + ya4 + xb2 + yb4 + more + word fline + xa0 + ya8 + xb2 + yb8 + more + word fline + xa0 + yaC + xb2 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more 'C + word farc + xa2 + ya6 + aA + ax2 + ay2 + more + word fline + xa0 + ya6 + xb0 + ybA + + word farc + xa2 + yaA + aC + ax2 + ay2 + more 'D + word farc + xa2 + ya6 + aF + ax2 + ay2 + more + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa4 + ya6 + xb4 + ybA + more + word fline + xa0 + ya4 + xb2 + yb4 + more + word fline + xa0 + yaC + xb2 + ybC + + word fline + xa0 + ya4 + xb0 + ybC + more 'E + word fline + xa0 + ya4 + xb4 + yb4 + more + word fline + xa0 + ya8 + xb3 + yb8 + more + word fline + xa0 + yaC + xb4 + ybC + + word fline + xa0 + ya4 + xb0 + ybC + more 'F + word fline + xa0 + ya8 + xb3 + yb8 + more + word fline + xa0 + yaC + xb4 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more 'G + word farc + xa2 + ya6 + aA + ax2 + ay2 + more + word fline + xa0 + ya6 + xb0 + ybA + more + word fline + xa4 + ya4 + xb4 + yb7 + more + word fline + xa3 + ya7 + xb4 + yb7 + + word fline + xa0 + ya4 + xb0 + ybC + more 'H + word fline + xa4 + ya4 + xb4 + ybC + more + word fline + xa0 + ya8 + xb4 + yb8 + + word fline + xa2 + ya4 + xb2 + ybC + more 'I + word fline + xa0 + ya4 + xb4 + yb4 + more + word fline + xa0 + yaC + xb4 + ybC + + word farc + xa2 + ya6 + aA + ax2 + ay2 + more 'J + word fline + xa4 + ya6 + xb4 + ybC + + word fline + xa0 + ya4 + xb0 + ybC + more 'K + word fline + xa4 + yaC + xb0 + yb8 + more + word fline + xa4 + ya4 + xb0 + yb8 + + word fline + xa0 + ya4 + xb0 + ybC + more 'L + word fline + xa0 + ya4 + xb4 + yb4 + + word fline + xa0 + ya4 + xb0 + ybC + more 'M + word fline + xa4 + ya4 + xb4 + ybC + more + word fline + xa2 + ya8 + xb0 + ybC + more + word fline + xa2 + ya8 + xb4 + ybC + + word fline + xa0 + ya4 + xb0 + ybC + more 'N + word fline + xa4 + ya4 + xb4 + ybC + more + word fline + xa4 + ya4 + xb0 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more '0 + word farc + xa2 + ya6 + aA + ax2 + ay2 + more + word fline + xa0 + ya6 + xb0 + ybA + more + word fline + xa4 + ya6 + xb4 + ybA + + word farc + xa2 + yaA + aB + ax2 + ay2 + more 'P + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa0 + ya8 + xb2 + yb8 + more + word fline + xa0 + yaC + xb2 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more 'Q + word farc + xa2 + ya6 + aA + ax2 + ay2 + more + word fline + xa0 + ya6 + xb0 + ybA + more + word fline + xa4 + ya6 + xb4 + ybA + more + word fline + xa2 + ya6 + xb4 + yb3 + + word farc + xa2 + yaA + aB + ax2 + ay2 + more 'R + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa0 + ya8 + xb2 + yb8 + more + word fline + xa0 + yaC + xb2 + ybC + more + word fline + xa4 + ya4 + xb2 + yb8 + + word farc + xa2 + yaA + a4 + ax2 + ay2 + more 'S + word farc + xa2 + ya6 + a6 + ax2 + ay2 + + word fline + xa2 + ya4 + xb2 + ybC + more 'T + word fline + xa0 + yaC + xb4 + ybC + + word farc + xa2 + ya6 + aA + ax2 + ay2 + more 'U + word fline + xa0 + ya6 + xb0 + ybC + more + word fline + xa4 + ya6 + xb4 + ybC + + word fline + xa2 + ya4 + xb0 + ybC + more 'V + word fline + xa2 + ya4 + xb4 + ybC + + word fline + xa0 + yaC + xb0 + yb4 + more 'W + word fline + xa4 + yaC + xb4 + yb4 + more + word fline + xa2 + ya8 + xb0 + yb4 + more + word fline + xa2 + ya8 + xb4 + yb4 + + word fline + xa4 + ya4 + xb0 + ybC + more 'X + word fline + xa0 + ya4 + xb4 + ybC + + word fline + xa0 + yaC + xb2 + yb8 + more 'Y + word fline + xa4 + yaC + xb2 + yb8 + more + word fline + xa2 + ya4 + xb2 + yb8 + + word fline + xa0 + yaC + xb4 + ybC + more 'Z + word fline + xa0 + ya4 + xb4 + ybC + more + word fline + xa0 + ya4 + xb4 + yb4 + + word fline + xa2 + yaD + xb2 + yb3 + more '[ + word fline + xa2 + yaD + xb4 + ybD + more + word fline + xa2 + ya3 + xb4 + yb3 + + word fline + xa4 + ya4 + xb0 + ybC '\ + + word fline + xa2 + yaD + xb2 + yb3 + more '[ + word fline + xa2 + yaD + xb0 + ybD + more + word fline + xa2 + ya3 + xb0 + yb3 + + word fline + xa2 + yaA + xb0 + yb6 + more '^ + word fline + xa2 + yaA + xb4 + yb6 + + word fline + xa0 + ya1 + xa4 + yb1 '_ + + word fline + xa1 + ya9 + xb3 + yb7 '` + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'a + word fline + xa4 + ya4 + xb4 + yb8 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'b + word fline + xa0 + ya4 + xb0 + ybC + + word farc + xa2 + ya6 + a9 + ax2 + ay2 + more 'c + word fline + xa2 + ya4 + xb4 + yb4 + more + word fline + xa2 + ya8 + xb4 + yb8 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'd + word fline + xa4 + ya4 + xb4 + ybC + + word farc + xa2 + ya6 + a4 + ax2 + ay2 + more 'e + word fline + xa0 + ya6 + xb4 + yb6 + more + word fline + xa2 + ya4 + xb4 + yb4 + + word farc + xa4 + yaA + aD + ax2 + ay2 + more 'f + word fline + xa0 + ya8 + xb4 + yb8 + more + word fline + xa2 + ya4 + xb2 + ybA + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'g + word farc + xa2 + ya3 + aF + ax2 + ay2 + more + word fline + xa4 + ya3 + xb4 + yb8 + more + word fline + xa1 + ya1 + xb2 + yb1 + + word farc + xa2 + ya6 + a8 + ax2 + ay2 + more 'h + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa4 + ya4 + xb4 + yb6 + + word fline + xa1 + ya4 + xb3 + yb4 + more 'i + word fline + xa2 + ya4 + xb2 + yb8 + more + word fline + xa1 + ya8 + xb2 + yb8 + more + word fline + xa2 + yaB + xb2 + ybA + + word farc + xa0 + ya3 + aF + ax2 + ay2 + more 'j + word fline + xa2 + ya3 + xb2 + yb8 + more + word fline + xa1 + ya8 + xb2 + yb8 + more + word fline + xa2 + yaB + xb2 + ybA + + word fline + xa0 + ya4 + xb0 + ybC + more 'k + word fline + xa0 + ya6 + xb2 + yb6 + more + word fline + xa2 + ya6 + xb4 + yb8 + more + word fline + xa2 + ya6 + xb4 + yb4 + + word fline + xa1 + ya4 + xb3 + yb4 + more 'l + word fline + xa2 + ya4 + xb2 + ybC + more + word fline + xa1 + yaC + xb2 + ybC + + word farc + xa1 + ya7 + a8 + ax1 + ay1 + more 'm + word farc + xa3 + ya7 + a8 + ax1 + ay1 + more + word fline + xa0 + ya4 + xb0 + yb8 + more + word fline + xa2 + ya4 + xb2 + yb7 + more + word fline + xa4 + ya4 + xb4 + yb7 + + word farc + xa2 + ya6 + a8 + ax2 + ay2 + more 'n + word fline + xa0 + ya4 + xb0 + yb8 + more + word fline + xa4 + ya4 + xb4 + yb6 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 'o + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'p + word fline + xa0 + ya1 + xb0 + yb8 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'q + word fline + xa4 + ya1 + xb4 + yb8 + + word farc + xa2 + ya7 + a8 + ax2 + ay1 + more 'r + word fline + xa0 + ya4 + xb0 + yb8 + + word farc + xa2 + ya7 + a9 + ax2 + ay1 + more 's + word farc + xa2 + ya5 + aB + ax2 + ay1 + more + word fline + xa0 + ya4 + xb2 + yb4 + more + word fline + xa2 + ya8 + xb4 + yb8 + + word farc + xa4 + ya6 + aE + ax2 + ay2 + more 't + word fline + xa0 + ya8 + xb4 + yb8 + more + word fline + xa2 + ya6 + xb2 + ybA + + word farc + xa2 + ya6 + aA + ax2 + ay2 + more 'u + word fline + xa0 + ya6 + xb0 + yb8 + more + word fline + xa4 + ya4 + xb4 + yb8 + + word fline + xa0 + ya8 + xb2 + yb4 + more 'v + word fline + xa4 + ya8 + xb2 + yb4 + + word farc + xa1 + ya5 + aA + ax1 + ay1 + more 'w + word farc + xa3 + ya5 + aA + ax1 + ay1 + more + word fline + xa0 + ya5 + xb0 + yb8 + more + word fline + xa2 + ya5 + xb2 + yb6 + more + word fline + xa4 + ya5 + xb4 + yb8 + + word fline + xa0 + ya8 + xb4 + yb4 + more 'x + word fline + xa0 + ya4 + xb4 + yb8 + + word farc + xa2 + ya6 + aA + ax2 + ay2 + more 'y + word farc + xa2 + ya3 + aF + ax2 + ay2 + more + word fline + xa4 + ya3 + xb4 + yb8 + more + word fline + xa0 + ya6 + xb0 + yb8 + more + word fline + xa1 + ya1 + xb2 + yb1 + + word fline + xa0 + ya8 + xb4 + yb8 + more 'z + word fline + xa4 + ya8 + xb0 + yb4 + more + word fline + xa0 + ya4 + xb4 + yb4 + + word farc + xa3 + yaA + aD + ax1 + ay3 + more '{ + word farc + xa1 + ya6 + aC + ax1 + ay2 + more + word farc + xa1 + yaA + aF + ax1 + ay2 + more + word farc + xa3 + ya6 + aE + ax1 + ay3 + + word fline + xa2 + ya3 + xb2 + ybD '| + + word farc + xa1 + yaA + aC + ax1 + ay3 + more '} + word farc + xa3 + ya6 + aD + ax1 + ay2 + more + word farc + xa3 + yaA + aE + ax1 + ay2 + more + word farc + xa1 + ya6 + aF + ax1 + ay3 + + word farc + xa1 + ya8 + a8 + ax1 + ay1 + more '~ + word farc + xa3 + ya8 + aA + ax1 + ay1 + +' Vector font - custom characters ($7F+) + + word fline + xa2 + ya9 + xb0 + yb4 + more 'delta + word fline + xa2 + ya9 + xb4 + yb4 + more + word fline + xa0 + ya4 + xb4 + yb4 + + word farc + xa2 + ya7 + a8 + ax2 + ay2 + more 'omega + word farc + xa1 + ya7 + aE + ax1 + ay2 + more + word farc + xa3 + ya7 + aF + ax1 + ay2 + more + word fline + xa1 + ya5 + xb1 + yb4 + more + word fline + xa3 + ya5 + xb3 + yb4 + more + word fline + xa0 + ya4 + xb1 + yb4 + more + word fline + xa4 + ya4 + xb3 + yb4 + + word farc + xa2 + ya8 + a0 + ax1 + ay1 'bullet + +CON fx = 3 'number of custom characters + +DAT + +'************************************* +'* Assembly language graphics driver * +'************************************* + + org +' +' +' Graphics driver - main loop +' +loop rdlong t1,par wz 'wait for command + if_z jmp #loop + + movd :arg,#arg0 'get 8 arguments + mov t2,t1 + mov t3,#8 +:arg rdlong arg0,t2 + add :arg,d0 + add t2,#4 + djnz t3,#:arg + + wrlong zero,par 'zero command to signify received + + call #setd 'set dx,dy from arg0,arg1 + + ror t1,#16+2 'lookup command address + add t1,#jumps + movs :table,t1 + rol t1,#2 + shl t1,#3 +:table mov t2,0 + shr t2,t1 + and t2,#$FF + jmp t2 'jump to command + + +jumps byte 0 '0 + byte setup_ '1 + byte color_ '2 + byte width_ '3 + byte plot_ '4 + byte line_ '5 + byte arc_ '6 + byte vec_ '7 + byte vecarc_ '8 + byte pix_ '9 + byte pixarc_ 'A + byte text_ 'B + byte textarc_ 'C + byte textmode_ 'D + byte fill_ 'E + byte loop 'F +' +' +' setup(x_tiles, y_tiles*16, x_origin, y_origin, base_ptr) bases_ptr, slices_ptr +' +setup_ mov xlongs,arg0 'set xlongs, ylongs + mov ylongs,arg1 + mov xorigin,arg2 'set xorigin, yorigin + mov yorigin,arg3 + mov basesptr,arg5 'set pointers + mov slicesptr,arg6 + + jmp #loop +' +' +' color(c) +' +color_ mov pcolor,arg0 'set pixel color + + jmp #loop +' +' +' width(w) pixel_passes +' +width_ mov pwidth,arg0 'set pixel width + mov passes,arg1 'set pixel passes + + jmp #loop +' +' +' plot(x, y) +' +plot_ call #plotd + + jmp #loop +' +' +' line(x, y) +' +line_ call #linepd + + jmp #loop +' +' +' arc(x, y, xr, yr, angle, anglestep, iterations, mode) +' +arc_ and arg7,#3 'limit mode + +:loop call #arca 'get arc dx,dy + + cmp arg7,#1 wz 'if not mode 1, set px,py + if_nz mov px,dx + if_nz mov py,dy + + tjz arg6,#loop 'if no points exit with new px,py + + cmp arg7,#3 wz 'if mode 3, set center + if_z call #setd + + test arg7,#1 wz 'if mode 0 or 2, plot point + if_z call #plotp + + test arg7,#1 wz 'if mode 1 or 3, plot line + if_nz call #linepd + + cmp arg7,#2 wz 'if mode 2, set mode 1 + if_z mov arg7,#1 + + add arg4,arg5 'step angle + djnz arg6,#:loop 'loop if more iterations + + jmp #loop +' +' +' vec(x, y, vecscale, vecangle, vecdef_ptr) +' vecarc(x, y, xr, yr, angle, vecscale, vecangle, vecdef_ptr) +' +' vecdef: word $8000/$4000+angle 'vector mode + 13-bit angle (mode: $4000=plot, $8000=line) +' word length 'vector length +' ... 'more vectors +' ... +' word 0 'end of definition +' +vecarc_ call #arcmod + +vec_ tjz arg2,#loop 'if scale 0, exit + +:loop rdword t7,arg4 wz 'get vector mode+angle + add arg4,#2 + + if_z jmp #loop 'if mode+angle 0, exit + + rdword t1,arg4 'get vector length + add arg4,#2 + + abs t2,arg2 wc 'add/sub vector angle to/from angle + mov t6,arg3 + sumc t6,t7 + + call #multiply 'multiply length by scale + add t1,#$80 'round up 1/2 lsb + shr t1,#8 + + mov t4,t1 'get arc dx,dy + mov t5,t1 + call #arcd + + test t7,h8000 wc 'plot pixel or draw line? + if_nc call #plotd + test t7,h8000 wc + if_c call #linepd + + jmp #:loop 'get next vector +' +' +' pix(x, y, pixrot, pixdef_ptr) +' pixarc(x, y, xr, yr, angle, pixrot, pixdef_ptr) +' +' pixdef: word +' byte xwords, ywords, xorigin, yorigin +' word %%xxxxxxxx,%%xxxxxxxx +' word %%xxxxxxxx,%%xxxxxxxx +' word %%xxxxxxxx,%%xxxxxxxx +' ... +' +pixarc_ call #arcmod + +pix_ mov t6,pcolor 'save color + + mov px,dx 'get center into px,py + mov py,dy + + mov sy,pwidth 'get actual pixel width + add sy,#1 + + rdbyte dx,arg3 'get dimensions into dx,dy + add arg3,#1 + rdbyte dy,arg3 + add arg3,#1 + + rdbyte t1,arg3 'get origin and adjust px,py + add arg3,#1 + rdbyte t2,arg3 + add arg3,#1 + neg t2,t2 + sub t2,#1 + add t2,dy + mov t3,sy +:adjust test arg2,#%001 wz + test arg2,#%110 wc + if_z sumnc px,t1 + if_nz sumc py,t1 + test arg2,#%010 wc + if_nz sumnc px,t2 + if_z sumnc py,t2 + djnz t3,#:adjust + +:yline mov sx,#0 'plot entire pix + mov t3,dx +:xword rdword t4,arg3 'read next pix word + add arg3,#2 + shl t4,#16 + mov t5,#8 +:xpixel rol t4,#2 'plot pixel within word + test t4,#1 wc 'set color + muxc pcolor,color1 + test t4,#2 wc + muxc pcolor,color2 wz '(z=1 if color=0) + if_nz call #plotp + test arg2,#%001 wz 'update px,py for next x + test arg2,#%110 wc + if_z sumc px,sy + if_nz sumnc py,sy + add sx,sy + djnz t5,#:xpixel 'another x pixel? + djnz t3,#:xword 'another x word? + if_z sumnc px,sx 'update px,py for next y + if_nz sumc py,sx + test arg2,#%010 wc + if_nz sumc px,sy + if_z sumc py,sy + djnz dy,#:yline 'another y line? + + mov pcolor,t6 'restore color + + jmp #loop +' +' +' text(x, y, @string) justx, justy +' textarc(x, y, xr, yr, angle, @string) justx, justy +' +textarc_ call #arcmod + +text_ add arg3,arg0 'add x into justx + add arg4,arg1 'add y into justy + +:chr rdbyte t1,arg2 wz 'get chr + add arg2,#1 + + if_z jmp #loop 'if 0, done + + sub t1,#$21 'if chr out of range, skip + cmp t1,#$7F-$21+fx wc + if_nc jmp #:skip + + mov arg5,fontptr 'scan font for chr definition +:scan tjz t1,#:def + rdword t2,arg5 + add arg5,#2 + test t2,h8000 wc + if_nc sub t1,#1 + jmp #:scan + +:def rdword t7,arg5 'get font definition word + add arg5,#2 + + call #fontxy 'extract initial x,y + + test t7,#$80 wc 'arc or line? + if_nc jmp #:line + + + mov t2,textsx 'arc, extract x radius + mov t3,#%0001_0001_1 + call #fontb + mov t4,t1 + + mov t2,textsy 'extract y radius + mov t3,#%0010_0011_1 + call #fontb + mov t5,t1 + + mov t2,#1 'extract starting angle + mov t3,#%0010_0011_0 + call #fontb + shl t1,#11 + + mov t6,t1 'extract angle sweep + mov t3,#%0010_0011_0 + call #fontb + neg arg6,t1 + shl arg6,#4 + add arg6,#65 + + call #arcd 'plot initial arc point + call #plotd + +:arc call #arcd 'connect subsequent arc points with lines + call #linepd + add t6,#$80 + djnz arg6,#:arc + + jmp #:more + + +:line call #plotd 'line, plot initial x,y + + call #fontxy 'extract terminal x,y + + call #linepd 'draw line + + +:more test t7,#$02 wc 'more font definition? + if_c jmp #:def + +:skip mov t1,textsp 'advance x to next chr position + mov t2,textsx + call #multiply + add arg3,t1 + + jmp #:chr 'get next chr + + +fontxy mov t2,textsx 'extract x + mov t3,#%0011_0111_0 + call #fontb + mov arg0,t1 + add arg0,arg3 + + mov t2,textsy 'extract y + mov t3,#%0100_1111_0 + call #fontb + mov arg1,t1 + add arg1,arg4 + +setd mov dx,xorigin 'set dx,dy from arg0,arg1 + add dx,arg0 + mov dy,yorigin + sub dy,arg1 +setd_ret +fontxy_ret ret + + +fontb mov t1,t7 'extract bitrange from font word + shr t3,#1 wc + and t1,t3 + if_c add t1,#1 + shr t3,#4 + shr t7,t3 + + shl t1,#32-4 'multiply t1[3..0] by t2 + mov t3,#4 +:loop shl t1,#1 wc + if_c add t1,t2 + djnz t3,#:loop + +fontb_ret ret +' +' +' textmode(x_scale, y_scale, spacing, justification) +' +textmode_ mov textsx,arg0 'set text x scale + mov textsy,arg1 'set text y scale + mov textsp,arg2 'set text spacing + + jmp #loop +' +' +' fill(x, y, da, db, db2, linechange, lines_minus_1) +' +fill_ shl dx,#16 'get left and right fractions + or dx,h8000 + mov t1,dx + + mov t2,xlongs 'get x pixels + shl t2,#4 + + add arg6,#1 'pre-increment line counter + +:yloop add dx,arg2 'adjust left and right fractions + add t1,arg3 + + cmps dx,t1 wc 'get left and right integers + if_c mov base0,dx + if_c mov base1,t1 + if_nc mov base0,t1 + if_nc mov base1,dx + sar base0,#16 + sar base1,#16 + + cmps base0,t2 wc 'left out of range? + if_c cmps hFFFFFFFF,base1 wc 'right out of range? + if_c cmp dy,ylongs wc 'y out of range? + if_nc jmp #:skip 'if any, skip + + mins base0,#0 'limit left and right + maxs base1,t2 wc + if_nc sub base1,#1 + + shl base0,#1 'make left mask + neg mask0,#1 + shl mask0,base0 + shr base0,#5 + + shl base1,#1 'make right mask + xor base1,#$1E + neg mask1,#1 + shr mask1,base1 + shr base1,#5 + + sub base1,base0 wz 'ready long count + add base1,#1 + + if_z and mask0,mask1 'if single long, merge masks + + shl base0,#1 'get long base + add base0,basesptr + rdword base0,base0 + shl dy,#2 + add base0,dy + shr dy,#2 + + mov bits0,mask0 'ready left mask +:xloop mov bits1,pcolor 'make color mask + and bits1,bits0 + rdlong pass,base0 'read-modify-write long + andn pass,bits0 + or pass,bits1 + wrlong pass,base0 + shl ylongs,#2 'advance to next long + add base0,ylongs + shr ylongs,#2 + cmp base1,#2 wz 'one more? + if_nz neg bits0,#1 'if not, ready full mask + if_z mov bits0,mask1 'if one more, ready right mask + djnz base1,#:xloop 'loop if more longs + +:skip sub arg5,#1 wc 'delta change? + if_c mov arg3,arg4 'if so, set new deltas +:same + add dy,#1 'adjust y + djnz arg6,#:yloop 'another y? + + jmp #loop +' +' +' Plot line from px,py to dx,dy +' +linepd cmps dx,px wc, wr 'get x difference + negc sx,#1 'set x direction + + cmps dy,py wc, wr 'get y difference + negc sy,#1 'set y direction + + abs dx,dx 'make differences absolute + abs dy,dy + + cmp dx,dy wc 'determine dominant axis + if_nc tjz dx,#:last 'if both differences 0, plot single pixel + if_nc mov count,dx 'set pixel count + if_c mov count,dy + mov ratio,count 'set initial ratio + shr ratio,#1 + if_c jmp #:yloop 'x or y dominant? + + +:xloop call #plotp 'dominant x line + add px,sx + sub ratio,dy wc + if_c add ratio,dx + if_c add py,sy + djnz count,#:xloop + + jmp #:last 'plot last pixel + + +:yloop call #plotp 'dominant y line + add py,sy + sub ratio,dx wc + if_c add ratio,dy + if_c add px,sx + djnz count,#:yloop + +:last call #plotp 'plot last pixel + +linepd_ret ret +' +' +' Plot pixel at px,py +' +plotd mov px,dx 'set px,py to dx,dy + mov py,dy + +plotp tjnz pwidth,#wplot 'if width > 0, do wide plot + + mov t1,px 'compute pixel mask + shl t1,#1 + mov mask0,#%11 + shl mask0,t1 + shr t1,#5 + + cmp t1,xlongs wc 'if x or y out of bounds, exit + if_c cmp py,ylongs wc + if_nc jmp #plotp_ret + + mov bits0,pcolor 'compute pixel bits + and bits0,mask0 + + shl t1,#1 'get address of pixel long + add t1,basesptr + mov t2,py + rdword t1,t1 + shl t2,#2 + add t1,t2 + + rdlong t2,t1 'write pixel + andn t2,mask0 + or t2,bits0 + wrlong t2,t1 +plotp_ret +plotd_ret ret +' +' +' Plot wide pixel +' +wplot mov t1,py 'if y out of bounds, exit + add t1,#7 + mov t2,ylongs + add t2,#7+8 + cmp t1,t2 wc + if_nc jmp #plotp_ret + + mov t1,px 'determine x long pair + sub t1,#8 + sar t1,#4 + cmp t1,xlongs wc + muxc jumps,#%01 '(use jumps[1..0] to store writes) + add t1,#1 + cmp t1,xlongs wc + muxc jumps,#%10 + + test jumps,#%11 wz 'if x out of bounds, exit + if_z jmp #plotp_ret + + shl t1,#1 'get base pair + add t1,basesptr + rdword base1,t1 + sub t1,#2 + rdword base0,t1 + + mov t1,px 'determine pair shifts + shl t1,#1 + movs :shift1,t1 + xor :shift1,#7<<1 + add t1,#9<<1 + movs :shift0,t1 + test t1,#$F<<1 wz '(account for special case) + if_z andn jumps,#%01 + + mov pass,#0 'ready to plot slices + mov slice,slicesptr + +:loop rdlong mask0,slice 'get next slice + mov mask1,mask0 + +:shift0 shl mask0,#0 'position slice +:shift1 shr mask1,#0 + + mov bits0,pcolor 'colorize slice + and bits0,mask0 + mov bits1,pcolor + and bits1,mask1 + + mov t1,py 'plot lower slice + add t1,pass + cmp t1,ylongs wc + if_c call #wslice + + mov t1,py 'plot upper slice + test pwidth,#1 wc + subx t1,pass + cmp t1,ylongs wc + if_c call #wslice + + add slice,#4 'next slice + add pass,#1 + cmp pass,passes wz + if_nz jmp #:loop + + jmp #plotp_ret +' +' +' Plot wide pixel slice +' +wslice shl t1,#2 'ready long offset + + add base0,t1 'plot left slice + test jumps,#%01 wc + if_c rdlong t2,base0 + if_c andn t2,mask0 + if_c or t2,bits0 + if_c wrlong t2,base0 + + add base1,t1 'plot right slice + test jumps,#%10 wc + if_c rdlong t2,base1 + if_c andn t2,mask1 + if_c or t2,bits1 + if_c wrlong t2,base1 + + sub base0,t1 'restore bases + sub base1,t1 + +wslice_ret ret +' +' +' Get arc point from args and then move args 5..7 to 2..4 +' +arcmod call #arca 'get arc using first 5 args + + mov arg0,dx 'set arg0,arg1 + sub arg0,xorigin + mov arg1,yorigin + sub arg1,dy + + mov arg2,arg5 'move args 5..7 to 2..4 + mov arg3,arg6 + mov arg4,arg7 + +arcmod_ret ret +' +' +' Get arc dx,dy from arg0,arg1 +' +' in: arg0,arg1 = center x,y +' arg2/t4 = x length +' arg3/t5 = y length +' arg4/t6 = 13-bit angle +' +' out: dx,dy = arc point +' +arca mov t4,arg2 'use args + mov t5,arg3 + mov t6,arg4 + +arcd call #setd 'reset dx,dy to arg0,arg1 + + mov t1,t6 'get arc dx + mov t2,t4 + call #polarx + add dx,t1 + + mov t1,t6 'get arc dy + mov t2,t5 + call #polary + sub dy,t1 +arcd_ret +arca_ret ret +' +' +' Polar to cartesian +' +' in: t1 = 13-bit angle +' t2 = 16-bit length +' +' out: t1 = x|y +' +polarx add t1,sine_90 'cosine, add 90° for sine lookup +polary test t1,sine_180 wz 'get sine quadrant 3|4 into nz + test t1,sine_90 wc 'get sine quadrant 2|4 into c + negc t1,t1 'if sine quadrant 2|4, negate table offset + or t1,sine_table 'or in sine table address >> 1 + shl t1,#1 'shift left to get final word address + rdword t1,t1 'read sine/cosine word + call #multiply 'multiply sine/cosine by length to get x|y + add t1,h8000 'add 1/2 lsb to round up x|y fraction + shr t1,#16 'justify x|y integer + negnz t1,t1 'if sine quadrant 3|4, negate x|y +polary_ret +polarx_ret ret + +sine_90 long $0800 '90° bit +sine_180 long $1000 '180° bit +sine_table long $E000 >> 1 'sine table address shifted right +' +' +' Multiply +' +' in: t1 = 16-bit multiplicand (t1[31..16] must be 0) +' t2 = 16-bit multiplier +' +' out: t1 = 32-bit product +' +multiply mov t3,#16 + shl t2,#16 + shr t1,#1 wc + +:loop if_c add t1,t2 wc + rcr t1,#1 wc + djnz t3,#:loop + +multiply_ret ret +' +' +' Defined data +' +zero long 0 'constants +d0 long $200 +h8000 long $8000 +hFFFFFFFF long $FFFFFFFF +color1 long %%1111111111111111 +color2 long %%2222222222222222 + +fontptr long 0 'font pointer (set before cognew command) + +pcolor long %%1111111111111111 'pixel color +pwidth long 0 'pixel width +passes long 1 'pixel passes +textsx long 1 'text scale x +textsy long 1 'text scale y +textsp long 6 'text spacing +' +' +' Undefined data +' +t1 res 1 'temps +t2 res 1 +t3 res 1 +t4 res 1 +t5 res 1 +t6 res 1 +t7 res 1 + +arg0 res 1 'arguments passed from high-level +arg1 res 1 +arg2 res 1 +arg3 res 1 +arg4 res 1 +arg5 res 1 +arg6 res 1 +arg7 res 1 + +basesptr res 1 'pointers +slicesptr res 1 + +xlongs res 1 'bitmap metrics +ylongs res 1 +xorigin res 1 +yorigin res 1 + +dx res 1 'line/plot coordinates +dy res 1 +px res 1 +py res 1 + +sx res 1 'line +sy res 1 +count res 1 +ratio res 1 + +pass res 1 'plot +slice res 1 +base0 res 1 +base1 res 1 +mask0 res 1 +mask1 res 1 +bits0 res 1 +bits1 res 1 + +{{ + ++------------------------------------------------------------------------------------------------------------------------------+ +¦ TERMS OF USE: MIT License ¦ ++------------------------------------------------------------------------------------------------------------------------------¦ +¦Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation ¦ +¦files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, ¦ +¦modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software¦ +¦is furnished to do so, subject to the following conditions: ¦ +¦ ¦ +¦The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.¦ +¦ ¦ +¦THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE ¦ +¦WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ¦ +¦COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ¦ +¦ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ¦ ++------------------------------------------------------------------------------------------------------------------------------+ +}} \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx1/hello1.spn b/zubehör/sphinx/spinx100225-ori/sphinx1/hello1.spn new file mode 100644 index 0000000..f9fc20b --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx1/hello1.spn @@ -0,0 +1,12 @@ +_xinfreq = 6_000_000 +_clkmode = xtal1 + pll16x +vidpin = 24 + +obj term : "tv_text" + +pub Main + term.start( vidpin ) + term.str( string("Howdy, ") ) + + waitcnt( clkfreq*2 + cnt ) + reboot diff --git a/zubehör/sphinx/spinx100225-ori/sphinx1/hello2.spn b/zubehör/sphinx/spinx100225-ori/sphinx1/hello2.spn new file mode 100644 index 0000000..ba95a0c --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx1/hello2.spn @@ -0,0 +1,11 @@ +obj + term : "isxtv" + f : "sxfile" + +pub Main + term.str( string("Howdy, ") ) + term.out( 13 ) + + f.Open( string("sphinx.bin"), "R" ) + f.Execute( 0 ) + diff --git a/zubehör/sphinx/spinx100225-ori/sphinx1/isxfs.sob b/zubehör/sphinx/spinx100225-ori/sphinx1/isxfs.sob new file mode 100644 index 0000000..3efd8cc Binary files /dev/null and b/zubehör/sphinx/spinx100225-ori/sphinx1/isxfs.sob differ diff --git a/zubehör/sphinx/spinx100225-ori/sphinx1/isxkb.sob b/zubehör/sphinx/spinx100225-ori/sphinx1/isxkb.sob new file mode 100644 index 0000000..6c6df31 Binary files /dev/null and b/zubehör/sphinx/spinx100225-ori/sphinx1/isxkb.sob differ diff --git a/zubehör/sphinx/spinx100225-ori/sphinx1/isxtv.sob b/zubehör/sphinx/spinx100225-ori/sphinx1/isxtv.sob new file mode 100644 index 0000000..cb0cad2 Binary files /dev/null and b/zubehör/sphinx/spinx100225-ori/sphinx1/isxtv.sob differ diff --git a/zubehör/sphinx/spinx100225-ori/sphinx1/lex.bin b/zubehör/sphinx/spinx100225-ori/sphinx1/lex.bin new file mode 100644 index 0000000..7f82997 Binary files /dev/null and b/zubehör/sphinx/spinx100225-ori/sphinx1/lex.bin differ diff --git a/zubehör/sphinx/spinx100225-ori/sphinx1/link.bin b/zubehör/sphinx/spinx100225-ori/sphinx1/link.bin new file mode 100644 index 0000000..80eb563 Binary files /dev/null and b/zubehör/sphinx/spinx100225-ori/sphinx1/link.bin differ diff --git a/zubehör/sphinx/spinx100225-ori/sphinx1/mouseiso.sob b/zubehör/sphinx/spinx100225-ori/sphinx1/mouseiso.sob new file mode 100644 index 0000000..40054ea Binary files /dev/null and b/zubehör/sphinx/spinx100225-ori/sphinx1/mouseiso.sob differ diff --git a/zubehör/sphinx/spinx100225-ori/sphinx1/sphinx.bin b/zubehör/sphinx/spinx100225-ori/sphinx1/sphinx.bin new file mode 100644 index 0000000..1fd5101 Binary files /dev/null and b/zubehör/sphinx/spinx100225-ori/sphinx1/sphinx.bin differ diff --git a/zubehör/sphinx/spinx100225-ori/sphinx1/sxfile.sob b/zubehör/sphinx/spinx100225-ori/sphinx1/sxfile.sob new file mode 100644 index 0000000..74738c3 Binary files /dev/null and b/zubehör/sphinx/spinx100225-ori/sphinx1/sxfile.sob differ diff --git a/zubehör/sphinx/spinx100225-ori/sphinx1/tv.sob b/zubehör/sphinx/spinx100225-ori/sphinx1/tv.sob new file mode 100644 index 0000000..1355ae2 Binary files /dev/null and b/zubehör/sphinx/spinx100225-ori/sphinx1/tv.sob differ diff --git a/zubehör/sphinx/spinx100225-ori/sphinx1/tv_text.sob b/zubehör/sphinx/spinx100225-ori/sphinx1/tv_text.sob new file mode 100644 index 0000000..183413b Binary files /dev/null and b/zubehör/sphinx/spinx100225-ori/sphinx1/tv_text.sob differ diff --git a/zubehör/sphinx/spinx100225-ori/sphinx1/tvtexted.spn b/zubehör/sphinx/spinx100225-ori/sphinx1/tvtexted.spn new file mode 100644 index 0000000..86f7c87 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx1/tvtexted.spn @@ -0,0 +1,245 @@ +''*************************************** +''* TV Text 40x13 v1.0 * +''* Author: Chip Gracey * +''* Copyright (c) 2006 Parallax, Inc. * +''* See end of file for terms of use. * +''*************************************** + +' Modified for ed by Michael Park + +CON + + cols = 40 + rows = 13 + + screensize = cols * rows + lastrow = screensize - cols + + tv_count = 14 + + +VAR + + long col, row, color, flag + + word screen[screensize] + long colors[8 * 2] + + long tv_status '0/1/2 = off/invisible/visible read-only (14 longs) + long tv_enable '0/non-0 = off/on write-only + long tv_pins '%pppmmmm = pin group, pin group mode write-only + long tv_mode '%tccip = tile,chroma,interlace,ntsc/pal write-only + long tv_screen 'pointer to screen (words) write-only + long tv_colors 'pointer to colors (longs) write-only + long tv_ht 'horizontal tiles write-only + long tv_vt 'vertical tiles write-only + long tv_hx 'horizontal tile expansion write-only + long tv_vx 'vertical tile expansion write-only + long tv_ho 'horizontal offset write-only + long tv_vo 'vertical offset write-only + long tv_broadcast 'broadcast frequency (Hz) write-only + long tv_auralcog 'aural fm cog write-only + + +OBJ + + tv : "tv" + + +PUB start(basepin) : okay + +'' Start terminal - starts a cog +'' returns false if no cog available + + setcolors(@palette) + out(0) + + longmove(@tv_status, @tv_params, tv_count) + tv_pins := (basepin & $38) << 1 | (basepin & 4 == 4) & %0101 + tv_screen := @screen + tv_colors := @colors + + okay := tv.start(@tv_status) + + +PUB stop + +'' Stop terminal - frees a cog + + tv.stop + + +PUB str(stringptr) + +'' Print a zero-terminated string + + repeat strsize(stringptr) + out(byte[stringptr++]) + + +PUB dec(value) | i + +'' Print a decimal number + + if value < 0 + -value + out("-") + + i := 1_000_000_000 + + repeat 10 + if value => i + out(value / i + "0") + value //= i + result~~ + elseif result or i == 1 + out("0") + i /= 10 + + +PUB hex(value, digits) + +'' Print a hexadecimal number + + value <<= (8 - digits) << 2 + repeat digits + out(lookupz((value <-= 4) & $F : "0".."9", "A".."F")) + + +PUB bin(value, digits) + +'' Print a binary number + + value <<= 32 - digits + repeat digits + out((value <-= 1) & 1 + "0") + + +PUB out(c) | i, k + +'' Output a character +'' +'' $00 = clear screen +'' $01 = home +'' $08 = backspace +'' $09 = tab (8 spaces per) +'' $0A = set X position (X follows) +'' $0B = set Y position (Y follows) +'' $0C = set color (color follows) +'' $0D = return +'' others = printable characters + + case flag + $00: case c + $00: wordfill(@screen, $220, screensize) + col := row := 0 + $01: col := row := 0 + $08: if col + col-- + $09: repeat + print(" ") + while col & 7 + $0A..$0C: flag := c + return + $0D: newline + other: print(c) + $0A: col := c // cols + $0B: row := c // rows + $0C: color := c & 7 + flag := 0 + +PUB setcolors(colorptr) | i, fore, back + +'' Override default color palette +'' colorptr must point to a list of up to 8 colors +'' arranged as follows: +'' +'' fore back +'' ------------ +'' palette byte color, color 'color 0 +'' byte color, color 'color 1 +'' byte color, color 'color 2 +'' ... + + repeat i from 0 to 7 + fore := byte[colorptr][i << 1] + back := byte[colorptr][i << 1 + 1] + colors[i << 1] := fore << 24 + back << 16 + fore << 8 + back + colors[i << 1 + 1] := fore << 24 + fore << 16 + back << 8 + back + + +PUB printNoAdvance(c) ' mpark + screen[row * cols + col] := (color << 1 + c & 1) << 10 + $200 + c & $FE + +PUB SetXY( x, y ) ' mpark + col := x + row := y + +PUB SetX( x ) ' mpark + col := x + +PUB SetY( y ) ' mpark + row := y + +PRI print(c) + + screen[row * cols + col] := (color << 1 + c & 1) << 10 + $200 + c & $FE + if ++col == cols + newline + +PRI newline | i + + col := 0 + if ++row == rows + row-- + wordmove(@screen, @screen[cols], lastrow) 'scroll lines + wordfill(@screen[lastrow], $220, cols) 'clear new line + + +DAT + +tv_params long 0 'status + long 1 'enable + long 0 'pins + long %10010 'mode + long 0 'screen + long 0 'colors + long cols 'hc + long rows 'vc + long 4 'hx + long 1 'vx + long 0 'ho + long 0 'vo + long 0 'broadcast + long 0 'auralcog + + + ' fore back + ' color color +palette byte $07, $0A '0 white / dark blue + byte $07, $BB '1 white / red + byte $9E, $9B '2 yellow / brown + byte $04, $07 '3 grey / white + byte $3D, $3B '4 cyan / dark cyan + byte $6B, $6E '5 green / gray-green + byte $BB, $CE '6 red / pink + byte $3C, $0A '7 cyan / blue + +{{ + ++------------------------------------------------------------------------------------------------------------------------------+ +¦ TERMS OF USE: MIT License ¦ ++------------------------------------------------------------------------------------------------------------------------------¦ +¦Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation ¦ +¦files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, ¦ +¦modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software¦ +¦is furnished to do so, subject to the following conditions: ¦ +¦ ¦ +¦The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.¦ +¦ ¦ +¦THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE ¦ +¦WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ¦ +¦COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ¦ +¦ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ¦ ++------------------------------------------------------------------------------------------------------------------------------+ +}} \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx2/bintree.spn b/zubehör/sphinx/spinx100225-ori/sphinx2/bintree.spn new file mode 100644 index 0000000..62778ed --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx2/bintree.spn @@ -0,0 +1,238 @@ +obj + str: "stringx" + +dat +cog long 0 + +pub Init( p0, p1 ) + pFree := p0 ' leave some room for the stack, then free space. + pLimit := p1 + + Stop + sync~~ + cog := cognew( @LookerUpper, @input ) + 1 + ifnot cog + abort string("Couldn't start bintree cog") + repeat while sync + +pub Stop + if cog + cogstop( cog~ - 1 ) + +pub FindInTable( s, p ) | d +{{ + Finds string s in table pointed to by p. + Returns pointer to s's data area if s is found, 0 otherwise. +}} + input[0] := s + input[1] := p + sync~~ + repeat while sync + return output +{ + ifnot p + return 0 + d := str.Compare( s, p+4 ) + ifnot d + return p + 4 + strsize(s) + 1 + if d < 0 + return FindInTable( s, Peekw(p) ) + ' else + return FindInTable( s, Peekw(p+2) ) +} + +pub AddToTable( s, pP ) | p, d +{{ + Adds string s to table. Note: pP is a pointer-to-pointer to table. + Returns a pointer to s's data area (actually pFree, so if you add + any data, increment pFree past it). +}} + ifnot p := PeekW( pP ) + PokeW( pP, pFree ) + PokeW( pFree, 0 ) + pFree += 2 + PokeW( pFree, 0 ) + pFree += 2 + str.Copy( pFree, s ) + pFree += strsize(s) + 1 + return pFree + + d := str.Compare( s, p+4 ) +{ + term.dec(d) + term.out(13) + waitcnt( clkfreq + cnt ) +} + ifnot d + abort string("Symbol already defined") + if d < 0 + return AddToTable( s, @word[p][0] ) + ' else + return AddToTable( s, @word[p][1] ) + +pub PeekW( p ) + return byte[p++] + byte[p] << 8 + +pub PokeW( p, w ) + byte[p++] := w + byte[p] := w >> 8 + +pub PeekL( p ) : t + repeat 4 + t := (t | byte[p++]) -> 8 + +pub PokeL( p, l ) + repeat 4 + byte[p++] := l + l >>= 8 + +dat +pFree long 0 +pLimit long 0 + +pub Alloc( n ) + result := pFree + if (pFree += n) > pLimit + abort string("Out of symbol table space") + +dat +input long 0 ' rendezvous variables for LookerUpper +output long 0 +sync long 1 + +{ +This PASM routine is equivalent to the following: + +pub FindInTable( s, p ) | d +{{ + Finds string s in table pointed to by p. + Returns pointer to s's data area if s is found, 0 otherwise. +}} + ifnot p + return 0 + d := str.Compare( s, p+4 ) + ifnot d + return p + 4 + strsize(s) + 1 + if d < 0 + return FindInTable( s, Peekw(p) ) + ' else + return FindInTable( s, Peekw(p+2) ) +} + +dat org 0 +LookerUpper + mov pInput, par ' Enter with par pointing to rendezvous area, + mov pOutput, par ' sync = 1 + add pOutput, #4 + mov pSync, par + add pSync, #8 + + rdlong pTable, pInput ' Save @tableStart + ' and ack to inform Spin program that the cog is running. +Ack + wrlong retval, pOutput + mov temp, #0 + wrlong temp, pSync + +:wait ' Wait for caller to set sync to indicate that input is ready. + rdlong temp, pSync wz + if_z jmp #:wait + + rdlong pString, pInput ' input[0] points to string to look up. + rdlong ptr, pOutput ' input[1] points to table. (input[1] = output) + + mov retval, #0 +:loop + tjz ptr, #Ack + + mov pLeft, pString ' Compare string + mov pRight, ptr ' to string at current position in table + add pRight, #4 ' (bump up ptr by 4 to skip two link words). + + call #StringCompare + + if_e jmp #:equal + if_b jmp #:less +:greater ' If left > right, + add ptr, #2 ' use the 2nd link. +:less ' If left < right, use 1st link. + rdbyte temp, ptr ' Follow the link + add ptr, #1 ' It would be nice to just "rdword ptr, ptr" here + rdbyte ptr, ptr ' but ptr might be odd so we have to go through + shl ptr, #8 ' some extra gyrations. + add ptr, temp + + jmp #:loop ' and recurse (well, just iterate). + +:equal ' If left = right, return ptr + 4 + strsize(pString) + 1 + mov retval, ptr + add retval, #5 +:x + rdbyte temp, pString wz ' add strsize(pString) + if_z jmp #:y + add retval, #1 + add pString, #1 + jmp #:x +:y + jmp #Ack + +StringCompare +' Compares zero-terminated strings pointed to by pLeft and pRight. +' On return, Z and C are set appropriately. + rdbyte temp, pLeft wz + add pLeft, #1 + if_z jmp #:leftEnd + rdbyte temp1, pRight wz + add pRight, #1 + if_z jmp #:rightEnd + cmp temp, temp1 wc, wz + if_e jmp #StringCompare ' If they match, try the next pair. + jmp #StringCompare_ret ' Otherwise, we're done. + +:leftEnd rdbyte temp1, pRight wz ' If we're at the end of both strings, + if_z jmp #StringCompare_ret ' leave (with Z set). + ' Otherwise, left string is shorter than the right + ' and therefore less. + neg temp, #1 + mov temp, temp wc, wz ' Set C=1 and Z=0 for "less than" + jmp #StringCompare_ret +:rightEnd ' Here we've reached the end of the right string. + ' The left string is longer than the right + ' and therefore greater. + mov temp, #1 wc, wz ' Set C=0 and Z=0 for "greater than" + +StringCompare_ret + ret + +temp res 1 +temp1 res 1 +ptr res 1 +pLeft res 1 +pRight res 1 +pString res 1 +pTable res 1 +pInput res 1 +pOutput res 1 +pSync res 1 +retval res 1 + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} + + \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx2/codegen.spn b/zubehör/sphinx/spinx100225-ori/sphinx2/codegen.spn new file mode 100644 index 0000000..33d3c4a --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx2/codegen.spn @@ -0,0 +1,1072 @@ +' 2010-02-25 new version number +con + _clkmode = xtal1 + pll8x + _xinfreq = 10_000_000 + + tvPin = 24 + sdPin = 16 + +obj + term: "isxtv" + kw: "kwdefs" + st: "symbols" + bt: "bintree" + fs: "sxfile" + str: "stringx" + token: "tokenrdr" + eval: "eval" + methods: "methods" + +pub Main | err, p + + err := \Try + if err + if err > 0 + term.str( err ) + else + term.str( string("Error ") ) + term.dec( err ) + term.out( 13 ) + if stackset and long[pSymbolTableSpace] <> $6666_6666 + term.str( string("Stack corrupt",13) ) + term.dec( token.LineNumber ) + term.out( "," ) + term.dec( token.Column + 1 ) + term.out( " " ) + term.out( "'" ) + term.str( token.Text ) + term.out( "'" ) + term.out( 13 ) + fs.Close + fs.Open( string("sphinx.bin"), "R" ) + else + fs.Close + if link + fs.Open( string("link.bin"), "R" ) + else + fs.Open( string("sphinx.bin"), "R" ) + bt.Stop + fs.Execute( 0 ) + +pri Try + ProcessCommandLine + if verbosity => 1 + term.str( string("codegen 100225", 13) ) + + Start + +pri ProcessCommandLine | nArgs, l + fs.Open( string("args.d8a"), "R" ) + nArgs := fs.ReadByte + ifnot nArgs-- + abort string("usage: compile spinfile [options]") + fs.ReadStringUpperCase( @tokenFilename, MAXFILENAMELENGTH ) + + l := strsize( @tokenFilename ) + if tokenFilename[l-4] == "." and tokenFilename[l-3] == "S" and tokenFilename[l-2] == "P" and tokenFilename[l-1] == "N" + tokenFilename[l-4]~ + if strsize( @tokenFilename ) > 8 + term.str( @tokenFilename ) + abort string(" -- filename too long") + str.Copy( @outputFilename, @tokenFilename ) + str.Copy( @binFilename, @tokenFilename ) + str.Append( @tokenFilename, string(".TOK") ) + str.Append( @outputFilename, string(".SOB") ) + str.Append( @binFilename, string(".BIN") ) + + ' Process command line arguments + + repeat while nArgs-- + fs.ReadStringUpperCase( @stringBuffer, MAXSTRINGBUFFERLENGTH ) + if stringBuffer[0] == "-" + stringBuffer[0] := "/" + if strcomp( @stringBuffer, string("/L") ) + link~~ + elseif strcomp( @stringBuffer, string("/V") ) + ifnot nArgs-- + abort string("/V must be followed by a number") + verbosity := fs.ReadNumber + elseif strcomp( @stringBuffer, string("/S") ) + ifnot nArgs-- + abort string("/S must be followed by a number") + STACKSPACE := fs.ReadNumber + if STACKSPACE & 3 + abort string("/S argument must be a multiple of 4") + elseif strcomp( @stringBuffer, string("/T") ) + ifnot nArgs-- + abort string("/T must be followed by a number") + TABLESPACE := fs.ReadNumber + if TABLESPACE & 3 + abort string("/T argument must be a multiple of 4") + 'else + ' ignore + + fs.Close + +con + MAXFILENAMELENGTH = 8 + 1 + 3 ' 8.3 + MAXSTRINGBUFFERLENGTH = 32 + +SXTVRENDEZVOUS = $8000 - 4 +RESERVED = SXTVRENDEZVOUS - 4 +SDSPIRENDEZVOUS = RESERVED - 3 * 4 +SXFS2RENDEZVOUS = SDSPIRENDEZVOUS - 4 * 4 ' four rendezvous variables +SXFSRENDEZVOUS = SXFS2RENDEZVOUS - 4 * 4 ' four rendezvous variables +METADATABUFFER = SXFSRENDEZVOUS - 512 + +_free = ($8000 - METADATABUFFER) / 4 + +var + byte tokenFilename[MAXFILENAMELENGTH+1] ' input .tok file + byte outputFilename[MAXFILENAMELENGTH+1] ' output .sob file + byte binFilename[MAXFILENAMELENGTH+1] ' output .bin file (just used to empty the .bin) + byte sobFilename[MAXFILENAMELENGTH+1] ' used for child .sob file(s) + byte stringBuffer[MAXSTRINGBUFFERLENGTH+1] ' temp string buffer + +dat +STACKSPACE long 575<<2 +TABLESPACE long 1500<<2 +verbosity byte 0 ' set by /V option +stackset byte 0 +link byte 0 ' set by /L; if non-zero, run link.bin automatically. + +{ + |<---STACKSPACE--->|<--------TABLESPACE---------->|<-----------OBJECTSPACE------------>|<-I/O RENDEZVOUS etc. + +-----+------------+-----------+------------------+------+----------------+------------+--+ + |stack| |symboltable| |header|dat/PASM|methods| | | + +-----+------------+-----------+------------------+------+----------------+------------+--+ + |tempstorage| ^ ^ |stringtemp| ^ + | | ^ ^ | + pObjSpace-+ pObjWork-+ | | +--$8000 + pStringWork-+ pObjTop-+ +} +var +' These next 3 vars actually live in methods.spin now. +' word pObjSpace ' points to area where the compiled object's header and bytecode will live (this pointer doesn't change) +' word pObjWork ' points to next available byte (this pointer changes as code is compiled) +' word pObjTop ' points just beyond available object workspace + + word pDatWork ' like pObjWork but for the DAT segment + word pSymbolTableSpace + +pri Start | i + pSymbolTableSpace := word[ $0a ] + STACKSPACE + + methods.set_pObjSpace( pSymbolTableSpace + TABLESPACE ) + methods.set_pObjTop( METADATABUFFER ) + + bt.Init( pSymbolTableSpace, methods.get_pObjSpace ) + st.Init + + long[ bt.Alloc(4) ] := $6666_6666 + stackset~~ + + ReadTimestamp + + if verbosity => 2 + term.str( string("stack space: ") ) + term.dec( STACKSPACE ) + term.str( string(13,"table space: ") ) + term.dec( TABLESPACE ) + term.str( string(13,"work space: ") ) + term.dec( methods.get_pObjTop - methods.get_pObjSpace ) + term.out( 13 ) + + term.str( string("Opening ") ) + term.str( @tokenFilename ) + term.out( 13 ) + token.Open( @tokenFilename ) + + bvarSize~ + wvarSize~ + lvarSize~ + nPubs := 1 ' pub indexes start at 1; 0th entry in object header is not a pub + nPris~ ' pri indexes have to be compensated later once final nPubs is known + nObjs~ + pObjList~ + pObjListEnd~ + + ParsePass1 + token.Close + + CheckStack + + varSize := (lvarSize + wvarSize + bvarSize + 3) & !3 + pDatWork := methods.get_pObjSpace + (nPubs + nPris + nObjs) << 2 ' each PUB/PRI/OBJ takes up 4 bytes in the object header + methods.set_pObjWork( pDatWork + datSize ) + bytefill( methods.get_pObjSpace, 0, pDatWork - methods.get_pObjSpace ) ' zero the header + + FixupOffsets( bt.PeekW( st.GetPSymbolTable ) ) + + token.Open( @tokenFilename ) + + ParsePass2 + token.Close + + methods.set_pObjWork( (methods.get_pObjWork + 3) & !3 ) ' Round up to multiple of 4 + + WriteSobFile + +pri CheckStack + if long[pSymbolTableSpace] <> $6666_6666 + abort string("Stack overflow") + +pri ReadTimestamp + if verbosity => 3 + term.str( string("reading timestamp: ") ) + + if fs.Open( string("timestmp.d8a"), "R" ) == 0 + timestamp := fs.ReadLong + 1 + fs.Close + else + timestamp := 1 + + if verbosity => 3 + term.dec( timestamp ) + term.out( 13 ) + + fs.Open( string("timestmp.d8a"), "W" ) + fs.WriteLong( timestamp ) + fs.Close + +pri WriteSobFile | p + + if nPubs == 1 ' recall that nPubs starts at 1 because of the 0th entry in the object header. + abort string("No PUB routines defined") + + ifnot link ' If we're not running the linker immediately after codegen, + if verbosity => 3 ' empty the .bin file if it exists(would be better to delete, + term.str( string("Zeroing ") ) ' but sxfs doesn't have that ability). If we forget to link, + term.str( @binFilename ) ' we'll get an error when we try to run the .bin. + term.out( 13 ) + + if fs.Open( @binFilename, "R" ) == 0 ' Check for existence + fs.Close + fs.Open( @binFilename, "W" ) + + fs.Close + + objBinSize := methods.get_pObjWork - methods.get_pObjSpace ' This gets stored in .sob header + word[methods.get_pObjSpace][0] := objBinSize ' This gets stored in object header + word[methods.get_pObjSpace][1] := nPubs + nPris + nObjs << 8 + + ' Compute checksum and hash + checksum~ + hash~ + p := methods.get_pObjSpace + repeat objBinSize + checksum += byte[p] + hash := (hash <- 1) ^ byte[p++] + + if verbosity => 2 + term.str( string("Writing ") ) + term.str( @outputFilename ) + term.out( 13 ) + + wordfill( @numExports, 0, 4 ) + ComputeSobInfo( bt.PeekW( st.GetPSymbolTable ) ) + + fs.Open( @outputFilename, "W" ) + fs.Write( @SobFileHeader, SIZEOFSOBHEADER ) + WriteExports( bt.PeekW( st.GetPSymbolTable ) ) + WriteImports + fs.Write( methods.get_pObjSpace, objBinSize ) + fs.Close + +pri FixupOffsets( p ) | s, t, v, size, headerSize, q +{{ + Goes through the symbol table and adjusts offsets of word VARs to put them after long VARs + and puts byte VARs after word VARs. + Also adjusts PRI method indexes so they come after PUBs, and OBJ indexes to put them after PRIs. + And now also adjusts DAT labels upward by the size of the object header. +}} + ifnot p + return + + FixupOffsets( bt.PeekW( p ) ) + + s := p + 4 + s += strsize(s) + 1 + if byte[s] == st#kVAR_SYMBOL ' var is followed by + ++s + size := byte[s++] ' 1-byte size (1, 2, 4) and 2-byte offset + t~ + if size == 2 + t := lvarSize ' word vars come after long vars + elseif size == 1 + t := lvarSize + wvarSize ' byte vars come after word vars + bt.PokeW( s, bt.PeekW(s) + t ) ' adjust var symbol's offset + elseif byte[s] == st#kPRI_SYMBOL + ++s + byte[s] += nPubs ' the PUBs are 1..nPubs-1, the PRIs are nPubs..nPubs+nPris-1 + elseif byte[s] == st#kOBJ_SYMBOL + ++s + byte[s][2] += nPubs + nPris ' the OBJs are nPubs+nPris.. + elseif byte[s] == st#kDAT_SYMBOL + headerSize := (nPubs + nPris + nObjs) << 2 + q := s ' start at global label + repeat ' and follow the linked list of local labels + bt.PokeW( q+2, bt.PeekW( q+2 ) + headerSize ) ' adjust label's dp + ifnot q := bt.PeekW( q+6 ) + quit + q += strsize(q) + 1 ' next in the list + + FixupOffsets( bt.PeekW( p + 2 ) ) + +{ +pri TraverseTable( p ) | s, t, v, q +{ + Symbol table dump. Call thusly: + TraverseTable( bt.PeekW( st.GetPSymbolTable ) ) +} + ifnot p + return + + TraverseTable( bt.PeekW( p ) ) + + s := p + 4 + term.str( s ) + s += strsize(s) + 1 + case t := byte[s++] + st#kINT_CON_SYMBOL: + v := bt.PeekL( s ) + term.out( "=" ) + term.dec( v ) + st#kPRI_SYMBOL, st#kPUB_SYMBOL: + if t == st#kPRI_SYMBOL + term.str( string(" pri: ") ) + else + term.str( string(" pub: ") ) + term.dec( byte[s++] ) ' method index + term.out( " " ) + term.dec( byte[s++] ) ' #params + st#kDAT_SYMBOL: + q := s-1 + repeat while q := bt.PeekW( q+6 ) + term.out(":") + term.str( q ) + q += strsize( q ) + 1 + term.str( string(" dat ") ) + case byte[s++] + 1: term.str( string("byte@") ) + 2: term.str( string("word@") ) + 4: term.str( string("long@") ) + term.hex( bt.PeekW(s), 4 ) + term.out(",") + term.hex( bt.PeekW(s+2), 4 ) + st#kVAR_SYMBOL: + term.str( string(" var ") ) + case byte[s++] + 1: term.str( string("byte@") ) + 2: term.str( string("word@") ) + 4: term.str( string("long@") ) + term.hex( bt.PeekW(s), 4 ) + st#kOBJ_SYMBOL: + term.out( ":" ) + term.str( bt.PeekW(s) ) + st#kSOB_SYMBOL: + term.out( ">" ) + term.hex( bt.PeekW(s), 4) + other: + term.out( "?" ) + term.hex( t, 2 ) + term.out( ";" ) + term.out( " " ) + + TraverseTable( bt.PeekW( p + 2 ) ) +} +con +SIZEOFSOBHEADER = 26 + +dat +SobFileHeader long + byte "SOB1" +timestamp long 0 +hash long 0 +numExports word 0 +exportSize word 0 +numImports word 0 +importSize word 0 +objBinSize word 0 +checksum byte 0 +{padding} byte 0 +varSize word 0 ' total size in bytes of vars (rounded up to multiple of 4) + + +pri ComputeSobInfo( p ) | pName, type +{{ + Traverses the symbol table and computes exportSize, numExports, importSize, numImports. + Initialize those variables to 0 before entering this routine. +}} + ifnot p + return + + pName := p + 4 + type := byte[pName + strsize(pName) + 1] + if type == st#kINT_CON_SYMBOL or type == st#kFLOAT_CON_SYMBOL + ++numExports + exportSize += strsize(pName) + 6 ' name + null + type + 4-byte value + elseif type == st#kPUB_SYMBOL + ++numExports + exportSize += strsize(pName) + 4 ' name + null + type + index + #args + elseif type == st#kOBJ_SYMBOL + pName := bt.PeekW( pName + strsize(pName) + 2 ) + ++numImports + importSize += strsize(pName) - 4 + 4 ' name (excluding ".SOB") + null + 2-byte count + reserved + + ComputeSobInfo( bt.PeekW( p ) ) + ComputeSobInfo( bt.PeekW( p + 2 ) ) + +pri WriteExports( p ) | pName, pData, type +{{ + Traverses the symbol table and writes exports to output file. +}} + ifnot p + return + + pName := p + 4 + pData := pName + strsize(pName) + 1 + type := byte[pData] + + if type == st#kINT_CON_SYMBOL or type == st#kFLOAT_CON_SYMBOL ' name + null + type + 4-byte value + fs.WriteString( pName ) + fs.WriteByte( type ) + fs.WriteLong( bt.PeekL( pData+1 ) ) + elseif type == st#kPUB_SYMBOL ' name + null + type + index + #args + fs.WriteString( pName ) + fs.WriteByte( type ) + fs.Write( pData+1, 2 ) ' index + #args + + WriteExports( bt.PeekW( p ) ) + WriteExports( bt.PeekW( p + 2 ) ) + +pri WriteImports | pName, pData, type +{{ + Traverses the OBJ list and writes imports to output file. + + We use a list so that the imports are written in the order they appear in the source. + This is important for OBJ symbols because we want the SOB imports to line up properly. +}} + pName := pObjList + repeat while pName + + pData := pName + strsize(pName) + 1 ' pName is name of symbol (e.g. "DEBUG") + ' pData points to symbol's data: 1-byte type + 2-byte pointer to SOB + 1-byte index + 2-byte count + 2-byte link + pName := bt.PeekW( pData + 1 ) ' pName is name of .sob file (e.g. "TV_TEXT.SOB") + fs.Write( pName, strsize(pName)-4 ) ' Write name but drop .SOB suffix. + fs.WriteByte( 0 ) ' Write null terminator + fs.WriteWord( bt.PeekW( pData + 4 ) ) ' Write count + fs.WriteByte( 0 ) ' Write reserved byte + + pName := bt.PeekW( pData + 6 ) ' link to next + +pri ParsePass1 + Eval.set_pass( 1 ) + InitDat + if verbosity => 2 + term.str( string("Pass 1") ) + term.out( 13 ) + ParseCon1 + repeat while token.Type <> kw#kEOF + ifnot token.IsBlockDesignator + abort string("Syntax error") + if token.Column + abort string("Block designator not in column 1") + if token.AdvanceIf( kw#kCON ) + ParseCon1 + elseif token.AdvanceIf( kw#kDAT ) + ParseDat1 + elseif token.AdvanceIf( kw#kOBJ ) + ParseObj1 + elseif token.AdvanceIf( kw#kPRI ) + ParseMethod1( st#kPRI_SYMBOL ) + elseif token.AdvanceIf( kw#kPUB ) + ParseMethod1( st#kPUB_SYMBOL ) + elseif token.AdvanceIf( kw#kVAR ) + ParseVar1 + else + abort string("Syntax error") + +pri ParsePass2 + Eval.set_pass( 2 ) + InitDat + if verbosity => 2 + term.str( string("Pass 2") ) + term.out( 13 ) + ParseCon2 + repeat while token.Type <> kw#kEOF + CheckStack + ifnot token.IsBlockDesignator + abort string("Syntax error") + if token.AdvanceIf( kw#kCON ) + ParseCon2 + elseif token.AdvanceIf( kw#kDAT ) + ParseDat2 + elseif token.AdvanceIf( kw#kOBJ ) + SkipBlock + elseif token.AdvanceIf( kw#kPRI ) + methods.Parse2( st#kPRI_SYMBOL ) + elseif token.AdvanceIf( kw#kPUB ) + methods.Parse2( st#kPUB_SYMBOL ) + elseif token.AdvanceIf( kw#kVAR ) + SkipBlock + else + abort string("Syntax error") + +pri SkipBlock + repeat until token.IsBlockDesignator or token.Type == kw#kEOF + token.Advance + +pri ParseCon1 | o, p, inc, v + o~ + token.AdvanceIf( kw#kEOL ) + repeat + inc := 1 + if token.AdvanceIf( kw#kOCTOTHORP ) + o := Eval.EvaluateExpression( 0 ) + elseif token.IsId ' Id +? + st.AddToTable( token.Text ) + byte[ p := bt.Alloc(1) ] := st#kINT_CON_SYMBOL ' p points to symbol type byte + ' in case we have to patch the type retroactively + token.Advance + if token.AdvanceIf( kw#kEQUAL ) ' Id = + v := Eval.TryToEvaluateExpression( 0 ) + if Eval.Succeeded + bt.PokeL( bt.Alloc(4), v ) + else ' it is undefined + byte[p] := st#kUNDEFINED_CON_SYMBOL + bt.Alloc(4) ' but we should allocate space for the eventual value. + elseif token.AdvanceIf( kw#kLBRACKET ) ' Id [ + inc := Eval.EvaluateExpression( 0 ) + token.Eat( kw#kRBRACKET ) + bt.PokeL( bt.Alloc(4), o ) + o += inc + else ' Plain Id + bt.PokeL( bt.Alloc(4), o ) + o += inc + else + quit + if token.Type == kw#kCOMMA or token.Type == kw#kEOL + token.Advance + else + abort string("Syntax error") + +pri ParseCon2 | o, p, inc + o~ + token.AdvanceIf( kw#kEOL ) + repeat + inc := 1 + if token.AdvanceIf( kw#kOCTOTHORP ) + o := Eval.EvaluateExpression( 0 ) + elseif token.IsId ' Id +? + p := st.SymbolLookup( token.Text ) + token.Advance + if token.AdvanceIf( kw#kEQUAL ) ' Id = + bt.PokeL( p+1, Eval.EvaluateExpression( 0 ) ) + byte[p] := st#kINT_CON_SYMBOL + elseif token.AdvanceIf( kw#kLBRACKET ) ' Id [ + inc := Eval.EvaluateExpression( 0 ) + token.Eat( kw#kRBRACKET ) + o += inc + else ' Plain Id + o += inc + else + quit + if token.Type == kw#kCOMMA or token.Type == kw#kEOL + token.Advance + else + abort string("Syntax error") + +var + word dp ' dp is the address in DAT space of current source line. + ' dp = pObjWork - pObjSpace + word ooo ' dp + ooo = cogx4; cogx4 / 4 = cog address of current source line. + word pGlobalLabel ' points to most-recently defined global label; used as the head of a linked list of local labels + byte alignment ' 1, 2, or 4 +{ + a DAT line consists of (in rough pseudo-bnf) one of the following: + 1) [label | :label] ORG|RES [ ] + 2) [label | :label] * (with commas between -- yeah, yeah, I said it was rough) + 3) [label | :label] [ ] , * + + As we process DAT statements and emit bytes, pDatWork increases, always pointing where the next byte will go. + dp = pDatWork - pObjSpace (i.e., dp 0 is the beginning of DAT space) + cogx4 = dp + ooo, where ooo is updated each time an ORG directive is encountered: + ooo = org_expression * 4 - dp + Example: + Let us say pObjSpace is 1000. The object header starts there. Say it takes up 100 bytes, so pDatWork is 1100. + In terms of DAT space, dp = 1100 - 1000 = 100. + Say there's an ORG 100, so ooo = 100 * 4 - 100 = 300. + A label defined at this point would have dp = 100, cogx4 = 100 + 300 = 400 (divide this by 4 to get cog address 100). + Suppose we assemble a PASM instruction and emit the four bytes. + Now pDatWork = 1104, dp = 104, and cogx4 = 104 + 300 = 404 (cog address 101). +} +pri InitDat + if Eval.get_pass == 1 + dp~ + ooo~ + else + ooo := methods.get_pObjSpace - pDatWork '= -dp + + pGlobalLabel~ + alignment := 1 + +pri ParseDat1 | pLabelData, p, v, size, count, dpInc, temp, cogx4 + Eval.EnteringDat + cogx4~ + repeat + pLabelData~ + if token.AdvanceIf( kw#kEOL ) + next + + if token.IsId ' label? + if byte[token.Text] == ":" ' local label? + ' Traverse the list of locals to check for duplicates + p := pGlobalLabel + repeat while p := bt.PeekW( p + 6 ) ' p points to string part of local label + if strcomp( p, token.Text ) + abort string("Duplicate local label") + p += strsize(p) + 1 ' Increment p past string part to data part + + p := bt.Alloc( strsize( token.Text ) + 9 ) ' p points to + str.Copy( p, token.Text ) ' local label's text followed by + pLabelData := p + strsize( token.Text ) + 1 ' 8 bytes of label data (to be filled in later) + byte[ pLabelData ] := st#kDAT_SYMBOL ' type + bt.PokeW( pLabelData+6, bt.PeekW(pGlobalLabel+6) ) ' pointer to local labels + ifnot pGlobalLabel + abort string("No preceding global label") + bt.PokeW( pGlobalLabel+6, p ) ' Insert this local label at head of list + + else ' plain old label + st.AddToTable( token.Text ) + pLabelData := bt.Alloc( 8 ) ' local label data + byte[ pLabelData ] := st#kDAT_SYMBOL ' type + bt.PokeW( pLabelData+6, 0 ) ' pointer to local labels + + pGlobalLabel := pLabelData + + token.Advance + + dpInc~ + if token.AdvanceIf( kw#kORG ) ' Case 1a: ORG [ ] + alignment := 4 + PadToAlignment + temp~ ' default ORG is 0 + if token.Type <> kw#kEOL + temp := Eval.EvaluateExpression( pGlobalLabel ) << 2 + ooo := temp - dp + cogx4 := dp + ooo + elseif token.AdvanceIf( kw#kRES ) ' Case 1b: RES [ ] + alignment := 4 + PadToAlignment + temp := 4 ' default RES is 1 long + if token.Type <> kw#kEOL + temp := Eval.EvaluateExpression( pGlobalLabel ) << 2 + cogx4 := dp + ooo + ooo += temp + elseif token.AdvanceIf( kw#kFIT ) + temp := 496 + if token.Type <> kw#kEOL + temp := Eval.EvaluateExpression( pGlobalLabel ) + if cogx4 > temp << 2 + abort string("Origin exceeds FIT limit") + elseif token.IsSize ' Case 2. BYTE/WORD/LONG * + alignment := |< (token.Type - kw#kBYTE) ' 1/2/4 + PadToAlignment + cogx4 := dp + ooo + token.Advance + if token.Type <> kw#kEOL + repeat + size := alignment + if token.IsSize + size := |< (token.Type - kw#kBYTE) ' 1/2/4 -- just size + token.Advance + v := Eval.TryToEvaluateExpression( pGlobalLabel ) + count := 1 + if token.AdvanceIf( kw#kLBRACKET ) + count := Eval.EvaluateExpression( pGlobalLabel ) + token.Eat( kw#kRBRACKET ) + dpInc += count * size + while token.AdvanceIf( kw#kCOMMA ) + elseif token.IsCond or token.IsPasm ' Case 3. [ ] + alignment := 4 + PadToAlignment + cogx4 := dp + ooo + dpInc := 4 + repeat + token.Advance + until token.Type == kw#kEOL + elseif token.Type <> kw#kEOL + abort string("Syntax error") + + if pLabelData ' Was a label defined on the current source line? + byte[pLabelData+1] := alignment ' data size + bt.PokeW( pLabelData+2, dp ) ' Address in DAT space + bt.PokeW( pLabelData+4, cogx4 ) ' Cog address x 4 + ' The local label linked list pointer was filled in previously + dp += dpInc + cogx4 += dpInc + + until token.IsBlockDesignator or token.Type == kw#kEOF + + datSize := dp + + Eval.LeavingDat + +pri ParseDat2 | pLabelData, p, v, size, count, temp, cond, pasmOp, ds, effect, oooInc + Eval.EnteringDat + oooInc~ + repeat + pLabelData~ + if token.AdvanceIf( kw#kEOL ) + next + + if token.IsId ' label? + if byte[token.Text] == ":" ' local label? + ' Traverse the list of locals to find this one. + p := pGlobalLabel + repeat while p := bt.PeekW( p + 6 ) ' p points to string part of local label + if strcomp( p, token.Text ) + quit + p += strsize(p) + 1 ' Increment p past string part to data part + pLabelData := p + strsize(p) + 1 + else ' plain old label + pLabelData := st.SymbolLookup( token.Text ) + pGlobalLabel := pLabelData + + token.Advance + + dp := pDatWork - methods.get_pObjSpace + + if token.AdvanceIf( kw#kORG ) ' Case 1: ORG + temp~ ' default ORG is 0 + alignment := 4 + PadToAlignment + if token.Type <> kw#kEOL + temp := Eval.EvaluateExpression( pGlobalLabel ) << 2 + ooo := temp - dp + elseif token.AdvanceIf( kw#kRES ) ' Case 1b: RES [ ] + alignment := 4 + PadToAlignment + oooInc := 4 ' default RES is 1 long + if token.Type <> kw#kEOL + oooInc := Eval.EvaluateExpression( pGlobalLabel ) << 2 + elseif token.AdvanceIf( kw#kFIT ) ' ignore FIT in pass 2 + if token.Type <> kw#kEOL + Eval.EvaluateExpression( pGlobalLabel ) + + elseif token.IsSize ' Case 2. BYTE/WORD/LONG * + alignment := |< (token.Type - kw#kBYTE) ' 1/2/4 + PadToAlignment + token.Advance + if token.Type == kw#kEOL + next + repeat + size := alignment + if token.IsSize + size := |< (token.Type - kw#kBYTE) ' 1/2/4 -- just size + token.Advance + v := Eval.EvaluateExpression( pGlobalLabel ) + count := 1 + if token.AdvanceIf( kw#kLBRACKET ) + count := Eval.EvaluateExpression( pGlobalLabel ) + token.Eat( kw#kRBRACKET ) + repeat count + temp := v + repeat size + EmitDat( temp ) + temp >>= 8 + while token.AdvanceIf( kw#kCOMMA ) + elseif token.IsCond or token.IsPasm + alignment := 4 + PadToAlignment + cond~~ + if token.IsCond + cond := token.GetCond + token.Advance + ifnot token.IsPasm + abort string("Expected PASM instruction") + ds := %11 + case token.Type + kw#kAND: pasmOp := $60bc0000 ' Special handling for double-duty PASM mnemonics + kw#kOR: pasmOp := $68bc0000 + kw#kWAITCNT: pasmOp := $f8bc0000 + kw#kWAITPEQ: pasmOp := $f03c0000 + kw#kWAITPNE: pasmOp := $f43c0000 + kw#kWAITVID: pasmOp := $fc3c0000 + kw#kCOGID: pasmOp := $0cfc0001 + ds := %10 + kw#kCOGINIT: pasmOp := $0c7c0002 + ds := %10 + kw#kCOGSTOP: pasmOp := $0cfc0003 + ds := %10 + kw#kCLKSET: pasmOp := $0c7c0000 + ds := %10 + other: + pasmOp := token.GetPasmOp + ds := token.GetPasmDS + + if token.Type == kw#kCALL ' special handling for CALL instruction + token.Advance + token.Eat( kw#kOCTOTHORP ) + ifnot token.IsId + abort string("Expected return label") + str.Copy( @stringBuffer, token.Text ) + str.Append( @stringBuffer, string("_RET") ) + ifnot p := st.SymbolLookup( @stringBuffer ) + abort string("Return label not found") + if byte[p] <> st#kDAT_SYMBOL + abort string("Non-DAT return label") + temp := bt.PeekW( p+4 ) + if temp & 3 + abort string("Return label is not long") + pasmOp |= ((temp >> 2 & $1ff) << 9) | (Eval.EvaluateExpression( pGlobalLabel ) & $1ff) ' combine destination and source + + else ' regular PASM instruction + token.Advance + if ds & %10 ' destination operand + pasmOp |= (Eval.EvaluateExpression( pGlobalLabel ) & $1ff) << 9 + if ds == %11 + token.Eat( kw#kCOMMA ) + if ds & %01 + if token.AdvanceIf( kw#kOCTOTHORP ) ' immediate? + pasmOp |= |< 22 ' set I + pasmOp |= Eval.EvaluateExpression( pGlobalLabel ) & $1ff ' source operand + + effect~ + if token.Type <> kw#kEOL + repeat + ifnot token.IsEffect + abort string("Expected PASM effect") + if token.GetEffect == 8 ' NR? + effect &= %110 ' clear R + else + effect |= token.GetEffect + token.Advance + while token.AdvanceIf( kw#kCOMMA ) + + if pasmOp == 0 and (cond <> -1 or effect ) + abort string("Conditions and effects not allowed on NOP") + + pasmOp |= (effect << 23) + if cond <> -1 + pasmOp := pasmOp & %111111_1111_0000_111111111_111111111 | (cond << 18) + + repeat 4 + EmitDat( pasmOp ) + pasmOp >>= 8 + + if pLabelData ' Was a label defined on the current source line? + if byte[pLabelData+1] <> alignment { data size +} or bt.PeekW( pLabelData+2 ) <> dp { Address in DAT space +} or bt.PeekW( pLabelData+4 ) <> dp + ~~ooo ' Cog address x 4 + term.dec(byte[pLabelData+1]) + term.out(" ") + term.dec(alignment) + term.out(13) + term.dec(bt.PeekW( pLabelData+2 )) + term.out(" ") + term.dec(dp) + term.out(13) + term.dec(bt.PeekW( pLabelData+4 )) + term.out(" ") + term.dec(dp+~~ooo) + abort string("Phase error") + + ooo += oooInc~ + + until token.IsBlockDesignator or token.Type == kw#kEOF + Eval.LeavingDat + +pri PadToAlignment + repeat (alignment - dp) & (alignment - 1) ' number of bytes needed to pad to new alignment + ++dp + if Eval.get_pass == 2 + EmitDat( 0 ) ' padding + +pri EmitDat( b ) + byte[pDatWork++] := b + +var + word pObjList ' OBJ symbols are linked together in a list. + word pObjListEnd ' Pointer to the last OBJ; append new OBJs at the end. + +pri ParseObj1 | i, count, pObj, pSob, pObjName +{{ + { [ ] } : +}} + token.AdvanceIf( kw#kEOL ) + repeat while token.IsId + pObjName := bt.Alloc( 0 ) + 4 ' Hacky way to get pointer to the name field of the symbol we're about to add. + st.AddToTable( token.Text ) + pObj := bt.Alloc( 8 ) ' type (1), ptr to sym table (2), index(1), count (2), ptr to next (2) + byte[pObj] := st#kOBJ_SYMBOL + + token.Advance + + count := 1 + if token.AdvanceIf( kw#kLBRACKET ) + count := Eval.EvaluateExpression( 0 ) + token.Eat( kw#kRBRACKET ) + + token.Eat( kw#kCOLON ) + + byte[pObj][3] := nObjs + nObjs += count + bt.PokeW( pObj+4, count ) + + ' Link this OBJ into the list of OBJs + if pObjListEnd ' this points to last OBJ name field + pObjListEnd += strsize(pObjListEnd)+1 ' now this points to OBJ data + bt.PokeW( pObjListEnd+6, pObjName ) ' make a link to new OBJ name field + + pObjListEnd := pObjName + bt.PokeW( pObj+6, 0 ) + + ifnot pObjList + pObjList := pObjName + + i~ + repeat + ifnot token.IsIntLiteral + abort string("Syntax error") + sobFilename[i++] := token.Value + if i > MAXFILENAMELENGTH-4 ' have to leave room for ".sob" suffix + abort string("SOB filename too long") + token.Advance + while token.AdvanceIf( kw#kCOMMA ) + + sobFilename[i]~ + str.ToUpper( @sobFilename ) + str.Append( @sobFilename, string(".SOB") ) + + ifnot pSob := st.SymbolLookup( @sobFilename ) + st.AddToTable( @sobFilename ) + byte[ pSob := bt.Alloc(3) ] := st#kSOB_SYMBOL ' type (1), ptr to sym table (2) + bt.PokeW( pSob+1, 0 ) + ReadSobFile( pSob+1 ) + bt.PokeW( pObj+1, pSob - strsize(@sobFilename) - 1 ) + + token.Eat( kw#kEOL ) + +con +SOBFILEFORMATVERSION = "S" + "O" << 8 + "B" << 16 + "1" << 24 ' "SOB1" + +pri ReadSobFile( pSobTable ) | p, t + if verbosity => 3 + term.str( string("Reading ") ) + term.str( @sobFilename ) + term.out( 13 ) + if fs.Open( @sobFilename, "R" ) <> 0 + term.str( @sobFilename ) + abort string(" -- couldn't open") + + if fs.Readlong <> SOBFILEFORMATVERSION ' SOB file format version + abort string("Unrecognized SOB file format") + fs.Readlong ' timestamp + fs.ReadLong ' hash + numExports := fs.ReadWord ' number of exports + exportSize := fs.ReadWord ' size of exports segment + fs.ReadWord ' number of imports + importSize := fs.ReadWord ' size of imports segment + fs.ReadWord ' size of bytecode segment + fs.ReadByte ' checksum + fs.ReadByte ' padding + fs.ReadWord ' size of sob's VAR space + + repeat numExports + fs.ReadStringUpperCase( @stringBuffer, MAXSTRINGBUFFERLENGTH ) + bt.AddToTable( @stringBuffer, pSobTable ) + case t := fs.ReadByte + st#kINT_CON_SYMBOL, st#kFLOAT_CON_SYMBOL: + p := bt.Alloc( 5 ) + byte[p++] := t + bt.PokeL( p, fs.ReadLong ) + st#kPUB_SYMBOL: + p := bt.Alloc( 3 ) + byte[p++] := t + byte[p++] := fs.ReadByte ' method index + byte[p++] := fs.ReadByte ' #params + + fs.Close + +pri ParseMethod1( type ) | nargs +' type = st#kPRI_SYMBOL or st#kPUB_SYMBOL + ifnot token.IsId + abort string("Expected ID") + st.AddToTable( token.Text ) + token.Advance + nargs~ + if token.AdvanceIf( kw#kLPAREN ) + repeat + ++nargs + ifnot token.IsId + abort string("Expected ID") + token.Advance + while token.AdvanceIf( kw#kCOMMA ) + token.Eat( kw#kRPAREN ) + if nargs > 255 + abort string("Too many parameters") + byte[ bt.Alloc(1) ] := type + if type == st#kPUB_SYMBOL + byte[ bt.Alloc(1) ] := nPubs++ + else + byte[ bt.Alloc(1) ] := nPris++ + byte[ bt.Alloc(1) ] := nargs + + SkipBlock + +var + word bvarSize ' size in bytes of byte var area + word wvarSize ' size in bytes of word var area + word lvarSize ' size in bytes of long var area + byte nPubs, nPris + word nObjs + word datSize ' size in bytes of DAT area + +pri ParseVar1 | s, t, dim + token.AdvanceIf( kw#kEOL ) + repeat while token.IsSize + if token.Type == kw#kBYTE + s~ + elseif token.Type == kw#kWORD + s := 1 + elseif token.Type == kw#kLONG + s := 2 + token.Advance + repeat + ifnot token.IsId + abort string("Expected ID") + st.AddToTable( token.Text ) + token.Advance + byte[ bt.Alloc(1) ] := st#kVAR_SYMBOL + byte[ bt.Alloc(1) ] := |< s + if token.AdvanceIf( kw#kLBRACKET ) + dim := Eval.EvaluateExpression( 0 ) + token.Eat( kw#kRBRACKET ) + else + dim := 1 + bt.PokeW( bt.Alloc(2), bvarSize[s] ) + bvarSize[s] += dim << s + while token.AdvanceIf( kw#kCOMMA ) + token.Eat( kw#kEOL ) + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} + \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx2/eval.spn b/zubehör/sphinx/spinx100225-ori/sphinx2/eval.spn new file mode 100644 index 0000000..7990199 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx2/eval.spn @@ -0,0 +1,216 @@ +obj + kw : "kwdefs" + token : "tokenrdr" + bt : "bintree" + st : "symbols" + +dat +pass byte 0 +insideDAT byte 0 +ignoreUndefined byte 0 +evalSuccess byte 0 +pGlobalLabel word 0 + +pub set_Pass( p ) + pass := p + +pub get_Pass + return pass + +pub EnteringDat + insideDAT~~ + +pub LeavingDat + insideDAT~ + +pub Succeeded + return evalSuccess + +pub TryToEvaluateExpression( _pGlobalLabel ) +{{ +}} + pGlobalLabel := _pGlobalLabel + ignoreUndefined~~ + evalSuccess~~ + return Evaluate( 13 ) + +pub EvaluateExpression( _pGlobalLabel ) + pGlobalLabel := _pGlobalLabel + ignoreUndefined~ + evalSuccess~~ + return Evaluate( 13 ) + +pri Evaluate( rbp ) | prec, lbp, t + prec := token.GetPrecedence + + if token.AdvanceIf( kw#kAT ) + result := EvaluateSymbol( true ) + elseif (token.IsUnaryOp and not token.IsPostfixOp) or token.Type == kw#kMINUS + t := token.Type + token.Advance + result := EvaluateUnary( t, prec ) + elseif token.AdvanceIf( kw#kLPAREN ) + result := Evaluate( 13 ) + token.Eat( kw#kRPAREN ) + elseif token.IsIntLiteral or token.IsFloatLiteral + result := token.Value + token.Advance + elseif token.IsReg + result := $1f0 + token.GetReg + token.Advance + else + result := EvaluateSymbol( false ) + + repeat + lbp := token.GetPrecedence + + if rbp =< lbp + quit + + t := token.Type + token.Advance + result := EvaluateBinary( t, result, Evaluate( lbp ) ) + +pri EvaluateSymbol( takeAddress ) | p, t, pObj, cogx4, pLocalLabels +{{ + CON symbols evaluate as their defined values, as do OBJ#constants. + DAT symbols evaluate differently depending on context. +}} + if byte[token.Text] == ":" ' local label? + ifnot pGlobalLabel + abort string("Unknown local label(1)") + + p := pGlobalLabel ' Search local label list for current token. + repeat + ifnot p := bt.PeekW( p + 6 ) ' p points to string part of local label + if ignoreUndefined + evalSuccess~ + token.Advance + return -1 ' dummy value + abort string("Unknown local label(2)") + if strcomp( p, token.Text ) + quit + p += strsize(p) + 1 ' Increment p past string part to data part + ' On exit, we've found the local label. + p += strsize(p) + 1 ' Increment p past string part to data part + + else + p := st.SymbolLookup( token.Text ) + ifnot p + if ignoreUndefined + evalSuccess~ + token.Advance + return -1 + abort string("Unknown symbol") + + t := byte[p] + + if t == st#kINT_CON_SYMBOL or t == st#kFLOAT_CON_SYMBOL or t == st#kBUILTIN_INT_SYMBOL or t == st#kBUILTIN_FLOAT_SYMBOL + ' TODO: should handle floats differently + if takeAddress + abort string("Can't take address of CON symbol") + token.Advance + return bt.PeekL( p+1 ) + if t == st#kUNDEFINED_CON_SYMBOL + if ignoreUndefined + evalSuccess~ + token.Advance + return -1 ' dummy value + abort string("Undefined CON symbol") + if t == st#kOBJ_SYMBOL + if takeAddress + abort string("Can't take address of OBJ symbol") + token.Advance + p := bt.PeekW( p+1 ) + pObj := bt.PeekW( p + strsize(p) + 2 ) + token.Eat( kw#kOCTOTHORP ) + ifnot p := bt.FindInTable( token.Text, pObj ) + abort string("CON symbol unknown in sub-object") + 't := byte[p] -- at this point, t should be either kINT_CON_SYMBOL or kFLOAT_CON_SYMBOL + ' TODO: should handle floats differently + token.Advance + return bt.PeekL( p+1 ) + + if t == st#kDAT_SYMBOL + if pass == 1 + if ignoreUndefined + evalSuccess~ + token.Advance + return -1 ' dummy value + if takeAddress + abort string("Can't take address of DAT symbol in pass 1") + if not insideDAT or takeAddress + token.Advance + return bt.PeekW( p+2 ) + + cogx4 := bt.PeekW( p+4 ) + if cogx4 & 3 + abort string("Address is not long") + token.Advance + return cogx4 >> 2 + + abort string("Invalid symbol in constant expression") + +pri EvaluateUnary( t, prec ) +{{ + +}} + result := Evaluate( prec ) + case t & $ff + $ed: -result + $e7: !result + $ff: not result + $f3: ||result + $f8: ^^result + $e9: ||result + other: abort string("Syntax error in constant expression(1)") + +pri EvaluateBinary( t, a, b ) + case t & $ff + $ec: return a + b + $ed: return a - b + $f4: return a * b + $f6: return a / b + $f5: return a ** b + $f7: return a // b + $e0: return a -> b + $e1: return a <- b + $e2: return a >> b + $e3: return a << b + $ee: return a ~> b + $ef: return a >< b + $e8: return a & b + $ea: return a | b + $eb: return a ^ b + $e4: return a #> b + $e5: return a <# b + $f9: return a < b + $fa: return a > b + $fc: return a == b + $fb: return a <> b + $fd: return a =< b + $fe: return a => b + $f0: return a and b + $f2: return a or b + other: abort string("Syntax error in constant expression(2)") + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} + \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx2/fltmath.spn b/zubehör/sphinx/spinx100225-ori/sphinx2/fltmath.spn new file mode 100644 index 0000000..4204f99 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx2/fltmath.spn @@ -0,0 +1,219 @@ +''*************************************** +''* Floating-Point Math * +''* Single-precision IEEE-754 * +''* Author: Chip Gracey * +''* Copyright (c) 2006 Parallax, Inc. * +''* See end of file for terms of use. * +''*************************************** + + +PUB FFloat(integer) : single | s, x, m + +''Convert integer to float + + if m := ||integer 'absolutize mantissa, if 0, result 0 + s := integer >> 31 'get sign + x := >|m - 1 'get exponent + m <<= 31 - x 'msb-justify mantissa + m >>= 2 'bit29-justify mantissa + + return Pack(@s) 'pack result + + +PUB FRound(single) : integer + +''Convert float to rounded integer + + return FInteger(single, 1) 'use 1/2 to round + + +PUB FTrunc(single) : integer + +''Convert float to truncated integer + + return FInteger(single, 0) 'use 0 to round + + +PUB FNeg(singleA) : single + +''Negate singleA + + return singleA ^ $8000_0000 'toggle sign bit + + +PUB FAbs(singleA) : single + +''Absolute singleA + + return singleA & $7FFF_FFFF 'clear sign bit + + +PUB FSqr(singleA) : single | s, x, m, root + +''Compute square root of singleA + + if singleA > 0 'if a =< 0, result 0 + + Unpack(@s, singleA) 'unpack input + + m >>= !x & 1 'if exponent even, shift mantissa down + x ~>= 1 'get root exponent + + root := $4000_0000 'compute square root of mantissa + repeat 31 + result |= root + if result ** result > m + result ^= root + root >>= 1 + m := result >> 1 + + return Pack(@s) 'pack result + + +PUB FAdd(singleA, singleB) : single | sa, xa, ma, sb, xb, mb + +''Add singleA and singleB + + Unpack(@sa, singleA) 'unpack inputs + Unpack(@sb, singleB) + + if sa 'handle mantissa negation + -ma + if sb + -mb + + result := ||(xa - xb) <# 31 'get exponent difference + if xa > xb 'shift lower-exponent mantissa down + mb ~>= result + else + ma ~>= result + xa := xb + + ma += mb 'add mantissas + sa := ma < 0 'get sign + ||ma 'absolutize result + + return Pack(@sa) 'pack result + + +PUB FSub(singleA, singleB) : single + +''Subtract singleB from singleA + + return FAdd(singleA, FNeg(singleB)) + + +PUB FMul(singleA, singleB) : single | sa, xa, ma, sb, xb, mb + +''Multiply singleA by singleB + + Unpack(@sa, singleA) 'unpack inputs + Unpack(@sb, singleB) + + sa ^= sb 'xor signs + xa += xb 'add exponents + ma := (ma ** mb) << 3 'multiply mantissas and justify + + return Pack(@sa) 'pack result + + +PUB FDiv(singleA, singleB) : single | sa, xa, ma, sb, xb, mb + +''Divide singleA by singleB + + Unpack(@sa, singleA) 'unpack inputs + Unpack(@sb, singleB) + + sa ^= sb 'xor signs + xa -= xb 'subtract exponents + + repeat 30 'divide mantissas + result <<= 1 + if ma => mb + ma -= mb + result++ + ma <<= 1 + ma := result + + return Pack(@sa) 'pack result + + +PRI FInteger(a, r) : integer | s, x, m + +'Convert float to rounded/truncated integer + + Unpack(@s, a) 'unpack input + + if x => -1 and x =< 30 'if exponent not -1..30, result 0 + m <<= 2 'msb-justify mantissa + m >>= 30 - x 'shift down to 1/2-lsb + m += r 'round (1) or truncate (0) + m >>= 1 'shift down to lsb + if s 'handle negation + -m + return m 'return integer + + +PRI Unpack(pointer, single) | s, x, m + +'Unpack floating-point into (sign, exponent, mantissa) at pointer + + s := single >> 31 'unpack sign + x := single << 1 >> 24 'unpack exponent + m := single & $007F_FFFF 'unpack mantissa + + if x 'if exponent > 0, + m := m << 6 | $2000_0000 '..bit29-justify mantissa with leading 1 + else + result := >|m - 23 'else, determine first 1 in mantissa + x := result '..adjust exponent + m <<= 7 - result '..bit29-justify mantissa + + x -= 127 'unbias exponent + + longmove(pointer, @s, 3) 'write (s,x,m) structure from locals + + +PRI Pack(pointer) : single | s, x, m + +'Pack floating-point from (sign, exponent, mantissa) at pointer + + longmove(@s, pointer, 3) 'get (s,x,m) structure into locals + + if m 'if mantissa 0, result 0 + + result := 33 - >|m 'determine magnitude of mantissa + m <<= result 'msb-justify mantissa without leading 1 + x += 3 - result 'adjust exponent + + m += $00000100 'round up mantissa by 1/2 lsb + if not m & $FFFFFF00 'if rounding overflow, + x++ '..increment exponent + + x := x + 127 #> -23 <# 255 'bias and limit exponent + + if x < 1 'if exponent < 1, + m := $8000_0000 + m >> 1 '..replace leading 1 + m >>= -x '..shift mantissa down by exponent + x~ '..exponent is now 0 + + return s << 31 | x << 23 | m >> 9 'pack result + +{{ + ++------------------------------------------------------------------------------------------------------------------------------+ +¦ TERMS OF USE: MIT License ¦ ++------------------------------------------------------------------------------------------------------------------------------¦ +¦Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation ¦ +¦files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, ¦ +¦modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software¦ +¦is furnished to do so, subject to the following conditions: ¦ +¦ ¦ +¦The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.¦ +¦ ¦ +¦THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE ¦ +¦WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ¦ +¦COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ¦ +¦ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ¦ ++------------------------------------------------------------------------------------------------------------------------------+ +}} \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx2/fltstr.spn b/zubehör/sphinx/spinx100225-ori/sphinx2/fltstr.spn new file mode 100644 index 0000000..b997b59 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx2/fltstr.spn @@ -0,0 +1,534 @@ +''***************************************** +''* Floating-Point <-> Strings v 1.2 * +''* Single-precision IEEE-754 * +''* Authors: Chip Gracey and Cam Thompson * +''* (C) 2006 Parallax, Inc. * +''* See end of file for terms of use. * +''***************************************** + +'' v1.0 - 01 May 2006 - original version +'' v1.1 - 12 Jul 2006 - added FloatToFormat routine +'' v1.2 - 06 Mar 2009 - added StringToFloat [mpark] +VAR + + long p, digits, exponent, integer, tens, zeros, precision + long positive_chr, decimal_chr, thousands_chr, thousandths_chr + byte float_string[20] + + +OBJ + ' The F object can be FloatMath, Float32 or Float32Full depending on the application + F : "FltMath" + +PUB FloatToString(Single) : StringPtr + +''Convert floating-point number to string +'' +'' entry: +'' Single = floating-point number +'' +'' exit: +'' StringPtr = pointer to resultant z-string +'' +'' Magnitudes below 1e+12 and within 1e-12 will be expressed directly; +'' otherwise, scientific notation will be used. +'' +'' examples results +'' ----------------------------------------- +'' FloatToString(0.0) "0" +'' FloatToString(1.0) "1" +'' FloatToString(-1.0) "-1" +'' FloatToString(^^2.0) "1.414214" +'' FloatToString(2.34e-3) "0.00234" +'' FloatToString(-1.5e-5) "-0.000015" +'' FloatToString(2.7e+6) "2700000" +'' FloatToString(1e11) "100000000000" +'' FloatToString(1e12) "1.000000e+12" +'' FloatToString(1e-12) "0.000000000001" +'' FloatToString(1e-13) "1.000000e-13" + + 'perform initial setup + StringPtr := Setup(Single) + + 'eliminate trailing zeros + if integer + repeat until integer // 10 + integer /= 10 + tens /= 10 + digits-- + else + digits~ + + 'express number according to exponent + case exponent + 'in range left of decimal + 11..0: + AddDigits(exponent + 1) + 'in range right of decimal + -1..digits - 13: + zeros := -exponent + AddDigits(1) + 'out of range, do scientific notation + other: + DoScientific + + 'terminate z-string + byte[p]~ + + +PUB FloatToScientific(Single) : StringPtr + +''Convert floating-point number to scientific-notation string +'' +'' entry: +'' Single = floating-point number +'' +'' exit: +'' StringPtr = pointer to resultant z-string +'' +'' examples results +'' ------------------------------------------------- +'' FloatToScientific(1e-9) "1.000000e-9" +'' FloatToScientific(^^2.0) "1.414214e+0" +'' FloatToScientific(0.00251) "2.510000e-3" +'' FloatToScientific(-0.0000150043) "-1.500430e-5" + + 'perform initial setup + StringPtr := Setup(Single) + + 'do scientific notation + DoScientific + + 'terminate z-string + byte[p]~ + + +PUB FloatToMetric(Single, SuffixChr) : StringPtr | x, y + +''Convert floating-point number to metric string +'' +'' entry: +'' Single = floating-point number +'' SuffixChr = optional ending character (0=none) +'' +'' exit: +'' StringPtr = pointer to resultant z-string +'' +'' Magnitudes within the metric ranges will be expressed in metric +'' terms; otherwise, scientific notation will be used. +'' +'' range name symbol +'' ----------------------- +'' 1e24 yotta Y +'' 1e21 zetta Z +'' 1e18 exa E +'' 1e15 peta P +'' 1e12 tera T +'' 1e9 giga G +'' 1e6 mega M +'' 1e3 kilo k +'' 1e0 - - +'' 1e-3 milli m +'' 1e-6 micro u +'' 1e-9 nano n +'' 1e-12 pico p +'' 1e-15 femto f +'' 1e-18 atto a +'' 1e-21 zepto z +'' 1e-24 yocto y +'' +'' examples results +'' ------------------------------------ +'' metric(2000.0, "m") "2.000000km" +'' metric(-4.5e-5, "A") "-45.00000uA" +'' metric(2.7e6, 0) "2.700000M" +'' metric(39e31, "W") "3.9000e+32W" + + 'perform initial setup + StringPtr := Setup(Single) + + 'determine thousands exponent and relative tens exponent + x := (exponent + 45) / 3 - 15 + y := (exponent + 45) // 3 + + 'if in metric range, do metric + if ||x =< 8 + 'add digits with possible decimal + AddDigits(y + 1) + 'if thousands exponent not 0, add metric indicator + if x + byte[p++] := " " + byte[p++] := metric[x] + 'if out of metric range, do scientific notation + else + DoScientific + + 'if SuffixChr not 0, add SuffixChr + if SuffixChr + byte[p++] := SuffixChr + + 'terminate z-string + byte[p]~ + + +PUB FloatToFormat(single, width, dp) : stringptr | n, w2 + +''Convert floating-point number to formatted string +'' +'' entry: +'' Single = floating-point number +'' width = width of field +'' dp = number of decimal points +'' +'' exit: +'' StringPtr = pointer to resultant z-string +'' +'' asterisks are displayed for format errors +'' leading blank fill is used + + ' get string pointer + stringptr := p := @float_string + + ' width must be 1 to 9, dp must be 0 to width-1 + w2 := width := width #> 1 <# 9 + dp := dp #> 0 <# (width - 2) + if dp > 0 + w2-- + if single & $8000_0000 or positive_chr + w2-- + + ' get positive scaled integer value + n := F.FRound(F.FMul(single & $7FFF_FFFF , F.FFloat(teni[dp]))) + + if n => teni[w2] + ' if format error, display asterisks + repeat while width + if --width == dp + if decimal_chr + byte[p++] := decimal_chr + else + byte[p++] := "." + else + byte[p++] := "*" + byte[p]~ + + else + ' store formatted number + p += width + byte[p]~ + + repeat width + byte[--p] := n // 10 + "0" + n /= 10 + if --dp == 0 + if decimal_chr + byte[--p] := decimal_chr + else + byte[--p] := "." + if n == 0 and dp < 0 + quit + + ' store sign + if single & $80000000 + byte[--p] := "-" + elseif positive_chr + byte[--p] := positive_chr + ' leading blank fill + repeat while p <> stringptr + byte[--p] := " " + +PUB SetPrecision(NumberOfDigits) + +''Set precision to express floating-point numbers in +'' +'' NumberOfDigits = Number of digits to round to, limited to 1..7 (7=default) +'' +'' examples results +'' ------------------------------- +'' SetPrecision(1) "1e+0" +'' SetPrecision(4) "1.000e+0" +'' SetPrecision(7) "1.000000e+0" + + precision := NumberOfDigits + + +PUB SetPositiveChr(PositiveChr) + +''Set lead character for positive numbers +'' +'' PositiveChr = 0: no character will lead positive numbers (default) +'' non-0: PositiveChr will lead positive numbers (ie " " or "+") +'' +'' examples results +'' ---------------------------------------- +'' SetPositiveChr(0) "20.07" "-20.07" +'' SetPositiveChr(" ") " 20.07" "-20.07" +'' SetPositiveChr("+") "+20.07" "-20.07" + + positive_chr := PositiveChr + + +PUB SetDecimalChr(DecimalChr) + +''Set decimal point character +'' +'' DecimalChr = 0: "." will be used (default) +'' non-0: DecimalChr will be used (ie "," for Europe) +'' +'' examples results +'' ---------------------------- +'' SetDecimalChr(0) "20.49" +'' SetDecimalChr(",") "20,49" + + decimal_chr := DecimalChr + + +PUB SetSeparatorChrs(ThousandsChr, ThousandthsChr) + +''Set thousands and thousandths separator characters +'' +'' ThousandsChr = +'' 0: no character will separate thousands (default) +'' non-0: ThousandsChr will separate thousands +'' +'' ThousandthsChr = +'' 0: no character will separate thousandths (default) +'' non-0: ThousandthsChr will separate thousandths +'' +'' examples results +'' ----------------------------------------------------------- +'' SetSeparatorChrs(0, 0) "200000000" "0.000729345" +'' SetSeparatorChrs(0, "_") "200000000" "0.000_729_345" +'' SetSeparatorChrs(",", 0) "200,000,000" "0.000729345" +'' SetSeparatorChrs(",", "_") "200,000,000" "0.000_729_345" + + thousands_chr := ThousandsChr + thousandths_chr := ThousandthsChr + + +PUB StringToFloat(strptr) : flt | significand, ssign, places, exp, esign +{{ + Converts string to floating-point number + entry: + strptr = pointer to z-string + + exit: + flt = floating-point number + + + Assumes the following floating-point syntax: [-] [0-9]* [ . [0-9]* ] [ e|E [-|+] [0-9]* ] + +-- +----- +----------- +------------------- + ¦ ¦ ¦ ¦ +---- +----- + Optional negative sign --------------------+ ¦ ¦ ¦ ¦ ¦ + Digits ----------------------------------------+ ¦ ¦ ¦ ¦ + Optional decimal point followed by digits ------------+ ¦ ¦ ¦ + Optional exponent -------------------------------------------------+ ¦ ¦ + optional exponent sign ------------------------------------------------+ ¦ + exponent digits -------------------------------------------------------------+ + + Examples of recognized floating-point numbers: + "123", "-123", "123.456", "123.456e+09" + Conversion stops as soon as an invalid character is encountered. No error-checking. + + Based on Ariba's StrToFloat in http://forums.parallax.com/forums/default.aspx?f=25&m=280607 + Expanded by Michael Park +}} + significand~ + ssign~ + exp~ + esign~ + places~ + repeat + case byte[strptr] + "-": + ssign~~ + ".": + places := 1 + "0".."9": + significand := significand * 10 + byte[strptr] - "0" + if places + ++places 'count decimal places + "e", "E": + ++strptr ' skip over the e or E + repeat + case byte[strptr] + "+": + ' ignore + "-": + esign~~ + "0".."9": + exp := exp * 10 + byte[strptr] - "0" + other: + quit + ++strptr + quit + other: + quit + ++strptr + + if ssign + -significand + flt := f.FFloat(significand) + + ifnot esign ' tenf table is in decreasing order, so the sign of exp is reversed + -exp + + if places + exp += places - 1 + + flt := f.FMul(flt, tenf[exp]) 'adjust flt's decimal point + + +PRI Setup(single) : stringptr + + 'limit digits to 1..7 + if precision + digits := precision #> 1 <# 7 + else + digits := 7 + + 'initialize string pointer + p := @float_string + + 'add "-" if negative + if single & $80000000 + byte[p++] := "-" + 'otherwise, add any positive lead character + elseif positive_chr + byte[p++] := positive_chr + + 'clear sign and check for 0 + if single &= $7FFFFFFF + + 'not 0, estimate exponent + exponent := ((single << 1 >> 24 - 127) * 77) ~> 8 + + 'if very small, bias up + if exponent < -32 + single := F.FMul(single, 1e13) + exponent += result := 13 + + 'determine exact exponent and integer + repeat + integer := F.FRound(F.FMul(single, tenf[exponent - digits + 1])) + if integer < teni[digits - 1] + exponent-- + elseif integer => teni[digits] + exponent++ + else + exponent -= result + quit + + 'if 0, reset exponent and integer + else + exponent~ + integer~ + + 'set initial tens and clear zeros + tens := teni[digits - 1] + zeros~ + + 'return pointer to string + stringptr := @float_string + + +PRI DoScientific + + 'add digits with possible decimal + AddDigits(1) + 'add exponent indicator + byte[p++] := "e" + 'add exponent sign + if exponent => 0 + byte[p++] := "+" + else + byte[p++] := "-" + ||exponent + 'add exponent digits + if exponent => 10 + byte[p++] := exponent / 10 + "0" + exponent //= 10 + byte[p++] := exponent + "0" + + +PRI AddDigits(leading) | i + + 'add leading digits + repeat i := leading + AddDigit + 'add any thousands separator between thousands + if thousands_chr + i-- + if i and not i // 3 + byte[p++] := thousands_chr + 'if trailing digits, add decimal character + if digits + AddDecimal + 'then add trailing digits + repeat while digits + 'add any thousandths separator between thousandths + if thousandths_chr + if i and not i // 3 + byte[p++] := thousandths_chr + i++ + AddDigit + + +PRI AddDigit + + 'if leading zeros, add "0" + if zeros + byte[p++] := "0" + zeros-- + 'if more digits, add current digit and prepare next + elseif digits + byte[p++] := integer / tens + "0" + integer //= tens + tens /= 10 + digits-- + 'if no more digits, add "0" + else + byte[p++] := "0" + + +PRI AddDecimal + + if decimal_chr + byte[p++] := decimal_chr + else + byte[p++] := "." + + +DAT + long 1e+38, 1e+37, 1e+36, 1e+35, 1e+34, 1e+33, 1e+32, 1e+31 + long 1e+30, 1e+29, 1e+28, 1e+27, 1e+26, 1e+25, 1e+24, 1e+23, 1e+22, 1e+21 + long 1e+20, 1e+19, 1e+18, 1e+17, 1e+16, 1e+15, 1e+14, 1e+13, 1e+12, 1e+11 + long 1e+10, 1e+09, 1e+08, 1e+07, 1e+06, 1e+05, 1e+04, 1e+03, 1e+02, 1e+01 +tenf long 1e+00, 1e-01, 1e-02, 1e-03, 1e-04, 1e-05, 1e-06, 1e-07, 1e-08, 1e-09 + long 1e-10, 1e-11, 1e-12, 1e-13, 1e-14, 1e-15, 1e-16, 1e-17, 1e-18, 1e-19 + long 1e-20, 1e-21, 1e-22, 1e-23, 1e-24, 1e-25, 1e-26, 1e-27, 1e-28, 1e-29 + long 1e-30, 1e-31, 1e-32, 1e-33, 1e-34, 1e-35, 1e-36, 1e-37, 1e-38 + +teni long 1, 10, 100, 1_000, 10_000, 100_000, 1_000_000, 10_000_000, 100_000_000, 1_000_000_000 + + byte "yzafpnum" +metric byte 0 + byte "kMGTPEZY" + +{{ ++------------------------------------------------------------------------------------------------------------------------------+ +¦ TERMS OF USE: MIT License ¦ ++------------------------------------------------------------------------------------------------------------------------------¦ +¦Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation ¦ +¦files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, ¦ +¦modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software¦ +¦is furnished to do so, subject to the following conditions: ¦ +¦ ¦ +¦The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.¦ +¦ ¦ +¦THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE ¦ +¦WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ¦ +¦COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ¦ +¦ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ¦ ++------------------------------------------------------------------------------------------------------------------------------+ +}} \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx2/isxfs.spn b/zubehör/sphinx/spinx100225-ori/sphinx2/isxfs.spn new file mode 100644 index 0000000..661adbe --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx2/isxfs.spn @@ -0,0 +1,80 @@ +SXTVRENDEZVOUS = $8000 - 4 +SXKBRENDEZVOUS = SXTVRENDEZVOUS - 4 +SDSPIRENDEZVOUS = SXKBRENDEZVOUS - 3 * 4 +SXFS2RENDEZVOUS = SDSPIRENDEZVOUS - 4 * 4 ' four rendezvous variables +SXFSRENDEZVOUS = SXFS2RENDEZVOUS - 4 * 4 ' four rendezvous variables +METADATABUFFER = SXFSRENDEZVOUS - 512 + +_free = ($8000 - METADATABUFFER) / 4 + +SIZEOFFILESTUFF = 512 + 24 + +pCommand = SXFSRENDEZVOUS +pParam0 = pCommand+4 +pParam1 = pCommand+8 +pParam2 = pCommand+12 + +pub Open( pFilestuff, pFilename, mode ) | filenameBuffer[3], p, i +{{ + mode is either "R" or "W". + Returns 0 on success, 1 if file not found (and opening for reading). +}} + return Command( "O", pFilestuff, pFilename, mode ) + +pub Close( pFilestuff ) + Command( "C", pFilestuff, 0, 0 ) + +pub Read( pFilestuff, pBuffer, nBytes ) +{{ + Returns number of bytes actually read, -1 at EOF. +}} + long[pParam0] := pFilestuff + long[pParam1] := pBuffer + long[pParam2] := nBytes + + long[pCommand] := "R" + repeat while long[pCommand] + if long[pParam0] < -2 ' don't abort for return code -1. + abort long[pParam0] + return long[pParam0] + +pub Write( pFilestuff, pBuffer, nBytes ) + return Command( "W", pFilestuff, pBuffer, nBytes ) + +pub Execute( pFilestuff, execmode ) +{{ + If execmode is non-0, all cogs are stopped except Spin interpreter. + If execmode is 0, running cogs are left running. +}} + Command( "X", pFilestuff, execmode, cogid ) + +pub Command( cmd, param0, param1, param2 ) + long[pParam0] := param0 + long[pParam1] := param1 + long[pParam2] := param2 + + long[pCommand] := cmd + repeat while long[pCommand] + if long[pParam0] < 0 + abort long[pParam0] + return long[pParam0] + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} + \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx2/isxtv.spn b/zubehör/sphinx/spinx100225-ori/sphinx2/isxtv.spn new file mode 100644 index 0000000..ed79757 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx2/isxtv.spn @@ -0,0 +1,96 @@ +''This file is an excerpt of tv.spin. Copyright and license are from tv.spin. +''*************************************** +''* TV Driver v1.1 * +''* Author: Chip Gracey * +''* Copyright (c) 2004 Parallax, Inc. * +''* See end of file for terms of use. * +''*************************************** + +'' Modified for Sphinx by Michael Park + + +SXTVRENDEZVOUS = $8000 - 4 + +PUB GetBasepin + repeat while long[SXTVRENDEZVOUS] + long[SXTVRENDEZVOUS]~~ ' ping the sxtv cog (send -1) + repeat while long[SXTVRENDEZVOUS] == -1 + return long[SXTVRENDEZVOUS]~ >> 8 + +PUB str(stringptr) + +'' Print a zero-terminated string + + repeat strsize(stringptr) + out(byte[stringptr++]) + + +PUB dec(value) | i + +'' Print a decimal number + + if value < 0 + -value + out("-") + + i := 1_000_000_000 + + repeat 10 + if value => i + out(value / i + "0") + value //= i + result~~ + elseif result or i == 1 + out("0") + i /= 10 + + +PUB hex(value, digits) + +'' Print a hexadecimal number + + value <<= (8 - digits) << 2 + repeat digits + out(lookupz((value <-= 4) & $F : "0".."9", "A".."F")) + + +PUB bin(value, digits) + +'' Print a binary number + + value <<= 32 - digits + repeat digits + out((value <-= 1) & 1 + "0") + + +pub out(ch) + repeat while long[SXTVRENDEZVOUS] + long[SXTVRENDEZVOUS] := ch + +pub Ping + out( -1 ) + +pub Enable + out( "E"<<8 ) + +pub Disable + out( "D"<<8 ) + +{{ ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} + \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx2/keywords.spn b/zubehör/sphinx/spinx100225-ori/sphinx2/keywords.spn new file mode 100644 index 0000000..612a0e4 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx2/keywords.spn @@ -0,0 +1,530 @@ +obj + bt: "bintree" + +pub Init + + tableStart += @tableStart + FixupTable( @tableStart + 2 ) + +pri FixupTable( p ) | q + q := bt.PeekW( p ) + if q + bt.PokeW( p, q += @tableStart ) + FixupTable( q ) + q := bt.PeekW( p + 2 ) + if q + bt.PokeW( p + 2, q += @tableStart ) + FixupTable( q ) + +pub KeywordLookup( s ) + return bt.FindInTable( s, tableStart ) + +con +{ + 31 (plain ID) + 30 (int literal) + 29 (float literal) + 28 ? + 27 unary + 26 binary/postfix + 25 pasm (TJZ, XOR) + 24 cond (IF_Z, IF_E) + 23 effect (WC, WZ) + 22 stmtfn (BYTEMOVE, WAITCNT) + 21 assignment op (-=, OR=) + 20 intrinsic + 19 prec3 + 18 prec2 + 17 d prec1 + 16 s prec0 + 15 pasmop spinop7 + 14 pasmop spinop6 + 13 pasmop spinop5 keyword + 12 pasmop spinop4 uniquifier + 11 pasmop spinop3 bits + 10 pasmop spinop2 | + 9 pasmop spinop1 | #args + 8 pasmop spinop0 V #args + 7 pasmop spinop7 id7 op + 6 pasmop spinop6 id6 op + 5 pasmop spinop5 id5 op + 4 pasmop spinop4 id4 op + 3 pasmop spinop3 cond3 id3 effect op + 2 pasmop spinop2 cond2 id2 effect op + 1 pasmop spinop1 cond1 id1 effect op + 0 pasmop spinop0 cond0 id0 effect op +} +con ' The following is auto-generated. Do not edit. + kID = $80000000 + kINTLITERAL = $40000000 + kFLOATLITERAL = $20000000 + kUNARY = $08000000 + kBINARY = $04000000 + kPOSTFIX = $04000000 + kPASM = $02000000 + kCOND = $01000000 + kEFFECT = $00800000 + kSTMTFN = $00400000 + kASSIGNMENT = $00200000 + kINTRINSIC = $00100000 + +' kBANG = $080100e7 +' kOCTOTHORPRANGLE = $040700e4 +' kAMPERSAND = $040300e8 +' kSTAR = $040500f4 +' kSTARSTAR = $040500f5 + kPLUS = $040600ec +' kPLUSPLUS = $0c002820 + kMINUS = $040600ed +' kMINUSMINUS = $0c003830 +' kMINUSRANGLE = $040200e0 +' kSLASH = $040500f6 +' kSLASHSLASH = $040500f7 +' kLANGLE = $040800f9 +' kLANGLEOCTOTHORP = $040700e5 +' kLANGLEMINUS = $040200e1 +' kLANGLELANGLE = $040200e3 +' kLANGLERANGLE = $040800fb +' kEQUALLANGLE = $040800fd +' kEQUALEQUAL = $040800fc +' kEQUALRANGLE = $040800fe +' kRANGLE = $040800fa +' kRANGLELANGLE = $040200ef +' kRANGLERANGLE = $040200e2 +' kRANGLEBAR = $080100f1 + kQUESTION = $0c000c08 + kAT = $08000000 + kATAT = $08000001 +' kCARET = $040400eb +' kCARETCARET = $080100f8 + kBAR = $040400ea +' kBARLANGLE = $080100f3 +' kBARBAR = $080100e9 + kTILDE = $0c001810 +' kTILDERANGLE = $040200ee + kTILDETILDE = $0c001c14 + kAND = $060a00f0 +' kNOT = $080900ff + kOR = $060b00f2 +' kABS = $0203a8bc +' kABSNEG = $0203acbc +' kADD = $020380bc +' kADDABS = $020388bc +' kADDS = $0203d0bc +' kADDSX = $0203d8bc +' kADDX = $0203c8bc +' kANDN = $020364bc + kCALL = $02015cfc +' kCMP = $0203843c +' kCMPS = $0203c03c +' kCMPSUB = $0203e0bc +' kCMPSX = $0203c43c +' kCMPX = $0203cc3c +' kDJNZ = $0203e4bc +' kHUBOP = $02030c3c +' kJMP = $02015c3c +' kJMPRET = $02035cbc +' kMAX = $02034cbc +' kMAXS = $020344bc +' kMIN = $020348bc +' kMINS = $020340bc +' kMOV = $0203a0bc +' kMOVD = $020354bc +' kMOVI = $020358bc +' kMOVS = $020350bc +' kMUXC = $020370bc +' kMUXNC = $020374bc +' kMUXNZ = $02037cbc +' kMUXZ = $020378bc +' kNEG = $0203a4bc +' kNEGC = $0203b0bc +' kNEGNC = $0203b4bc +' kNEGNZ = $0203bcbc +' kNEGZ = $0203b8bc +' kNOP = $02000000 +' kRCL = $020334bc +' kRCR = $020330bc +' kRDBYTE = $020300bc +' kRDLONG = $020308bc +' kRDWORD = $020304bc +' kRET = $02005c7c +' kREV = $02033cbc +' kROL = $020324bc +' kROR = $020320bc +' kSAR = $020338bc +' kSHL = $02032cbc +' kSHR = $020328bc +' kSUB = $020384bc +' kSUBABS = $02038cbc +' kSUBS = $0203d4bc +' kSUBSX = $0203dcbc +' kSUBX = $0203ccbc +' kSUMC = $020390bc +' kSUMNC = $020394bc +' kSUMNZ = $02039cbc +' kSUMZ = $020398bc +' kTEST = $0203603c +' kTJNZ = $0203e83c +' kTJZ = $0203ec3c +' kWRBYTE = $0203003c +' kWRLONG = $0203083c +' kWRWORD = $0203043c +' kXOR = $02036cbc + kPAR = $00000001 +' kCNT = $00000002 +' kINA = $00000003 +' kINB = $00000004 +' kOUTA = $00000005 +' kOUTB = $00000006 +' kDIRA = $00000007 +' kDIRB = $00000008 +' kCTRA = $00000009 +' kCTRB = $0000000a +' kFRQA = $0000000b +' kFRQB = $0000000c +' kPHSA = $0000000d +' kPHSB = $0000000e +' kVCFG = $0000000f + kVSCL = $00000010 +' kIF_A = $01000001 +' kIF_AE = $01000003 +' kIF_ALWAYS = $0100000f +' kIF_B = $0100000c +' kIF_BE = $0100000e +' kIF_C = $0100000c +' kIF_C_AND_NZ = $01000004 +' kIF_C_AND_Z = $01000008 +' kIF_C_EQ_Z = $01000009 +' kIF_C_NE_Z = $01000006 +' kIF_C_OR_NZ = $0100000d +' kIF_C_OR_Z = $0100000e +' kIF_E = $0100000a +' kIF_NC = $01000003 +' kIF_NC_AND_NZ = $01000001 +' kIF_NC_AND_Z = $01000002 +' kIF_NC_OR_NZ = $01000007 +' kIF_NC_OR_Z = $0100000b +' kIF_NE = $01000005 +' kIF_NEVER = $01000000 +' kIF_NZ = $01000005 +' kIF_NZ_AND_C = $01000004 +' kIF_NZ_AND_NC = $01000001 +' kIF_NZ_OR_C = $0100000e +' kIF_NZ_OR_NC = $0100000b +' kIF_Z = $0100000a +' kIF_Z_AND_C = $01000008 +' kIF_Z_AND_NC = $01000002 +' kIF_Z_EQ_C = $01000009 +' kIF_Z_NE_C = $01000006 +' kIF_Z_OR_C = $0100000e +' kIF_Z_OR_NC = $0100000b +' kNR = $00800008 +' kWC = $00800002 +' kWR = $00800001 +' kWZ = $00800004 + kCON = $00000011 + kDAT = $00000012 + kOBJ = $00000013 + kPRI = $00000014 + kPUB = $00000015 + kVAR = $00000016 + kBYTE = $00000017 + kWORD = $00000018 + kLONG = $00000019 +' kBYTEFILL = $00400318 +' kWORDFILL = $00400319 +' kLONGFILL = $0040031a +' kBYTEMOVE = $0040031c +' kWORDMOVE = $0040031d +' kLONGMOVE = $0040031e + kCLKSET = $02400220 + kCOGSTOP = $02400121 +' kLOCKRET = $00400122 + kWAITCNT = $02400123 + kWAITPEQ = $0240031b + kWAITPNE = $0240031f + kWAITVID = $02400227 + kOCTOTHORP = $0000001a +' kDOLLAR = $0000001b + kLPAREN = $0000001c + kRPAREN = $0000001d + kCOMMA = $0000001e + kDOT = $0000001f + kDOTDOT = $00000020 + kCOLON = $00000021 + kCOLONEQUAL = $00200022 + kEQUAL = $00000023 + kABORT = $00000024 + kCASE = $00000025 + kCHIPVER = $00100000 + kCLKFREQ = $00100010 + kCLKMODE = $00100020 + kCOGID = $02100003 + kCOGINIT = $02100004 + kCOGNEW = $00100005 + kREBOOT = $00100006 +' kSTRCOMP = $00100172 +' kSTRSIZE = $00100161 +' kLOCKCLR = $0012b2f1 +' kLOCKNEW = $001292d0 +' kLOCKSET = $0012a2e1 +' kLOOKDOWN = $00113111 +' kLOOKDOWNZ = $00113110 +' kLOOKUP = $00112101 +' kLOOKUPZ = $00112100 + kCONSTANT = $00000026 + kELSE = $00000027 + kELSEIF = $00000028 + kELSEIFNOT = $00000029 +' kFILE = $0000002a + kFIT = $0000002b +' kFLOAT = $0000002c + kFROM = $0000002d + kIF = $0000002e + kIFNOT = $0000002f + kNEXT = $00000030 + kORG = $00000031 +' kORGX = $00000032 + kOTHER = $00000033 + kQUIT = $00000034 + kREPEAT = $00000035 + kRES = $00000036 + kRESULT = $00000037 + kRETURN = $00000038 +' kROUND = $00000039 + kSPR = $0000003a + kSTEP = $0000003b + kSTRING = $0000003c + kTO = $0000003d +' kTRUNC = $0000003e + kUNTIL = $0000003f + kWHILE = $00000040 + kLBRACKET = $00000041 + kBACKSLASH = $00000042 + kRBRACKET = $00000043 + kLBRACE = $00000044 + kRBRACE = $00000045 + kEOL = $000000fd + kEOF = $000000fe + kUNKNOWN = $000000ff +dat +tableStart word $0002 + + byte $0e,$00,$63,$06,$49,$4e,$41,$00,$03,$00,$00,$00,$1c,$00,$d6,$02 + byte $43,$4d,$50,$53,$58,$00,$3c,$c4,$03,$02,$27,$00,$57,$01,$3d,$3e + byte $00,$fe,$00,$08,$04,$32,$00,$c2,$00,$2d,$3e,$00,$e0,$00,$02,$04 + byte $3c,$00,$83,$00,$2a,$00,$f4,$00,$05,$04,$46,$00,$65,$00,$24,$00 + byte $1b,$00,$00,$00,$50,$00,$5a,$00,$23,$00,$1a,$00,$00,$00,$00,$00 + byte $00,$00,$21,$00,$e7,$00,$01,$08,$00,$00,$00,$00,$23,$3e,$00,$e4 + byte $00,$07,$04,$6f,$00,$79,$00,$28,$00,$1c,$00,$00,$00,$00,$00,$00 + byte $00,$26,$00,$e8,$00,$03,$04,$00,$00,$00,$00,$29,$00,$1d,$00,$00 + byte $00,$8d,$00,$ad,$00,$2c,$00,$1e,$00,$00,$00,$97,$00,$a2,$00,$2b + byte $00,$ec,$00,$06,$04,$00,$00,$00,$00,$2a,$2a,$00,$f5,$00,$05,$04 + byte $00,$00,$00,$00,$2b,$2b,$00,$20,$28,$00,$0c,$b8,$00,$00,$00,$2d + byte $2d,$00,$30,$38,$00,$0c,$00,$00,$00,$00,$2d,$00,$ed,$00,$06,$04 + byte $cd,$00,$16,$01,$3c,$23,$00,$e5,$00,$07,$04,$d8,$00,$f7,$00,$2f + byte $2f,$00,$f7,$00,$05,$04,$e3,$00,$ed,$00,$2e,$2e,$00,$20,$00,$00 + byte $00,$00,$00,$00,$00,$2e,$00,$1f,$00,$00,$00,$00,$00,$00,$00,$2f + byte $00,$f6,$00,$05,$04,$02,$01,$0c,$01,$3a,$3d,$00,$22,$00,$20,$00 + byte $00,$00,$00,$00,$3a,$00,$21,$00,$00,$00,$00,$00,$00,$00,$3c,$00 + byte $f9,$00,$08,$04,$20,$01,$41,$01,$3d,$00,$23,$00,$00,$00,$2b,$01 + byte $36,$01,$3c,$3c,$00,$e3,$00,$02,$04,$00,$00,$00,$00,$3c,$2d,$00 + byte $e1,$00,$02,$04,$00,$00,$00,$00,$3c,$3e,$00,$fb,$00,$08,$04,$4c + byte $01,$00,$00,$3d,$3d,$00,$fc,$00,$08,$04,$00,$00,$00,$00,$3d,$3c + byte $00,$fd,$00,$08,$04,$64,$01,$0d,$02,$41,$44,$44,$58,$00,$bc,$c8 + byte $03,$02,$72,$01,$bc,$01,$41,$42,$4f,$52,$54,$00,$24,$00,$00,$00 + byte $7d,$01,$9d,$01,$3e,$7c,$00,$f1,$00,$01,$08,$88,$01,$92,$01,$3e + byte $3c,$00,$ef,$00,$02,$04,$00,$00,$00,$00,$3e,$00,$fa,$00,$08,$04 + byte $00,$00,$00,$00,$3e,$3e,$00,$e2,$00,$02,$04,$a7,$01,$b1,$01,$40 + byte $00,$00,$00,$00,$08,$00,$00,$00,$00,$3f,$00,$08,$0c,$00,$0c,$00 + byte $00,$00,$00,$40,$40,$00,$01,$00,$00,$08,$cb,$01,$f2,$01,$41,$44 + byte $44,$41,$42,$53,$00,$bc,$88,$03,$02,$da,$01,$e6,$01,$41,$42,$53 + byte $4e,$45,$47,$00,$bc,$ac,$03,$02,$00,$00,$00,$00,$41,$42,$53,$00 + byte $bc,$a8,$03,$02,$00,$00,$00,$00,$41,$44,$44,$00,$bc,$80,$03,$02 + byte $00,$02,$00,$00,$41,$44,$44,$53,$58,$00,$bc,$d8,$03,$02,$00,$00 + byte $00,$00,$41,$44,$44,$53,$00,$bc,$d0,$03,$02,$1d,$02,$7f,$02,$43 + byte $48,$49,$50,$56,$45,$52,$00,$00,$00,$10,$00,$2e,$02,$54,$02,$42 + byte $59,$54,$45,$46,$49,$4c,$4c,$00,$18,$03,$40,$00,$3b,$02,$47,$02 + byte $41,$4e,$44,$4e,$00,$bc,$64,$03,$02,$00,$00,$00,$00,$41,$4e,$44 + byte $00,$f0,$00,$0a,$06,$00,$00,$00,$00,$42,$59,$54,$45,$00,$17,$00 + byte $00,$00,$61,$02,$72,$02,$43,$41,$4c,$4c,$00,$fc,$5c,$01,$02,$00 + byte $00,$00,$00,$42,$59,$54,$45,$4d,$4f,$56,$45,$00,$1c,$03,$40,$00 + byte $00,$00,$00,$00,$43,$41,$53,$45,$00,$25,$00,$00,$00,$8b,$02,$ba + byte $02,$43,$4d,$50,$00,$3c,$84,$03,$02,$9b,$02,$ab,$02,$43,$4c,$4b + byte $4d,$4f,$44,$45,$00,$20,$00,$10,$00,$00,$00,$00,$00,$43,$4c,$4b + byte $46,$52,$45,$51,$00,$10,$00,$10,$00,$00,$00,$00,$00,$43,$4c,$4b + byte $53,$45,$54,$00,$20,$02,$40,$02,$c9,$02,$00,$00,$43,$4d,$50,$53 + byte $55,$42,$00,$bc,$e0,$03,$02,$00,$00,$00,$00,$43,$4d,$50,$53,$00 + byte $3c,$c0,$03,$02,$e3,$02,$73,$04,$49,$46,$5f,$42,$00,$0c,$00,$00 + byte $01,$f0,$02,$b0,$03,$45,$4c,$53,$45,$00,$27,$00,$00,$00,$01,$03 + byte $63,$03,$43,$4f,$4e,$53,$54,$41,$4e,$54,$00,$26,$00,$00,$00,$11 + byte $03,$38,$03,$43,$4f,$47,$49,$4e,$49,$54,$00,$04,$00,$10,$02,$1d + byte $03,$2a,$03,$43,$4e,$54,$00,$02,$00,$00,$00,$00,$00,$00,$00,$43 + byte $4d,$50,$58,$00,$3c,$cc,$03,$02,$00,$00,$00,$00,$43,$4f,$47,$49 + byte $44,$00,$03,$00,$10,$02,$48,$03,$57,$03,$43,$4f,$47,$53,$54,$4f + byte $50,$00,$21,$01,$40,$02,$00,$00,$00,$00,$43,$4f,$47,$4e,$45,$57 + byte $00,$05,$00,$10,$00,$00,$00,$00,$00,$43,$4f,$4e,$00,$11,$00,$00 + byte $00,$70,$03,$96,$03,$44,$49,$52,$41,$00,$07,$00,$00,$00,$7d,$03 + byte $8a,$03,$43,$54,$52,$42,$00,$0a,$00,$00,$00,$00,$00,$00,$00,$43 + byte $54,$52,$41,$00,$09,$00,$00,$00,$00,$00,$00,$00,$44,$41,$54,$00 + byte $12,$00,$00,$00,$a3,$03,$00,$00,$44,$4a,$4e,$5a,$00,$bc,$e4,$03 + byte $02,$00,$00,$00,$00,$44,$49,$52,$42,$00,$08,$00,$00,$00,$bd,$03 + byte $1f,$04,$46,$52,$51,$42,$00,$0c,$00,$00,$00,$c9,$03,$f7,$03,$46 + byte $49,$54,$00,$2b,$00,$00,$00,$db,$03,$ea,$03,$45,$4c,$53,$45,$49 + byte $46,$4e,$4f,$54,$00,$29,$00,$00,$00,$00,$00,$00,$00,$45,$4c,$53 + byte $45,$49,$46,$00,$28,$00,$00,$00,$00,$00,$00,$00,$46,$49,$4c,$45 + byte $00,$2a,$00,$00,$00,$04,$04,$12,$04,$46,$52,$4f,$4d,$00,$2d,$00 + byte $00,$00,$00,$00,$00,$00,$46,$4c,$4f,$41,$54,$00,$2c,$00,$00,$00 + byte $00,$00,$00,$00,$46,$52,$51,$41,$00,$0b,$00,$00,$00,$2c,$04,$53 + byte $04,$49,$46,$5f,$41,$00,$01,$00,$00,$01,$37,$04,$45,$04,$49,$46 + byte $00,$2e,$00,$00,$00,$00,$00,$00,$00,$48,$55,$42,$4f,$50,$00,$3c + byte $0c,$03,$02,$00,$00,$00,$00,$49,$46,$4e,$4f,$54,$00,$2f,$00,$00 + byte $00,$65,$04,$00,$00,$49,$46,$5f,$41,$4c,$57,$41,$59,$53,$00,$0f + byte $00,$00,$01,$00,$00,$00,$00,$49,$46,$5f,$41,$45,$00,$03,$00,$00 + byte $01,$81,$04,$77,$05,$49,$46,$5f,$4e,$45,$00,$05,$00,$00,$01,$93 + byte $04,$0c,$05,$49,$46,$5f,$43,$5f,$4f,$52,$5f,$5a,$00,$0e,$00,$00 + byte $01,$a6,$04,$d5,$04,$49,$46,$5f,$43,$5f,$41,$4e,$44,$5f,$5a,$00 + byte $08,$00,$00,$01,$b3,$04,$c1,$04,$49,$46,$5f,$43,$00,$0c,$00,$00 + byte $01,$00,$00,$00,$00,$49,$46,$5f,$42,$45,$00,$0e,$00,$00,$01,$00 + byte $00,$00,$00,$49,$46,$5f,$43,$5f,$41,$4e,$44,$5f,$4e,$5a,$00,$04 + byte $00,$00,$01,$e7,$04,$f9,$04,$49,$46,$5f,$43,$5f,$4e,$45,$5f,$5a + byte $00,$06,$00,$00,$01,$00,$00,$00,$00,$49,$46,$5f,$43,$5f,$45,$51 + byte $5f,$5a,$00,$09,$00,$00,$01,$00,$00,$00,$00,$49,$46,$5f,$43,$5f + byte $4f,$52,$5f,$4e,$5a,$00,$0d,$00,$00,$01,$20,$05,$50,$05,$49,$46 + byte $5f,$4e,$43,$5f,$41,$4e,$44,$5f,$5a,$00,$02,$00,$00,$01,$2e,$05 + byte $3b,$05,$49,$46,$5f,$4e,$43,$00,$03,$00,$00,$01,$00,$00,$00,$00 + byte $49,$46,$5f,$45,$00,$0a,$00,$00,$01,$00,$00,$00,$00,$49,$46,$5f + byte $4e,$43,$5f,$41,$4e,$44,$5f,$4e,$5a,$00,$01,$00,$00,$01,$63,$05 + byte $00,$00,$49,$46,$5f,$4e,$43,$5f,$4f,$52,$5f,$5a,$00,$0b,$00,$00 + byte $01,$00,$00,$00,$00,$49,$46,$5f,$4e,$43,$5f,$4f,$52,$5f,$4e,$5a + byte $00,$07,$00,$00,$01,$84,$05,$f3,$05,$49,$46,$5f,$5a,$00,$0a,$00 + byte $00,$01,$99,$05,$cc,$05,$49,$46,$5f,$4e,$5a,$5f,$41,$4e,$44,$5f + byte $4e,$43,$00,$01,$00,$00,$01,$a7,$05,$b8,$05,$49,$46,$5f,$4e,$5a + byte $00,$05,$00,$00,$01,$00,$00,$00,$00,$49,$46,$5f,$4e,$45,$56,$45 + byte $52,$00,$00,$00,$00,$01,$00,$00,$00,$00,$49,$46,$5f,$4e,$5a,$5f + byte $41,$4e,$44,$5f,$43,$00,$04,$00,$00,$01,$e0,$05,$00,$00,$49,$46 + byte $5f,$4e,$5a,$5f,$4f,$52,$5f,$4e,$43,$00,$0b,$00,$00,$01,$00,$00 + byte $00,$00,$49,$46,$5f,$4e,$5a,$5f,$4f,$52,$5f,$43,$00,$0e,$00,$00 + byte $01,$05,$06,$3e,$06,$49,$46,$5f,$5a,$5f,$4e,$45,$5f,$43,$00,$06 + byte $00,$00,$01,$19,$06,$2c,$06,$49,$46,$5f,$5a,$5f,$41,$4e,$44,$5f + byte $4e,$43,$00,$02,$00,$00,$01,$00,$00,$00,$00,$49,$46,$5f,$5a,$5f + byte $41,$4e,$44,$5f,$43,$00,$08,$00,$00,$01,$00,$00,$00,$00,$49,$46 + byte $5f,$5a,$5f,$45,$51,$5f,$43,$00,$09,$00,$00,$01,$51,$06,$00,$00 + byte $49,$46,$5f,$5a,$5f,$4f,$52,$5f,$4e,$43,$00,$0b,$00,$00,$01,$00 + byte $00,$00,$00,$49,$46,$5f,$5a,$5f,$4f,$52,$5f,$43,$00,$0e,$00,$00 + byte $01,$72,$06,$84,$09,$52,$45,$54,$55,$52,$4e,$00,$38,$00,$00,$00 + byte $80,$06,$1a,$08,$4e,$45,$47,$4e,$5a,$00,$bc,$bc,$03,$02,$8c,$06 + byte $64,$07,$4d,$41,$58,$00,$bc,$4c,$03,$02,$99,$06,$00,$07,$4c,$4f + byte $4e,$47,$00,$19,$00,$00,$00,$a9,$06,$d0,$06,$4c,$4f,$43,$4b,$43 + byte $4c,$52,$00,$f1,$b2,$12,$00,$b5,$06,$c1,$06,$4a,$4d,$50,$00,$3c + byte $5c,$01,$02,$00,$00,$00,$00,$49,$4e,$42,$00,$04,$00,$00,$00,$00 + byte $00,$00,$00,$4a,$4d,$50,$52,$45,$54,$00,$bc,$5c,$03,$02,$e0,$06 + byte $f0,$06,$4c,$4f,$43,$4b,$52,$45,$54,$00,$22,$01,$40,$00,$00,$00 + byte $00,$00,$4c,$4f,$43,$4b,$4e,$45,$57,$00,$d0,$92,$12,$00,$00,$00 + byte $00,$00,$4c,$4f,$43,$4b,$53,$45,$54,$00,$e1,$a2,$12,$00,$12,$07 + byte $45,$07,$4c,$4f,$4f,$4b,$44,$4f,$57,$4e,$5a,$00,$10,$31,$11,$00 + byte $23,$07,$34,$07,$4c,$4f,$4e,$47,$4d,$4f,$56,$45,$00,$1e,$03,$40 + byte $00,$00,$00,$00,$00,$4c,$4f,$4e,$47,$46,$49,$4c,$4c,$00,$1a,$03 + byte $40,$00,$00,$00,$00,$00,$4c,$4f,$4f,$4b,$44,$4f,$57,$4e,$00,$11 + byte $31,$11,$00,$55,$07,$00,$00,$4c,$4f,$4f,$4b,$55,$50,$5a,$00,$00 + byte $21,$11,$00,$00,$00,$00,$00,$4c,$4f,$4f,$4b,$55,$50,$00,$01,$21 + byte $11,$00,$71,$07,$ca,$07,$4d,$55,$58,$43,$00,$bc,$70,$03,$02,$7d + byte $07,$a3,$07,$4d,$4f,$56,$00,$bc,$a0,$03,$02,$89,$07,$96,$07,$4d + byte $49,$4e,$00,$bc,$48,$03,$02,$00,$00,$00,$00,$4d,$41,$58,$53,$00 + byte $bc,$44,$03,$02,$00,$00,$00,$00,$4d,$49,$4e,$53,$00,$bc,$40,$03 + byte $02,$b0,$07,$bd,$07,$4d,$4f,$56,$49,$00,$bc,$58,$03,$02,$00,$00 + byte $00,$00,$4d,$4f,$56,$44,$00,$bc,$54,$03,$02,$00,$00,$00,$00,$4d + byte $4f,$56,$53,$00,$bc,$50,$03,$02,$d6,$07,$ff,$07,$4e,$45,$47,$00 + byte $bc,$a4,$03,$02,$e4,$07,$f2,$07,$4d,$55,$58,$4e,$5a,$00,$bc,$7c + byte $03,$02,$00,$00,$00,$00,$4d,$55,$58,$4e,$43,$00,$bc,$74,$03,$02 + byte $00,$00,$00,$00,$4d,$55,$58,$5a,$00,$bc,$78,$03,$02,$0d,$08,$00 + byte $00,$4e,$45,$47,$4e,$43,$00,$bc,$b4,$03,$02,$00,$00,$00,$00,$4e + byte $45,$47,$43,$00,$bc,$b0,$03,$02,$27,$08,$d5,$08,$50,$48,$53,$42 + byte $00,$0e,$00,$00,$00,$33,$08,$87,$08,$4f,$52,$47,$00,$31,$00,$00 + byte $00,$3f,$08,$65,$08,$4e,$4f,$54,$00,$ff,$00,$09,$08,$4c,$08,$59 + byte $08,$4e,$45,$58,$54,$00,$30,$00,$00,$00,$00,$00,$00,$00,$4e,$45 + byte $47,$5a,$00,$bc,$b8,$03,$02,$00,$00,$00,$00,$4e,$4f,$50,$00,$00 + byte $00,$00,$02,$71,$08,$7c,$08,$4f,$42,$4a,$00,$13,$00,$00,$00,$00 + byte $00,$00,$00,$4e,$52,$00,$08,$00,$80,$00,$00,$00,$00,$00,$4f,$52 + byte $00,$f2,$00,$0b,$06,$94,$08,$bc,$08,$4f,$55,$54,$42,$00,$06,$00 + byte $00,$00,$a2,$08,$af,$08,$4f,$54,$48,$45,$52,$00,$33,$00,$00,$00 + byte $00,$00,$00,$00,$4f,$52,$47,$58,$00,$32,$00,$00,$00,$00,$00,$00 + byte $00,$4f,$55,$54,$41,$00,$05,$00,$00,$00,$c9,$08,$00,$00,$50,$48 + byte $53,$41,$00,$0d,$00,$00,$00,$00,$00,$00,$00,$50,$41,$52,$00,$01 + byte $00,$00,$00,$e4,$08,$30,$09,$52,$44,$4c,$4f,$4e,$47,$00,$bc,$08 + byte $03,$02,$f0,$08,$15,$09,$52,$43,$4c,$00,$bc,$34,$03,$02,$fc,$08 + byte $08,$09,$50,$55,$42,$00,$15,$00,$00,$00,$00,$00,$00,$00,$50,$52 + byte $49,$00,$14,$00,$00,$00,$00,$00,$00,$00,$51,$55,$49,$54,$00,$34 + byte $00,$00,$00,$24,$09,$00,$00,$52,$44,$42,$59,$54,$45,$00,$bc,$00 + byte $03,$02,$00,$00,$00,$00,$52,$43,$52,$00,$bc,$30,$03,$02,$3c,$09 + byte $69,$09,$52,$45,$53,$00,$36,$00,$00,$00,$4b,$09,$5a,$09,$52,$45 + byte $42,$4f,$4f,$54,$00,$06,$00,$10,$00,$00,$00,$00,$00,$52,$44,$57 + byte $4f,$52,$44,$00,$bc,$04,$03,$02,$00,$00,$00,$00,$52,$45,$50,$45 + byte $41,$54,$00,$35,$00,$00,$00,$75,$09,$00,$00,$52,$45,$54,$00,$7c + byte $5c,$00,$02,$00,$00,$00,$00,$52,$45,$53,$55,$4c,$54,$00,$37,$00 + byte $00,$00,$91,$09,$0e,$0b,$56,$53,$43,$4c,$00,$10,$00,$00,$00,$9e + byte $09,$57,$0a,$53,$55,$42,$53,$00,$bc,$d4,$03,$02,$aa,$09,$00,$0a + byte $53,$50,$52,$00,$3a,$00,$00,$00,$b8,$09,$dc,$09,$52,$4f,$55,$4e + byte $44,$00,$39,$00,$00,$00,$c4,$09,$d0,$09,$52,$4f,$4c,$00,$bc,$24 + byte $03,$02,$00,$00,$00,$00,$52,$45,$56,$00,$bc,$3c,$03,$02,$00,$00 + byte $00,$00,$52,$4f,$52,$00,$bc,$20,$03,$02,$e8,$09,$f4,$09,$53,$48 + byte $4c,$00,$bc,$2c,$03,$02,$00,$00,$00,$00,$53,$41,$52,$00,$bc,$38 + byte $03,$02,$00,$00,$00,$00,$53,$48,$52,$00,$bc,$28,$03,$02,$10,$0a + byte $3c,$0a,$53,$54,$52,$53,$49,$5a,$45,$00,$61,$01,$10,$00,$20,$0a + byte $2d,$0a,$53,$54,$52,$43,$4f,$4d,$50,$00,$72,$01,$10,$00,$00,$00 + byte $00,$00,$53,$54,$45,$50,$00,$3b,$00,$00,$00,$00,$00,$00,$00,$53 + byte $54,$52,$49,$4e,$47,$00,$3c,$00,$00,$00,$4b,$0a,$00,$00,$53,$55 + byte $42,$41,$42,$53,$00,$bc,$8c,$03,$02,$00,$00,$00,$00,$53,$55,$42 + byte $00,$bc,$84,$03,$02,$64,$0a,$c2,$0a,$54,$4a,$4e,$5a,$00,$3c,$e8 + byte $03,$02,$72,$0a,$9a,$0a,$53,$55,$4d,$4e,$43,$00,$bc,$94,$03,$02 + byte $7f,$0a,$8d,$0a,$53,$55,$42,$58,$00,$bc,$cc,$03,$02,$00,$00,$00 + byte $00,$53,$55,$42,$53,$58,$00,$bc,$dc,$03,$02,$00,$00,$00,$00,$53 + byte $55,$4d,$43,$00,$bc,$90,$03,$02,$a7,$0a,$b5,$0a,$53,$55,$4d,$5a + byte $00,$bc,$98,$03,$02,$00,$00,$00,$00,$53,$55,$4d,$4e,$5a,$00,$bc + byte $9c,$03,$02,$00,$00,$00,$00,$54,$45,$53,$54,$00,$3c,$60,$03,$02 + byte $d0,$0a,$f5,$0a,$55,$4e,$54,$49,$4c,$00,$3f,$00,$00,$00,$db,$0a + byte $e7,$0a,$54,$4f,$00,$3d,$00,$00,$00,$00,$00,$00,$00,$54,$4a,$5a + byte $00,$3c,$ec,$03,$02,$00,$00,$00,$00,$54,$52,$55,$4e,$43,$00,$3e + byte $00,$00,$00,$02,$0b,$00,$00,$56,$43,$46,$47,$00,$0f,$00,$00,$00 + byte $00,$00,$00,$00,$56,$41,$52,$00,$16,$00,$00,$00,$1a,$0b,$e5,$0b + byte $58,$4f,$52,$00,$bc,$6c,$03,$02,$2b,$0b,$91,$0b,$57,$4f,$52,$44 + byte $46,$49,$4c,$4c,$00,$19,$03,$40,$00,$3b,$0b,$6b,$0b,$57,$41,$49 + byte $54,$56,$49,$44,$00,$27,$02,$40,$02,$4b,$0b,$5b,$0b,$57,$41,$49 + byte $54,$50,$45,$51,$00,$1b,$03,$40,$02,$00,$00,$00,$00,$57,$41,$49 + byte $54,$43,$4e,$54,$00,$23,$01,$40,$02,$00,$00,$00,$00,$57,$41,$49 + byte $54,$50,$4e,$45,$00,$1f,$03,$40,$02,$79,$0b,$84,$0b,$57,$48,$49 + byte $4c,$45,$00,$40,$00,$00,$00,$00,$00,$00,$00,$57,$43,$00,$02,$00 + byte $80,$00,$00,$00,$00,$00,$57,$4f,$52,$44,$00,$18,$00,$00,$00,$a0 + byte $0b,$cb,$0b,$57,$52,$4c,$4f,$4e,$47,$00,$3c,$08,$03,$02,$ab,$0b + byte $bc,$0b,$57,$52,$00,$01,$00,$80,$00,$00,$00,$00,$00,$57,$4f,$52 + byte $44,$4d,$4f,$56,$45,$00,$1d,$03,$40,$00,$00,$00,$00,$00,$57,$52 + byte $42,$59,$54,$45,$00,$3c,$00,$03,$02,$d6,$0b,$00,$00,$57,$5a,$00 + byte $04,$00,$80,$00,$00,$00,$00,$00,$57,$52,$57,$4f,$52,$44,$00,$3c + byte $04,$03,$02,$ef,$0b,$2c,$0c,$7c,$00,$ea,$00,$04,$04,$f9,$0b,$17 + byte $0c,$5e,$00,$eb,$00,$04,$04,$03,$0c,$0d,$0c,$5c,$00,$42,$00,$00 + byte $00,$00,$00,$00,$00,$5b,$00,$41,$00,$00,$00,$00,$00,$00,$00,$5d + byte $00,$43,$00,$00,$00,$21,$0c,$00,$00,$7b,$00,$44,$00,$00,$00,$00 + byte $00,$00,$00,$5e,$5e,$00,$f8,$00,$01,$08,$36,$0c,$56,$0c,$7e,$00 + byte $10,$18,$00,$0c,$41,$0c,$4c,$0c,$7c,$7c,$00,$e9,$00,$01,$08,$00 + byte $00,$00,$00,$7c,$3c,$00,$f3,$00,$01,$08,$00,$00,$00,$00,$7d,$00 + byte $45,$00,$00,$00,$61,$0c,$00,$00,$7e,$7e,$00,$14,$1c,$00,$0c,$00 + byte $00,$00,$00,$7e,$3e,$00,$ee,$00,$02,$04 + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx2/kwdefs.spn b/zubehör/sphinx/spinx100225-ori/sphinx2/kwdefs.spn new file mode 100644 index 0000000..eb4ef69 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx2/kwdefs.spn @@ -0,0 +1,274 @@ +pub blah +con ' The following is auto-generated. Do not edit. + kID = $80000000 + kINTLITERAL = $40000000 + kFLOATLITERAL = $20000000 + kUNARY = $08000000 + kBINARY = $04000000 + kPOSTFIX = $04000000 + kPASM = $02000000 + kCOND = $01000000 + kEFFECT = $00800000 + kSTMTFN = $00400000 + kASSIGNMENT = $00200000 + kINTRINSIC = $00100000 + +' kBANG = $080100e7 +' kOCTOTHORPRANGLE = $040700e4 +' kAMPERSAND = $040300e8 +' kSTAR = $040500f4 +' kSTARSTAR = $040500f5 + kPLUS = $040600ec +' kPLUSPLUS = $0c002820 + kMINUS = $040600ed +' kMINUSMINUS = $0c003830 +' kMINUSRANGLE = $040200e0 +' kSLASH = $040500f6 +' kSLASHSLASH = $040500f7 +' kLANGLE = $040800f9 +' kLANGLEOCTOTHORP = $040700e5 +' kLANGLEMINUS = $040200e1 +' kLANGLELANGLE = $040200e3 +' kLANGLERANGLE = $040800fb +' kEQUALLANGLE = $040800fd +' kEQUALEQUAL = $040800fc +' kEQUALRANGLE = $040800fe +' kRANGLE = $040800fa +' kRANGLELANGLE = $040200ef +' kRANGLERANGLE = $040200e2 +' kRANGLEBAR = $080100f1 + kQUESTION = $0c000c08 + kAT = $08000000 + kATAT = $08000001 +' kCARET = $040400eb +' kCARETCARET = $080100f8 + kBAR = $040400ea +' kBARLANGLE = $080100f3 +' kBARBAR = $080100e9 + kTILDE = $0c001810 +' kTILDERANGLE = $040200ee + kTILDETILDE = $0c001c14 + kAND = $060a00f0 +' kNOT = $080900ff + kOR = $060b00f2 +' kABS = $0203a8bc +' kABSNEG = $0203acbc +' kADD = $020380bc +' kADDABS = $020388bc +' kADDS = $0203d0bc +' kADDSX = $0203d8bc +' kADDX = $0203c8bc +' kANDN = $020364bc + kCALL = $02015cfc +' kCMP = $0203843c +' kCMPS = $0203c03c +' kCMPSUB = $0203e0bc +' kCMPSX = $0203c43c +' kCMPX = $0203cc3c +' kDJNZ = $0203e4bc +' kHUBOP = $02030c3c +' kJMP = $02015c3c +' kJMPRET = $02035cbc +' kMAX = $02034cbc +' kMAXS = $020344bc +' kMIN = $020348bc +' kMINS = $020340bc +' kMOV = $0203a0bc +' kMOVD = $020354bc +' kMOVI = $020358bc +' kMOVS = $020350bc +' kMUXC = $020370bc +' kMUXNC = $020374bc +' kMUXNZ = $02037cbc +' kMUXZ = $020378bc +' kNEG = $0203a4bc +' kNEGC = $0203b0bc +' kNEGNC = $0203b4bc +' kNEGNZ = $0203bcbc +' kNEGZ = $0203b8bc +' kNOP = $02000000 +' kRCL = $020334bc +' kRCR = $020330bc +' kRDBYTE = $020300bc +' kRDLONG = $020308bc +' kRDWORD = $020304bc +' kRET = $02005c7c +' kREV = $02033cbc +' kROL = $020324bc +' kROR = $020320bc +' kSAR = $020338bc +' kSHL = $02032cbc +' kSHR = $020328bc +' kSUB = $020384bc +' kSUBABS = $02038cbc +' kSUBS = $0203d4bc +' kSUBSX = $0203dcbc +' kSUBX = $0203ccbc +' kSUMC = $020390bc +' kSUMNC = $020394bc +' kSUMNZ = $02039cbc +' kSUMZ = $020398bc +' kTEST = $0203603c +' kTJNZ = $0203e83c +' kTJZ = $0203ec3c +' kWRBYTE = $0203003c +' kWRLONG = $0203083c +' kWRWORD = $0203043c +' kXOR = $02036cbc + kPAR = $00000001 +' kCNT = $00000002 +' kINA = $00000003 +' kINB = $00000004 +' kOUTA = $00000005 +' kOUTB = $00000006 +' kDIRA = $00000007 +' kDIRB = $00000008 +' kCTRA = $00000009 +' kCTRB = $0000000a +' kFRQA = $0000000b +' kFRQB = $0000000c +' kPHSA = $0000000d +' kPHSB = $0000000e +' kVCFG = $0000000f + kVSCL = $00000010 +' kIF_A = $01000001 +' kIF_AE = $01000003 +' kIF_ALWAYS = $0100000f +' kIF_B = $0100000c +' kIF_BE = $0100000e +' kIF_C = $0100000c +' kIF_C_AND_NZ = $01000004 +' kIF_C_AND_Z = $01000008 +' kIF_C_EQ_Z = $01000009 +' kIF_C_NE_Z = $01000006 +' kIF_C_OR_NZ = $0100000d +' kIF_C_OR_Z = $0100000e +' kIF_E = $0100000a +' kIF_NC = $01000003 +' kIF_NC_AND_NZ = $01000001 +' kIF_NC_AND_Z = $01000002 +' kIF_NC_OR_NZ = $01000007 +' kIF_NC_OR_Z = $0100000b +' kIF_NE = $01000005 +' kIF_NEVER = $01000000 +' kIF_NZ = $01000005 +' kIF_NZ_AND_C = $01000004 +' kIF_NZ_AND_NC = $01000001 +' kIF_NZ_OR_C = $0100000e +' kIF_NZ_OR_NC = $0100000b +' kIF_Z = $0100000a +' kIF_Z_AND_C = $01000008 +' kIF_Z_AND_NC = $01000002 +' kIF_Z_EQ_C = $01000009 +' kIF_Z_NE_C = $01000006 +' kIF_Z_OR_C = $0100000e +' kIF_Z_OR_NC = $0100000b +' kNR = $00800008 +' kWC = $00800002 +' kWR = $00800001 +' kWZ = $00800004 + kCON = $00000011 + kDAT = $00000012 + kOBJ = $00000013 + kPRI = $00000014 + kPUB = $00000015 + kVAR = $00000016 + kBYTE = $00000017 + kWORD = $00000018 + kLONG = $00000019 +' kBYTEFILL = $00400318 +' kWORDFILL = $00400319 +' kLONGFILL = $0040031a +' kBYTEMOVE = $0040031c +' kWORDMOVE = $0040031d +' kLONGMOVE = $0040031e + kCLKSET = $02400220 + kCOGSTOP = $02400121 +' kLOCKRET = $00400122 + kWAITCNT = $02400123 + kWAITPEQ = $0240031b + kWAITPNE = $0240031f + kWAITVID = $02400227 + kOCTOTHORP = $0000001a +' kDOLLAR = $0000001b + kLPAREN = $0000001c + kRPAREN = $0000001d + kCOMMA = $0000001e + kDOT = $0000001f + kDOTDOT = $00000020 + kCOLON = $00000021 + kCOLONEQUAL = $00200022 + kEQUAL = $00000023 + kABORT = $00000024 + kCASE = $00000025 + kCHIPVER = $00100000 + kCLKFREQ = $00100010 + kCLKMODE = $00100020 + kCOGID = $02100003 + kCOGINIT = $02100004 + kCOGNEW = $00100005 + kREBOOT = $00100006 +' kSTRCOMP = $00100172 +' kSTRSIZE = $00100161 +' kLOCKCLR = $0012b2f1 +' kLOCKNEW = $001292d0 +' kLOCKSET = $0012a2e1 +' kLOOKDOWN = $00113111 +' kLOOKDOWNZ = $00113110 +' kLOOKUP = $00112101 +' kLOOKUPZ = $00112100 + kCONSTANT = $00000026 + kELSE = $00000027 + kELSEIF = $00000028 + kELSEIFNOT = $00000029 +' kFILE = $0000002a + kFIT = $0000002b +' kFLOAT = $0000002c + kFROM = $0000002d + kIF = $0000002e + kIFNOT = $0000002f + kNEXT = $00000030 + kORG = $00000031 +' kORGX = $00000032 + kOTHER = $00000033 + kQUIT = $00000034 + kREPEAT = $00000035 + kRES = $00000036 + kRESULT = $00000037 + kRETURN = $00000038 +' kROUND = $00000039 + kSPR = $0000003a + kSTEP = $0000003b + kSTRING = $0000003c + kTO = $0000003d +' kTRUNC = $0000003e + kUNTIL = $0000003f + kWHILE = $00000040 + kLBRACKET = $00000041 + kBACKSLASH = $00000042 + kRBRACKET = $00000043 + kLBRACE = $00000044 + kRBRACE = $00000045 + kEOL = $000000fd + kEOF = $000000fe + kUNKNOWN = $000000ff + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} + \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx2/lex.spn b/zubehör/sphinx/spinx100225-ori/sphinx2/lex.spn new file mode 100644 index 0000000..e235909 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx2/lex.spn @@ -0,0 +1,166 @@ +{{ + Lex + + usage: lex filename [options] + + Reads filename.spn on SD card, writes tokens to filename.tok. + +}} +con + _clkmode = xtal1 + pll8x + _xinfreq = 10_000_000 + + tvPin = 24 + sdPin = 16 + +obj + term: "isxtv" + token: "tokenizr" + kw: "keywords" + fs: "sxfile" ' used for writing .tok file + str: "stringx" + bt: "bintree" + +pub Main | err, p + err := \Try + if err + if err > 0 + term.str( err ) + else + term.str( string("Error ") ) + term.dec( err ) + term.out( 13 ) + term.dec( token.LineNumber ) + term.out( "," ) + term.dec( token.Column + 1 ) + term.out( " " ) + term.out( "'" ) + term.str( pTokenText ) + term.out( "'" ) + term.out( 13 ) + fs.Close + fs.Open( string("sphinx.bin"), "R" ) + else + fs.Close + if compile + fs.Open( string("codegen.bin"), "R" ) + else + fs.Open( string("sphinx.bin"), "R" ) + bt.Stop + fs.Execute( 0 ) + +var + long pTokenText + +pri Try + bt.Init( 0, 0 ) + ProcessCommandLine + if verbosity => 1 + term.str( string("lex 090627", 13) ) + Start + +pri ProcessCommandLine | nArgs, l + fs.Open( string("args.d8a"), "R" ) + nArgs := fs.ReadByte + ifnot nArgs-- + abort string("usage: lex spinfile [options]") + fs.ReadStringUpperCase( @spinFilename, MAXFILENAMELENGTH ) + + l := strsize( @spinFilename ) + if spinFilename[l-4] == "." and spinFilename[l-3] == "S" and spinFilename[l-2] == "P" and spinFilename[l-1] == "N" + spinFilename[l-4]~ + if strsize( @spinFilename ) > 8 + term.str( @spinFilename ) + abort string(" -- filename too long") + str.Copy( @outputFilename, @spinFilename ) + str.Append( @spinFilename, string(".SPN") ) + str.Append( @outputFilename, string(".TOK") ) + + ' Process command line arguments + + repeat while nArgs-- + fs.ReadStringUpperCase( @stringBuffer, MAXSTRINGBUFFERLENGTH ) + if stringBuffer[0] == "-" + stringBuffer[0] := "/" + if strcomp( @stringBuffer, string("/C") ) + compile~~ + elseif strcomp( @stringBuffer, string("/L") ) + compile~~ + elseif strcomp( @stringBuffer, string("/V") ) + ifnot nArgs-- + abort string("/V must be followed by a number") + verbosity := fs.ReadNumber + 'else ignore + + fs.Close + +con + MAXFILENAMELENGTH = 8 + 1 + 3 ' 8.3 + MAXSTRINGBUFFERLENGTH = 32 + +var + byte spinFilename[MAXFILENAMELENGTH+1] ' input .spi file + byte outputFilename[MAXFILENAMELENGTH+1] ' output .tok file + byte stringBuffer[MAXSTRINGBUFFERLENGTH+1] ' temp string buffer + +dat +verbosity byte 0 ' set by /V option +compile byte 0 ' set by /C or /L: if non-zero, run compile.bin automatically. +type long 0 +lineNum word 0 +column word 0 + +pri Start | v + + kw.Init + pTokenText := token.GetPText + + if verbosity => 2 + term.str( string("Reading ") ) + term.str( @spinFilename ) + term.out( 13 ) + token.Open( @spinFilename ) + + if verbosity => 2 + term.str( string("Writing ") ) + term.str( @outputFilename ) + term.out( 13 ) + fs.Open( @outputFilename, "W" ) + + repeat + type := token.Type + lineNum := token.LineNumber + column := token.Column + fs.Write( @type, 8 ) ' long + word + word + + if type == kw#kINTLITERAL or type == kw#kFLOATLITERAL + v := token.Value + fs.Write( @v, 4 ) + else + fs.Write( pTokenText, strsize(pTokenText) + 1 ) + + if token.Type == kw#kEOF + quit + token.Advance + token.Close + fs.Close + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} + \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx2/link.spn b/zubehör/sphinx/spinx100225-ori/sphinx2/link.spn new file mode 100644 index 0000000..f5f72e2 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx2/link.spn @@ -0,0 +1,616 @@ +{ + .sob linker +2009 +April + 10 Successfully linked two test programs + 15 SOB1 format: + #args in exported pubs now just one byte + added byte to imports for possible future use with object "pointers" + rearranged fields in SOB file header so that longs are long-aligned in memory +June + 9 Sphinxified + timestamp comparison + 12 Removed /s and /t options + 18 Don't stop on first out-of-date error. + +To do: + removal of duplicate sobs + + +Usage: link sobname [options] +sobname is name of .sob file, with or without .sob suffix. +Options start with / or - and are case-insensitive: + /v -- Sets verbosity level. Higher values of n => more verbose. Default is 0. + + SOB file format + + 0 4 bytes: SOB file format version # + 4 4 bytes: OBJ timestamp or version + 8 4 bytes: hash of OBJ's binary code. + 12 2 bytes: NUMEXPORTS + 14 2 bytes: EXPORTSIZE + 16 2 bytes: NUMIMPORTS + 18 2 bytes: IMPORTSIZE + 20 2 bytes: OBJBINSIZE (this is always a multiple of 4) + 22 1 byte: checksum + 23 1 byte: reserved + 24 2 bytes: size of OBJ's VAR space. + 26 EXPORTSIZE bytes: exported symbols: CONs, PUBs, maybe PRIs. + IMPORTSIZE bytes: OBJ's sub-OBJs. + OBJBINSIZE bytes: the compiled OBJ: header followed by methods. + + Export record format + + name + null + 0 + 4-byte int CON int + name + null + 1 + 4-byte float CON float + name + null + 2 + index + #args PUB + name + null + 3 + index + #args PRI (not exported) + + Import record format + + name + null + 2-byte count + reserved + + Export and import names are uppercase. Import name must not include ".SOB" or other suffix. + +} +SIZEOFSOBHEADER = 26 + +obj + term: "isxtv" + fs[2]: "sxfile" + str: "stringx" + +pub Main | err + err := \Try + if err + if err > 0 + term.str( err ) + else + term.str( string("Error ") ) + term.dec( err ) + term.out( 13 ) + + fs[0].Close + fs[0].Open( string("sphinx.bin"), "R" ) + fs[0].Execute( 0 ) + +dat +STACKSPACE long 500 ' in bytes; must be multiple of 4 +TABLESPACE long 1000 ' in bytes; must be multiple of 4 +WORKSPACE long 0 +verbosity byte 0 +outOfDate byte 0 +ignoreOutOfDate byte 0 + +pri Try | nArgs, pTable, pWork, l, p, totalVarSize + + fs.Open( string("args.d8a"), "R" ) + nArgs := fs.ReadByte + ifnot nArgs-- + abort string("usage: link sobname [options]") + fs.ReadStringUpperCase( @sobName, MAXFILENAMELENGTH ) + + l := strsize( @sobName ) + if sobName[l-4] == "." and sobName[l-3] == "S" and sobName[l-2] == "O" and sobName[l-1] == "B" + sobName[l-4]~ + if strsize( @sobName ) > 8 + term.str( @sobName ) + abort string(" -- sobname too long") + str.Copy( @outputName, @sobName ) + + ' Process command line arguments + + repeat while nArgs-- + fs.ReadStringUpperCase( @stringBuffer, 20 ) + if stringBuffer[0] == "-" + stringBuffer[0] := "/" + if strcomp( @stringBuffer, string("/V") ) + ifnot nArgs-- + abort string("/V must be followed by a number") + verbosity := fs.ReadNumber + elseif strcomp( @stringBuffer, string("/I") ) + ignoreOutOfDate~~ +{ + elseif strcomp( @stringBuffer, string("/S") ) + ifnot nArgs-- + abort string("/S must be followed by a number") + STACKSPACE := fs.ReadNumber + if STACKSPACE & 3 + abort string("/S argument must be a multiple of 4") + elseif strcomp( @stringBuffer, string("/T") ) + ifnot nArgs-- + abort string("/T must be followed by a number") + TABLESPACE := fs.ReadNumber + if TABLESPACE & 3 + abort string("/T argument must be a multiple of 4") +} + 'else + 'ignore + + fs.Close + + if verbosity => 1 + term.str( string("link 090627", 13) ) + + pTable := word[$000a] + STACKSPACE + pWork := pTable + TABLESPACE + WORKSPACE := 32768-pWork + + if verbosity => 2 + term.dec( WORKSPACE ) + term.str( string(" bytes of work space", 13) ) + + if WORKSPACE =< 0 + abort string("No work space") + + SobInit( pTable, TABLESPACE ) + AddSob( @sobName ) + ProcessSob( pTable, true ) + checksum~ + totalVarSize := ComputeAddressAndTotalVarSize( pTable, $0010 ) + + word[@header][3] := $0010 + word[@header[$08]] := objBinEndAddress + word[@header[$0a]] := objBinEndAddress + totalVarSize + 8 + word[@header[$0c]] := firstPubOffset + $0010 + word[@header[$0e]] := word[@header[$0a]] + firstPubLocalsSize + (firstPubNumArgs + 1) << 2 + + AddToChecksum( @header, $10 ) + AddToChecksum( @footer, 8 ) + header[5] := -checksum + + if verbosity => 3 + p := pTable + repeat while p + term.str( word[p +_pName] ) + term.out( " " ) + term.hex( word[p +_startAddress], 4 ) + term.out( " " ) + term.dec( word[p +_totalVarSize] ) + term.out( " " ) + term.hex( byte[p +_checksum], 2 ) + term.out( 13 ) + p := word[p +_pNextSorted] + + if not outOfDate or ignoreOutOfDate + str.Append( @outputName, string(".BIN") ) + if verbosity => 2 + term.str( string("Writing ") ) + term.str( @outputName ) + term.out( 13 ) + WriteBinaryFile( @outputName, pTable, pWork, WORKSPACE ) + else + term.str( string("No .bin written", 13) ) + +pri WriteBinaryFile( pFilename, pSob, pBuff, buffsize ) | n, p, pImports, pCounts, interObjectOffset, varOffset +{{ + Go down the priority-sorted list of sobs assigning them hub addresses such that they follow one + another in memory. On the way back up the list, compute each sob's total VAR size (the sob's + own VARs plus its imported sobs' VARs.) + Also updates checksum. + Return value is the current sob's total VAR size. Only the top object's return value is looked at. +}} + fs[0].Open( pFilename, "W" ) + fs[0].Write( @header, 16 ) + + repeat while pSob + str.Copy( @stringBuffer, word[pSob +_pName] ) + str.Append( @stringBuffer, string(".SOB") ) + if verbosity => 2 + term.str( @stringBuffer ) + term.str( string(" -- copying", 13) ) + + n := word[pSob +_objBinSize] + if n > buffsize + abort string("work area too small") + + fs[1].Open( @stringBuffer, "R" ) + fs[1].SkipBytes( SIZEOFSOBHEADER + word[pSob +_exportImportSize] ) + fs[1].Read( pBuff, n ) + fs[1].Close + + p := pBuff + byte[pBuff][2] << 2 ' byte[2] is index of 1st obj entry; multiply by 4 bytes/entry + varOffset := word[pSob +_varSize] + pImports := word[pSob +_pImports] + pCounts := word[pSob +_pCounts] + repeat word[pSob +_nImports] + interObjectOffset := word[ word[pImports] +_startAddress] - word[pSob +_startAddress] + repeat word[pCounts] + word[p] := interObjectOffset + p += 2 + word[p] := varOffset + p += 2 + varOffset += word[ word[pImports] +_totalVarSize] + + pImports += 2 + pCounts += 2 + + + fs[0].Write( pBuff, n ) + pSob := word[pSob +_pNextSorted] + fs[0].Close + +{{ + objBinEndAddress := address ' end address will point just beyond the last obj in hub memory. + ' Here we're just overwriting as we go and keeping the last one. + + ComputeAddressAndTotalVarSize( word[p +_pNextSorted], address ) + + checksum += byte[p +_checksum] ' this is the partial checksum of the obj (doesn't count its sub-object table because + ' sub-object links are not known until link time (i.e., now)) + totalVarSize := word[p +_varSize] + pImports := word[p +_pImports] + pCounts := word[p +_pCounts] + repeat word[p +_nImports] ' for each import, add the import's VAR size multiplied by its count + interObjectOffset := word[ word[pImports] +_startAddress] - word[p +_startAddress] + repeat word[pCounts] + AddToChecksum( @totalVarSize, 2 ) ' checksum needs to include this half of an object table entry + AddToChecksum( @interObjectOffset, 2 ) ' and this other half of an object table entry + + totalVarSize += word[ word[pImports] +_totalVarSize] + + pImports += 2 + pCounts += 2 + + word[p +_totalVarSize] := totalVarSize +}} + +var + word firstPubLocalsSize + word firstPubOffset + word firstPubNumArgs + word objBinEndAddress + byte checksum + long clk_freq + long xin_freq + long clk_mode + long free + long stack + +pri ReadExports( numExports ) | firstPub, type, val, index, nArgs, i, p, f, frequency + f~ + firstPub~~ + stack := 16 + frequency := 12_000_000 + + repeat numExports + fs.ReadStringUpperCase( @stringBuffer, MAXEXPORTLENGTH ) + case type := fs.ReadByte + 0, 1: ' int or float CON + val := fs.ReadLong + 2, 3: ' PUB or PRI + index := fs.ReadByte + nArgs := fs.ReadByte + if firstPub~ + firstPubNumArgs := nArgs + + repeat i from 0 to 4 + if strcomp( @stringBuffer, @@ptrs[i] ) + if type + term.str( @stringBuffer ) + abort string(" -- not an int CON") + clk_freq[i] := val + f |= |< i + + f &= 7 + if clk_mode & 3 + f |= 8 + case f ' four bits: rc|clkmode|xinfreq|clkfreq + %0000: ' none of clkmode/xinfreq/clkfreq specified + %0001..%0011: abort string("_CLKMODE must be specified") + %0100: abort string("_CLKFREQ or _XINFREQ must be specified") + %0101: frequency := clk_freq + %0110: frequency := xin_freq * ((clk_mode >> 6) #> 1) + %0111: if clk_freq <> xin_freq * ((clk_mode >> 6) #> 1) + abort string("conflicting _CLKFREQ and _XINFREQ") + %1000..%1011: ' these cases shouldn't happen + %1100: ' this case is OK + %1101..%1111: abort string("RCFAST/SLOW incompatible with _CLKFREQ/_XINFREQ") + + long[@header] := frequency + + header[4] := ComputeClkmodeByte( clk_mode ) + +pri ComputeClkmodeByte( mode ) : m | b1, b2, i +{ +rcfast $001 exactly one 1 in 0000_0000_00xx incompatible with clkfreq/xinfreq +rcslow $002 + or +xinput $004 exactly one 1 in 0000_00xx_xx00 and requires clkfreq/xinfreq +xtal1 $008 up to one 1 in 0xxx_xx00_0000 +xtal2 $010 +xtal3 $020 +pll1x $040 +pll2x $080 +pll4x $100 +pll8x $200 +pll16x $400 +} + b1 := -1 ' b1 is the position of the single 1 in mode[5..0]. + repeat i from 0 to 5 + if mode & |< i + if b1 <> -1 + abort string("invalid _CLKMODE") ' only one 1 allowed + b1 := i + m := lookupz( b1: $00, $01, $22, $2a, $32, $3a ) + + b2 := -1 ' b2 is the position of single 1 in mode[10..6] (-1 if no 1 bit) + repeat i from 6 to 10 + if mode & |< i + if b2 <> -1 + abort string("invalid _CLKMODE (multiple PLL)") ' only one 1 allowed + b2 := i + + if b1 < 2 ' RCFAST/RCSLOW? + if b2 <> -1 ' b2 better not be set + abort string("invalid _CLKMODE (RC+PLL)") + else ' one of the X-modes + if b2 <> -1 + m |= $40 ' PLLENA + m += b2 - 5 + + +dat +ptrs word @s0, @s1, @s2, @s3, @s4 +s0 byte "_CLKFREQ", 0 +s1 byte "_XINFREQ", 0 +s2 byte "_CLKMODE", 0 +s3 byte "_FREE", 0 +s4 byte "_STACK", 0 + + +dat + long +header byte 0[16] +footer byte $ff, $ff, $f9, $ff + byte $ff, $ff, $f9, $ff + +con + MAXFILENAMELENGTH = 8 + 1 + 3 ' 8.3 + MAXEXPORTLENGTH = 32 + +var + byte stringBuffer[MAXEXPORTLENGTH+1] + byte sobName[MAXFILENAMELENGTH+1] + byte outputName[MAXFILENAMELENGTH+1] + +con +#0 +_pNext[2] +_pNextSorted[2] +_pName[2] +_nImports[2] +_pImports[2] +_pCounts[2] +_startAddress[2] +_objBinSize[2] +_totalVarSize[2] +_varSize[2] +_timestamp[4] +_exportImportSize[2] +_checksum[1] +_[1] ' for alignment: _SIZEOFSOBINFO must be a multiple of 4 +_SIZEOFSOBINFO + +SOBFILEFORMATVERSION = "S" + "O" << 8 + "B" << 16 + "1" << 24 ' "SOB1" + +dat +pSobSpace word 0 +SOBSSIZE word 0 +pDataSpace word 0 +pFirst word 0 +pLast word 0 +pLastSorted word 0 + +pri SobInit( p, size ) + pFirst := pSobSpace := p + SOBSSIZE := size + pDataSpace := pSobSpace + SOBSSIZE + + pLastSorted := pLast := pFirst + + word[pFirst +_pNext]~ + word[pFirst +_pNextSorted]~ + +pri ComputeAddressAndTotalVarSize( p, address ) : totalVarSize | pImports, pCounts, interObjectOffset +{{ + Go down the priority-sorted list of sobs assigning them hub addresses such that they follow one + another in memory. On the way back up the list, compute each sob's total VAR size (the sob's + own VARs plus its imported sobs' VARs.) + Also updates checksum. + Return value is the current sob's total VAR size. Only the top object's return value is looked at. +}} + ifnot p + return + + word[p +_startAddress] := address + address += word[p +_objBinSize] + + objBinEndAddress := address ' end address will point just beyond the last obj in hub memory. + ' Here we're just overwriting as we go and keeping the last one. + + ComputeAddressAndTotalVarSize( word[p +_pNextSorted], address ) + + checksum += byte[p +_checksum] ' this is the partial checksum of the obj (doesn't count its sub-object table because + ' sub-object links are not known until link time (i.e., now)) + totalVarSize := word[p +_varSize] + pImports := word[p +_pImports] + pCounts := word[p +_pCounts] + repeat word[p +_nImports] ' for each import, add the import's VAR size multiplied by its count + interObjectOffset := word[ word[pImports] +_startAddress] - word[p +_startAddress] + repeat word[pCounts] + AddToChecksum( @totalVarSize, 2 ) ' checksum needs to include this half of an object table entry + AddToChecksum( @interObjectOffset, 2 ) ' and this other half of an object table entry + + totalVarSize += word[ word[pImports] +_totalVarSize] + + pImports += 2 + pCounts += 2 + + word[p +_totalVarSize] := totalVarSize + +pri AddToChecksum( p, n ) + repeat n + checksum += byte[p++] + +pri AddSob( pName ) : p | n +{{ + Copies name to data area, appends name to the sobs list, returns pointer to new sob entry. +}} + if verbosity => 2 + term.str(string("adding ")) + term.str(pName) + term.out(13) + + p := pSobSpace + pSobSpace += _SIZEOFSOBINFO + + n := strsize(pName) + 1 + bytemove( Alloc(n), pName, n ) + + word[pLast +_pNext] := p + word[pLastSorted +_pNextSorted] := p + word[p +_pName] := pDataSpace + word[p +_pNext]~ + word[p +_pNextSorted]~ + pLast := p + pLastSorted := p + +pri Alloc( n ) + pDataSpace := (pDataSpace - n) & $fffffffc ' long-aligned + if pDataSpace < pSobSpace + abort string("Insufficient sob table space") + return pDataSpace + +pri FindSob( pName ) : p | pPrev +{{ + Search the sob list in priority order. If a sob in the list matches name, + update priority-order links to put the sob at the end and return a pointer to it. + Otherwise, return 0. +}} + p := pPrev := pFirst + repeat while p + if strcomp( word[p +_pName], pName ) + if p <> pLastSorted + word[pPrev +_pNextSorted] := word[p +_pNextSorted] + word[pLastSorted +_pNextSorted] := p + word[p +_pNextSorted]~ + pLastSorted := p + return + pPrev := p + p := word[p +_pNextSorted] + return 0 + +pri ProcessSob( p, top ) | len, numExports, exportSize, numImports, importSize, objBinSize, hash, pStart, temp, pImports, pCounts, ts0, ts1 +{{ + Reads the sob file identified by p, appends the sob's imports to the sob list, + then recursively processes the imported sobs. + top is true for the top sob, false for all other sobs. +}} + Str.Copy( @stringBuffer, word[p +_pName] ) + Str.Append( @stringBuffer, string(".SOB") ) + + if verbosity => 2 + term.str( string("Reading [") ) + term.str( @stringBuffer ) + term.out( "]" ) + term.out( 13 ) + + fs.Open( @stringBuffer, "R" ) + + if fs.Readlong <> SOBFILEFORMATVERSION ' SOB file format version + abort string("Unrecognized SOB file format") + long[p +_timestamp] := fs.Readlong ' timestamp + hash := fs.ReadLong ' hash + numExports := fs.ReadWord ' number of exports + exportSize := fs.ReadWord ' size of exports segment + numImports := fs.ReadWord ' number of imports + importSize := fs.ReadWord ' size of imports segment + word[p +_objBinSize] := fs.ReadWord ' size of bytecode segment + byte[p +_checksum] := fs.ReadByte ' checksum + fs.ReadByte ' padding + word[p +_varSize] := fs.ReadWord ' size of sob's VAR space + + ts0 := long[p +_timestamp] + + if top + ReadExports( numExports ) + else + fs.SkipBytes( exportSize ) + + word[p +_exportImportSize] := exportSize + importSize + + word[p +_nImports] := numImports + word[p +_pImports] := pImports := Alloc( numImports << 1 ) ' points to an array of sob pointers + word[p +_pCounts] := pCounts := Alloc( numImports << 1 ) ' points to an array of sob counts + + pStart := pLast + repeat numImports + fs.ReadStringUpperCase( @stringBuffer, 8 ) + ts1 := GetTimestamp( @stringBuffer ) + if ts0 and ts1 ' Only compare non-zero timestamps + if ts0 =< ts1 + term.str( word[p+_pName] ) + term.str( string(".SOB is older than ") ) + term.str( @stringBuffer ) + term.str( string(".SOB", 13) ) + outOfDate~~ + ifnot temp := FindSob( @stringBuffer ) + temp := AddSob( @stringBuffer ) + word[pImports] := temp + word[pCounts] := fs.ReadWord + fs.ReadByte ' reserved byte + if verbosity => 3 + term.str( word[ word[pImports] +_pName] ) + term.out( "*" ) + term.dec( word[pCounts] ) + term.out( 13 ) + pImports += 2 + pCounts += 2 + + if top + fs.SkipBytes( $4 ) ' look into the top sob's object header + firstPubOffset := fs.ReadWord ' and get offset to first pub + firstPubLocalsSize := fs.ReadWord ' and size of first pub's locals + + fs.Close + + ' Process the imported sobs + + pStart := word[pStart +_pNext] + repeat while pStart + ProcessSob( pStart, false ) + pStart := word[pStart +_pNext] + + if verbosity => 2 + term.str( string("done with ") ) + term.str( word[p +_pName] ) + term.out( 13 ) + +pri GetTimestamp( pFilename ) + str.Append( pFilename, string(".SOB") ) + fs[1].Open( pFilename, "R" ) + fs[1].ReadLong + result := fs[1].ReadLong + fs[1].Close + byte[pFilename][ strsize(pFilename) - 4 ]~ ' remove .SOB tail + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} + \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx2/methods.spn b/zubehör/sphinx/spinx100225-ori/sphinx2/methods.spn new file mode 100644 index 0000000..cec76d7 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx2/methods.spn @@ -0,0 +1,1172 @@ +' 2010-01-25 fix for outa[x..y] := z + +obj + bt : "bintree" + st : "symbols" + kw : "kwdefs" + eval : "eval" + token : "tokenrdr" + +var + long pLocalSymbols + byte repeatDepth ' nested REPEAT depth. 0 => at top level + word pStringWork + word pObjSpace + word pObjWork + word pObjTop + +pub get_pObjSpace + return pObjSpace + +pub set_pObjSpace( p ) + pObjSpace := p + +pub get_pObjWork + return pObjWork + +pub set_pObjWork( p ) + pObjWork := p + +pub get_pObjTop + return pObjTop + +pub set_pObjTop( p ) + pObjTop := p + +pub Parse2( type ) | pSym, pHeaderEntry, dim, localOffset, addedResult +{{ + Second pass processing of PRI and PUB methods. +}} + pLocalSymbols := bt.Alloc( 2 ) ' Local symbol table space will be freed at the end of this method + bt.PokeW( pLocalSymbols, 0 ) + + pStringWork := pObjTop ' temp string storage starts at high end of memory + + pSym := st.SymbolLookup( token.Text ) + + pHeaderEntry := pObjSpace + byte[pSym][1] << 2 ' method index * 4 + + token.Advance ' past method name + + localOffset := 4 ' LOC+0 is RESULT, LOC+4, +8, +12... are params, beyond that are locals + ' parse parameter names + if token.AdvanceIf( kw#kLPAREN ) + repeat + ifnot token.IsId + abort string("Expected ID") + if st.SymbolLookup( token.Text ) + abort string("Expected unique parameter name") + bt.AddToTable( token.Text, pLocalSymbols ) + bt.PokeW( bt.Alloc(2), localOffset ) + localOffset += 4 + token.Advance + while token.AdvanceIf( kw#kCOMMA ) + token.Eat( kw#kRPAREN ) + + ' parse return value + addedResult~ + if token.AdvanceIf( kw#kCOLON ) + ifnot token.IsId or token.Type == kw#kRESULT + abort string("Expected ID") + if st.SymbolLookup( token.Text ) + abort string("Expected unique result name") + bt.AddToTable( token.Text, pLocalSymbols ) + bt.PokeW( bt.Alloc(2), 0 ) + addedResult := token.Type == kw#kRESULT + token.Advance + + ifnot addedResult + bt.AddToTable( string("RESULT"), pLocalSymbols ) + bt.PokeW( bt.Alloc(2), 0 ) + + ' parse local variables + if token.AdvanceIf( kw#kBAR ) + ifnot token.IsId + abort string("Expected ID") + repeat + if st.SymbolLookup( token.Text ) + abort string("Expected unique variable name") + bt.AddToTable( token.Text, pLocalSymbols ) + bt.PokeW( bt.Alloc(2), localOffset ) + token.Advance + if token.AdvanceIf( kw#kLBRACKET ) + dim := Eval.EvaluateExpression( 0 ) + token.Eat( kw#kRBRACKET ) + else + dim := 1 + localOffset += dim << 2 + while token.AdvanceIf( kw#kCOMMA ) + token.Eat( kw#kEOL ) + + word[pHeaderEntry][0] := pObjWork - pObjSpace + ' Now store size of locals in header. + word[pHeaderEntry][1] := localOffset - (byte[pSym][2] + 1) << 2 + +''' DumpLocals( bt.PeekW( pLocalSymbols ) )''' + + repeatDepth~ + pFloatingReferences~ + + CompileStatements( -1 ) + + Emit( $32 ) ' RETURN + + StringCleanup + ResolveFloatingReferences + + bt.Alloc( pLocalSymbols - bt.Alloc(0) ) ' hack to free local symbol table memory + ' should be fine as long as no permanent allocations were made + +pri CompileStatements( col ) | p, op, nArgs + repeat until token.IsBlockDesignator or token.Type == kw#kEOF or token.Column =< col + if token.Type == kw#kIF or token.Type == kw#kIFNOT + CompileIf + elseif token.Type == kw#kREPEAT + CompileRepeat + elseif token.Type == kw#kCASE + CompileCase + elseif token.AdvanceIf( kw#kRETURN ) + if token.Type == kw#kEOL + Emit( $32 ) ' RETURN + else + CompileExpression( 13, true, false ) + Emit( $33 ) ' RETVAL + token.Eat( kw#kEOL ) + elseif token.AdvanceIf( kw#kABORT ) + if token.Type == kw#kEOL + Emit( $30 ) ' ABORT + else + CompileExpression( 13, true, false ) + Emit( $31 ) ' ABOVAL + token.Eat( kw#kEOL ) + elseif token.AdvanceIf( kw#kNEXT ) + NextQuitHelper( nextDest ) + elseif token.AdvanceIf( kw#kQUIT ) + NextQuitHelper( quitDest ) + elseif token.IsStmtFn + op := token.GetSpinOpcode + nArgs := token.GetNumArgs + token.Advance + CompileArgs( nArgs ) + Emit( op ) + token.Eat( kw#kEOL ) + elseifnot token.AdvanceIf( kw#kEOL ) + CompileExpression( 13, false, false ) + token.Eat( kw#kEOL ) + +pri NextQuitHelper( dest ) + ifnot repeatDepth + abort string("No enclosing REPEAT") + if caseNesting + EmitPushInt( caseNesting << 3 ) + Emit( $14 ) ' mystery op + + Emit( $04 ) ' GOTO + MakeFloatingReference( pObjWork, dest ) + Emit( $80 ) ' placeholder + Emit( $00 ) + token.Eat( kw#kEOL ) + +pri CompileIf | col, jumpOp, pIfJump, pElseJump +{{ + Current token is IF, IFNOT, ELSEIF, or ELSEIFNOT. +}} + col := token.Column + if token.Type == kw#kIF or token.Type == kw#kELSEIF + jumpOp := $0a ' JPF + else + jumpOp := $0b ' JPT + token.Advance + CompileExpression( 13, true, false ) + pIfJump := MakeForwardJump( jumpOp ) + token.Eat( kw#kEOL ) + CompileStatements( col ) + if token.Column == col + if token.AdvanceIf( kw#kELSE ) + pElseJump := MakeForwardJump( $04 ) ' GOTO + ResolveForwardJump( pIfJump ) + token.Eat( kw#kEOL ) + CompileStatements( col ) + ResolveForwardJump( pElseJump ) + return + if token.Type == kw#kELSEIF or token.Type == kw#kELSEIFNOT + pElseJump := MakeForwardJump( $04 ) ' GOTO + ResolveForwardJump( pIfJump ) + CompileIf + ResolveForwardJump( pElseJump ) + return + ResolveForwardJump( pIfJump ) + +pri MakeForwardJump( jumpOp ) +{{ + Emits jump instruction with 2-byte jump offset to be filled in by a subsequent call to ResolveJump. + Returns a pointer to the jump instruction; pass this pointer to ResolveJump. +}} + result := pObjWork + Emit( jumpOp ) + Emit( $00 ) + Emit( $00 ) + +pri ResolveForwardJump( pJump ) | d, p +{{ + Resolves the jump instruction at pJump. If that instruction is part of a linked list + of jumps (as in a bunch of QUIT jumps out of a loop) then this method resolves all + the linked jumps. +}} + repeat while pJump + d := pObjWork - pJump - 3 + p := bt.PeekW( pJump + 1 ) + if d =< 16383 + byte[pJump][1] := $80 + (d >> 8) + byte[pJump][2] := d + else + abort string("Jump out of range(1)") + pJump := p + +pri MarkBackwardJumpDestination + return pObjWork + +pri ResolveBackwardJump( jumpOp, pDest ) | d +{{ + Emits a jump instruction to the location pointed to by pDest. +}} + Emit( jumpOp ) + d := pDest - pObjWork - 1 ' d < 0 + if d => -64 + Emit( d + 128 ) + elseif --d => -16384 ' decrementing d to compensate for emitting an additional byte + Emit( (d >> 8) + 256 ) + Emit( d ) + else + abort string("Jump out of range(2)") + +var + word nextDest ' destination for NEXT + word quitDest ' destination for QUIT +dat +uniqueDest word $8000 + +var + byte caseNesting { #CASE levels between REPEAT and NEXT or QUIT. E.g. + REPEAT + CASE + NEXT caseNesting = 1 + CASE + REPEAT + NEXT caseNesting = 0 + NEXT caseNesting = 2 +} + +pri CompileRepeat | col, pJump, saveNextDest, saveQuitDest, pQuitJump, jumpOp, topDest, fromAllowed, p, q { +}, pFromVarStart { points to start of code for REPEAT FROM variable +}, pFromVarEnd { points to end " +}, pFromVarOp { points to the PUSH op that has to change to USING +}, pFromToExprStart { points to start of code for FROM..TO.. expressions +}, pFromToExprEnd { points to end " +}, pStepExprStart { points to start of STEP expression +}, pStepExprEnd { points to end " +}, saveCaseNesting +{{ + Current token is REPEAT +}} + saveNextDest := nextDest + saveQuitDest := quitDest + ++repeatDepth + nextDest := uniqueDest++ + quitDest := uniqueDest++ + + saveCaseNesting := caseNesting~ ' save case nesting, make it 0 + + col := token.Column + token.Advance + if token.AdvanceIf( kw#kEOL ) ' Uncounted REPEAT or REPEAT ... WHILE/UNTIL -- can't tell until the end of the loop + topDest := MarkBackwardJumpDestination + CompileStatements( col ) + + jumpOp := $04 ' GOTO (used if this is an uncounted REPEAT) + if token.Column == col + if token.AdvanceIf( kw#kWHILE ) + jumpOp := $0b ' JPT + elseif token.AdvanceIf( kw#kUNTIL ) + jumpOp := $0a ' JPF + if jumpOp == $04 + Retarget( nextDest, topDest ) ' for plain uncounted REPEAT, NEXT jumps to the top of the loop. + else + Retarget( nextDest, pObjWork ) ' for REPEAT ... WHILE/UNTIL , NEXT jumps to the expression. + CompileExpression( 13, true, false ) + token.Eat( kw#kEOL ) + + ResolveBackwardJump( jumpOp, topDest ) ' back to top of loop + Retarget( quitDest, pObjWork ) + + elseif token.Type == kw#kWHILE or token.Type == kw#kUNTIL + jumpOp := $0a ' JPF + if token.Type == kw#kUNTIL + jumpOp := $0b ' JPT + token.Advance + nextDest := topDest := MarkBackwardJumpDestination + CompileExpression( 13, true, false ) + token.Eat( kw#kEOL ) + pJump := MakeForwardJump( jumpOp ) + CompileStatements( col ) + ResolveBackwardJump( $04, topDest ) ' GOTO top of loop + ResolveForwardJump( pJump ) + Retarget( quitDest, pObjWork ) + + else ' REPEAT expr or REPEAT var FROM... + pFromVarStart := pObjWork + fromAllowed := CompileExpression( 13, true, true ) + if token.AdvanceIf( kw#kFROM ) ' REPEAT var FROM... + ifnot fromAllowed + abort string("FROM not allowed") + { + REPEAT var FROM f TO t STEP s + If we just generated the bytecode in order, we'd get + vPUSHffffttttssss + What we want is + ffffvPOP + the body of the loop + ssssffffttttvUSING+RPTINCJ + (vPUSH is the code for pushing var; we'll modify the PUSH op to POP and then to USING.) + So: + Generate vPUSH, copy it to temp storage, and reset pObjWork to overwrite it. + Generate ffff and note pObjWork. + Generate tttt, copy fffftttt to temp storage. + Generate ssss, copy to temp storage. + Reset pObjWork to overwrite ttttssss. + Modify vPUSH to vPOP, emit it after ffff. + Generate the code for the body of the loop. + Emit ssss. + Emit fffftttt. + Modify vPOP to vUSING, emit it. + Emit RPTINCJ or RPTADDJ + } + pFromVarOp := fromAllowed + pFromVarEnd := pObjWork + p := SaveBytes( pFromVarStart, pFromVarEnd ) + pObjWork := pFromVarStart ' overwrite var code + pFromVarEnd -= pFromVarStart - p + pFromVarOp -= pFromVarStart - p + pFromVarStart := p + + pFromToExprStart := pObjWork + CompileExpression( 13, true, false ) ' FROM expression + token.Eat( kw#kTO ) + q := pObjWork ' we're going to reset pObjWork to this point to overwrite TO and STEP expressions. + CompileExpression( 13, true, false ) ' TO expression + pFromToExprEnd := pObjWork + p := bt.Alloc( pFromToExprEnd - pFromToExprStart ) + bytemove( p, pFromToExprStart, pFromToExprEnd - pFromToExprStart ) + pFromToExprEnd -= pFromToExprStart - p + pFromToExprStart := p + pStepExprStart~ + if token.AdvanceIf( kw#kSTEP ) + pStepExprStart := pObjWork + CompileExpression( 13, true, false ) ' STEP expression + pStepExprEnd := pObjWork + p := SaveBytes( pStepExprStart, pStepExprEnd ) + pStepExprEnd -= pStepExprStart - p + pStepExprStart := p + token.Eat( kw#kEOL ) + + pObjWork := q + + ' change PUSH to POP + if byte[pFromVarOp] | 1 == $3f ' reg? + byte[pFromVarOp][1] += $20 ' modify following byte: $9r => $br + else + ++byte[pFromVarOp] ' PUSH => POP + + repeat p from pFromVarStart to pFromVarEnd-1 + Emit( byte[p] ) + + topDest := MarkBackwardJumpDestination + + CompileStatements( col ) + + Retarget( nextDest, pObjWork ) + + jumpOp := $02 ' RPTINCJ for no STEP + if pStepExprStart ' emit STEP expression if present + repeat p from pStepExprStart to pStepExprEnd - 1 + Emit( byte[p] ) + jumpOp := $06 ' RPTADDJ for STEP + + repeat p from pFromToExprStart to pFromToExprEnd - 1 ' emit FROM and TO expressions + Emit( byte[p] ) + + ' change POP to USING + if byte[pFromVarOp] | 1 == $3f ' reg? + byte[pFromVarOp][1] += $20 ' modify following byte: $br => $dr + else + ++byte[pFromVarOp] ' POP => USING + + repeat p from pFromVarStart to pFromVarEnd-1 ' emit USING VAR expression + Emit( byte[p] ) + ResolveBackwardJump( jumpOp, topDest ) + + Retarget( quitDest, pObjWork ) + + else ' REPEAT expr + token.Eat( kw#kEOL ) + pQuitJump := MakeForwardJump( $08 ) ' LOOPJPF + topDest := MarkBackwardJumpDestination + + CompileStatements( col ) + + Retarget( nextDest, pObjWork ) + ResolveBackwardJump( $09, topDest ) ' LOOPRPT + ResolveForwardJump( pQuitJump ) + Retarget( quitDest, pObjWork ) + + caseNesting := saveCaseNesting ' restore case nesting + nextDest := saveNextDest + quitDest := saveQuitDest + --repeatDepth + +pri SaveBytes( p, q ) : r | l + r := bt.Alloc( l := q - p ) + bytemove( r, p, l ) + +pri CompileCase | col, matchCol, otherEncountered, p0, p1, p2, pMatch, pCase +{{ + Current token is CASE. +}} + ++caseNesting + otherEncountered~ + p0~ + p1~ + col := token.Column + token.Advance + Emit( $39 ) ' PUSH#k2 + MakeFloatingReference( pObjWork, pObjWork ) ' Eventually this will be the offset (within the obj) to the end of the CASE construct. + pCase := pObjWork + Emit( 0 ) ' placeholder + Emit( 0 ) ' " + CompileExpression( 13, true, false ) + token.Eat( kw#kEOL ) + matchCol := token.Column + if matchCol =< col + abort string("No cases encountered") + repeat while token.Column > col + if token.AdvanceIf( kw#kOTHER ) + otherEncountered~~ + token.Eat( kw#kCOLON ) + CompileStatements( matchCol ) + Emit( $0c ) ' GOTO [] + Swaperoo( p0, p1, pObjWork ) + quit + else + pMatch := pObjWork + repeat + CompileExpression( 13, true, false ) + if token.AdvanceIf( kw#kDOTDOT ) + CompileExpression( 13, true, false ) + Emit( $0e ) ' CASER + MakeFloatingReference( pObjWork, pMatch ) + Emit( $80 ) + Emit( 0 ) + else + Emit( $0d ) ' CASE + MakeFloatingReference( pObjWork, pMatch ) + Emit( $80 ) + Emit( 0 ) + while token.AdvanceIf( kw#kCOMMA ) + token.Eat( kw#kCOLON ) + Retarget( pMatch, pObjWork ) + Swaperoo( p0, p1, pObjWork ) + p0 += pObjWork - p1 + CompileStatements( matchCol ) + Emit( $0c ) ' GOTO [] + p1 := pObjWork + + ifnot otherEncountered + Emit( $0c ) ' GOTO [] + Swaperoo( p0, p1, pObjWork ) + + Retarget( pCase, pObjWork ) + --caseNesting + +var + word pFloatingReferences +{ + Floating reference data structure: 2-byte source address, 2-byte destination address, 2-byte pointer to next floating reference. + Floating refs are stored in temporary bt.Alloc-ed memory which is reclaimed after each method is compiled. +} +pri MakeFloatingReference( src, dst ) | p + p := bt.Alloc( 6 ) + bt.PokeW( p , src ) + bt.PokeW( p+2, dst ) + bt.PokeW( p+4, pFloatingReferences ) + pFloatingReferences := p + +pri Retarget( dst0, dst1 ) | p +{{ + Retarget any floating refs with destination dst0 to dst1. +}} + p := pFloatingReferences + repeat while p + if bt.PeekW( p+2 ) == dst0 + bt.PokeW( p+2, dst1 ) + p := bt.PeekW( p+4 ) + +pri ResolveFloatingReferences | p, src, dst, b, d + + p := pFloatingReferences + repeat while p + dst := bt.PeekW( p+2 ) + src := bt.PeekW( p ) + b := byte[src-1] + if b == $39 ' PUSH#k2 at beginning of CASE + byte[src] := (dst - pObjSpace) >> 8 + byte[src+1] := dst - pObjSpace + elseif b == $0d or b == $0e or b == $04 or b == $0a or b == $0b or b == $87 ' CASE or CASER or GOTO or JPF or JPT or PUSH#.B (for STRING) + d := dst - src - 2 ' relative offset + if b == $87 ' except for PUSH#.B + d := dst - pObjSpace + byte[src] := (d >> 8) | $80 ' SHOULDDO: range check + byte[src+1] := d + p := bt.PeekW( p+4 ) + +pri Swaperoo( p0, p1, p2 ) | pFR, src, dst +{{ + Exchanges bytes [p0..p1) with [p1..p2) + E.g. abcdeXYZ => XYZabcde + Updates any floating references that have endpoints in [p0..p2) +}} + if p0 == p1 + return + + pFR := pFloatingReferences + repeat while pFR + bt.PokeW( pFR , AdjustEndpoint( bt.PeekW( pFR ), p0, p1, p2 ) ) + bt.PokeW( pFR+2, AdjustEndpoint( bt.PeekW( pFR+2 ), p0, p1, p2 ) ) + pFR := bt.PeekW( pFR+4 ) + + Reverse( p0, p1 ) + Reverse( p1, p2 ) + Reverse( p0, p2 ) + +pri AdjustEndpoint( p, p0, p1, p2 ) +{{ + Addresses [p0..p1) will be swapped with [p1..p2). + If p is in the affected range, return p's new value; otherwise, just return p +}} + if p0 =< p and p < p1 + return p + p2 - p1 ' [p0..p1) will be shifted p2-p1 bytes + if p1 =< p and p < p2 + return p - p1 + p0 ' p used to be p-p1 from p1, will be p-p1 from p0 + return p + +pri Reverse( i, j ) | t +{{ + Reverses bytes [i..j) + E.g. abcde => edcba +}} + repeat while i < --j + t := byte[i] + byte[i++] := byte[j] + byte[j] := t + +pri CompileString | p, size +{{ + Current token is the ( after STRING. + + Copy the string byte-by-byte to pObjWork, then copy the string up to + temp string storage in high memory. The reason for this nutty two-step is + the string length is unknown to begin with, so we don't know how much + temp string storage to allocate, but we can't leave the string at pObjWork + because it will doubtlessly be overwritten by subsequent calls to Emit. +}} + token.Eat( kw#kLPAREN ) + p := pObjWork + repeat + byte[p++] := Eval.EvaluateExpression( 0 ) + while token.AdvanceIf( kw#kCOMMA ) + byte[p++]~ + size := p - pObjWork + if (pStringWork -= size) < pObjWork + abort string("Out of string space") + bytemove( pStringWork, pObjWork, size ) + Emit( $87 ) ' PUSH#.B + MakeFloatingReference( pObjWork, pStringWork ) + Emit( 0 ) ' placeholder: this will eventually be the address of the string. + Emit( 0 ) + + token.Eat( kw#kRPAREN ) + +pri StringCleanup | size, p +{{ + Call this at the end of compiling a method to move the strings down to abut the rest of the method code + and adjust floating references. +}} + p := pFloatingReferences + repeat while p + bt.PokeW( p+2, AdjustEndpoint( bt.PeekW( p+2 ), pObjWork, pStringWork, pObjTop ) ) + p := bt.PeekW( p+4 ) + + size := pObjTop - pStringWork ' we're going to move this many bytes + bytemove( pObjWork, pStringWork, size ) ' + pObjWork += size + +con +#0, opPUSH, opPOP, opUSING, opPEA, opNONE = -1 +#0, MEMSPACE, DATSPACE, VARSPACE, LOCALSPACE, REGSPACE, SPRSPACE + +pri CompileExpression( rbp, push, fromAllowed ) | prec, opcode, opcode2, lbp + prec := token.GetPrecedence + + if token.AdvanceIf( kw#kAT ) + CompileVariable( push, opPEA, 0, false ) + elseif token.AdvanceIf( kw#kMINUS ) + if push + if token.IsIntLiteral or token.IsFloatLiteral + EmitPushInt( -token.Value ) + token.Advance + else + CompileExpression( prec, push, false ) + Emit( $e6 ) ' NEG + else ' in-place negate requires variable operand + CompileVariable( push, opUSING, $46, false ) ' NEG + elseif token.AdvanceIf( kw#kPLUS ) + if push + if token.IsIntLiteral or token.IsFloatLiteral + EmitPushInt( token.Value ) + token.Advance + else ' in-place negate requires variable operand + CompileVariable( push, opPUSH, 0, false ) ' just push + else + abort string("Syntax error after +") + elseif token.IsPostfixOp ' At this point, a postfix op is a prefix op + opcode := token.GetSpinOpcode + token.Advance + CompileVariable( push, opUSING, opcode, false ) + elseif token.AdvanceIf( kw#kATAT ) ' special handling for @@ + if push + CompileExpression( prec, push, false ) + Emit( $97 ) 'PUSH#.B OBJ+0[] + Emit( 0 ) + else + abort string("@@ must push") + elseif token.IsUnaryOp + opcode := token.GetSpinOpcode + opcode2 := token.GetSpinOpcode2 + ifnot opcode2 + opcode2 := opcode - $a0 + token.Advance + if push + CompileExpression( prec, push, false ) + Emit( opcode ) + else ' in-place unary op requires variable operand + CompileVariable( push, opUSING, opcode2, false ) + elseif token.AdvanceIf( kw#kLPAREN ) + CompileExpression( 13, push, false ) + token.Eat( kw#kRPAREN ) + elseif token.IsIntLiteral or token.IsFloatLiteral + if push + EmitPushInt( token.Value ) + token.Advance + else + abort string("Unexpected literal") + elseif token.IsId + result := CompileId( push, fromAllowed, false ) + elseif token.AdvanceIf( kw#kSTRING ) + CompileString + elseif token.AdvanceIf( kw#kCONSTANT ) + token.Eat( kw#kLPAREN ) + EmitPushInt( Eval.EvaluateExpression( 0 ) ) + token.Eat( kw#kRPAREN ) + elseif token.AdvanceIf( kw#kBACKSLASH ) + CompileId( push, false, true ) + elseif token.IsIntrinsic + CompileIntrinsic( push ) + else + result := CompileVariable( push, opNONE, 0, fromAllowed ) + + repeat + lbp := token.GetPrecedence + if rbp =< lbp + quit + opcode := token.GetSpinOpcode + token.Advance + CompileExpression( lbp, push, false ) + Emit( opcode ) + result~ + +pri Emit( b ) + if pObjWork => pStringWork + abort string("Out of obj space") + byte[pObjWork++] := b + +pri EmitPushInt( v ) | mask, i, negate +{{ + Emits the code the push integer v. +}} + if( v == -1 ) + Emit( $34 ) ' PUSH#-1 + elseif( v == 0 ) + Emit( $35 ) ' PUSH#0 + elseif( v == 1 ) + Emit( $36 ) ' PUSH#-1 + elseif Kp( v ) + ' nothing to do; Kp emits if necessary + else + negate~ + mask~~ + repeat i from 1 to 4 + mask <<= 8 + if (v & mask) == 0 + quit + if (v | !mask) == -1 + negate~~ + !v + quit + + ' here i indicates how many bytes of v to emit (1..4) + v <<= (4-i)<<3 ' left-justify the i bytes we're interested in + Emit( $37 + i ) ' PUSH#k1/PUSH#k2/PUSH#k3/PUSH#k4 + repeat i + Emit( v >> 24 ) ' pushing them out MSByte first + v <<= 8 + if negate + Emit( $e7 ) ' BIT_NOT + +pri Kp( v ) : f | b, m +{{ + If v is one of the special bit patterns below, Kp emits the appropriate code and returns true; + otherwise just returns false. + + Pattern Emits + 2^(b+1) => %000bbbbb + 2^(b+1)-1 => %001bbbbb + !(2^(b+1)) => %010bbbbb + -(2^(b+1)) => %011bbbbb +}} + m := 2 + repeat b from 0 to 30 + f~~ + if v == m + quit + if v == m-1 + b |= $20 + quit + if v == !m + b |= $40 + quit + if v == -m + b |= $60 + quit + m <<= 1 + f~ + if f + Emit( $37 ) ' PUSH#kp + Emit( b ) + +pri CompileId( push, fromAllowed, abortFlag ) | p, type + p := st.SymbolLookup( token.Text ) + ifnot p ' If it's not in the main symbol table... + if abortFlag + abort string("Expected method call") + return CompileVariable( push, opNONE, 0, fromAllowed ) ' ...it might be a local variable. + + type := byte[p] + return CompileIdHelper( p, type, 0, push, fromAllowed, abortFlag, 0, 0 ) + +pri CompileIdHelper( p, type, objIndex, push, fromAllowed, abortFlag, i0, i1 ) | v, methodIndex, nArgs, pObj, expectCon +{{ + returns non-zero if FROM may follow +}} + if abortFlag + ifnot type == st#kPUB_SYMBOL or type == st#kPRI_SYMBOL or type == st#kOBJ_SYMBOL + abort string("Expected method call") + if type == st#kINT_CON_SYMBOL or type == st#kFLOAT_CON_SYMBOL or type == st#kBUILTIN_INT_SYMBOL or type == st#kBUILTIN_FLOAT_SYMBOL + if push + v := bt.PeekL( p+1 ) + EmitPushInt( v ) + else + abort string("CON symbol not allowed here") + token.Advance + elseif type == st#kPUB_SYMBOL or type == st#kPRI_SYMBOL + Emit( ($01 & not push) | ($02 & abortFlag) ) + ' push abort Emit + ' true false $00 ' FRAME call w/ return value + ' false false $01 ' FRAME call w/o return value + ' true true $02 + ' false true $03 + token.Advance + methodIndex := byte[p][1] + nArgs := byte[p][2] + CompileArgs( nArgs ) + if objIndex + if i0 == i1 + Emit( $06 ) ' CALLOBJ + else + Swaperoo( i0, i1, pObjWork ) + Emit( $07 ) ' CALLOBJ[] + Emit( objIndex ) + Emit( methodIndex ) ' method # + else + Emit( $05 ) ' CALL + Emit( methodIndex ) ' method # + elseif type == st#kOBJ_SYMBOL + token.Advance + objIndex := byte[p][3] + p := bt.PeekW( p+1 ) + pObj := bt.PeekW( p + strsize(p) + 2 ) + if token.AdvanceIf( kw#kLBRACKET ) + i0 := pObjWork + CompileExpression( 13, true, false ) + i1 := pObjWork + token.Eat( kw#kRBRACKET ) + token.Eat( kw#kDOT ) + expectCon~ + elseif token.AdvanceIf( kw#kOCTOTHORP ) + expectCon~~ + elseif token.AdvanceIf( kw#kDOT ) + expectCon~ + else + abort string("Expected . or #") + ifnot p := bt.FindInTable( token.Text, pObj ) + abort string("Symbol unknown in sub-object") + type := byte[p] + if expectCon and ( type == st#kINT_CON_SYMBOL or type == st#kFLOAT_CON_SYMBOL ) { +} or not expectCon and ( type == st#kPUB_SYMBOL or type == st#kPRI_SYMBOL ) + CompileIdHelper( p, type, objIndex, push, false, abortFlag, i0, i1 ) + elseif expectCon + abort string("Expected CON symbol") + else + abort string("Expected PUB symbol") + else + result := CompileVariable( push, opNONE, 0, fromAllowed ) + +pri CompileArgs( n ) | t + ifnot n + return + t := kw#kLPAREN + repeat n + token.Eat( t ) ' 1st time, '('; subsequently, ',' + t := kw#kCOMMA + CompileExpression( 13, true, false ) + token.Eat( kw#kRPAREN ) + +pri CompileVariable( push, memop, spinOpcode, fromAllowed ) | space, offset, size, subscripted, dim, p, t, p0, p1 +{{ + Current token is anything that could be a variable: BYTE/WORD/LONG, a special register, SPR, an id. + Returns pointer to PUSH instruction if FROM is permitted to follow, false otherwise. +}} + p0~ + p1~ + subscripted~ + if token.IsSize '========== BYTE/WORD/LONG + space := MEMSPACE + size := |< (token.Type - kw#kBYTE) ' size = 1, 2, or 4 + token.Advance + if token.AdvanceIf( kw#kLBRACKET ) + p0 := pObjWork + CompileExpression( 13, true, false ) + p1 := pObjWork + token.Eat( kw#kRBRACKET ) + if subscripted := token.AdvanceIf( kw#kLBRACKET ) + CompileExpression( 13, true, false ) + p1 := pObjWork + token.Eat( kw#kRBRACKET ) + elseif token.IsReg '========== register (PAR, INA, etc.) + if memop == opPEA + abort string("Can't take address of register") + space := REGSPACE + offset := token.GetReg + size := 2 ' repurpose size for registers: 2 for plain reg + token.Advance + if token.AdvanceIf( kw#kLBRACKET ) + p0 := pObjWork + size~ ' 0 for reg[] + CompileExpression( 13, true, false ) + if token.AdvanceIf( kw#kDOTDOT ) + ++size ' 1 for reg[..] + CompileExpression( 13, true, false ) + p1 := pObjWork + token.Eat( kw#kRBRACKET ) + elseif token.AdvanceIf( kw#kSPR ) '========== SPR + if memop == opPEA + abort string("Can't take address of register") + space := SPRSPACE + token.Eat( kw#kLBRACKET ) + CompileExpression( 13, true, false ) + token.Eat( kw#kRBRACKET ) + elseif token.IsId or token.Type == kw#kRESULT '========== id or RESULT + if p := st.SymbolLookup( token.Text ) + t := byte[p++] + if t == st#kDAT_SYMBOL or t == st#kVAR_SYMBOL + if t == st#kDAT_SYMBOL + space := DATSPACE + else + space := VARSPACE + size := byte[p++] + offset := bt.PeekW( p ) + else + abort string("Expected variable") + elseif p := bt.FindInTable( token.Text, bt.PeekW( pLocalSymbols ) ) + space := LOCALSPACE + size := 4 + offset := bt.PeekW( p ) + else + abort string("Expected variable") + token.Advance + if token.AdvanceIf( kw#kDOT ) + ifnot token.IsSize + abort string("Syntax error") + size := |< (token.Type - kw#kBYTE) + token.Advance + if subscripted := token.AdvanceIf( kw#kLBRACKET ) + p0 := pObjWork + CompileExpression( 13, true, false ) + p1 := pObjWork + token.Eat( kw#kRBRACKET ) + else '========== + abort string("Syntax error") + + ' Now look for assignment or postfix op following variable + + if token.AdvanceIf( kw#kCOLONEQUAL ) ' Straight assignment + if memop <> opNONE + abort string("Assignment not allowed here") + CompileExpression( 13, true, false ) + Swaperoo( p0, p1, pObjWork ) + if( push ) + EmitVariable( space, size, offset, subscripted, opUSING ) + Emit( $80 ) + else + EmitVariable( space, size, offset, subscripted, opPOP ) + return false + elseif token.IsAssignmentOp ' Assignment op (+=, AND=) + spinOpcode := token.GetSpinOpcode - $a0 + token.Advance + CompileExpression( 13, true, false ) + Swaperoo( p0, p1, pObjWork ) + memop := opUSING + elseif token.IsPostfixOp ' Postfix (++) + if memop <> opNONE + abort string("Postfix op not allowed here") + spinOpcode := token.GetSpinOpcode2 + token.Advance + memop := opUSING + + if $20 =< spinOpcode and spinOpcode < $40 ' If pre/post inc/dec, adjust opcode based on size: + spinOpcode += (size >> 1) << 1 + 2 ' size 1, 2, 4 => +2, +4, +6 + if push + spinOpcode |= $80 + if memop == opNONE + memop := opPUSH + if memop == opPUSH and fromAllowed + result := pObjWork + + EmitVariable( space, size, offset, subscripted, memop ) + if memop == opUSING + Emit( spinOpcode ) + +pri EmitVariable( space, size, offset, subscripted, memop ) | op + if space == REGSPACE + Emit( $3d + size ) ' size means something different for reg: 0 => reg[], 1 => reg[..], 0 => reg + Emit( $90 + offset + (memop << 5) ) ' PUSH/POP/USING => $9r/$br/$dr + return + + if space == SPRSPACE + Emit( $24 + memop ) ' PUSH/POP/USING => $24/$25/$26 + return + + if size == 4 and offset < 32 and not subscripted + op := %0100_0000 + offset + memop ' offset is a multiple of 4, given that size = 4 + if space == VARSPACE + Emit( op ) + return + elseif space == LOCALSPACE + Emit( op + %0010_0000 ) + return + op := $80 + ((size>>1) << 5) + (space<<2) + memop + if subscripted + op += |< 4 + Emit( op ) + if( space <> MEMSPACE ) + if offset < $80 + Emit( offset ) + else + Emit( (offset >> 8) | $80 ) ' high byte with MSB set + Emit( offset ) ' low byte + +pri CompileIntrinsic( push ) | t + t := token.Type + token.Advance + if t & $10_00_0 ' LOOKUP|DOWN[Z] end with $1x_xx_x + CompileLookX( t, push ) + return + if t & $20_00_0 ' LOCKCLR/NEW/SET end with $2x_xx_x + CompileLock( t, push ) + return + if t & $100 ' STRCOMP/STRSIZE end with $1x_x + AssertPush( push ) + CompileArgs( t & 3 ) ' could be 1 or 2 + Emit( t >> 4 ) + return + + case t + kw#kCHIPVER: + AssertPush( push ) + Emit( $34 ) ' PUSH#-1 + Emit( $80 ) ' PUSH.B Mem[] + kw#kCLKFREQ: + AssertPush( push ) + Emit( $35 ) ' PUSH#0 + Emit( $c0 ) ' PUSH.L Mem[] + kw#kCLKMODE: + AssertPush( push ) + EmitPushInt( 4 ) + Emit( $80 ) ' PUSH.B Mem[] + kw#kCOGID: + AssertPush( push ) + Emit( $3f ) ' REGPUSH cogid + Emit( $89 ) + kw#kCOGINIT: + AssertNotPush( push ) + CompileCoginewt( false, true ) + kw#kCOGNEW: + CompileCoginewt( push, false ) + kw#kREBOOT: + AssertNotPush( push ) + EmitPushInt( $80 ) + EmitPushInt( $00 ) + Emit( $20 ) ' CLKSET + +pri AssertPush( push ) + ifnot push + abort string("Unexpected (must push)") + +pri AssertNotPush( push ) + if push + abort string("Unexpected (can't push)") + +pri CompileLookX( t, push ) | op, opr, dest +{{ + Current token is ( after LOOKUP/LOOKUPZ/LOOKDOWN/LOOKDOWNZ. + t = token.Type +}} + AssertPush( push ) + op := (t >> 4) & $ff + opr := (t >> 12) & $ff + EmitPushInt( t & 1 ) + Emit( $39 ) ' PUSH#k2 + dest := uniqueDest++ + MakeFloatingReference( pObjWork, dest ) + Emit( 0 ) ' placeholder + Emit( 0 ) + + token.Eat( kw#kLPAREN ) + CompileExpression( 13, true, false ) + token.Eat( kw#kCOLON ) + repeat + CompileExpression( 13, true, false ) + if token.AdvanceIf( kw#kDOTDOT ) + CompileExpression( 13, true, false ) + Emit( opr ) + else + Emit( op ) + while token.AdvanceIf( kw#kCOMMA ) + Emit( $0f ) ' LOOKEND + Retarget( dest, pObjWork ) + + token.Eat( kw#kRPAREN ) + +pri CompileLock( t, push ) | op +{{ + Current token is ( after LOCKCLR/NEW/SET. + t = token.Type +}} + op := (t >> (4 + 8 & push)) & $ff ' fn op is bits 19..12; sub op is 11..4 + CompileArgs( t & 1 ) ' only two possibilities for these LOCK* guys. + Emit( op ) + +pri CompileCoginewt( push, init ) | p0, p1, mark, pSym, index, nArgs +{{ + Compile either COGINIT (init=true) or COGNEW (init=false). + Current token is the ( after COGINIT/NEW. + COGINIT( , , ) + COGNEW( ) +}} + token.Eat( kw#kLPAREN ) + + mark~ + if init + p0 := pObjWork + CompileExpression( 13, true, false ) ' exprA + p1 := pObjWork + token.Eat( kw#kCOMMA ) + + ' see if the current token (start of exprB) is a method name + if (pSym := st.SymbolLookup( token.Text )) and (byte[pSym] == st#kPRI_SYMBOL or byte[pSym] == st#kPUB_SYMBOL) + ' Short-circuit evaluation would be nice here, but this works (it's just a little wasteful). + mark~~ + index := byte[pSym][1] + nArgs := byte[pSym][2] + token.Advance ' exprB is a method call, which + CompileArgs( nArgs ) ' we handle here ourselves + Emit( $39 ) ' PUSH#k2 + Emit( nArgs ) + Emit( index ) + else + ifnot init + Emit( $34 ) ' PUSH#-1 + CompileExpression( 13, true, false ) ' exprB is a plain old expression + + token.Eat( kw#kCOMMA ) + CompileExpression( 13, true, false ) ' exprC + if mark + Emit( $15) ' MARK + if init and mark + Swaperoo( p0, p1, pObjWork ) + Emit( $3f ) ' REGPUSH $8f? + Emit( $8f ) + Emit( $37 ) ' PUSH#kp -4 ($fffffffc) + Emit( $61 ) + Emit( $d1 ) ' POP.L Mem[][] + + if push + Emit( $28 ) ' COGIFUN + else + Emit( $2c ) ' COGISUB + + token.Eat( kw#kRPAREN ) +{''' +pri DumpLocals( p ) | s, t + ifnot p + return + + s := p + 4 + term.str( s ) + s += strsize(s) + 1 + term.out( "@" ) + t := bt.PeekW( s ) + term.dec( t ) + term.out( 13 ) + + DumpLocals( bt.PeekW( p ) ) + DumpLocals( bt.PeekW( p + 2 ) ) +}''' + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} + \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx2/sphinx.spn b/zubehör/sphinx/spinx100225-ori/sphinx2/sphinx.spn new file mode 100644 index 0000000..103766a --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx2/sphinx.spn @@ -0,0 +1,367 @@ +{ + _clkfreq = 96_000_000 ' Hybrid + _clkmode = xtal1 + pll16x + + tvPins = 24 + kbPins = 12 + sdPins = 8 +} + _clkfreq = 80_000_000 ' Hydra + _clkmode = xtal1 + pll8x + + tvPins = 24 + kbPins = 13 + sdPins = 16 +{ + Simple command line + +2009 +April + 15 Adding file transfer to/from PC via serial + 16 0.02 + SendFile bugfix (while blksize == 1024) + Tries to run .bin before .eep now. +June + 4 Changing name from cl to sphinx. Converting to use sxfs, sxtv. + 15 sxkb; adding c and cl commands + 23 Corrected clock mode calculation. +} + +obj + kb: "sxkb" + term: "sxtv" + sxfs: "sxfs" + f: "sxfile" + ser: "fdserial" + +con +SXTVRENDEZVOUS = $8000 - 4 +SXKBRENDEZVOUS = SXTVRENDEZVOUS - 4 +SDSPIRENDEZVOUS = SXKBRENDEZVOUS - 3 * 4 +SXFS2RENDEZVOUS = SDSPIRENDEZVOUS - 4 * 4 ' four rendezvous variables +SXFSRENDEZVOUS = SXFS2RENDEZVOUS - 4 * 4 ' four rendezvous variables +METADATABUFFER = SXFSRENDEZVOUS - 512 + +_free = ($8000 - METADATABUFFER) / 4 + +pub Main | err, p + if term.start( tvPins, SXTVRENDEZVOUS ) + term.str( string("============= Sphinx 090627 ============", 13) ) + term.str( string("video @ pin ") ) + term.dec( tvPins ) + term.str( string(13, "keyboard @ pin ") ) + term.dec( kbPins ) + term.str( string(13, "SD @ pin ") ) + term.dec( sdPins ) + term.out( 13 ) + sxfs.start( sdPins ) + kb.start( kbPins ) + + repeat + if ina[31] ' USB cable connected? + ser.start( 31, 30, %0000, 19200 ) + f.Close + err := \DoIt + if err + if err > 0 + term.str( err ) + else + term.str( string("Error ") ) + term.dec( err ) + term.out( 13 ) + else + term.str( string("Normal exit") ) ' This never happens + +pri DoIt | ch + term.out( ">" ) + term.out( "_" ) + term.out( 8 ) + repeat + if kb.peekkey + EditCmdLine + Execute + term.out( ">" ) + term.out( "_" ) + term.out( 8 ) + if (ch := ser.rxcheck) <> -1 + term.out( 8 ) + FileTransfer( ch ) + term.out( ">" ) + term.out( "_" ) + term.out( 8 ) + +con + MAXCMDLINELENGTH = 78 ' some arbitray limit. + CR = $0d + BKSP = $c8 + +var + byte cmdLine[MAXCMDLINELENGTH+1] ' +1 for null terminator + long cmdLineLength + +pri EditCmdLine | key + cmdLineLength~ ' cursor is always at end of command line + + repeat + case key := kb.key + $20..$7f: + if cmdLineLength < MAXCMDLINELENGTH + cmdLine[ cmdLineLength++ ] := key + term.out( key ) + term.out( "_" ) + term.out( 8 ) + CR: + term.out( " " ) + term.out( 13 ) + cmdLine[ cmdLineLength ]~ + return true + BKSP: + if cmdLineLength + --cmdLineLength + term.out( " " ) + term.out( 8 ) + term.out( 8 ) + term.out( "_" ) + term.out( 8 ) + +pri FileTransfer( cmd ) | ch, i + if cmd <> "G" and cmd <> "P" + term.out( cmd ) + abort string(" -- unrecognized command from PC") + i~ + repeat + ch := RxSerByte + if i => FILENAMEBUFFERSIZE + abort string("Filename too long") + filename[i++] := ch + while ch + + if cmd == "G" + term.str( string("sending ") ) + term.str( @filename ) + term.out( 13 ) + SendFileToPC + else + term.str( string("receiving ") ) + term.str( @filename ) + term.out( 13 ) + ReceiveFileFromPC + +pri SendFileToPC | blksize, i, chksum, b, n + if f.Open( @filename, "R" ) <> 0 + term.str( @filename ) + abort string(" -- can't open file for reading") + TxSerByte( "A" ) ' ack + + n~ + repeat + blksize := f.Read( @buffer, 1024 ) + if blksize == -1 + blksize~ + TxSerByte( blksize.byte[0] ) + TxSerByte( blksize.byte[1] ) + i~ + chksum~ + repeat blksize + b := buffer[i++] + chksum += b + TxSerByte( b ) + n += blksize + if chksum & $ff <> RxSerByte + abort string("Checksum error") + while blksize == 1024 + f.Close + term.dec( n ) + term.str( string(" bytes sent", 13) ) + +pri ReceiveFileFromPC | blksize, i, chksum, b, n + if f.Open( @filename, "W" ) <> 0 + term.str( @filename ) + abort string(" -- can't open file for writing") + TxSerByte( "A" ) ' ack + + n~ + repeat + blksize~ + blksize.byte[0] := RxSerByte + blksize.byte[1] := RxSerByte + if blksize > 1024 + abort string("Block size > 1024") + i~ + chksum~ + repeat blksize + b := RxSerByte + buffer[i++] := b + chksum += b + n += blksize + f.Write( @buffer, blksize ) + TxSerByte( chksum ) + while blksize == 1024 + f.Close + term.dec( n ) + term.str( string(" bytes received", 13) ) + +pri RxSerByte : b +' ser.rx with timeout + b := ser.rxtime( TIMEOUT ) + if b == -1 + abort string("RxSerByte timed out") + +pri TxSerByte( b ) +' just for symmetry with RxSerByte + ser.tx( b ) + +con +TIMEOUT = 500 + +var + byte buffer[1024] + +pri Execute | n, p, q, run, c + c~ + ifnot n := ParseCmdLine + return + p := @cmdLine + ToUpper(p) + + if run := strcomp( @cmdLine, string("RUN") ) + --n + p += strsize(p) + 1 + elseif strcomp( @cmdLine, string("C") ) + c := 1 + --n + p += strsize(p) + 1 ' command arg1 arg2... + elseif strcomp( @cmdLine, string("CL") ) ' run command arg1 arg2... + c := 2 ' c arg1 arg2... + --n ' cl arg1 arg2... + p += strsize(p) + 1 + + ifnot n + abort string("No file specified") + + f.Open( string("args.d8a"), "W" ) ' write args + if c == 0 + q := p + strsize(p) + 1 ' for run and plain command, skip first arg (command name) + --n + f.Write( @n, 1 ) + repeat n + f.Write( q, strsize(q) + 1 ) + q += strsize(q) + 1 + else ' for c and cl, + ++n ' add extra arg (/c or /l) + f.Write( @n, 1 ) + repeat n-1 + f.Write( p, strsize(p) + 1 ) + p += strsize(p) + 1 + if c == 1 + f.Write( string("/c"), 3 ) + else + f.Write( string("/l"), 3 ) + + n~ + f.Write( @n, 1 ) ' final terminating null + f.Close + + if c + if f.Open( string("lex.bin"), "R" ) <> 0 + abort string("lex.bin not found") + ser.stop + f.Execute( 0 ) + + + if EndsWith( p, string(".BIN") ) or EndsWith( p, string(".EEP") ) + if f.Open( p, "R" ) <> 0 + term.str( p ) + abort string(" -- not found") + else + if strsize(p) > MAXFILENAMELENGTH - 4 + term.str( p ) + abort string(" -- filename too long") + bytemove( @filename, p, strsize(p) + 1 ) + bytemove( @filename + strsize(p), string(".BIN"), 5 ) + if f.Open( @filename, "R" ) <> 0 + bytemove( @filename + strsize(p), string(".EEP"), 5 ) + if f.Open( @filename, "R" ) <> 0 + term.str( p ) + abort string(" -- no .bin or .eep found") + ser.stop + f.Execute( run ) + +pri ToUpper( p ) + repeat while byte[p] + if "a" =< byte[p] and byte[p] =< "z" + byte[p] += "A" - "a" + ++p + +pri EndsWith( p, s ) + if strsize(p) < strsize(s) + return false + p += strsize(p) - strsize(s) + repeat while byte[p] + if byte[p++] <> byte[s++] + return false + return true + +con + MAXFILENAMELENGTH = 12 ' 8 + . + 3 + FILENAMEBUFFERSIZE = MAXFILENAMELENGTH + 1 ' 8 + . + 3 + null + CMDNAMEBUFFERSIZE = 9 ' 8 + null + +var + byte filename[MAXFILENAMELENGTH+1] ' 8 + . + 3 + null + +pri ParseCmdLine : n | pSrc, pDst, state +{{ + Converts cmdLine from " ab de fg \" to "ab\de\fg\" ('\' = null). + Returns # of "words". +}} +{ + state whitespace null other char + 0 ++pSrc; append \0; quit append char; => 1 + 1 append \0; ++n; => 0 append \0; ++n; quit append char; +} + pSrc := @cmdLine + pDst := @cmdLine + state~ + repeat + if state == 0 + if byte[pSrc] == " " + ++pSrc + elseif byte[pSrc] == 0 + byte[pDst++]~ + quit + else + byte[pDst++] := byte[pSrc++] + state := 1 + elseif state == 1 + if byte[pSrc] == " " + ++pSrc + byte[pDst++]~ + ++n + state~ + elseif byte[pSrc] == 0 + byte[pDst++]~ + ++n + quit + else + byte[pDst++] := byte[pSrc++] + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} + \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx2/stringx.spn b/zubehör/sphinx/spinx100225-ori/sphinx2/stringx.spn new file mode 100644 index 0000000..c5d8c1e --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx2/stringx.spn @@ -0,0 +1,43 @@ +pub Compare( p, q ) | lp, lq, d +{{ + Compares two strings. Returns a negative number if first string is "less than" the second, + 0 if they're identical, a positive number otherwise. +}} + lp := strsize(p) + lq := strsize(q) + repeat lp <# lq + if (d := byte[p++] - (byte[q++] & $7f)) + return ~~d + return lp-lq + +pub Copy( p, q ) + bytemove( p, q, strsize(q) + 1 ) + +pub Append( p, q ) + Copy( p + strsize(p), q ) + +pub ToUpper( p ) + repeat while byte[p] + if "a" =< byte[p] and byte[p] =< "z" + byte[p] += constant( "A" - "a" ) + ++p + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} + \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx2/sxfile.spin b/zubehör/sphinx/spinx100225-ori/sphinx2/sxfile.spin new file mode 100644 index 0000000..921eae9 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx2/sxfile.spin @@ -0,0 +1,98 @@ +obj + isxfs: "isxfs" + +var +long filestuff[isxfs#SIZEOFFILESTUFF / 4] + +pub Open( pFilename, mode ) + return isxfs.Open( @filestuff, pFilename, mode ) + +pub Close + isxfs.Close( @filestuff ) + +pub Read( ptr, n ) + return isxfs.Read( @filestuff, ptr, n ) + +pub Write( ptr, n ) + return isxfs.Write( @filestuff, ptr, n ) + +pub Length +{{ + Only valid for files opened for reading. +}} + return long[@filestuff] + +pub Execute( mode ) + isxfs.Execute( @filestuff, mode ) + isxfs.Close( @filestuff ) ' we only get here if Execute fails for some reason. + +pub ReadString( p, MAXLENGTH ) | ch + repeat MAXLENGTH + 1 + ch := ReadByte + ifnot byte[p++] := ch + return + abort string("ReadString: string too long") + +pub ReadStringUpperCase( p, MAXLENGTH ) | ch + repeat MAXLENGTH + 1 + ch := ReadByte + if "a" =< ch and ch =< "z" + ch -= constant("a" - "A") + ifnot byte[p++] := ch + return + abort string("ReadStringUpperCase: string too long") + +pub WriteString( p ) + Write( p, strsize(p) + 1 ) + +pub ReadNumber | ch + repeat + ifnot ch := ReadByte + return + if ch < "0" or ch > "9" + abort string("ReadNumber: non-numeric character") + result := result * 10 + ch - "0" + +pub ReadByte : ch + Read( @ch, 1 ) + +pub WriteByte( b ) + Write( @b, 1 ) + +pub ReadWord + return ReadByte + (ReadByte << 8) + +pub WriteWord( w ) + Write( @w, 2 ) + +pub ReadLong + return ReadByte + (ReadByte << 8) + (ReadByte << 16) + (ReadByte << 24) + +pub WriteLong( l ) + Write( @l, 4 ) + +pub SkipBytes( n ) + repeat while n => 32768 + Read( $8000, 32768 ) + n -= 32768 + Read( $8000, n ) + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} + \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx2/sxfs.spn b/zubehör/sphinx/spinx100225-ori/sphinx2/sxfs.spn new file mode 100644 index 0000000..bcbd8d1 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx2/sxfs.spn @@ -0,0 +1,871 @@ +SXTVRENDEZVOUS = $8000 - 4 +SXKBRENDEZVOUS = SXTVRENDEZVOUS - 4 +SDSPIRENDEZVOUS = SXKBRENDEZVOUS - 3 * 4 +SXFS2RENDEZVOUS = SDSPIRENDEZVOUS - 4 * 4 ' four rendezvous variables +SXFSRENDEZVOUS = SXFS2RENDEZVOUS - 4 * 4 ' four rendezvous variables +METADATABUFFER = SXFSRENDEZVOUS - 512 + +_free = ($8000 - METADATABUFFER) / 4 + +{ + sxfsrendezvous sdspirendezvous +--------+ +--------+ +-------+ + | <===> command <===> | | <=====> command <=====> | | + Spin | | | | | +routines| <===> param0 <====> | SXFS | <=====> param <=====> | SDSPI | + | | cog | | cog | + | ----> param1 -----> | | ------> blockno ------> | | + | | | +-------+ + | ----> param2 -----> | | +--------+ | | sxfs2rendezvous + | | +-------+ + | | <====> command <======> | | + | | | | <==> (sxfsrendezvous) + | | <====> param0 <=======> | SXFS2 | + | | | cog | <==> (sdspirendezvous) + | | | | + +--------+ +-------+ + + +SXFS cog handles file reading: open, read, execute, close(?). +SXFS2 cog, under SXFS's direction, handles file writing: open, write, close. +SDSPI cog handles SD card sector reading and writing. + +SXFS cog communicates with main program via sxfsrendezvous and Spin interface routines. +SXFS cog communicates with SXFS2 cog via sxfs2rendezvous. +SXFS cog communicates with SDSPI cog via sdspirendezvous. + +-1: eof, general error +-100: bad command +-101: not FAT16 +-102: file not found +-104: bad mode +-106: file not closed +-107: directory full +-109: file not properly opened +-110: FAT full. +-113: bad filename + +} + +obj + sxfs2: "sxfs2" + sdspi : "sxsdspiq" + +pub Start( sdPin ) | pbrSector + + ' Determine if sxfs cog and, by association, sxfs2 and sdspi cogs, are already running. + ' If not, start them up. + ' Returns true if the cogs needed to be started, false if the cogs were already running. + + ifnot Ping + result~~ + ' start sdspi cog and initialize SD card + long[pSdspiCommand] := "I" + sdspi.start( sdPin, pSdspiCommand ) + repeat while long[pSdspiCommand] + if long[pSdspiParam] + abort long[pSdspiParam] + + pbrSector := ReadPbr + + ' start sxfs cog + long[pCommand] := "?" + if cognew( @sxfsEntry, 0 ) < 0 + abort -1 + repeat while long[pCommand] + + ' start sxfs2 cog + sxfs2.Start( pbrSector ) + +pri ReadPbr : pbrSector + repeat + sdspi.readblock( pbrSector, pMetadataBuffer ) + if bytecompare( pMetadataBuffer+$36, string("FAT16"), 5 ) + quit + if pbrSector + abort -101 ' not FAT16 + pbrSector := PeekL( pMetadataBuffer + $1c6 ) + + bytesPerSector := PeekW( pMetadataBuffer + $0b ) + sectorsPerCluster := byte[pMetadataBuffer][$0d] + clusterShift := >| sectorsPerCluster - 1 + reservedSectors := PeekW( pMetadataBuffer + $0e ) + numberOfFats := byte[pMetadataBuffer][$10] + sectorsPerFat := PeekW( pMetadataBuffer + $16 ) + RootDirEntries := PeekW( pMetadataBuffer + $11 ) + fatSector0 := pbrSector + reservedSectors + dirSector0 := fatSector0 + numberOfFats * sectorsPerFat + dataSector0 := dirSector0 + rootDirEntries >> 4 + +pri bytecompare( _p, _q, _n ) + repeat _n + if byte[_p++] <> byte[_q++] + return + return true + +pri PeekW( a ) + return byte[a++] + byte[a] << 8 + +pri PeekL( a ) + return byte[a++] + byte[a++] << 8 + byte[a++] << 16 + byte[a] << 24 + +pri Ping +{{ + returns 1 if bmfs cog is active, 0 otherwise. +}} + long[pCommand] := "?" + if long[pCommand] + return 0 + else + return 1 + +con + SECTORSIZE = 512 + SECTORSHIFT = 9 + DIRSIZE = 32 + +con +' filestuff definitions +' filestuff must be long-aligned +{ long } _length = 0 +{ long } _leftInFile = 4 +{ long } _sopDir = 8 ' sector/offset "pointer" to directory entry +{ long } _sopTail = 12 ' sector/offset "pointer" to last cluster# in FAT chain +{ word } _cluster = 16 +{ word } _sector = 18 ' sector# within cluster; ranges from 0 to sectorsPerCluster-1 +{ word } _bp = 20 ' byte pointer (actually an index into the sector buffer); range [0..511] +{ word } _mode = 22 ' 0: closed; "R": open for reading; "W": open for writing. + _buffer = 24 ' 512-byte buffer starts here + +SIZEOFFILESTUFF = SECTORSIZE + 24 + +dat +{{ + command param0 param1 param2 + "?" -- -- -- Do nothing, but acknowledge to indicate that sxfs cog is active. + "O" filestuff filename mode Open a file, populate filestuff fields. mode is "R" or "W". + "R" filestuff buffer num Reads num bytes into buffer from file specified by filestuff. + "W" filestuff buffer num Writes num bytes from buffer to file specified by filestuff. + "C" filestuff -- -- Closes file specified by filestuff. + "X" filestuff execmode cog Executes file. + +}} + org 0 +SXFSEntry + +AckNoReturnCode + mov temp, #0 ' clear return code +AckReturnCode ' enter here with temp = return code + wrlong temp, pParam0 + mov temp, #0 + wrlong temp, pCommand ' clear command to signal operation complete. + +:ready ' wait for new command + rdlong temp, pCommand wz + if_z jmp #:ready + + cmp temp, #"?" wz + if_e jmp #AckNoReturnCode + cmp temp, #"O" wz + if_e jmp #Open + cmp temp, #"R" wz + if_e jmp #Read + cmp temp, #"W" wz + if_e jmp #Write + cmp temp, #"C" wz + if_e jmp #Close + cmp temp, #"X" wz + if_e jmp #Execute + ' else + neg temp, #100 ' -100: bad command + jmp #AckReturnCode + + +'********************************************************************************************************************* +'* * +'* Open stuff * +'* * +'********************************************************************************************************************* +Open ' ( param0 = pFilestuff, param1 = pFilename, param2 = mode ) +{ + Return value: + File found File not found Error + mode = "R" 0 1 < 0 + mode = "W" 0 0 < 0 + +Mode W will either open an existing file or create a new file. +} + rdword pFilestuff, pParam0 + rdword pFilename, pParam1 + + mov p, pFilestuff + add p, #_mode + rdword temp, p wz + if_nz neg temp, #106 ' -106: file not closed + if_nz jmp #AckReturnCode + + call #MassageFilename + + rdword temp, pParam2 + cmp temp, #"R" wz + if_e jmp #:openForReading + cmp temp, #"W" wz + if_e jmp #:openForWriting + neg temp, #104 ' -104: bad mode + jmp #AckReturnCode +:openForReading + call #FindFile + + mov p, pFilestuff + add p, #_sopDir ' pFilestuff->sopDir = 0 => file not found + rdlong temp, p wz + if_z mov temp, #1 ' return 1 to indicate file not found + if_z jmp #AckReturnCode + + mov p, sop ' sop sector is still in memory + and p, #$1ff + add p, pMetadataBuffer + add p, #$1a ' point to cluster information + rdword temp, p + + mov q, pFilestuff + add q, #_cluster + wrword temp, q + + add p, #2 ' point to length information + rdlong temp, p + + sub q, #_cluster-_length ' q points to length + wrlong temp, q + add q, #_leftInFile-_length ' q points to leftInFile + wrlong temp, q + + add q, #_sector-_leftInFile ' q points to sector + mov temp, #0 + wrword temp, q + + add q, #_bp-_sector ' q points to bp + wrword k512, q + + mov p, pFilestuff + add p, #_mode + mov temp, #"R" + wrword temp, p ' save mode + + jmp #AckNoReturnCode + +:openForWriting + mov sop, dirSector0 ' sop "points" to directory entries: + shl sop, #9 ' incremented by 32 each time through the loop. + mov sopDir, #0 ' sopDir "points" to the directory entry + ' that will be used or reused for the file being opened. + mov i, rootDirEntries +:forEachDirEntry ' Loop through the directory entries, looking for a deleted entry, + ' an empty entry, or an entry that matches pFilename. + mov sector, sop + shr sector, #9 + call #ReadMetadataSector + mov p, sop + and p, #$1ff + add p, pMetadataBuffer ' p points to the current directory entry + add p, #$0b + rdbyte temp, p ' p[$0b] = attribute byte + sub p, #$0b + and temp, #$02 wz ' If hidden, + if_nz jmp #:next ' skip. Hidden dir entries include long name entries. + + rdbyte temp, p ' p[0] + cmp temp, #$e5 wz ' = $e5? (deleted directory entry?) + if_e cmp sopDir, #0 wz ' save pointer in sopDir (just the first time) + if_e mov sopDir, sop + + tjz temp, #:quit ' empty directory entry? We're done + + mov q, pFilename ' matching filename? Done. + mov n, #11 + call #ByteComp + if_e jmp #:quit +:next + add sop, #DIRSIZE + djnz i, #:forEachDirEntry +:quit + cmp i, #0 wz ' did we go through the whole directory? + if_z neg temp, #107 ' -107: directory full + if_z jmp #AckReturnCode + + cmp sopDir, #0 wz ' if sopDir hasn't been set yet, + if_e mov sopDir, sop ' set it to sop. + + mov p, pFilestuff + add p, #_sopDir + wrlong sopDir, p ' pFilestuff->sopDir := sopDir + add p, #_sopTail-_sopDir + add sopDir, #$1a + wrlong sopDir, p ' pFilestuff->sopTail := sopDir + $1a + ' (points to directory entry's cluster field). + mov sector, sopDir + shr sector, #9 ' Get the chosen directory entry into memory + call #ReadMetadataSector ' if it isn't already. + + mov p, sopDir ' Recall that sopDir was changed + and p, #$1ff ' to point to the cluster field, + add p, pMetadataBuffer ' so p now points to the cluster field in the buffer. + + rdword cluster, p ' Save the cluster field. + mov temp, #0 + wrword temp, p ' Zero the cluster field. + sub p, #$1a ' Point to start of directory entry + + rdbyte temp, p ' Check to see if this was a deleted dir entry. + cmp temp, #$e5 wz ' If it was, we definitely do not want to zero the + if_e mov cluster, #0 ' cluster chain, so set cluster to 0. + + mov q, pFilename ' Store the filename in the directory entry. + mov n, #11 + call #ByteCopy + + mov temp, #$20 ' Set the attribute byte (immediately following name) + wrbyte temp, p + add p, #$10-$0b ' Point to creation date. + mov temp, aDate ' 2001/01/01 + wrword temp, p + add p, #$12-$10 ' Point to last access date. + wrword temp, p + add p, #$18-$12 ' Point to last update date. + wrword temp, p + + mov dirty, #1 ' We've modified metadata. + + tjz cluster, #:done +:forEachClusterInList ' Traverse the cluster list and zero each link. + + mov sector, cluster + shr sector, #8 + add sector, fatSector0 + call #ReadMetadataSector ' Read FAT sector for current cluster + + mov p, cluster + and p, #$ff + shl p, #1 + add p, pMetadataBuffer ' Point p at cluster entry in FAT + + rdword cluster, p ' Get next cluster link. + cmp cluster, #1 wc, wz ' Break if cluster <= 1 + if_be jmp #:done + + mov temp, #0 + wrword temp, p ' Zero the cluster link. + mov dirty, #1 ' We've modified metadata. + + cmp cluster, kfff0 wc, wz ' repeat unless new cluster >= $fff0 + if_b jmp #:forEachClusterInList +:done + mov p, pFilestuff + add p, #_sector + mov temp, #0 + wrword temp, p ' pFilestuff->sector := 0 + add p, #_bp-_sector + wrword temp, p ' pFilestuff->bp := 0 + + mov p, pFilestuff + mov temp, #0 + wrlong temp, p ' pFilestuff->length := 0 + add p, #_mode + mov temp, #"W" + wrword temp, p ' save mode + + jmp #AckNoReturnCode + +MassageFilename +{ + Take the null-terminated 8.3 filename pointed to by pFilename, + move it into memory starting at pFilestuff->buffer and expand it to 11 characters; + change pFilename to point to the expanded filename. +} + mov p, pFilestuff + add p, #_buffer + mov q, p + add p, #1 + mov temp, #" " + wrbyte temp, q + mov n, #10 + call #ByteCopy + + mov q, pFilename ' q is src + mov p, pFilestuff ' p is dst + add p, #_buffer + mov i, #9 ' Copy up to 8 chars (stop at . or null). +:upTo8 + rdbyte temp, q + add q, #1 + tjz temp, #:done + cmp temp, #"." wz + if_z jmp #:dot + call #ValidateChar + wrbyte temp, p + add p, #1 + djnz i, #:upTo8 + ' If we fall through, we've copied 9 characters (tsk tsk). + neg temp, #113 ' -113: bad filename + jmp #AckReturnCode +:dot + mov p, pFilestuff + add p, #_buffer+8 + mov i, #4 ' Copy up to 3 chars (stop at null). +:upTo3 + rdbyte temp, q + add q, #1 + tjz temp, #:done + call #ValidateChar + wrbyte temp, p + add p, #1 + djnz i, #:upTo3 + ' If we fall through, we've copied 4 characters (tsk tsk ). + neg temp, #113 ' -113: bad filename + jmp #AckReturnCode +:done + mov pFilename, pFilestuff + add pFilename, #_buffer + +MassageFilename_ret ret + +FindFile +{ + pFilename points to 11-character buffer (e.g. "BLAH TXT"). + pFilestuff points to a filestuff structure. + Return value: + If file is found, pFilestuff->sopDir is disk address of directory entry. + If file is not found, pFilestuff->sopDir is 0. +} + mov sop, dirSector0 ' sop starts at dirSector0<<9, counts up by DIRSIZE + shl sop, #SECTORSHIFT + mov i, rootDirEntries +:loop + mov sector, sop + shr sector, #9 + call #readMetadataSector + mov p, sop + and p, #$1ff + add p, pMetadataBuffer + rdbyte temp, p wz + if_z jmp #:notfound + + add p, #$0b + rdbyte temp, p ' p[$0b] = attribute byte + sub p, #$0b + and temp, #$02 wz ' If hidden, + if_nz jmp #:next ' skip. Hidden dir entries include long name entries. + + mov q, pFilename + mov n, #11 + call #ByteComp + if_e jmp #:found +:next + add sop, #DIRSIZE + djnz i, #:loop +:notfound + mov sop, #0 +:found + mov p, pFilestuff + add p, #_sopDir + wrlong sop, p +FindFile_ret ret + + +'********************************************************************************************************************* +'* * +'* Read stuff * +'* * +'********************************************************************************************************************* +Read ' ( param0 = pFilestuff, param1 = ptr, param2 = n ) +{ + Read n bytes from file described by pIoblock into memory starting at p. + Returns number of bytes actually read or -1 if attempting to read past EOF. +} + rdlong pFilestuff, pParam0 + rdlong destPtr, pParam1 + rdlong nBytes, pParam2 + + mov p, pFilestuff ' Verify that file was opened for reading. + add p, #_mode + rdword temp, p + cmp temp, #"R" wz + if_ne neg temp, #109 ' -109: file not properly opened + if_ne jmp #AckReturnCode + sub p, #_mode-_leftInFile + + ' Adjust nBytes depending on how much is left to read in file. + ' E.g. if we're 10 bytes from EOF and we try to read 15 bytes, + ' just read 10. If we're at EOF and try to read 15 bytes, return -1. + rdlong temp, p + max nBytes, temp ' nBytes is lesser of nBytes and leftInFile + tjnz temp, #:x + neg temp, #1 ' -1: eof + jmp #ackReturnCode +:x + mov retcode, nBytes +:while + mov leftInSector, k512 ' leftInSector = 512 - pFilestuff->bp + mov p, pFilestuff + add p, #_bp + rdword temp, p ' temp = bp + sub leftInSector, temp + cmp leftInSector, nBytes wc, wz + if_ae jmp #:endwhile + mov p, destPtr + mov q, pFilestuff + add q, #_buffer ' q points to buffer area + add q, temp ' offset by bp (= temp) + mov n, leftInSector + call #ByteCopy ' bytemove( p, q, n ) + add destPtr, leftInSector ' destPtr += leftInSector + sub nBytes, leftInSector ' nBytes -= leftInSector + mov p, pFilestuff ' long[pIoblock+_leftInFile] -= leftInSector + add p, #_leftInFile + rdlong temp, p + sub temp, leftInSector + wrlong temp, p + +' sdspi.readblock( dataSector0 + (word[pFilestuff+_cluster] - 2) << clusterShift + word[pFilestuff+_sector], pFilestuff+_buffer ) + add p, #_cluster-_leftInFile + rdword temp, p ' temp = (cluster + sub temp, #2 ' - 2) + shl temp, clusterShift ' << clusterShift + add temp, dataSector0 ' + dataSector0 + add p, #_sector-_cluster + rdword temp1, p + add temp, temp1 ' + cluster + wrlong temp, pSdspiBlockno ' Prepare to read sector + add p, #_buffer-_sector + wrlong p, pSdspiParam + mov temp, #"R" + call #SdspiCommand + +' if ++word[pFilestuff+_sector] == sectorsPerCluster + mov p, pFilestuff + add p, #_sector + rdword temp, p + add temp, #1 + wrword temp, p + cmp temp, sectorsPerCluster wz + if_ne jmp #:y + +' word[pIoblock+_sector]~ + mov temp, #0 + wrword temp, p +' word[pFilestuff+_cluster] := NextCluster( word[pFilestuff+_cluster] ) + sub p, #_sector-_cluster + rdword cluster, p + call #NextCluster '( cluster ) + mov p, pFilestuff + add p, #_cluster + wrword cluster, p +:y +' word[pFilestuff+_bp]~ + mov p, pFilestuff + add p, #_bp + mov temp, #0 + wrword temp, p + + jmp #:while +:endwhile +' bytemove( destPtr, pIoblock + word[pIoblock+_bp], n ) + mov p, destPtr + mov q, pFilestuff + add q, #_bp + rdword temp, q + add q, #_buffer-_bp + add q, temp + mov n, nBytes + call #ByteCopy + +' long[pIoblock+_leftInFile] -= n + mov p, pFilestuff + add p, #_leftInFile + rdlong temp, p + sub temp, nBytes + wrlong temp, p +' word[pIoblock+_bp] += n + add p, #_bp-_leftInFile + rdword temp, p + add temp, nBytes + wrword temp, p + + mov temp, retcode + jmp #AckReturnCode + +NextCluster ' ( cluster ) +{ + Given cluster, determines next cluster in FAT. + Result in cluster. +} + cmp cluster, #1 wc, wz + if_be jmp #NextCluster_ret + cmp cluster, kfff0 wc, wz + if_ae jmp #NextCluster_ret + + mov sector, cluster + shr sector, #8 + add sector, fatSector0 + call #ReadMetadataSector + mov p, cluster + and p, #$ff + shl p, #1 + add p, pMetadataBuffer + rdword cluster, p + +NextCluster_ret ret + +kfff0 long $fff0 + +'********************************************************************************************************************* +'* * +'* Write stuff * +'* * +'********************************************************************************************************************* +Write + rdlong p, pParam0 ' p = pFilestuff + add p, #_mode ' Verify that file was opened for writing. + rdword temp, p + cmp temp, #"W" wz + if_ne neg temp, #109 ' -109: file not properly opened + if_ne jmp #AckReturnCode + + call #FlushMetadataSector + neg currentsector, #1 ' invalidate current sector 'cuz we're about to hand the reins + ' to sxfs2 cog. + mov temp, #"W" + wrlong temp, pSxfs2Command +:wait rdlong temp, pSxfs2Command wz + if_nz jmp #:wait + + rdlong temp, pSxfs2Param + jmp #AckReturnCode + +'********************************************************************************************************************* +'* * +'* Close stuff * +'* * +'********************************************************************************************************************* +Close ' ( param0 = pFilestuff ) + rdlong pFilestuff, pParam0 + mov p, pFilestuff + add p, #_mode + rdword temp, p + + cmp temp, #"W" wz + if_e jmp #:closew + +' Files opened in mode "W" need special closing code, but for mode "R" or anything else +' (like file not even open) we can just do this: + + mov temp, #0 + wrword temp, p ' clear mode + jmp #AckNoReturnCode ' and we're done + +:closew + mov temp, #0 ' clear mode + wrword temp, p + + call #FlushMetadataSector + neg currentsector, #1 ' invalidate current sector 'cuz we're about to hand the reins + ' to sxfs2 cog. + mov temp, #"C" + wrlong temp, pSxfs2Command +:wait rdlong temp, pSxfs2Command wz + if_nz jmp #:wait + + rdlong temp, pSxfs2Param + jmp #AckReturnCode + +'********************************************************************************************************************* +'* * +'* Execute stuff * +'* * +'********************************************************************************************************************* +Execute ' ( pFilestuff, execmode, cogid ) + call #FlushMetadataSector + neg currentsector, #1 ' invalidate current sector 'cuz we're about to hand the reins + ' to sxfs2 cog. + mov temp, #"X" + wrlong temp, pSxfs2Command +:wait rdlong temp, pSxfs2Command wz + if_nz jmp #:wait + + rdlong temp, pSxfs2Param + jmp #AckReturnCode + +'********************************************************************************************************************* +'* * +'* Utility stuff * +'* * +'********************************************************************************************************************* + +ByteCopy ' ( p, q, n ) + tjz n, #ByteCopy_ret +:loop rdbyte temp, q + add q, #1 + wrbyte temp, p + add p, #1 + djnz n, #:loop + +ByteCopy_ret ret + +ByteComp ' ( p, q, n ) +{ + Compares j bytes starting at p and q. + Returns Z if they match, NZ if they differ. + Destroys p, q, and j. +} + rdbyte temp, p + add p, #1 + rdbyte temp1, q + add q, #1 + cmp temp, temp1 wz + if_z djnz n, #ByteComp + +ByteComp_ret ret + + +ValidateChar +{ + Make sure that temp is a valid filename character (for our purposes, 0-9, A-Z, _). +} + cmp temp, #"a" wc, wz + if_b jmp #:notLowerCase + cmp temp, #"z" wc, wz + if_a jmp #:notLowerCase + sub temp, #"a"-"A" ' convert to upper-case + jmp #ValidateChar_ret +:notLowerCase + cmp temp, #"A" wc, wz + if_b jmp #:notAlpha + cmp temp, #"Z" wc, wz + if_be jmp #ValidateChar_ret +:notAlpha + cmp temp, #"0" wc, wz + if_b jmp #:notNumeric + cmp temp, #"9" wc, wz + if_be jmp #ValidateChar_ret +:notNumeric + cmp temp, #"_" wz + if_e jmp #ValidateChar_ret + + mov temp, #113 ' -113: bad filename + jmp #AckReturnCode + +ValidateChar_ret ret + + + + + +ReadMetadataSector ' ( sector ) + call #FlushMetadataSector + + cmp sector, currentSector wz + if_e jmp #ReadMetadataSector_ret + wrlong pMetadataBuffer, pSdspiParam + wrlong sector, pSdspiBlockno + mov currentSector, sector + + mov temp, #"R" + call #SdspiCommand +ReadMetadataSector_ret ret + +FlushMetadataSector + tjz dirty, #FlushMetadataSector_ret + mov dirty, #0 + + ' write current sector + wrlong pMetadataBuffer, pSdspiParam + wrlong currentSector, pSdspiBlockno + mov temp, #"W" + call #SdspiCommand +FlushMetadataSector_ret ret + +SdspiCommand + wrlong temp, pSdspiCommand +:wait + rdlong temp, pSdspiCommand wz + if_nz jmp #:wait + + rdlong temp, pSdspiParam wz + if_nz jmp #AckReturnCode + +SdspiCommand_ret ret + +kFAT1 long "F" + "A"<<8 + "T"<<16 + "1"<<24 +k512 long 512 +dirty long 0 +currentSector long -1 +aDate long $2a21 + +pMetadataBuffer long METADATABUFFER + +pCommand long SXFSRENDEZVOUS+0 +pParam0 long SXFSRENDEZVOUS+4 +pParam1 long SXFSRENDEZVOUS+8 +pParam2 long SXFSRENDEZVOUS+12 + +pSdspiCommand long SDSPIRENDEZVOUS+0 +pSdspiParam long SDSPIRENDEZVOUS+4 +pSdspiBlockno long SDSPIRENDEZVOUS+8 + +pSxfs2Command long SXFS2RENDEZVOUS+0 +pSxfs2Param long SXFS2RENDEZVOUS+4 + +bytesPerSector long 0 +sectorsPerCluster long 0 +clusterShift long 0 +reservedSectors long 0 +numberOfFats long 0 +sectorsPerFat long 0 +rootDirEntries long 0 +fatSector0 long 0 +dirSector0 long 0 +dataSector0 long 0 + +temp res 1 +temp1 res 1 +i res 1 +j res 1 +n res 1 +p res 1 +q res 1 +sop res 1 +byte4 res 0 +sopDir res 1 +sector res 1 +cluster res 1 + +pFilename res 1 +pFilestuff res 1 +destPtr res 1 +nBytes res 1 +leftInFile res 1 +leftInSector res 1 +retcode res 1 + + fit + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} + \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx2/sxfs2.spn b/zubehör/sphinx/spinx100225-ori/sphinx2/sxfs2.spn new file mode 100644 index 0000000..8c00bb4 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx2/sxfs2.spn @@ -0,0 +1,529 @@ +SXTVRENDEZVOUS = $8000 - 4 +RESERVED = SXTVRENDEZVOUS - 4 +SDSPIRENDEZVOUS = RESERVED - 3 * 4 +SXFS2RENDEZVOUS = SDSPIRENDEZVOUS - 4 * 4 ' four rendezvous variables +SXFSRENDEZVOUS = SXFS2RENDEZVOUS - 4 * 4 ' four rendezvous variables +METADATABUFFER = SXFSRENDEZVOUS - 512 + +_free = ($8000 - METADATABUFFER) / 4 + +con +SECTORSIZE = 512 + +' filestuff definitions +' filestuff must be long-aligned +{ long } _length = 0 +{ long } _leftInFile = 4 +{ long } _sopDir = 8 ' sector/offset "pointer" to directory entry +{ long } _sopTail = 12 ' sector/offset "pointer" to last cluster# in FAT chain +{ word } _cluster = 16 +{ word } _sector = 18 ' sector# within cluster; ranges from 0 to sectorsPerCluster-1 +{ word } _bp = 20 ' byte pointer (actually an index into the sector buffer); range [0..511] +{ word } _mode = 22 ' 0: closed; "R": open for reading; "W": open for writing. + _buffer = 24 ' 512-byte buffer starts here + +SIZEOFFILESTUFF = SECTORSIZE + 24 + +pub Start( pbrSector ) + + bytesPerSector := PeekW( pMetadataBuffer + $0b ) + sectorsPerCluster := byte[pMetadataBuffer][$0d] + clusterShift := >| sectorsPerCluster - 1 + reservedSectors := PeekW( pMetadataBuffer + $0e ) + numberOfFats := byte[pMetadataBuffer][$10] + sectorsPerFat := PeekW( pMetadataBuffer + $16 ) + RootDirEntries := PeekW( pMetadataBuffer + $11 ) + fatSector0 := pbrSector + reservedSectors + dirSector0 := fatSector0 + numberOfFats * sectorsPerFat + dataSector0 := dirSector0 + rootDirEntries >> 4 + + ' start sxfs2 cog + long[pCommand] := "?" + if cognew( @Sxfs2Entry, 0 ) < 0 + abort -1 + repeat while long[pCommand] + +pri PeekW( a ) + return byte[a++] + byte[a] << 8 + +pri PeekL( a ) + return byte[a++] + byte[a++] << 8 + byte[a++] << 16 + byte[a] << 24 + +dat + org 0 +Sxfs2Entry +AckNoReturnCode + mov temp, #0 ' clear return code +AckReturnCode ' enter here with temp = return code + wrlong temp, pParam + mov temp, #0 + wrlong temp, pCommand ' clear command to signal operation complete. + + mov dirty, temp ' Ensure that metatdata is flushed before coming here. + neg temp, #1 + mov currentSector, temp + +:ready ' wait for new command + rdlong temp, pCommand wz + if_z jmp #:ready + + cmp temp, #"?" wz + if_e jmp #AckNoReturnCode + cmp temp, #"W" wz + if_e jmp #Write + cmp temp, #"C" wz + if_e jmp #Close + cmp temp, #"X" wz + if_e jmp #Execute + ' else + neg temp, #100 ' return code -100 : bad command + jmp #AckReturnCode + +'********************************************************************************************************************* +'* * +'* Write stuff * +'* * +'********************************************************************************************************************* +Write ' ( pFilestuff, ptr, n ) + rdlong pFilestuff, pSxfsParam0 + rdlong srcPtr, pSxfsParam1 + rdlong nBytes, pSxfsParam2 + + mov retcode, nBytes + + mov p, pFilestuff ' long[ pFilestuff+_length ] += n + 'add p, #_length (unnecessary cuz _length = 0) + rdlong temp, p + add temp, nBytes + wrlong temp, p + + +' repeat while (leftInSector := SECTORSIZE - word[pIoblock+_bp]) < n +:while + mov p, pFilestuff + add p, #_bp ' p points to pFilestuff->bp + mov leftInSector, k512 + rdword temp, p ' temp = pFilestuff->bp + sub leftInSector, temp + cmp leftInSector, nBytes wc, wz + if_ae jmp #:done +' bytemove( pFilestuff + _buffer + word[pFilestuff+_bp], ptr, leftInSector ) + mov p, pFilestuff + add p, #_buffer + add p, temp ' p now points bp bytes into buffer. + mov q, srcPtr + mov n, leftInSector + call #ByteCopy +' ptr += leftInSector + add srcPtr, leftInSector ' advance the source pointer by #bytes written. +' n -= leftInSector + sub nBytes, leftInSector ' decrease #bytes to write by #bytes written. +' WriteNextSector( pIoblock ) + call #WriteNextSector + + jmp #:while +:done +' bytemove( pFilestuff + _buffer + word[pIoblock+_bp], ptr, n ) + mov p, pFilestuff + add p, #_buffer + add p, temp ' temp = pFilestuff->bp + mov q, srcPtr + mov n, nBytes + call #ByteCopy +' word[pFilestuff+_bp] += n + mov p, pFilestuff + add p, #_bp + rdword temp, p + add temp, nBytes ' advance bp by #bytes written. + wrword temp, p + + call #FlushMetadataSector + + mov temp, retcode + jmp #AckReturnCode + +WriteNextSector + mov p, pFilestuff + add p, #_sector + rdword temp, p wz + if_nz jmp #:writeSector ' sector# <> 0? Write that sector. + +' Writing sector 0 implies that we're starting a new cluster, so find an empty slot in the FAT + mov cluster, #0 + mov sector, fatSector0 + mov i, sectorsPerFat +:forEachFatSector + call #ReadMetadataSector + + mov p, pMetadataBuffer + mov j, #256 +:forEachSlotInSector + rdword temp, p wz ' examine current slot + if_z jmp #:foundEmptySlot + + add p, #2 + add cluster, #1 + djnz j, #:forEachSlotInSector + + add sector, #1 + djnz i, #:forEachFatSector + + neg temp, #110 ' -110: FAT full. + jmp #AckReturnCode +:foundEmptySlot + neg temp, #1 + wrword temp, p ' Claim empty slot by writing $ffff. + mov dirty, #1 ' We've modified metadata. + + mov sop, sector + shl sop, #9 + sub p, pMetadataBuffer + add sop, p ' sop "points" to slot. + + mov p, pFilestuff + add p, #_cluster + wrword cluster, p ' save cluster# in pFilestuff->cluster + + sub p, #_cluster-_sopTail ' p points to pFilestuff->sopTail + rdlong sopTail, p ' get "pointer" to end of cluster list. + + mov sector, sopTail ' Read the sector that sopTail "points" to. + shr sector, #9 + call #ReadMetadataSector + + and sopTail, #$1ff + add sopTail, pMetadataBuffer ' Use sopTail as pointer into buffer. + wrword cluster, sopTail ' Now the word pointed to by pFilestuff->sopTail + ' is updated with the new cluster#. + mov dirty, #1 + + wrlong sop, p ' p is still pointing to pFilestuff->sopTail so + ' update pFilestuff->sopTail to point to new tail. +:writeSector + mov p, pFilestuff + add p, #_cluster ' p points to pFilestuff->cluster + rdword i, p ' using i for sector# + sub i, #2 + shl i, clusterShift + add i, dataSector0 ' At this point, i is the first sector of the cluster. + + add p, #_sector-_cluster ' p points to pFilestuff->sector + rdword temp, p + add i, temp ' Now i is the correct sector of the cluster. + add temp, #1 + wrword temp, p ' Increment pFilestuff->sector + cmp temp, sectorsPerCluster wz + mov temp, #0 ' if pFilestuff->sector = sectorsPerCluster, + if_e wrword temp, p ' pFilestuff->sector := 0. + add p, #_bp-_sector ' p points to pFilestuff->bp + wrword temp, p ' pFilestuff->bp = 0. + + wrlong i, pSdspiBlockno + add p, #_buffer-_bp + wrlong p, pSdspiParam + mov temp, #"W" + call #SdspiCommand +WriteNextSector_ret ret + +'********************************************************************************************************************* +'* * +'* Close stuff * +'* * +'********************************************************************************************************************* +Close ' ( pFilestuff ) + rdlong pFilestuff, pSxfsParam0 + + mov p, pFilestuff + add p, #_bp + rdword temp, p wz ' If there's stuff waiting to be written + if_nz call #WriteNextSector ' (i.e. bp <> 0), write it. + mov p, pFilestuff + add p, #_sopDir + rdlong sop, p ' sop "points" to directory entry. + + mov sector, sop + shr sector, #9 + call #ReadMetadataSector ' We want to update metadata length info. + and sop, #$1ff + add sop, pMetadataBuffer + add sop, #$1c ' sop points to length in metadata buffer. + mov p, pFilestuff ' p points to pFilestuff->length. + rdlong temp, p + wrlong temp, sop ' store length in metadata. + mov dirty, #1 + call #FlushMetadataSector + + jmp #AckNoReturnCode + +'********************************************************************************************************************* +'* * +'* Execute stuff * +'* * +'********************************************************************************************************************* +Execute ' ( pFilestuff, execmode, cogid ) +{ + Loads 63 sectors from file and executes. Requires that the file be contiguous on the SD card, + which is generally accomplished by formatting the card with cluster size >= 32k. + This reads 63 sectors instead of 64 to avoid writing junk into the rendezvous areas. + It is conceivable that some executable files will not run because of this. + + This routine does handle clock speed changes. + + If execmode is 0, start Spin interpreter in cog specified by cogid. + If execmode is 1, start Spin interpreter in cog specified by cogid and stop all other cogs. +} + call #FlushMetadataSector ' just in case + neg currentsector, #1 ' invalidate current sector 'cuz metadata buffer is about to be overwritten + + rdlong pFilestuff, pSxfsParam0 + + rdlong filesize, pFilestuff wz ' length of file + if_z neg temp, #1 ' if file is empty, return -1: EOF + if_z jmp #AckReturnCode ' This is a bit of a hack. The Sphinx compiler really + ' should delete outdated .bin or .eep files to force + ' (re)linking, but since sxfs doesn't know how to + ' delete files (yet(?)), the compiler just makes + ' a file empty instead of deleting it. This test + ' here catches empty executable files and bails, + ' preventing a crash. + + rdlong execmode, pSxfsParam1 + + rdbyte callingCog, pSxfsParam2 ' stop Spin interpreter + cogstop callingCog + + rdlong oldClkfreq, #0 ' save clkfreq + rdbyte oldClkmode, #4 ' save clkmode + + mov p, pFilestuff + add p, #_cluster + rdword temp, p ' temp = (cluster + sub temp, #2 ' - 2) + shl temp, clusterShift ' << clusterShift + add temp, dataSector0 ' + dataSector0 + mov p, temp ' p repurposed here as sector# + + mov i, #63 ' read 63 contiguous sectors + mov q, #0 +:loop + wrlong p, pSdspiBlockno ' Prepare to read sector p + wrlong q, pSdspiParam ' to memory pointed to by q + mov temp, #"R" + call #SdspiCommand + add p, #1 ' Next sector + add q, k512 ' Next 512-byte block of memory + djnz i, #:loop + + ' clear memory above the loaded file + mov i, #1 + shl i, #15 ' i = 32768 + sub i, filesize wz ' - file size + if_z jmp #:z + mov temp, #0 +:y + wrbyte temp, filesize ' repurpose filesize as pointer + add filesize, #1 + djnz i, #:y +:z + ' store those nutty $fff9ffff longs + rdword p, #$0a + sub p, #4 + wrlong kfff9ffff, p + sub p, #4 + wrlong kfff9ffff, p + + tjz execmode, #:dontChangeClock ' execmode = 0? skip cog-killing and clock change + + cogid temp + mov i, #0 + mov j, #8 +:cogkill + cmp i, temp wz ' kill all cogs except self + if_ne cogstop i ' (suicide comes later) + add i, #1 + djnz j, #:cogkill + + ' The following code is borrowed liberally from sdspiFemto: + rdlong temp, #0 ' new clock frequency + cmp temp, oldClkfreq wz ' compared to old + rdbyte temp, #4 ' get new clock mode in advance + if_ne jmp #:changeClock + cmp temp, oldClkmode wz ' compare new clock mode to old + if_e jmp #:dontChangeClock + +:changeClock and temp, #$f8 ' Force use of RCFAST clock while + clkset temp ' letting requested clock start + mov i, time_xtal +:startupDelay djnz i, #:startupDelay ' Allow 20ms@20MHz for xtal/pll to settle + rdbyte temp, #4 ' Then switch to selected clock + clkset temp + jmp #:x + +:dontChangeClock + wrlong oldClkfreq, #0 ' Restore old clock frequency + wrbyte oldClkmode, #4 ' and mode. + +:x + or interpreter, callingCog + coginit interpreter ' start new Spin interpreter in the same cog. + + tjz execmode, #AckNoReturnCode ' execmode = 0? Done. + + cogid temp ' kill + cogstop temp ' self + + +interpreter long ($0004 << 16) | ($F004 << 2) | %0000 ' Thanks to sdspiFemto +time_xtal long 20 * 20000 / 4 / 1 ' 20ms (@20MHz, 1 inst/loop) + +'********************************************************************************************************************* +'* * +'* Utility stuff * +'* * +'********************************************************************************************************************* +{ +Out'(outch) ''' +:w rdbyte outtemp, pTerm wz +if_nz jmp #:w +wrbyte outch, pTerm +Out_ret ret + +OutHex'(outx, outn) ''' + mov outtemp, outn + sub outtemp, #1 + shl outtemp, #2 + ror outx, outtemp +:loop + mov outch, outx + and outch, #$0f + add outch, #"0" + cmp outch, #"9" wc, wz + if_a add outch, #"a"-"0"-10 + call #out + rol outx, #4 + djnz outn, #:loop +Outhex_ret ret +pTerm long $7ffc +outch long 0 +outx long 0 +outn long 0 +outtemp long 0 ''' +} + +ByteCopy ' ( p, q, n ) + tjz n, #ByteCopy_ret +:loop rdbyte temp, q + add q, #1 + wrbyte temp, p + add p, #1 + djnz n, #:loop + +ByteCopy_ret ret + +ReadMetadataSector ' ( sector ) + call #FlushMetadataSector + + cmp sector, currentSector wz + if_e jmp #ReadMetadataSector_ret + wrlong pMetadataBuffer, pSdspiParam + wrlong sector, pSdspiBlockno + mov currentSector, sector + mov temp, #"R" + call #SdspiCommand +ReadMetadataSector_ret ret + +FlushMetadataSector + tjz dirty, #FlushMetadataSector_ret + mov dirty, #0 + + ' write current sector + wrlong pMetadataBuffer, pSdspiParam + wrlong currentSector, pSdspiBlockno + mov temp, #"W" + call #SdspiCommand +FlushMetadataSector_ret ret + +SdspiCommand + wrlong temp, pSdspiCommand +:wait + rdlong temp, pSdspiCommand wz + if_nz jmp #:wait + + rdlong temp, pSdspiParam wz + if_nz jmp #AckReturnCode + +SdspiCommand_ret ret + + +k512 long 512 +kfff9ffff long $fff9ffff +dirty long 0 +currentSector long -1 +pMetadataBuffer long METADATABUFFER + +pSxfsCommand long SXFSRENDEZVOUS+0 +pSxfsParam0 long SXFSRENDEZVOUS+4 +pSxfsParam1 long SXFSRENDEZVOUS+8 +pSxfsParam2 long SXFSRENDEZVOUS+12 + +pSdspiCommand long SDSPIRENDEZVOUS+0 +pSdspiParam long SDSPIRENDEZVOUS+4 +pSdspiBlockno long SDSPIRENDEZVOUS+8 + +pCommand long SXFS2RENDEZVOUS+0 +pParam long SXFS2RENDEZVOUS+4 + +bytesPerSector long 0 +sectorsPerCluster long 0 +clusterShift long 0 +reservedSectors long 0 +numberOfFats long 0 +sectorsPerFat long 0 +rootDirEntries long 0 +fatSector0 long 0 +dirSector0 long 0 +dataSector0 long 0 + +temp res 1 +i res 1 +j res 1 +n res 1 +p res 1 +q res 1 +pFilestuff res 1 +sop res 1 +sopTail res 1 +srcPtr res 1 +nBytes res 1 +cluster res 1 +sector res 1 +leftInSector res 1 +filesize res 1 +execmode res 1 +callingCog res 1 +oldClkfreq res 1 +oldClkmode res 1 + +retcode res 1 + + fit + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} + \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx2/sxkb.spn b/zubehör/sphinx/spinx100225-ori/sphinx2/sxkb.spn new file mode 100644 index 0000000..3bf5a33 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx2/sxkb.spn @@ -0,0 +1,728 @@ +''******************************* +''* PS/2 Keyboard Driver v2.0 * +''* (C) 2004 Parallax, Inc. * +''* Modified by Michael Green * +''* to support Hydra as well * +''******************************* +{ +Modified by Michael Park for Sphinx +2009/06/15 +} + +SXKBRENDEZVOUS = $7ff8 + +VAR + long cog + +PUB start(pingroup) : okay + +'' Start keyboard driver - starts a cog +'' returns false if no cog available +'' +'' pingroup = 1st pin number for 2-pin group for PS/2 I/O +'' (1st - data signal, 2nd - clock signal) +'' Even number selects Demo Board I/O convention +'' +'' use 100-ohm resistors between pins and jack +'' use 10K-ohm resistors to pull jack-side signals to VDD +'' connect jack-power to 5V, jack-gnd to VSS +'' +'' pingroup = 1st pin number for 4-pin group for PS/2 I/O +'' Odd number selects Hydra I/O convention +'' +'' 1st pin drives NPN base for PS/2 'data' signal pull-down +'' 2nd pin reads PS/2 'data' signal +'' 3rd pin drives NPN base for PS/2 'clock' signal pull-down +'' 4th pin reads PS/2 'clock' signal +'' +'' use 2.2K-ohm resistors between 1st/3rd pins and NPN bases +'' use 22K-ohm resistors between 2nd/4th pins and PS/2-side signals +'' use 2.2K-ohm resistors to pull PS/2-side signals to 5V +'' connect PS/2 power to 5V, PS/2 gnd to vss +'' +'' all lock-keys will be enabled, NumLock will be initially 'on', +'' and auto-repeat will be set to 15cps with a delay of .5s + + okay := startx(pingroup, %0_000_100, %01_01000) + +PUB startx(pingroup, locks, auto) | okay + +'' Like start, but allows you to specify lock settings and auto-repeat +'' +'' locks = lock setup +'' bit 6 disallows shift-alphas (case set soley by CapsLock) +'' bits 5..3 disallow toggle of NumLock/CapsLock/ScrollLock state +'' bits 2..0 specify initial state of NumLock/CapsLock/ScrollLock +'' (eg. %0_001_100 = disallow ScrollLock, NumLock initially 'on') +'' +'' auto = auto-repeat setup +'' bits 6..5 specify delay (0=.25s, 1=.5s, 2=.75s, 3=1s) +'' bits 4..0 specify repeat rate (0=30cps..31=2cps) +'' (eg %01_00000 = .5s delay, 30cps repeat) + + long[pRendezvous]~~ ' ping + if long[pRendezvous]~ == -1 ' no response + longmove(@_pingroup, @pingroup, 3) + okay := cog := cognew(@entry, 0) + 1 + +PUB peekkey + +'' Returns a 0 if the buffer is empty +'' returns next key if buffer not empty +'' but doesn't remove the key from buffer + + return long[pRendezvous] + +PUB key : keycode + +'' Get key (never waits) +'' returns key (0 if buffer empty) + + if keycode := long[pRendezvous] + long[pRendezvous]~ + +PUB getkey : keycode + +'' Get next key (may wait for keypress) +'' returns key + + repeat until (keycode := key) + +DAT +'****************************************** +'* Assembly language PS/2 keyboard driver * +'****************************************** + + org +' +' +' Entry +' +entry + mov x,_pingroup 'get mask for 1st pin + andn x,#1 + test _pingroup,#1 wz + mov dwmask,#1 + shl dwmask,x + mov drmask,dwmask + if_nz shl drmask,#1 + mov cwmask,drmask + shl cwmask,#1 + mov crmask,cwmask + if_nz shl crmask,#1 + + if_nz or dira,dwmask 'set directions + if_nz or dira,cwmask + + mov _head,#0 'reset output parameter _head + mov _tail, #0 +' +' +' Reset keyboard +' +reset test _pingroup,#1 wz + if_nz andn outa,dwmask 'let PS/2 lines float (pulled up) + if_nz andn outa,cwmask + if_z mov dira,#0 + + movd :par,#_present 'reset output parameters _present/_states[8] + mov x,#1+8 +:par mov 0,#0 + add :par,dlsb + djnz x,#:par + + mov stat,#8 'set reset flag +' +' +' Update parameters +' +update + call #Rendezvous + + test stat,#8 wc 'if reset flag, transmit reset command + if_c mov data,#$FF + if_c call #transmit +' +' +' Get scancode +' +newcode + mov stat,#0 'reset state + +:same call #receive 'receive byte from keyboard + + cmp data,#$83+1 wc 'scancode? + + if_nc cmp data,#$AA wz 'powerup/reset? + if_nc_and_z jmp #configure + + if_nc cmp data,#$E0 wz 'extended? + if_nc_and_z or stat,#1 + if_nc_and_z jmp #:same + + if_nc cmp data,#$F0 wz 'released? + if_nc_and_z or stat,#2 + if_nc_and_z jmp #:same + + if_nc jmp #newcode 'unknown, ignore +' +' +' Translate scancode and enter into buffer +' + test stat,#1 wc 'lookup code with extended flag + rcl data,#1 + call #look + + cmp data,#0 wz 'if unknown, ignore + if_z jmp #newcode + + mov t,_states+6 'remember lock keys in _states + + mov x,data 'set/clear key bit in _states + shr x,#5 + add x,#_states + movd :reg,x + mov y,#1 + shl y,data + test stat,#2 wc +:reg muxnc 0,y + + if_nc cmpsub data,#$F0 wc 'if released or shift/ctrl/alt/win, done + if_c jmp #update + + mov y,_states+7 'get shift/ctrl/alt/win bit pairs + shr y,#16 + + cmpsub data,#$E0 wc 'translate keypad, considering numlock + if_c test _locks,#%100 wz + if_c_and_z add data,#@keypad1-@table + if_c_and_nz add data,#@keypad2-@table + if_c call #look + if_c jmp #:flags + + cmpsub data,#$DD wc 'handle scrlock/capslock/numlock + if_c mov x,#%001_000 + if_c shl x,data + if_c andn x,_locks + if_c shr x,#3 + if_c shr t,#29 'ignore auto-repeat + if_c andn x,t wz + if_c xor _locks,x + if_c add data,#$DD + if_c_and_nz or stat,#4 'if change, set configure flag to update leds + + test y,#%11 wz 'get shift into nz + + if_nz cmp data,#$60+1 wc 'check shift1 + if_nz_and_c cmpsub data,#$5B wc + if_nz_and_c add data,#@shift1-@table + if_nz_and_c call #look + if_nz_and_c andn y,#%11 + + if_nz cmp data,#$3D+1 wc 'check shift2 + if_nz_and_c cmpsub data,#$27 wc + if_nz_and_c add data,#@shift2-@table + if_nz_and_c call #look + if_nz_and_c andn y,#%11 + + test _locks,#%010 wc 'check shift-alpha, considering capslock + muxnc :shift,#$20 + test _locks,#$40 wc + if_nz_and_nc xor :shift,#$20 + cmp data,#"z"+1 wc + if_c cmpsub data,#"a" wc +:shift if_c add data,#"A" + if_c andn y,#%11 + +:flags ror data,#8 'add shift/ctrl/alt/win flags + mov x,#4 '+$100 if shift +:loop test y,#%11 wz '+$200 if ctrl + shr y,#2 '+$400 if alt + if_nz or data,#1 '+$800 if win + ror data,#1 + djnz x,#:loop + rol data,#12 + + mov x, _tail 'if room in buffer and key valid, enter + sub x,#1 + and x,#$F + cmp x,_head wz + if_e jmp #:z + test data,#$FF wz + if_z jmp #:z + + mov x, #buffer + add x, _head + movd :store, x + nop +:store mov 0-0, data ' buffer[x] := data + add _head,#1 + and _head,#$F +:z + test stat,#4 wc 'if not configure flag, done + if_nc jmp #update 'else configure to update leds +' +' +' Configure keyboard +' +configure mov data,#$F3 'set keyboard auto-repeat + call #transmit + mov data,_auto + and data,#%11_11111 + call #transmit + + mov data,#$ED 'set keyboard lock-leds + call #transmit + mov data,_locks + rev data,#-3 & $1F + test data,#%100 wc + rcl data,#1 + and data,#%111 + call #transmit + + mov x,_locks 'insert locks into _states + and x,#%111 + shl _states+7,#3 + or _states+7,x + ror _states+7,#3 + + mov _present,#1 'set _present + + jmp #update 'done +' +' +' Lookup byte in table +' +look ror data,#2 'perform lookup + movs :reg,data + add :reg,#table + shr data,#27 + mov x,data +:reg mov data,0 + shr data,x + + jmp #rand 'isolate byte +' +' +' Transmit byte to keyboard +' +transmit test _pingroup,#1 wz + if_z or dira,cwmask + if_nz or outa,cwmask 'pull clock low + movs napshr,#13 'hold clock for ~128us (must be >100us) + call #nap + if_z or dira,dwmask + if_nz or outa,dwmask 'pull data low + movs napshr,#18 'hold data for ~4us + call #nap + if_z xor dira,cwmask + if_nz andn outa,cwmask 'release clock + + test data,#$0FF wc 'append parity and stop bits to byte + muxnc data,#$100 + or data,dlsb + + mov x,#10 'ready 10 bits +transmit_bit call #wait_c0 'wait until clock low + shr data,#1 wc 'output data bit + test _pingroup,#1 wz + if_z muxnc dira,dwmask + if_nz muxnc outa,dwmask + mov wcond,c1 'wait until clock high + call #wait + djnz x,#transmit_bit 'another bit? + + mov wcond,c0d0 'wait until clock and data low + call #wait + mov wcond,c1d1 'wait until clock and data high + call #wait + + call #receive_ack 'receive ack byte with timed wait + cmp data,#$FA wz 'if ack error, reset keyboard + if_nz jmp #reset +transmit_ret ret +' +' +' Receive byte from keyboard +' +receive +:waitpne + call #Rendezvous + mov x, ina 'wait indefinitely for initial clock low + and x, crmask + cmp x, crmask wz + if_e jmp #:waitpne + +receive_ack mov x,#11 'ready 11 bits +receive_bit call #wait_c0 'wait until clock low + movs napshr,#16 'pause ~16us + call #nap + test drmask,ina wc 'input data bit + rcr data,#1 + mov wcond,c1 'wait until clock high + call #wait + djnz x,#receive_bit 'another bit? + + shr data,#22 'align byte + test data,#$1FF wc 'if parity error, reset keyboard + if_nc jmp #reset +rand and data,#$FF 'isolate byte +look_ret +receive_ack_ret +receive_ret ret +' +' +' Communicate with the rest of the Propeller via "rendezvous" in hub memory. +' +Rendezvous + rdlong t, pRendezvous wz ' if rendezvous = 0 (location empty), + if_z jmp #:clearToSend ' go fill it with character in buffer. + add t, #1 wz ' if rendezvous = -1 + if_nz jmp #Rendezvous_ret ' someone is pinging to see if sxkb cog is alive; + sub t, #2 ' set rendezvous to -2 to ack. + wrlong t, pRendezvous + jmp #Rendezvous_ret +:clearToSend + cmp _head, _tail wz + if_e jmp #Rendezvous_ret + mov x, _tail + add x, #buffer + movs :read, x + nop +:read mov data, 0-0 ' data := buffer[_tail] + wrlong data, pRendezvous + add _tail, #1 + and _tail, #$0f +Rendezvous_ret ret + +' +' +' Wait for clock/data to be in required state(s) +' +wait_c0 mov wcond,c0 '(wait until clock low) + +wait mov y,tenms 'set timeout to 10ms + +wloop movs napshr,#18 'nap ~4us + call #nap + test crmask,ina wc 'check required state(s) + test drmask,ina wz 'loop until got state(s) or timeout +wcond if_never djnz y,#wloop '(replaced with c0/c1/c0d0/c1d1) + + tjz y,#reset 'if timeout, reset keyboard +wait_ret +wait_c0_ret ret + + +c0 if_c djnz y,#wloop '(if_never replacements) +c1 if_nc djnz y,#wloop +c0d0 if_c_or_nz djnz y,#wloop +c1d1 if_nc_or_z djnz y,#wloop +' +' +' Nap +' +nap rdlong t,#0 'get clkfreq +napshr shr t,#0-0 'shr scales time (set to 13/16/18) + min t,#10 'ensure waitcnt won't snag (was 3 but snagged; upped to 10 [mp]) + add t,cnt 'add cnt to time + waitcnt t,#0 'wait until time elapses (nap) + +nap_ret ret +' +' +' Initialized data +' +' +dlsb long 1 << 9 +tenms long 10_000 / 4 +' +' +' Lookup table +' ascii scan extkey regkey ()=keypad +' +table word $0000 '00 + word $00D8 '01 F9 + word $0000 '02 + word $00D4 '03 F5 + word $00D2 '04 F3 + word $00D0 '05 F1 + word $00D1 '06 F2 + word $00DB '07 F12 + word $0000 '08 + word $00D9 '09 F10 + word $00D7 '0A F8 + word $00D5 '0B F6 + word $00D3 '0C F4 + word $0009 '0D Tab + word $0060 '0E ` + word $0000 '0F + word $0000 '10 + word $F5F4 '11 Alt-R Alt-L + word $00F0 '12 Shift-L + word $0000 '13 + word $F3F2 '14 Ctrl-R Ctrl-L + word $0071 '15 q + word $0031 '16 1 + word $0000 '17 + word $0000 '18 + word $0000 '19 + word $007A '1A z + word $0073 '1B s + word $0061 '1C a + word $0077 '1D w + word $0032 '1E 2 + word $F600 '1F Win-L + word $0000 '20 + word $0063 '21 c + word $0078 '22 x + word $0064 '23 d + word $0065 '24 e + word $0034 '25 4 + word $0033 '26 3 + word $F700 '27 Win-R + word $0000 '28 + word $0020 '29 Space + word $0076 '2A v + word $0066 '2B f + word $0074 '2C t + word $0072 '2D r + word $0035 '2E 5 + word $CC00 '2F Apps + word $0000 '30 + word $006E '31 n + word $0062 '32 b + word $0068 '33 h + word $0067 '34 g + word $0079 '35 y + word $0036 '36 6 + word $CD00 '37 Power + word $0000 '38 + word $0000 '39 + word $006D '3A m + word $006A '3B j + word $0075 '3C u + word $0037 '3D 7 + word $0038 '3E 8 + word $CE00 '3F Sleep + word $0000 '40 + word $002C '41 , + word $006B '42 k + word $0069 '43 i + word $006F '44 o + word $0030 '45 0 + word $0039 '46 9 + word $0000 '47 + word $0000 '48 + word $002E '49 . + word $EF2F '4A (/) / + word $006C '4B l + word $003B '4C ; + word $0070 '4D p + word $002D '4E - + word $0000 '4F + word $0000 '50 + word $0000 '51 + word $0027 '52 ' + word $0000 '53 + word $005B '54 [ + word $003D '55 = + word $0000 '56 + word $0000 '57 + word $00DE '58 CapsLock + word $00F1 '59 Shift-R + word $EB0D '5A (Enter) Enter + word $005D '5B ] + word $0000 '5C + word $005C '5D \ + word $CF00 '5E WakeUp + word $0000 '5F + word $0000 '60 + word $0000 '61 + word $0000 '62 + word $0000 '63 + word $0000 '64 + word $0000 '65 + word $00C8 '66 BackSpace + word $0000 '67 + word $0000 '68 + word $C5E1 '69 End (1) + word $0000 '6A + word $C0E4 '6B Left (4) + word $C4E7 '6C Home (7) + word $0000 '6D + word $0000 '6E + word $0000 '6F + word $CAE0 '70 Insert (0) + word $C9EA '71 Delete (.) + word $C3E2 '72 Down (2) + word $00E5 '73 (5) + word $C1E6 '74 Right (6) + word $C2E8 '75 Up (8) + word $00CB '76 Esc + word $00DF '77 NumLock + word $00DA '78 F11 + word $00EC '79 (+) + word $C7E3 '7A PageDn (3) + word $00ED '7B (-) + word $DCEE '7C PrScr (*) + word $C6E9 '7D PageUp (9) + word $00DD '7E ScrLock + word $0000 '7F + word $0000 '80 + word $0000 '81 + word $0000 '82 + word $00D6 '83 F7 + +keypad1 byte $CA, $C5, $C3, $C7, $C0, 0, $C1, $C4, $C2, $C6, $C9, $0D, "+-*/" + +keypad2 byte "0123456789.", $0D, "+-*/" + +shift1 byte "{|}", 0, 0, "~" + +shift2 byte $22, 0, 0, 0, 0, "<_>?)!@#$%^&*(", 0, ":", 0, "+" + +_pingroup long 0 +_locks long 0 +_auto long 0 +pRendezvous long SXKBRENDEZVOUS +' +' Uninitialized data +' +buffer res 16 +dwmask res 1 'output driver mask for data +drmask res 1 'input mask for data +cwmask res 1 'output driver mask for clock +crmask res 1 'input mask for data +stat res 1 +data res 1 +x res 1 +y res 1 +t res 1 + +_tail res 1 +_head res 1 'write-only +_present res 1 'write-only +_states res 8 'write-only + + fit +'' +'' +'' _________ +'' Key Codes +'' +'' 00..DF = keypress and keystate +'' E0..FF = keystate only +'' +'' +'' 09 Tab +'' 0D Enter +'' 20 Space +'' 21 ! +'' 22 " +'' 23 # +'' 24 $ +'' 25 % +'' 26 & +'' 27 ' +'' 28 ( +'' 29 ) +'' 2A * +'' 2B + +'' 2C , +'' 2D - +'' 2E . +'' 2F / +'' 30 0..9 +'' 3A : +'' 3B ; +'' 3C < +'' 3D = +'' 3E > +'' 3F ? +'' 40 @ +'' 41..5A A..Z +'' 5B [ +'' 5C \ +'' 5D ] +'' 5E ^ +'' 5F _ +'' 60 ` +'' 61..7A a..z +'' 7B { +'' 7C | +'' 7D } +'' 7E ~ +'' +'' 80-BF (future international character support) +'' +'' C0 Left Arrow +'' C1 Right Arrow +'' C2 Up Arrow +'' C3 Down Arrow +'' C4 Home +'' C5 End +'' C6 Page Up +'' C7 Page Down +'' C8 Backspace +'' C9 Delete +'' CA Insert +'' CB Esc +'' CC Apps +'' CD Power +'' CE Sleep +'' CF Wakeup +'' +'' D0..DB F1..F12 +'' DC Print Screen +'' DD Scroll Lock +'' DE Caps Lock +'' DF Num Lock +'' +'' E0..E9 Keypad 0..9 +'' EA Keypad . +'' EB Keypad Enter +'' EC Keypad + +'' ED Keypad - +'' EE Keypad * +'' EF Keypad / +'' +'' F0 Left Shift +'' F1 Right Shift +'' F2 Left Ctrl +'' F3 Right Ctrl +'' F4 Left Alt +'' F5 Right Alt +'' F6 Left Win +'' F7 Right Win +'' +'' FD Scroll Lock State +'' FE Caps Lock State +'' FF Num Lock State +'' +'' +100 if Shift +'' +200 if Ctrl +'' +400 if Alt +'' +800 if Win +'' +'' eg. Ctrl-Alt-Delete = $6C9 +'' +'' +'' Note: Driver will buffer up to 15 keystrokes, then ignore overflow. +{{ ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx2/sxsdspiq.spn b/zubehör/sphinx/spinx100225-ori/sphinx2/sxsdspiq.spn new file mode 100644 index 0000000..26a879b --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx2/sxsdspiq.spn @@ -0,0 +1,334 @@ +' sdspi: SPI interface to a Secure Digital card. +' +' Copyright 2008 Radical Eye Software +' Modified 2009 by Michael Park: added pointer to rendezvous variables. +' +' See end of file for terms of use. +' +' You probably never want to call this; you want to use fsrw +' instead (which calls this); this is only the lowest layer. +' +' Assumes SD card is interfaced using four consecutive Propeller +' pins, as follows (assuming the base pin is pin 0): +' 3.3v +' | | | | | | +' R R R R R R 20k +' p0 --------*-+-+-+-+-+------ do +' p1 ----------*-+-+-+-+------ clk +' p2 ------------*-+-+-+------ di +' p3 --------------*-+-+------ cs (dat3) +' 150 +-+------ irq (dat1) +' +------ p9 (dat2) +' +' The 20k resistors +' are pullups, and should be there on all six lines (even +' the ones we don't drive). +' +' This code is not general-purpose SPI code; it's very specific +' to reading SD cards, although it can be used as an example. +' +' The code does not use CRC at the moment (this is the default). +' With some additional effort we can probe the card to see if it +' supports CRC, and if so, turn it on. +' +' All operations are guarded by a watchdog timer, just in case +' no card is plugged in or something else is wrong. If an +' operation does not complete in one second it is aborted. +' +con + sectorsize = 512 + sectorshift = 9 + +var + long cog + long pCommand, pParam, pBlockno ' rendezvous between spin and assembly +pub stop + if cog + cogstop(cog~ - 1) +pub start(basepin, pRendezvous) +' +' Initialize the card! Send a whole bunch of +' clocks (in case the previous program crashed +' in the middle of a read command or something), +' then a reset command, and then wait until the +' card goes idle. +' + do := basepin++ + clk := basepin++ + di := basepin++ + cs := basepin + stop + + pCommand := pRendezvous + pParam := pRendezvous + 4 + pBlockno := pRendezvous + 8 + + long[pCommand] := "I" + cog := 1 + cognew(@entry, pRendezvous) + repeat while long[pCommand] + if long[pParam] + abort long[pParam] + return 0 +pub readblock(n, b) +' +' Read a single block. The "n" passed in is the +' block number (blocks are 512 bytes); the b passed +' in is the address of 512 blocks to fill with the +' data. +' + long[pParam] := b + long[pBlockno] := n + long[pCommand] := "R" + repeat while long[pCommand] + if long[pParam] + abort long[pParam] + return 0 +pub writeblock(n, b) +' +' Write a single block. Mirrors the read above. +' + long[pParam] := b + long[pBlockno] := n + long[pCommand] := "W" + repeat while long[pCommand] + if long[pParam] + abort long[pParam] + return 0 +dat + org +entry mov comptr,par + mov parptr,par + add parptr,#4 + mov parptr2,parptr + add parptr2,#4 +' set up + mov acca,#1 + shl acca,di + or dira,acca + mov acca,#1 + shl acca,clk + or dira,acca + mov acca,#1 + shl acca,do + mov domask,acca + mov acca,#1 + shl acca,cs + or dira,acca + mov csmask,acca + neg phsb,#1 + mov frqb,#0 + mov acca,nco + add acca,clk + mov ctra,acca + mov acca,nco + add acca,di + mov ctrb,acca + mov ctr2,onek +oneloop + call #sendiohi + djnz ctr2,#oneloop + mov starttime,cnt + mov cmdo,#0 + mov cmdp,#0 + call #cmd + or outa,csmask + call #sendiohi +initloop + mov cmdo,#55 + call #cmd + mov cmdo,#41 + call #cmd + or outa,csmask + cmp accb,#1 wz + if_z jmp #initloop + wrlong accb,parptr +' reset frqa and the clock +finished + mov frqa,#0 + wrlong frqa,comptr + or outa,csmask + neg phsb,#1 + call #sendiohi +pause + mov acca,#511 + add acca,cnt + waitcnt acca,#0 +waitloop + mov starttime,cnt + rdlong acca,comptr wz + cmp acca,#"B" wz + if_z jmp #byteio + mov ctr2,sector + cmp acca,#"R" wz + if_z jmp #rblock + cmp acca,#"W" wz + if_nz jmp #pause +wblock + mov starttime,cnt + mov cmdo,#24 + rdlong cmdp,parptr2 + call #cmd + mov phsb,#$fe + call #sendio + rdlong accb,parptr + neg frqa,#1 +wbyte + rdbyte phsb,accb + shl phsb,#23 + add accb,#1 + mov ctr,#8 +wbit mov phsa,#8 + shl phsb,#1 + djnz ctr,#wbit + djnz ctr2,#wbyte + neg phsb,#1 + call #sendiohi + call #sendiohi + call #readresp + and accb,#$1f + sub accb,#5 + wrlong accb,parptr + call #busy + jmp #finished +rblock + mov starttime,cnt + mov cmdo,#17 + rdlong cmdp,parptr2 + call #cmd + call #readresp + rdlong accb,parptr + sub accb,#1 +rbyte + mov phsa,hifreq + mov frqa,freq + add accb,#1 + test domask,ina wc + addx acca,acca + test domask,ina wc + addx acca,acca + test domask,ina wc + addx acca,acca + test domask,ina wc + addx acca,acca + test domask,ina wc + addx acca,acca + test domask,ina wc + addx acca,acca + test domask,ina wc + addx acca,acca + mov frqa,#0 + test domask,ina wc + addx acca,acca + wrbyte acca,accb + djnz ctr2,#rbyte + mov frqa,#0 + neg phsb,#1 + call #sendiohi + call #sendiohi + or outa,csmask + wrlong ctr2,parptr + jmp #finished +byteio + rdlong phsb,parptr + call #sendio + wrlong accb,parptr + jmp #finished +sendio + rol phsb,#24 +sendiohi + mov ctr,#8 + neg frqa,#1 + mov accb,#0 +bit mov phsa,#8 + test domask,ina wc + addx accb,accb + rol phsb,#1 + djnz ctr,#bit +sendio_ret +sendiohi_ret + ret +checktime + mov duration,cnt + sub duration,starttime + cmp duration,clockfreq wc +checktime_ret + if_c ret + neg duration,#13 + wrlong duration,parptr + jmp #finished +cmd + andn outa,csmask + neg phsb,#1 + call #sendiohi + mov phsb,cmdo + add phsb,#$40 + call #sendio + mov phsb,cmdp + shl phsb,#9 + call #sendiohi + call #sendiohi + call #sendiohi + call #sendiohi + mov phsb,#$95 + call #sendio +readresp + neg phsb,#1 + call #sendiohi + call #checktime + cmp accb,#$ff wz + if_z jmp #readresp +cmd_ret +readresp_ret + ret +busy + neg phsb,#1 + call #sendiohi + call #checktime + cmp accb,#$0 wz + if_z jmp #busy +busy_ret + ret + +di long 0 +do long 0 +clk long 0 +cs long 0 +nco long $1000_0000 +hifreq long $e0_00_00_00 +freq long $20_00_00_00 +clockfreq long 80_000_000 +onek long 1000 +sector long 512 +domask res 1 +csmask res 1 +acca res 1 +accb res 1 +cmdo res 1 +cmdp res 1 +comptr res 1 +parptr res 1 +parptr2 res 1 +ctr res 1 +ctr2 res 1 +starttime res 1 +duration res 1 +{{ +' Permission is hereby granted, free of charge, to any person obtaining +' a copy of this software and associated documentation files +' (the "Software"), to deal in the Software without restriction, +' including without limitation the rights to use, copy, modify, merge, +' publish, distribute, sublicense, and/or sell copies of the Software, +' and to permit persons to whom the Software is furnished to do so, +' subject to the following conditions: +' +' The above copyright notice and this permission notice shall be included +' in all copies or substantial portions of the Software. +' +' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +' EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +' MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +' IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +' CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +' TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +' SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +}} \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx2/sxtv.spn b/zubehör/sphinx/spinx100225-ori/sphinx2/sxtv.spn new file mode 100644 index 0000000..43adc4e --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx2/sxtv.spn @@ -0,0 +1,916 @@ +''*************************************** +''* TV Driver v1.1 * +''* Author: Chip Gracey * +''* Copyright (c) 2004 Parallax, Inc. * +''* See end of file for terms of use. * +''*************************************** + +' v1.0 - 01 May 2006 - original version +' v1.1 - 17 May 2006 - pixel tile size can now be 16 x 32 to enable more efficient +' character displays utilizing the internal font - see 'tv_mode' +{ +2009 +May + 11 Moved blank line tasks into one-time initialization section. + Difficulty: one task was flipping the interlace bit of _mode, necessitating a reload of _mode + every superfield. Removed the flip and changed the sense of the Z tests that depended on _mode<1> + being flipped. + 12 Implemented simple scrolling terminal output in background task. + Difficulty: have to keep Z clear so that mainline interlaced code works properly. +June + 9 Added "D"isable and "E"nable commands. + 20 Changing ping response to include basepin. +} + +CON + + fntsc = 3_579_545 'NTSC color frequency + lntsc = 3640 'NTSC color cycles per line * 16 + sntsc = 624 'NTSC color cycles per sync * 16 + + fpal = 4_433_618 'PAL color frequency + lpal = 4540 'PAL color cycles per line * 16 + spal = 848 'PAL color cycles per sync * 16 + + paramcount = 14 +' colortable = $180 'start of colortable inside cog + + cols = 40 + rows = 13 + +VAR + long cog + long rendezvous + +PUB start(basepin, rv) | okay + +'' Start TV driver - starts a cog if necessary +'' returns true if it had to start a cog, false if cog was already running. +'' + _basepin := basepin + rendezvous := rv + long[rendezvous]~~ ' ping the sxtv cog (send -1) + waitcnt( clkfreq/10 + cnt ) + if long[rendezvous] <> -1 ' if the cog is alive it'll set this to _basepin<<8 + long[rendezvous]~ + return false + + _pins := (basepin & $38) << 1 | (basepin & 4 == 4) & %0101 + + if cog := cognew(@entry, rendezvous) + 1 + return true + else + abort string("Couldn't start sxtv cog") + +PUB stop + +'' Stop TV driver - frees a cog + + if cog + cogstop(cog~ - 1) + +PUB GetBasepin + repeat while long[rendezvous] + long[rendezvous]~~ ' ping the sxtv cog (send -1) + repeat while long[rendezvous] == -1 + return long[rendezvous]~ >> 8 + +PUB str(stringptr) + +'' Print a zero-terminated string + + repeat strsize(stringptr) + out(byte[stringptr++]) + + +PUB dec(value) | _i + +'' Print a decimal number + + if value < 0 + -value + out("-") + + _i := 1_000_000_000 + + repeat 10 + if value => _i + out(value / _i + "0") + value //= _i + result~~ + elseif result or _i == 1 + out("0") + _i /= 10 + + +PUB hex(value, digits) + +'' Print a hexadecimal number + + value <<= (8 - digits) << 2 + repeat digits + out(lookupz((value <-= 4) & $F : "0".."9", "A".."F")) + + +PUB bin(value, digits) + +'' Print a binary number + + value <<= 32 - digits + repeat digits + out((value <-= 1) & 1 + "0") + + +pub out( c ) + repeat while byte[rendezvous] + byte[rendezvous] := c + +DAT + +'******************************* +'* Assembly language TV driver * +'******************************* + + org +' +' +' Entry +' +entry + call #init + mov taskptr,#tasks 'reset tasks + +' +' +' Superfield +' +superfield + + test _mode,#%0001 wc 'if ntsc, set phaseflip + if_nc mov phaseflip,phasemask + + test _mode,#%0010 wz 'get interlace into nz +mov temp, #0 wz ''' I messed something up and now Z has to be set, not clear. +' +' +' Field +' +field mov x,vinv 'do invisible back porch lines +:black call #hsync 'do hsync + waitvid burst,sync_high2 'do black + jmpret taskret,taskptr 'call task section (z undisturbed) + djnz x,#:black 'another black line? + +' wrlong visible,par 'set status to visible + + mov x,vb 'do visible back porch lines + call #blank_lines + + + + + mov y,_vt 'set vertical tiles + movs :getchars4, #text '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +:line + mov vx,_vx 'set vertical expand + mov t1,#32 + mov chset, chset0 +:vert + if_z xor interlace,#1 'interlace skip? + if_z tjz interlace,#:skip + + call #hsync 'do hsync + + mov vscl,hb 'do visible back porch pixels + xor tile,colortable + waitvid tile,#0 + + mov x,_ht 'set horizontal tiles + shr x, #2 'divide by 4 + + mov vscl,hx 'set horizontal expand + +:getchars4 mov chars4, 0-0 + mov t3, #4 +:loop4 + mov char, chars4 + ror chars4, #8 + and char, #$ff + shr char, #1 wc + shl char, #7 + add char, chset + rdlong pixels16, char +' xor colors4, phaseflip + if_nc waitvid colortable, pixels16 + if_c waitvid colortable+1, pixels16 + djnz t3, #:loop4 + add :getchars4, #1 + djnz x, #:getchars4 + + mov vscl,hf 'do visible front porch pixels + mov tile,colortable'phaseflip +' xor tile,colortable + waitvid tile,#0 + sub :getchars4, #10 + +:skip + add chset, #4 + djnz t1, #:vert + + add :getchars4, #10 + djnz y,#:line 'another tile line? + + if_z xor interlace,#1 wz 'get interlace and field1 into z + + test _mode,#%0001 wc 'do visible front porch lines + mov x,vf + if_nz_and_c add x,#1 + call #blank_lines + +' if_z wrlong invisible,par 'unless interlace and field1, set status to invisible + + if_z_eq_c call #hsync 'if required, do short line + if_z_eq_c mov vscl,hrest + if_z_eq_c waitvid burst,sync_high2 + if_z_eq_c xor phaseflip,phasemask + + call #vsync_high 'do high vsync pulses + + movs vsync1,#sync_low1 'do low vsync pulses + movs vsync2,#sync_low2 + call #vsync_low + + call #vsync_high 'do high vsync pulses + + if_nz mov vscl,hhalf 'if odd frame, do half line + if_nz waitvid burst,sync_high2 + + if_z jmp #field 'if interlace and field1, display field2 + jmp #superfield 'else, new superfield +' +' +' Blank lines +' +blank_lines call #hsync 'do hsync + + xor tile,colortable 'do background + waitvid tile,#0 + + djnz x,#blank_lines + +blank_lines_ret ret +' +' +' Horizontal sync +' +hsync test _mode,#%0001 wc 'if pal, toggle phaseflip +' if_c xor phaseflip,phasemask + + mov vscl,sync_scale1 'do hsync + mov tile,burst'phaseflip +' xor tile,burst + waitvid tile,sync_normal + + mov vscl,hvis 'setup in case blank line + mov tile,#0'phaseflip + +hsync_ret ret +' +' +' Vertical sync +' +vsync_high movs vsync1,#sync_high1 'vertical sync + movs vsync2,#sync_high2 + +vsync_low mov x,vrep + +vsyncx mov vscl,sync_scale1 +vsync1 waitvid burst,sync_high1 + + mov vscl,sync_scale2 +vsync2 waitvid burst,sync_high2 + + djnz x,#vsyncx +vsync_low_ret +vsync_high_ret ret +' +' +' Tasks - performed in sections during invisible back porch lines +' +tasks + +clearscreen + mov i, #14 ' clear 13 lines + 1 extra to make scrolling easier +:lines + mov j, #40/4 ' 40 columns, 4 chars at a time +:chars +:storem mov text, x20202020 + add :storem, d0 ' inc dst + djnz j, #:chars + jmpret taskptr,taskret + djnz i, #:lines + +waitforchar + mov temp, #0 ' clear buffer: ready to accept next byte + wrlong temp, par +waitnoclear +:wait + jmpret taskptr,taskret + + rdlong ch, par + tjz ch, #:wait + ' got a byte + + mov temp, cmdPing ' roundabout comparisons to avoid changing Z. + sub temp, ch ' ch = -1 is just a ping to see if this cog is alive. + tjz temp, #ping + mov temp, cmdDisable + sub temp, ch + tjz temp, #disable + mov temp, cmdEnable + sub temp, ch + tjz temp, #enable + neg temp, #256 ' at this point, if ch is > 255, it must be _basepin<<8 + and temp, ch ' as set by a previous ping, so we just ignore it + tjnz temp, #waitnoclear ' (leave the long pointed to by par undisturbed). + +:char + mov temp, #8 + sub temp, ch + tjz temp, #:bksp + mov temp, #13 + sub temp, ch + tjnz temp, #:printchar + call #cr + jmp #waitforchar + +:bksp + sub col, #1 ' warning: no error-checking + jmp #waitforchar + +:printchar + mov temp, #40 + sub temp, col + tjnz temp, #:nocr + call #cr +:nocr + mov temp, col + shr temp, #2 + add temp, #text+12*40/4 + movs :get4chars, temp + movd :put4chars, temp + + mov i, col + and i, #3 + shl i, #3 ' col&3 => 0, 8, 16, 24 +:get4chars mov temp, 0-0 + ror temp, i + andn temp, #$ff + or temp, ch + rol temp, i +:put4chars mov 0-0, temp + + add col, #1 + + + jmp #waitforchar + +cr + movs :move4chars, #text + 40 / 4 + movd :move4chars, #text + + mov i, #13 ' copy 13 lines up. Since we have an extra blank line at the bottom + ' (see clearscreen) the last visible line is automatically cleared. +:copyline + mov j, #40/4 +:move4chars mov 0-0, 0-0 + add :move4chars, d0s0 + djnz j, #:move4chars + jmpret taskptr,taskret + djnz i, #:copyline + + mov col, #0 + +cr_ret ret + + + +ping + mov temp, _basepin + shl temp, #8 + wrlong temp, par + jmp #waitnoclear + +enable + mov dira, saveDira + mov dirb, saveDirb + jmp #waitforchar +disable + mov dira, #0 + mov dirb, #0 + jmp #waitforchar + + +' +' +' Initialized data +' +x20202020 long $20202020 +chset0 long $8000 +m8 long 8_000_000 +m128 long 128_000_000 +d0 long 1 << 9 << 0 +d6 long 1 << 9 << 6 +d0s0 long 1 << 9 << 0 + 1 << 0 +d0s1 long 1 << 9 << 0 + 1 << 1 +interlace long 0 +invisible long 1 +visible long 2 +phaseflip long $00000000 +phasemask long $F0F0F0F0 +line long $00060000 +lineinc long $10000000 +linerot long 0 +pins0 long %11110000_01110000_00001111_00000111 +pins1 long %11111111_11110111_01111111_01110111 +sync_high1 long %0101010101010101010101_101010_0101 +sync_high2 long %01010101010101010101010101010101 'used for black +sync_low1 long %1010101010101010101010101010_0101 +sync_low2 long %01_101010101010101010101010101010 +colortable +' long $07_0a_07_0a ' white on blue +' long $07_07_0a_0a +' long $bc_02_bc_02 ' green on black +' long $bc_bc_02_02 +' long $05_02_05_02 ' white on black +' long $05_05_02_02 + long $02_05_02_05 ' black on white + long $02_02_05_05 +' long $8a_8c_8a_8c ' black on yellow +' long $8a_8a_8c_8c + + +' +' +' NTSC/PAL metrics tables +' ntsc pal +' ---------------------------------------------- +wtab word lntsc - sntsc, lpal - spal 'hvis + word lntsc / 2 - sntsc, lpal / 2 - spal 'hrest + word lntsc / 2, lpal / 2 'hhalf + word 243, 286 'vvis + word 10, 18 'vinv + word 6, 5 'vrep + word $02_8A, $02_AA 'burst +wtabx +ltab long fntsc 'fcolor + long fpal + long sntsc >> 4 << 12 + sntsc 'sync_scale1 + long spal >> 4 << 12 + spal + long 67 << 12 + lntsc / 2 - sntsc 'sync_scale2 + long 79 << 12 + lpal / 2 - spal + long %0101_00000000_01_10101010101010_0101 'sync_normal + long %010101_00000000_01_101010101010_0101 +ltabx + +cmdPing long -1 +cmdEnable long "E"<<8 +cmdDisable long "D"<<8 +_basepin long 0 +' +' +' Parameter buffer +' +_enable long 1 'enable +_pins long 0 'pins +_mode long %10010 'mode +_screen long 0 'screen +_colors long 0 'colors +_ht long cols 'hc +_vt long rows 'vc +_hx long 4 'hx +_vx long 1 'vx +_ho long 0 'ho +_vo long 0 'vo +_broadcast long 0 'broadcast +_auralcog long 0 'auralcog + + +' +' +' Uninitialized data +' +i long 0 +j long 0 +col long 0 +ch long 0 +temp long 0 + +char long 0 +chset long 0 +chars4 long 0 +pixels16 long 0 +taskptr long 0 'tasks +taskret long 0 +t1 long 0 +t2 long 0 +t3 long 0 +m1 long 0 +m2 long 0 + +x long 0 'display +y long 0 +hf long 0 +hb long 0 +vf long 0 +vb long 0 +hx long 0 +vx long 0 +hc2x long 0 +screen long 0 +tile long 0 +pixels long 0 +lineadd long 0 + +hvis long 0 'loaded from word table +hrest long 0 +hhalf long 0 +vvis long 0 +vinv long 0 +vrep long 0 +burst long 0 + +fcolor long 0 'loaded from long table +sync_scale1 long 0 +sync_scale2 long 0 +sync_normal long 0 + +saveDira long 0 +saveDirb long 0 + + +text ' Cog memory from this point on will be reclaimed as text buffer. + +init + mov t1,_pins 'set video pins and directions + test t1,#$08 wc + if_nc mov t2,pins0 + if_c mov t2,pins1 + test t1,#$40 wc + shr t1,#1 + shl t1,#3 + shr t2,t1 + movs vcfg,t2 + shr t1,#6 + movd vcfg,t1 + shl t1,#3 + and t2,#$FF + shl t2,t1 + if_nc mov dira,t2 + if_nc mov saveDira, t2 + if_nc mov dirb,#0 + if_nc mov saveDirb, #0 + if_c mov dira,#0 + if_c mov saveDira, #0 + if_c mov dirb,t2 '+18 + if_c mov saveDirb, t2 + + + + movs :rd,#wtab 'load ntsc/pal metrics from word table + movd :wr,#hvis + mov t1,#wtabx - wtab + test _mode,#%0001 wc +:rd mov t2,0 + add :rd,#1 + if_nc shl t2,#16 + shr t2,#16 +:wr mov 0,t2 + add :wr,d0 + djnz t1,#:rd '+54 + + if_nc movs :ltab,#ltab 'load ntsc/pal metrics from long table + if_c movs :ltab,#ltab+1 + movd :ltab,#fcolor + mov t1,#(ltabx - ltab) >> 1 +:ltab mov 0,0 + add :ltab,d0s1 + djnz t1,#:ltab '+17 + + rdlong t1,#0 'get CLKFREQ + shr t1,#1 'if CLKFREQ < 16MHz, cancel _broadcast + cmp t1,m8 wc + if_c mov _broadcast,#0 + shr t1,#1 'if CLKFREQ < color frequency * 4, disable +' cmp t1,fcolor wc +' if_c jmp #disabled '+11 + + + mov t1,fcolor 'set ctra pll to fcolor * 16 + call #divide 'if ntsc, set vco to fcolor * 32 (114.5454 MHz) + test _mode,#%0001 wc 'if pal, set vco to fcolor * 16 (70.9379 MHz) + if_c movi ctra,#%00001_111 'select fcolor * 16 output (ntsc=/2, pal=/1) + if_nc movi ctra,#%00001_110 + if_nc shl t2,#1 + mov frqa,t2 '+147 + + mov t1,_broadcast 'set ctrb pll to _broadcast + mov t2,#0 'if 0, turn off ctrb + tjz t1,#:off + min t1,m8 'limit from 8MHz to 128MHz + max t1,m128 + mov t2,#%00001_100 'adjust _broadcast to be within 4MHz-8MHz +:scale shr t1,#1 '(vco will be within 64MHz-128MHz) + cmp m8,t1 wc + if_c add t2,#%00000_001 + if_c jmp #:scale +:off movi ctrb,t2 + call #divide + mov frqb,t2 '+165 + + mov t1,#%10100_000 'set video configuration + test _pins,#$01 wc '(swap broadcast/baseband output bits?) + if_c or t1,#%01000_000 + test _mode,#%1000 wc '(strip chroma from broadcast?) + if_nc or t1,#%00010_000 + test _mode,#%0100 wc '(strip chroma from baseband?) + if_nc or t1,#%00001_000 + and _auralcog,#%111 '(set aural cog) + or t1,_auralcog + movi vcfg,t1 '+10 + + mov hx,_hx 'compute horizontal metrics + shl hx,#8 + or hx,_hx + shl hx,#4 + + mov hc2x,_ht + shl hc2x,#1 + + mov t1,_ht + mov t2,_hx + call #multiply + mov hf,hvis + sub hf,t1 + shr hf,#1 wc + mov hb,_ho + addx hb,hf + sub hf,_ho '+52 + + mov t1,_vt 'compute vertical metrics + mov t2,_vx + call #multiply + test _mode,#%10000 wc 'consider tile size + muxc linerot,#1 + mov lineadd,lineinc + if_c shr lineadd,#1 + if_c shl t1,#1 + test _mode,#%0010 wc 'consider interlace + if_c shr t1,#1 + mov vf,vvis + sub vf,t1 + shr vf,#1 wc + neg vb,_vo + addx vb,vf + add vf,_vo '+53 + + +init_ret ret + +' +' +' Divide t1/CLKFREQ to get frqa or frqb value into t2 +' +divide rdlong m1,#0 'get CLKFREQ + + mov m2,#32+1 +:loop cmpsub t1,m1 wc + rcl t2,#1 + shl t1,#1 + djnz m2,#:loop + +divide_ret ret '+140 +' +' +' Multiply t1 * t2 * 16 (t1, t2 = bytes) +' +multiply shl t2,#8+4-1 + + mov m1,#8 +:loop shr t1,#1 wc + if_c add t1,t2 + djnz m1,#:loop + +multiply_ret ret '+37 + + +'' +''___ +''VAR 'TV parameters - 14 contiguous longs +'' +'' long tv_status '0/1/2 = off/invisible/visible read-only +'' long tv_enable '0/non-0 = off/on write-only +'' long tv_pins '%pppmmmm = pin group, pin group mode write-only +'' long tv_mode '%tccip = tile,chroma,interlace,ntsc/pal write-only +'' long tv_screen 'pointer to screen (words) write-only +'' long tv_colors 'pointer to colors (longs) write-only +'' long tv_ht 'horizontal tiles write-only +'' long tv_vt 'vertical tiles write-only +'' long tv_hx 'horizontal tile expansion write-only +'' long tv_vx 'vertical tile expansion write-only +'' long tv_ho 'horizontal offset write-only +'' long tv_vo 'vertical offset write-only +'' long tv_broadcast 'broadcast frequency (Hz) write-only +'' long tv_auralcog 'aural fm cog write-only +'' +''The preceding VAR section may be copied into your code. +''After setting variables, do start(@tv_status) to start driver. +'' +''All parameters are reloaded each superframe, allowing you to make live +''changes. To minimize flicker, correlate changes with tv_status. +'' +''Experimentation may be required to optimize some parameters. +'' +''Parameter descriptions: +'' _________ +'' tv_status +'' +'' driver sets this to indicate status: +'' 0: driver disabled (tv_enable = 0 or CLKFREQ < requirement) +'' 1: currently outputting invisible sync data +'' 2: currently outputting visible screen data +'' _________ +'' tv_enable +'' +'' 0: disable (pins will be driven low, reduces power) +'' non-0: enable +'' _______ +'' tv_pins +'' +'' bits 6..4 select pin group: +'' %000: pins 7..0 +'' %001: pins 15..8 +'' %010: pins 23..16 +'' %011: pins 31..24 +'' %100: pins 39..32 +'' %101: pins 47..40 +'' %110: pins 55..48 +'' %111: pins 63..56 +'' +'' bits 3..0 select pin group mode: +'' %0000: %0000_0111 - baseband +'' %0001: %0000_0111 - broadcast +'' %0010: %0000_1111 - baseband + chroma +'' %0011: %0000_1111 - broadcast + aural +'' %0100: %0111_0000 broadcast - +'' %0101: %0111_0000 baseband - +'' %0110: %1111_0000 broadcast + aural - +'' %0111: %1111_0000 baseband + chroma - +'' %1000: %0111_0111 broadcast baseband +'' %1001: %0111_0111 baseband broadcast +'' %1010: %0111_1111 broadcast baseband + chroma +'' %1011: %0111_1111 baseband broadcast + aural +'' %1100: %1111_0111 broadcast + aural baseband +'' %1101: %1111_0111 baseband + chroma broadcast +'' %1110: %1111_1111 broadcast + aural baseband + chroma +'' %1111: %1111_1111 baseband + chroma broadcast + aural +'' ----------------------------------------------------------- +'' active pins top nibble bottom nibble +'' +'' the baseband signal nibble is arranged as: +'' bit 3: chroma signal for s-video (attach via 560-ohm resistor) +'' bits 2..0: baseband video (sum 270/560/1100-ohm resistors to form 75-ohm 1V signal) +'' +'' the broadcast signal nibble is arranged as: +'' bit 3: aural subcarrier (sum 560-ohm resistor into network below) +'' bits 2..0: visual carrier (sum 270/560/1100-ohm resistors to form 75-ohm 1V signal) +'' _______ +'' tv_mode +'' +'' bit 4 selects between 16x16 and 16x32 pixel tiles: +'' 0: 16x16 pixel tiles (tileheight = 16) +'' 1: 16x32 pixel tiles (tileheight = 32) +'' +'' bit 3 controls chroma mixing into broadcast: +'' 0: mix chroma into broadcast (color) +'' 1: strip chroma from broadcast (black/white) +'' +'' bit 2 controls chroma mixing into baseband: +'' 0: mix chroma into baseband (composite color) +'' 1: strip chroma from baseband (black/white or s-video) +'' +'' bit 1 controls interlace: +'' 0: progressive scan (243 display lines for NTSC, 286 for PAL) +'' less flicker, good for motion +'' 1: interlaced scan (486 display lines for NTSC, 572 for PAL) +'' doubles the vertical display lines, good for text +'' +'' bit 0 selects NTSC or PAL format +'' 0: NTSC +'' 3016 horizontal display ticks +'' 243 or 486 (interlaced) vertical display lines +'' CLKFREQ must be at least 14_318_180 (4 * 3_579_545 Hz)* +'' 1: PAL +'' 3692 horizontal display ticks +'' 286 or 572 (interlaced) vertical display lines +'' CLKFREQ must be at least 17_734_472 (4 * 4_433_618 Hz)* +'' +'' * driver will disable itself while CLKFREQ is below requirement +'' _________ +'' tv_screen +'' +'' pointer to words which define screen contents (left-to-right, top-to-bottom) +'' number of words must be tv_ht * tv_vt +'' each word has two bitfields: a 6-bit colorset ptr and a 10-bit pixelgroup ptr +'' bits 15..10: select the colorset* for the associated pixel tile +'' bits 9..0: select the pixelgroup** address %ppppppppppcccc00 (p=address, c=0..15) +'' +'' * colorsets are longs which each define four 8-bit colors +'' +'' ** pixelgroups are longs which define (left-to-right, top-to-bottom) the 2-bit +'' (four color) pixels that make up a 16x16 or a 32x32 pixel tile +'' _________ +'' tv_colors +'' +'' pointer to longs which define colorsets +'' number of longs must be 1..64 +'' each long has four 8-bit fields which define colors for 2-bit (four color) pixels +'' first long's bottom color is also used as the screen background color +'' 8-bit color fields are as follows: +'' bits 7..4: chroma data (0..15 = blue..green..red..)* +'' bit 3: controls chroma modulation (0=off, 1=on) +'' bits 2..0: 3-bit luminance level: +'' values 0..1: reserved for sync - don't use +'' values 2..7: valid luminance range, modulation adds/subtracts 1 (beware of 7) +'' value 0 may be modulated to produce a saturated color toggling between levels 1 and 7 +'' +'' * because of TV's limitations, it doesn't look good when chroma changes abruptly - +'' rather, use luminance - change chroma only against a black or white background for +'' best appearance +'' _____ +'' tv_ht +'' +'' horizontal number pixel tiles - must be at least 1 +'' practical limit is 40 for NTSC, 50 for PAL +'' _____ +'' tv_vt +'' +'' vertical number of pixel tiles - must be at least 1 +'' practical limit is 13 for NTSC, 15 for PAL (26/30 max for interlaced NTSC/PAL) +'' _____ +'' tv_hx +'' +'' horizontal tile expansion factor - must be at least 3 for NTSC, 4 for PAL +'' +'' make sure 16 * tv_ht * tv_hx + ||tv_ho + 32 is less than the horizontal display ticks +'' _____ +'' tv_vx +'' +'' vertical tile expansion factor - must be at least 1 +'' +'' make sure * tv_vt * tv_vx + ||tv_vo + 1 is less than the display lines +'' _____ +'' tv_ho +'' +'' horizontal offset in ticks - pos/neg value (0 for centered image) +'' shifts the display right/left +'' _____ +'' tv_vo +'' +'' vertical offset in lines - pos/neg value (0 for centered image) +'' shifts the display up/down +'' ____________ +'' tv_broadcast +'' +'' broadcast frequency expressed in Hz (ie channel 2 is 55_250_000) +'' if 0, modulator is turned off - saves power +'' +'' broadcasting requires CLKFREQ to be at least 16_000_000 +'' while CLKFREQ is below 16_000_000, modulator will be turned off +'' ___________ +'' tv_auralcog +'' +'' selects cog to supply aural fm signal - 0..7 +'' uses ctra pll output from selected cog +'' +'' in NTSC, the offset frequency must be 4.5MHz and the max bandwidth +-25KHz +'' in PAL, the offset frequency and max bandwidth vary by PAL type + +{{ + ++------------------------------------------------------------------------------------------------------------------------------+ +¦ TERMS OF USE: MIT License ¦ ++------------------------------------------------------------------------------------------------------------------------------¦ +¦Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation ¦ +¦files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, ¦ +¦modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software¦ +¦is furnished to do so, subject to the following conditions: ¦ +¦ ¦ +¦The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.¦ +¦ ¦ +¦THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE ¦ +¦WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ¦ +¦COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ¦ +¦ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ¦ ++------------------------------------------------------------------------------------------------------------------------------+ +}} \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx2/symbols.spn b/zubehör/sphinx/spinx100225-ori/sphinx2/symbols.spn new file mode 100644 index 0000000..c2ac225 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx2/symbols.spn @@ -0,0 +1,83 @@ +obj + bt: "bintree" +dat +pSymbolTable word 0 + +pub Init + + FixupTable( @table + 2 ) + pSymbolTable := @table + bt.PokeW( pSymbolTable, @table + 2 ) + +pri FixupTable( p ) | q + q := bt.PeekW( p ) + if q + bt.PokeW( p, q += @table ) + FixupTable( q ) + q := bt.PeekW( p + 2 ) + if q + bt.PokeW( p + 2, q += @table ) + FixupTable( q ) + +pub SymbolLookup( s ) + return bt.FindInTable( s, bt.PeekW(pSymbolTable) ) + +pub AddToTable( s ) + bt.AddToTable( s, pSymbolTable ) + +pub GetPSymbolTable + return pSymbolTable + +con #0 +' In the symbol table, the symbol's name (null-terminated) is followed by one of the following type bytes +' which is in turn followed by additional data: +{0} kINT_CON_SYMBOL ' followed by 4-byte constant +{1} kFLOAT_CON_SYMBOL ' followed by 4-byte constant +{2} kPUB_SYMBOL ' followed by 1-byte method index, 1-byte #params +{3} kPRI_SYMBOL ' followed by 1-byte method index, 1-byte #params +{4} kOBJ_SYMBOL ' followed by 2-byte pointer to child object's symbol table, 1-byte index, 2-byte count, + ' 2-byte pointer to next OBJ in linked list +{5} kVAR_SYMBOL ' followed by 1-byte size (1, 2, 4), 2-byte var offset +{6} kDAT_SYMBOL ' followed by 1-byte size (1, 2, 4), 2-byte dat offset, 2-byte cog address * 4, 2-byte pointer to local labels +{7} kSOB_SYMBOL ' followed by 2-byte pointer to SOB's symbol table +{8} kUNDEFINED_CON_SYMBOL ' followed by 4-byte constant to be determined +{9} kBUILTIN_INT_SYMBOL ' followed by 4-byte constant +{10}kBUILTIN_FLOAT_SYMBOL ' followed by 4-byte constant + +dat +table word 0 + byte $10,$00,$85,$00,$50,$4f,$53,$58,$00,$09,$ff,$ff,$ff,$7f,$1f,$00 + byte $58,$00,$50,$4c,$4c,$31,$58,$00,$09,$40,$00,$00,$00,$2b,$00,$48 + byte $00,$50,$49,$00,$0a,$db,$0f,$49,$40,$39,$00,$00,$00,$4e,$45,$47 + byte $58,$00,$09,$00,$00,$00,$80,$00,$00,$00,$00,$46,$41,$4c,$53,$45 + byte $00,$09,$00,$00,$00,$00,$00,$00,$00,$00,$50,$4c,$4c,$31,$36,$58 + byte $00,$09,$00,$04,$00,$00,$67,$00,$76,$00,$50,$4c,$4c,$34,$58,$00 + byte $09,$00,$01,$00,$00,$00,$00,$00,$00,$50,$4c,$4c,$32,$58,$00,$09 + byte $80,$00,$00,$00,$00,$00,$00,$00,$50,$4c,$4c,$38,$58,$00,$09,$00 + byte $02,$00,$00,$95,$00,$c3,$00,$58,$49,$4e,$50,$55,$54,$00,$09,$04 + byte $00,$00,$00,$a5,$00,$b5,$00,$52,$43,$53,$4c,$4f,$57,$00,$09,$02 + byte $00,$00,$00,$00,$00,$00,$00,$52,$43,$46,$41,$53,$54,$00,$09,$01 + byte $00,$00,$00,$00,$00,$00,$00,$54,$52,$55,$45,$00,$09,$ff,$ff,$ff + byte $ff,$d2,$00,$e1,$00,$58,$54,$41,$4c,$32,$00,$09,$10,$00,$00,$00 + byte $00,$00,$00,$00,$58,$54,$41,$4c,$31,$00,$09,$08,$00,$00,$00,$00 + byte $00,$00,$00,$58,$54,$41,$4c,$33,$00,$09,$20,$00,$00,$00 + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} + \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx2/tokenizr.spn b/zubehör/sphinx/spinx100225-ori/sphinx2/tokenizr.spn new file mode 100644 index 0000000..652b6da --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx2/tokenizr.spn @@ -0,0 +1,430 @@ +' 2009-05-02 Modified to detect when inside DAT, handle : specially (for local labels) + +con + _clkmode = xtal1 + pll8x + _xinfreq = 10_000_000 + _stack = 1000 +obj + f: "sxfile" + floatString: "FltStr" + kw: "keywords" + bt: "bintree" + +pub Open( pFilename ) + + if f.Open( pFilename, "R") <> 0 + abort string("can't open file") + + InitReadLine + + insideDAT~ + + Advance ' prime the pump + +pub Close + f.Close + +{ + bytes~ + InitReadLine + GetNextToken ' prime the pump + + t := cnt + repeat + case tokenType + EOL_TOKEN: + term.str( @tokenText ) + EOF_TOKEN: + quit + ID_TOKEN: + term.str( @tokenText ) + OP_TOKEN: + INT_TOKEN: + term.out( "#" ) + term.dec( tokenValue ) + FLOAT_TOKEN: + term.out( "F" ) + term.str( floatString.FloatToString( tokenValue ) ) + term.out( "\" ) + GetNextToken + term.out( 13 ) +'} +{ repeat while SkipWhitespace + term.dec( lineNo ) + term.out( "," ) + term.dec( cp+1 ) + term.out( ":" ) + if cp == lineLength + term.str( string("(eol)")) + else + term.out( lineBuffer[cp++] ) + term.out( 13 ) +'} +{ + repeat + r := sdfat.pread( @buf, BUFFERSIZE ) + if r < 0 + quit + bytes += r +'} +{ + repeat 100 + r := sdfat.pgetc + if r < 0 + quit + ++bytes + term.dec(r) + term.out( "," ) +'} + +con + MAXTOKENLENGTH = 32 + BUFFERSIZE = 200 + +var + byte tokenText[MAXTOKENLENGTH+1] + long tokenType + word tokenLineNumber + word tokenCol + long tokenValue + byte insideDAT + +pub GetPText + return @tokenText + +pub Type + return tokenType + +pub Column + return tokenCol + +pub LineNumber + return tokenLineNumber + +pub Value + return tokenValue + +pub Advance | i, radix, fp, x, hack + if inStringLiteral + if comma + comma~ + ifnot tokenValue + abort string("Unterminated string") + if lineBuffer[cp] <> $22 ' double-quote + tokenType := kw#kCOMMA + return + ++cp + inStringLiteral~ + else + comma~~ + tokenType := kw#kINTLITERAL + tokenValue := lineBuffer[cp++] + return + + if SkipWhitespace + if cp == lineLength + tokenType := kw#kEOL + bytemove( @tokenText, string("(EOL)"), 6 ) + tokenLineNumber := lineNo + tokenCol := cp + elseif lineBuffer[cp] == $22 ' double-quote + tokenLineNumber := LineNo + tokenCol := cp + ++cp + if LineBuffer[cp] == $22 + abort string("Empty string") + comma~ + inStringLiteral~~ + Advance + elseif lineBuffer[cp] == "%" or lineBuffer[cp] == "$" + tokenType := kw#kINTLITERAL + tokenLineNumber := lineNo + tokenCol := cp + if lineBuffer[cp] == "%" + if lineBuffer[cp+1] == "%" + radix := 4 + ++cp + else + radix := 2 + else + radix := 16 + ++cp + ifnot IsDigit( lineBuffer[cp], radix, false ) + abort string("Bad character in number") + tokenValue~ + repeat while IsDigit( lineBuffer[cp], radix, true ) + if lineBuffer[cp] <> "_" + tokenValue := tokenValue * radix + DigitValue( linebuffer[cp] ) + ++cp + elseif IsDigit( lineBuffer[cp], 10, false ) + tokenLineNumber := lineNo + tokenCol := cp + i~ + fp~ {0 => integer + 1 => have seen . + 2 => have seen e or E + 3 => have seen + or - } + repeat while IsDigit( lineBuffer[cp], 10, true ) { +} or ( fp < 1 and lineBuffer[cp] == "." and lineBuffer[cp+1] <> "." ) { +} or ( fp < 2 and (lineBuffer[cp] == "e" or lineBuffer[cp] == "E") ) { +} or ( (fp == 1 or fp == 2) and (lineBuffer[cp] == "+" or lineBuffer[cp] == "-") ) + if lineBuffer[cp] == "." + fp := 1 + if lineBuffer[cp] == "e" or lineBuffer[cp] == "E" + fp := 2 + if lineBuffer[cp] == "+" or lineBuffer[cp] == "-" + fp := 3 + if lineBuffer[cp] <> "_" + if i => MAXTOKENLENGTH + abort string("Token too long") + tokenText[i++] := lineBuffer[cp] + ++cp + tokenText[i]~ + if fp + tokenType := kw#kFLOATLITERAL + tokenValue := floatString.StringToFloat( @tokenText ) + else + tokenType := kw#kINTLITERAL + tokenValue~ + i~ + repeat while tokenText[i] + tokenValue := tokenValue * 10 + DigitValue( tokenText[i++] ) + elseif IsAlpha( lineBuffer[cp] ) + i~ + tokenLineNumber := lineNo + tokenCol := cp + repeat while IsAlpha( lineBuffer[cp] ) or IsDigit( lineBuffer[cp], 10, true ) + if i => MAXTOKENLENGTH + abort string("Token too long") + tokenText[i++] := ToUpper( lineBuffer[cp++] ) + tokenText[i]~ + x := kw.KeywordLookup( @tokenText ) + if x + tokenType := bt.PeekL( x ) + if kw#kCON =< tokenType and tokenType =< kw#kVAR and tokenCol == 0 + insideDAT := tokenType == kw#kDAT + else + tokenType := kw#kID + else ' non-alphanumeric + tokenLineNumber := lineNo + tokenCol := cp + i~ + if lineBuffer[cp] < $20 or lineBuffer[cp] => $80 + abort string("Illegal character (UNICODE?)") + + if insideDat and lineBuffer[cp] == ":" and IsAlpha( lineBuffer[cp+1] ) + tokenText[i++] := lineBuffer[cp++] + repeat while IsAlpha( lineBuffer[cp] ) or IsDigit( lineBuffer[cp], 10, true ) + if i => MAXTOKENLENGTH + abort string("Token too long") + tokenText[i++] := ToUpper( lineBuffer[cp++] ) + tokenText[i]~ + tokenType := kw#kID + else + repeat + if cp < lineLength + tokenText[i++] := lineBuffer[cp++] + else + tokenText[i++] := " " + ++cp + tokenText[i]~ + while x := kw.KeywordLookup( @tokenText ) + if i > 1 + tokenText[--i]~ ' shorten token by 1 + --cp + tokenType := bt.PeekL( kw.KeywordLookup( @tokenText ) ) + else + tokenType := kw#kUNKNOWN + + if IsBinary ' This next block is a total hack to see if a binary op + hack := blankLine ' hack is followed by "=" making it an assignment op + SkipWhitespace ' It parses "and ==" as "(and=) =" instead of "(and)(==)" + if lineBuffer[cp] == "=" ' PropTool does the latter. So this is wrong, but hopefully + tokenText[i++] := lineBuffer[cp++] ' not *too* wrong. + tokenText[i]~ + tokenType |= kw#kASSIGNMENT + else + blankLine := hack ' restore (this hack is necessary to reset the eol condition trigger in SkipWhitespace) + else + tokenType := kw#kEOF + bytemove( @tokenText, string("(EOF)"), 6 ) + tokenLineNumber := lineNo + tokenCol := cp + +pri ToUpper( ch ) + if "a" =< ch and ch =< "z" + ch += constant( "A" - "a" ) + return ch + +pri IsAlpha( ch ) + return "a" =< ch and ch =< "z" or "A" =< ch and ch =< "Z" or ch == "_" + +pri IsDigit( ch, radix, u ) | upper +{{ + Returns non-zero if ch is an acceptable digit given radix (2, 4, 10, or 16), false otherwise. + Pass u = true if the underscore ("_") is an acceptable value for ch. +}} + if ch == "_" + return u + upper := constant("0"-1) + radix + if radix =< 10 + return "0" =< ch and ch =< upper + ' else radix == 16 + return "0" =< ch and ch =< "9" or "a" =< ch and ch =< "f" or "A" =< ch and ch =< "F" + +pri DigitValue( ch ) + if ch =< "9" + return ch - "0" + if ch =< "F" + return ch + constant( 10 - "A" ) + if ch =< "f" + return ch + constant( 10 - "a" ) + +pub IsBinary +{{ + Returns non-zero (not necessarily -1) if token is a binary operator. + Returns 0 otherwise. +}} + return ( tokenType & constant(kw#kUNARY|kw#kBINARY) ) == kw#kBINARY + +var + byte lineBuffer[BUFFERSIZE] + byte lineLength + byte lineRemainder + byte eolLength + word lineNo + byte cp + byte blankLine + byte inStringLiteral ' indicates we are splitting up a string literal + byte comma ' flag for returning commas when splitting up a string literal + +pri SkipWhitespace +'' Returns true on success, false on failure (eof). +'' lineBuffer[cp] is the next non-whitespace character +'' (comments count as whitespace). + repeat + repeat while cp => lineLength + ifnot blankLine + blankLine~~ + return true + ifnot ReadLine + return false + if lineBuffer[cp] == 9 + abort string("Illegal TAB character") + if lineBuffer[cp] == "'" ' quote comment? + cp := lineLength ' skip to end of line + elseif lineBuffer[cp] == "}" + abort string("Unexpected '}'") + elseif lineBuffer[cp] == "{" + SkipComment + elseif lineBuffer[cp] == " " + ++cp + else ' non-blank character + blankLine~ + return true + +pri SkipComment | depth + if cp+1 < lineLength and lineBuffer[cp+1] == "{" + ++cp + repeat + repeat while cp => lineLength + ifnot ReadLine + abort string("Unterminated comment") + if cp+1 < lineLength and lineBuffer[cp] == "}" and lineBuffer[cp+1] == "}" + cp += 2 + return + ++cp + else + ++cp + depth := 1 + repeat + repeat while cp => lineLength + ifnot ReadLine + abort string("Unterminated comment") + if lineBuffer[cp] == "{" + ++cp + ++depth + elseif lineBuffer[cp] == "}" + ++cp + ifnot --depth + return + else + ++cp + +pri InitReadLine + lineLength~ + lineRemainder~ + eolLength~ + lineNo~ + cp~ + blankLine~~ + inStringLiteral~ +{ + |<--------------- BUFFERSIZE --------------->| + +--------------------------------------------+ + | | | | | + +--------------------------------------------+ + |<-lineLength ->| | | + eolLength ->| |<- | + |<- lineRemainder ->| +} +pri ReadLine | bytes, i +'' Reads a line into lineBuff. Returns true on success, false on failure (eof) +'' The line in lineBuff is terminated with a null byte. Calling programs should +'' not modify any memory in lineBuff after the null (the "remainder" section in +'' the diagram above) because that's the following line(s). + +' First, move remainder up to start of buffer + bytemove( @lineBuffer, @lineBuffer[lineLength+eolLength], lineRemainder ) +' Fill the rest of the buffer with new data + bytes := f.Read( @lineBuffer[lineRemainder], BUFFERSIZE-lineRemainder ) + ' pread returns #bytes read, but after eof it returns negative numbers + if bytes > 0 + lineRemainder += bytes + + ifnot lineRemainder + ++lineNo + cp~ + return false + + repeat i from 0 to (lineRemainder-2) #> 0 + if lineBuffer[i] == 13 or lineBuffer[i] == 10 + eolLength := 1 ' cr or lf + if lineBuffer[i] == 13 and lineBuffer[i+1] == 10 + ++eolLength ' cr+lf + lineBuffer[i]~ ' set terminating null + lineLength := i + lineRemainder -= lineLength + eolLength + ++lineNo ' first line of file is line 1 + cp~ + return true + + if lineRemainder < BUFFERSIZE + lineLength := lineRemainder~ + lineBuffer[lineLength]~ + ++lineNo + cp~ + return true + + abort string("Input line too long") + + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} + \ No newline at end of file diff --git a/zubehör/sphinx/spinx100225-ori/sphinx2/tokenrdr.spn b/zubehör/sphinx/spinx100225-ori/sphinx2/tokenrdr.spn new file mode 100644 index 0000000..9788e26 --- /dev/null +++ b/zubehör/sphinx/spinx100225-ori/sphinx2/tokenrdr.spn @@ -0,0 +1,272 @@ +obj + sxfs: "isxfs" + kw: "kwdefs" + bt: "bintree" + +dat + long +filestuff byte 0[sxfs#SIZEOFFILESTUFF] + +pub Open( pFilename ) + + if \sxfs.Open( @filestuff, pFilename, "R" ) <> 0 + abort string("can't open file") + + Advance ' prime the pump + +pub Close + sxfs.Close( @filestuff ) + +con + MAXTOKENLENGTH = 32 + +dat +tokenType long 0 +tokenValue long 0 +tokenLineNumber word 0 +tokenCol word 0 +tokenText byte 0[MAXTOKENLENGTH+1] + +pub Text + return @tokenText + +pub Type + return tokenType + +pub Column + return tokenCol + +pub LineNumber + return tokenLineNumber + +pub Value + return tokenValue + +pub AdvanceIf( t ) +{{ + If current token's type is t, advance and return true; + otherwise return false without advancing. + t should be one of the specific token types, not a generic type like kCOND. +}} + if tokenType <> t + return false + Advance + return true + +pub Eat( t ) +{{ + Like Advance, but asserts that the soon-to-be-previous token's type is t. + t should be one of the specific token types, not a generic type like kCOND. +}} + if tokenType <> t + abort string("Syntax error (unexpected)") + Advance + +pub Advance + tokenType := ReadLong + tokenLineNumber := ReadWord + tokenCol := ReadWord + if tokenType == kw#kINTLITERAL or tokenType == kw#kFLOATLITERAL + sxfs.Read( @filestuff, @tokenValue, 4 ) + else + ReadString( @tokenText, MAXTOKENLENGTH ) + +pub IsId +{{ + Returns non-zero (not necessarily -1) if token is a plain old identifier. + Returns 0 otherwise. +}} + return tokenType & kw#kID + +pub IsIntLiteral +{{ + Returns non-zero (not necessarily -1) if token is an int literal. + Returns 0 otherwise. +}} + return tokenType & kw#kINTLITERAL + +pub IsFloatLiteral +{{ + Returns non-zero (not necessarily -1) if token is an float literal. + Returns 0 otherwise. +}} + return tokenType & kw#kFLOATLITERAL + +pub IsUnaryOp +{{ + Returns non-zero (not necessarily -1) if token is a unary operator. + Returns 0 otherwise. +}} + return tokenType & kw#kUNARY + +pub IsBinaryOp +{{ + Returns non-zero (not necessarily -1) if token is a binary operator. + Returns 0 otherwise. +}} + return ( tokenType & constant(kw#kUNARY|kw#kBINARY) ) == kw#kBINARY + +pub IsPostfixOp +{{ + Returns non-zero (not necessarily -1) if token is a postfix operator. + Returns 0 otherwise. +}} + return ( tokenType & constant(kw#kUNARY|kw#kPOSTFIX) ) == constant(kw#kUNARY|kw#kPOSTFIX) + +pub IsAssignmentOp +{{ + Returns non-zero (not necessarily -1) if token is an assignment operator. + Returns 0 otherwise. +}} + return tokenType & kw#kASSIGNMENT + +pub GetPrecedence +{{ + If token is an operator, returns its precedence. + If token isn't, returns 13. +}} + if tokenType & constant( kw#kBINARY | kw#kUNARY ) + return (tokenType >> 16) & $0f + else + return 13 + +pub GetSpinOpcode +{{ + If token is an operator or a statement function, returns its Spin opcode. + If token isn't, returns nonsense. +}} + return tokenType & $ff + +pub GetSpinOpcode2 +{{ + If token is a postfix operator, returns its alternate Spin opcode. + If token isn't, returns nonsense. +}} + return (tokenType >> 8) & $ff + +pub IsPasm +{{ + Returns non-zero (not necessarily -1) if token is a PASM mnemonic. + Returns 0 otherwise. +}} + return tokenType & kw#kPASM + +pub GetPasmOp +{{ + If token is a PASM mnemonic, return its PASM opcode. +}} + return tokenType << 16 + +pub GetPasmDS +{{ + If token is a PASM mnemonic, return its DS information. +}} + return (tokenType >> 16) & 3 + +pub IsCond +{{ + Returns non-zero (not necessarily -1) if token is a PASM condition code (e.g., IF_A). + Returns 0 otherwise. +}} + return tokenType & kw#kCOND + +pub GetCond +{{ + Returns condition bits if token is a PASM condition code. +}} + return tokenType & $0f + +pub IsEffect +{{ + Returns non-zero (not necessarily -1) if token is a PASM effect (e.g., WC). + Returns 0 otherwise. +}} + return tokenType & kw#kEFFECT + +pub GetEffect +{{ + Returns effect bits if token is a PASM effect. +}} + return tokenType & $0f + +pub IsReg +{{ + Returns non-zero (not necessarily -1) if token is a special register (e.g., PHSA). + Returns 0 otherwise. +}} + return kw#kPAR =< tokenType and tokenType =< kw#kVSCL + +pub GetReg +{{ + Returns register# if token is a special register. +}} + return tokenType - kw#kPAR + +pub IsBlockDesignator +{{ + Returns true if token is a block designator (e.g., DAT). +}} + return kw#kCON =< tokenType and tokenType =< kw#kVAR + +pub IsSize +{{ + Returns true if token is BYTE, WORD, or LONG. +}} + return kw#kBYTE =< tokenType and tokenType =< kw#kLONG + +pub IsStmtFn +{{ + Returns non-zero (not necessarily -1) if token is a "statement function" (e.g. BYTEMOVE, WAITCNT). + Returns 0 otherwise. +}} + return tokenType & kw#kSTMTFN + +pub GetNumArgs +{{ + Returns #args if token is a "statement function". +}} + return (tokenType >> 8) & 3 + +pub IsIntrinsic +{{ + Returns non-zero (not necessarily -1) if token is an intrinsic (e.g., COGNEW, LOOKUP). + Returns 0 otherwise. +}} + return tokenType & kw#kINTRINSIC + +pri ReadString( p, MAXLENGTH ) | ch + repeat MAXLENGTH + 1 + ch := ReadByte + if "a" =< ch and ch =< "z" + ch -= constant("a" - "A") + ifnot byte[p++] := ch + return + abort string("ReadString: string too long") + +pri ReadByte : ch + sxfs.Read( @filestuff, @ch, 1 ) + +pri ReadWord + return ReadByte + (ReadByte << 8) + +pri ReadLong + return ReadByte + (ReadByte << 8) + (ReadByte << 16) + (ReadByte << 24) + +{{ +Copyright (c) 2009 Michael Park ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} diff --git a/zubehör/startracker/bin/stint.bel b/zubehör/startracker/bin/stint.bel new file mode 100644 index 0000000..e056b11 Binary files /dev/null and b/zubehör/startracker/bin/stint.bel differ diff --git a/zubehör/startracker/bin/stplay.bin b/zubehör/startracker/bin/stplay.bin new file mode 100644 index 0000000..bdbe4a5 Binary files /dev/null and b/zubehör/startracker/bin/stplay.bin differ diff --git a/zubehör/startracker/notiz.rtf b/zubehör/startracker/notiz.rtf new file mode 100644 index 0000000..942455e Binary files /dev/null and b/zubehör/startracker/notiz.rtf differ diff --git a/zubehör/startracker/source/bellatrix-code/Corner_BottomLeft.dat b/zubehör/startracker/source/bellatrix-code/Corner_BottomLeft.dat new file mode 100644 index 0000000..5941fa4 Binary files /dev/null and b/zubehör/startracker/source/bellatrix-code/Corner_BottomLeft.dat differ diff --git a/zubehör/startracker/source/bellatrix-code/Corner_topleft.dat b/zubehör/startracker/source/bellatrix-code/Corner_topleft.dat new file mode 100644 index 0000000..0fdf59f Binary files /dev/null and b/zubehör/startracker/source/bellatrix-code/Corner_topleft.dat differ diff --git a/zubehör/startracker/source/bellatrix-code/Corner_topright.dat b/zubehör/startracker/source/bellatrix-code/Corner_topright.dat new file mode 100644 index 0000000..cb56785 Binary files /dev/null and b/zubehör/startracker/source/bellatrix-code/Corner_topright.dat differ diff --git a/zubehör/startracker/source/bellatrix-code/HV_Break.dat b/zubehör/startracker/source/bellatrix-code/HV_Break.dat new file mode 100644 index 0000000..ccdfe3b --- /dev/null +++ b/zubehör/startracker/source/bellatrix-code/HV_Break.dat @@ -0,0 +1,2 @@ +ÿÿÿ_ÿÿÿ_ÿÿÿ_ÿÿÿ_ÿÿÿ_ÿÿÿ_ÿÿÿ_ÿÿÿ_ÿÿÿ_ÿÿÿ_ÿÿÿ_ÿÿÿ_ÿÿÿ_ÿÿÿ_ªªª +ªªª diff --git a/zubehör/startracker/source/bellatrix-code/HV_Break2.dat b/zubehör/startracker/source/bellatrix-code/HV_Break2.dat new file mode 100644 index 0000000..53f8c70 --- /dev/null +++ b/zubehör/startracker/source/bellatrix-code/HV_Break2.dat @@ -0,0 +1,3 @@ +ªªª +ªªª +ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿUUUUUU \ No newline at end of file diff --git a/zubehör/startracker/source/bellatrix-code/endcap_Med_left.dat b/zubehör/startracker/source/bellatrix-code/endcap_Med_left.dat new file mode 100644 index 0000000..524d651 --- /dev/null +++ b/zubehör/startracker/source/bellatrix-code/endcap_Med_left.dat @@ -0,0 +1 @@ +UUÕÿUUýÿUÕÿÿUõÿÿUÿÿÿÔÿÿÿÔÿÿÿôÿÿÿøÿÿÿèÿÿÿèÿÿÿªÿÿÿªúÿÿªêÿÿªªþÿªªêÿ \ No newline at end of file diff --git a/zubehör/startracker/source/bellatrix-code/endcap_Med_right.dat b/zubehör/startracker/source/bellatrix-code/endcap_Med_right.dat new file mode 100644 index 0000000..81b7eaa --- /dev/null +++ b/zubehör/startracker/source/bellatrix-code/endcap_Med_right.dat @@ -0,0 +1 @@ +ÿWUUÿUUÿÿWUÿÿ_UÿÿÿUÿÿÿÿÿÿÿÿÿÿÿÿ/ÿÿÿ+ÿÿÿ+ÿÿÿªÿÿ¯ªÿÿ«ªÿ¿ªªÿ«ªª \ No newline at end of file diff --git a/zubehör/startracker/source/bellatrix-code/endcap_Small_left.dat b/zubehör/startracker/source/bellatrix-code/endcap_Small_left.dat new file mode 100644 index 0000000..7c14573 Binary files /dev/null and b/zubehör/startracker/source/bellatrix-code/endcap_Small_left.dat differ diff --git a/zubehör/startracker/source/bellatrix-code/endcap_Small_right.dat b/zubehör/startracker/source/bellatrix-code/endcap_Small_right.dat new file mode 100644 index 0000000..66db08d --- /dev/null +++ b/zubehör/startracker/source/bellatrix-code/endcap_Small_right.dat @@ -0,0 +1,4 @@ +UUÿ_UÿÿUÿÿWÿÿ_ÿÿÿÿÿÿÿÿÿÿ¿ÿÿ¯ +ÿÿ« +ÿÿª +ÿ¯ª*¿ªª*ªªª*ªªª* \ No newline at end of file diff --git a/zubehör/startracker/source/bellatrix-code/filled_space.dat b/zubehör/startracker/source/bellatrix-code/filled_space.dat new file mode 100644 index 0000000..85f2b75 --- /dev/null +++ b/zubehör/startracker/source/bellatrix-code/filled_space.dat @@ -0,0 +1 @@ +ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ \ No newline at end of file diff --git a/zubehör/startracker/source/bellatrix-code/font_29p5.dat b/zubehör/startracker/source/bellatrix-code/font_29p5.dat new file mode 100644 index 0000000..13c2f85 Binary files /dev/null and b/zubehör/startracker/source/bellatrix-code/font_29p5.dat differ diff --git a/zubehör/startracker/source/bellatrix-code/stint.spin b/zubehör/startracker/source/bellatrix-code/stint.spin new file mode 100644 index 0000000..673c2b3 --- /dev/null +++ b/zubehör/startracker/source/bellatrix-code/stint.spin @@ -0,0 +1,670 @@ +''LCARS tryout in XGA * +'Trying to emulate look of this page: http://www.lcarscom.net/databank.htm +'Copyright 2008 Raymond Allen + +{{ --------------------------------------------------------------------------------------------------------- + +Hive-Computer-Projekt + +Name : StarTracker +Chip : Bellatrix-Code (soundplayer) +Version : 0.1 +Dateien : stint.spin + +Beschreibung : Grafiktreiber für StarTracker + +Eigenschaften : + +Logbuch : + +Kommandoliste: + +0 1 Tastaturstatus abfragen +0 2 Tastaturzeichen holen +0 3 n Screensteuerzeichen +0 3 0 CLS +0 3 1 Home +0 3 2 Backspace +0 3 3 TAB +0 3 4 n SETCUR Cursorzeichen auf n setzen +0 3 5 POS1 +0 3 6 x SETX +0 3 7 y SETY +0 3 8 (x) GETX +0 3 9 (y) GETY +0 3 10 c SETCOL +0 3 11 n SLINE +0 3 13 SCREENINIT +0 3 14 CURON +0 3 15 CUROFF +0 99 Reboot und neuen Treiber laden +0 100 testfunktion + +1..255 Zeichenausgabe + + + --------------------------------------------------------------------------------------------------------- }} + + +CON + + _clkmode = xtal1 + pll16x + _xinfreq = 5_000_000 + + 'number of custom 16x16 characters + nuchars = (6*3+1*7+47+23*2+20*5) '!!!!! you must have the correct # here for alignment later + +'signaldefinitionen regnatix + +#0, D0,D1,D2,D3,D4,D5,D6,D7 'datenbus +#8, BEL_VGABASE 'vga-signale (8pin) +#16, BEL_KEYBC,BEL_KEYBD 'keyboard-signale +#18, BEL_MOUSEC,BEL_MOUSED 'maus-signale +#20, BEL_VIDBASE 'video-signale(3pin) +#23, BEL_SELECT 'belatrix-auswahlsignal +#24, HBEAT 'front-led + BUSCLK 'bustakt + BUS_WR '/wr - schreibsignal + BUS_HS ' '/hs - quittungssignal + +COLS = 64 +ROWS = 48 +TILES = cols * rows + +TAB1 = 16 +TAB2 = 32 +TAB3 = 48 +SPACETILE = $8000 + $20 << 6 + +VGA_BASPORT = 8 'vga startport +VGA_RESX = COLS * 16 'vga anzahl pixel x +VGA_RESY = ROWS * 16 'vga anzahl pixel y +KEYB_DPORT = BEL_KEYBD 'tastatur datenport +KEYB_CPORT = BEL_KEYBC 'tastatur taktport +MOUSE_DPORT = BEL_MOUSED +MOUSE_CPORT = BEL_MOUSEC +CURSORCHAR = $0E 'cursorzeichen + +DB_WAIT = %00000001_00000000_00000000_00000000 'dira-wert f?r wait-status am bus +DB_IN = %00001001_00000000_00000000_00000000 'dira-wert f?r datenbuseingabe +DB_OUT = %00001001_00000000_00000000_11111111 'dira-wert f?r datenbusausgabe +CNT_HBEAT = 5_000_0000 'blinkgeschw. front-led + + +VAR + + 'variables for display + long col, row, color, flag + long array[tiles/2] + long stackhb[9] 'stack f?r hbeat-cog + byte cursor 'cursorzeichen + byte curstat 'cursorstatus 1 = ein + byte sline 'startzeile des scrollfensters + byte eline 'endzeile des scrollfensters + + 'for custom characters + word user_charbase + + 'for drawing buttons + word ptr + byte boxcolor + byte sBuffer[32] 'stingpuffer + + +OBJ + + vga : "stvga" + keyb : "stkeyb" + + +PUB main | zeichen +{{interpreter f?r hostdialog}} + + init_subsysteme 'bus/vga/keyboard/maus initialisieren + repeat + zeichen := bus_getchar '1. zeichen empfangen + if zeichen > 0 + print_char(zeichen) + else + zeichen := bus_getchar '2. zeichen kommando empfange + case zeichen + 1: bus_putchar(keyb.gotkey) '1: Tastaturstatus senden + 2: bus_putchar(keyb.key) '2: Tastaturzeichen senden + 3: zeichen := bus_getchar '3: Sonderzeichen von $100 bis $1FF ausgeben + print_char(zeichen + $100) + + 10: cmd_bitmap1 + 11: cmd_fillbox + 12: cmd_drawtxt + 99: reboot '99: bellatrix neu starten + 100: gfx1 + +PUB gfx1 + +PUB cmd_bitmap1 | nBitmap,pBitmap,xPos,yPos,xSize,ySize,clr +'Bitmap1Bit(@endcap_med_left,1,1,1,2,1) +'Bitmap1Bit(pBitmap, xPos, yPos, xSize, ySize, clr) + nBitmap := bus_getchar + xPos := bus_getchar + yPos := bus_getchar + xSize := bus_getchar + ySize := bus_getchar + clr := bus_getchar + case nBitmap + 0: pBitmap := @title + 1: pBitmap := @footer + 2: pBitmap := @button1 + 3: pBitmap := @button2 + 4: pBitmap := @button3 + 5: pBitmap := @button4 + 6: pBitmap := @button5 + 7: pBitmap := @button6 + 8: pBitmap := @button7 + 9: pBitmap := @button8 + 10: pBitmap := @button9 + 11: pBitmap := @corner_topleft + 12: pBitmap := @corner_topright + 13: pBitmap := @corner_bottomLeft + 14: pBitmap := @endcap_med_left + 15: pBitmap := @endcap_med_right + 16: pBitmap := @endcap_small_left + 17: pBitmap := @endcap_small_right + Bitmap1Bit(pBitmap, xPos, yPos, xSize, ySize, clr) + + +PUB cmd_fillbox | left,top,width,height,clr,bBottomBreak,bRightBreak,bTrimRight +'FillBlock(3,1,35,2,3,false,false,false) +'FillBlock(left,top,width,height,clr,bBottomBreak,bRightBreak,bTrimRight) + left := bus_getchar + top := bus_getchar + width := bus_getchar + height := bus_getchar + clr := bus_getchar + bBottomBreak := bus_getchar + bRightBreak := bus_getchar + bTrimRight := bus_getchar + FillBlock(left,top,width,height,clr,bBottomBreak,bRightBreak,bTrimRight) + +PUB cmd_drawtxt | nButton,pButton,nLen,c,i +'DrawText(@button,@string,bInvert) + nButton := bus_getchar + nLen := bus_getchar + repeat i from 0 to nLen - 1 + c := bus_getchar + sBuffer[i] := c + sBuffer[i+1] := 0 + case nButton + 0: pButton := @title + 1: pButton := @footer + 2: pButton := @button1 + 3: pButton := @button2 + 4: pButton := @button3 + 5: pButton := @button4 + 6: pButton := @button5 + 7: pButton := @button6 + 8: pButton := @button7 + 9: pButton := @button8 + 10: pButton := @button9 + DrawText(pButton, @sBuffer,false) + +PUB init_subsysteme +{{initialisierung des belatrix-chips}} + cognew(led_hbeat, @stackhb) 'heartbeat aktivieren + bus_init 'bussignale initialisieren + + '64 byte align the user characters + user_charbase := @uchar & $FFC0 'destination + 'user_charbase_offset := user_charbase-@uchar + longmove(user_charbase,@uchar,16*nuchars) + + keyb.start(keyb_dport, keyb_cport) 'tastaturport starten + vga.start(vga_basport, @array, @vgacolors, 0,0,0) 'vga-treiber starten + + print_char($100) 'bildschirm l?schen + cursor := CURSORCHAR 'cursorzeichen setzen + curstat := 1 'cursor anschalten + sline := 2 + eline := rows + +PUB bus_init +{{initialisierung des bussystems}} + dira := db_in 'datenbus auf eingabe schalten + outa[bus_hs] := 1 'handshake inaktiv + +PUB bus_putchar(zeichen) +{{ein byte ?ber bus ausgeben}} + waitpeq(%00000010_00000000_00000000_00000000,%00000010_10000000_00000000_00000000,0) 'busclk=1? & prop2=0? + dira := db_out 'datenbus auf ausgabe stellen + outa[7..0] := zeichen 'daten ausgeben + outa[bus_hs] := 0 'daten g?ltig + waitpeq(%00000000_00000000_00000000_00000000,%00000010_00000000_00000000_00000000,0) 'busclk=0? + 'waitcnt(1_000 + cnt) 'zeit f?r master + outa[bus_hs] := 1 'daten ung?ltig + dira := db_in 'bus freigeben + +PUB bus_getchar : zeichen +{{ein byte ?ber bus empfangen}} + waitpeq(%00000010_00000000_00000000_00000000,%00000010_10000000_00000000_00000000,0) 'busclk=1? & prop2=0? + zeichen := ina[7..0] 'daten einlesen + outa[bus_hs] := 0 'daten quittieren + outa[bus_hs] := 1 + waitpeq(%00000000_00000000_00000000_00000000,%00000010_00000000_00000000_00000000,0) 'busclk=0? + +PUB led_hbeat +{{led_hbeat - herzschlag f?r front-led}} + dira := db_in + repeat + !outa[hbeat] + waitcnt(cnt_hbeat + cnt) + +PUB print_str(strptr) +{{zeichenkette auf bildschirm ausgeben}} + repeat while byte[strptr] + print_char(byte[strptr++]) + + +PUB print_char(c) | code,n +{{zeichen auf bildschirm ausgeben}} +'' Print a character +'' +'' $0D = new line +'' $20..$FF = character +'' $100 = clear screen +'' $101 = home +'' $108 = backspace +''$110..$11F = select color + + case c + + $00..$0C: + pchar(c) + if curstat == 1 + schar(cursor) + + $0D: 'return? + if curstat == 1 + schar($20) + newline + if curstat == 1 + schar(cursor) + + $0E..$FF: 'character? + pchar(c) + if curstat == 1 + schar(cursor) + + $100: 'clear screen? + if curstat == 1 + schar($20) + n := sline * cols * 2 + wordfill(@array + n, spacetile, tiles - n) + row := sline + col := 0 + if curstat == 1 + schar(cursor) + + $101: 'home? + row := sline + col := 0 + + $102: 'backspace? + if col + if curstat == 1 + schar($20) + col-- + if curstat == 1 + schar(cursor) + + $103: 'tab + if col < TAB1 + if curstat == 1 + schar($20) + col := TAB1 + if curstat == 1 + schar(cursor) + return + if col < TAB2 + if curstat == 1 + schar($20) + col := TAB2 + if curstat == 1 + schar(cursor) + return + if col < TAB3 + if curstat == 1 + schar($20) + col := TAB3 + if curstat == 1 + schar(cursor) + return + $104: 'setcur + code := bus_getchar + cursor := code + if curstat == 1 + schar(code) + + $105: 'pos1 + if curstat == 1 + schar($20) + col := 0 + if curstat == 1 + schar(cursor) + + $106: 'setx + if curstat == 1 + schar($20) + col := bus_getchar + if curstat == 1 + schar(cursor) + + $107: 'sety + if curstat == 1 + schar($20) + row := bus_getchar * 2 + sline '2 tiles pro zeichen! + if curstat == 1 + schar(cursor) + + $108: 'getx + bus_putchar(col) + + $109: 'gety + bus_putchar(row / 2) + + $110: 'setcolor + color := bus_getchar + + $111: 'sline + sline := bus_getchar * 2 + + $112: 'eline + eline := bus_getchar * 2 + + $113: 'screeninit + wordfill(@array, spacetile, tiles) + row := 0 + col := 0 + sline := 0 + + $114: 'curon + curstat := 1 + schar(cursor) + + $115: 'curoff + if curstat == 1 + schar($20) + curstat := 0 + + $116: 'scrollup + scrollup + + $130..$13F: 'select color? + color := c & $F + +PRI schar(c)| i,k +'schreibt zeichen an aktuelle position ohne cursorposition zu ver?ndern + k := color << 1 + c & 1 + i := $8000 + (c & $FE) << 6 + k + array.word[row * cols + col] := i 'oberes tile setzen + array.word[(row + 1) * cols + col] := i | $40 'unteres tile setzen + +PRI pchar(c) +'schreibt zeichen an aktuelle position z?hlt position weiter + schar(c) + if ++col == cols + newline + +PUB newline | i + + col := 0 + if (row += 2) == rows + row -= 2 + 'scroll lines + repeat i from sline to rows-3 + + wordmove(@array.word[i*cols], @array.word[(i+2)*cols], cols) 'wordmove(dest,src,cnt) + 'clear new line + wordfill(@array.word[(rows-2)*cols], spacetile, cols<<1) + +PUB scrollup | i 'scrollt den screen nach oben + 'scroll lines + repeat i from sline to rows-3 + wordmove(@array.word[i*cols], @array.word[(i+2)*cols], cols) 'wordmove(dest,src,cnt) + 'clear new line + wordfill(@array.word[(rows-2)*cols], spacetile, cols<<1) + +PRI DrawText(pBmp,str,bInvert)|x1,x2,i,j,b,k,c,s +'draw prop font into bitmap + k:=0 'current column + repeat s from 0 to strsize(str)-1 + c:=byte[str][s] + if (c=>32) and (c=<(95+2)) 'note: char 96=dot, 97=degree + x1:=word[@FontTable][c-32] + x2:=word[@FontTable][c-32+1] + repeat i from x1 to x2-1 + DrawFontColumn(i,j,pBmp,k,b) + 'repeat j from 0 to 31 + ' b:=getFontPixel(i,j) + ' setFontPixel(pBmp,k,j,b) + k++ + +PRI DrawFontColumn(x,y,pdest,k,b)|dtile,stile,doffset,soffset,psrc,d,pixel,j + stile:=x/16 + soffset:=(x//16)*2 + psrc:=@font+4*16*stile+user_charbase-@uchar + dtile:=k/16 + doffset:=(k//16)*2 + pdest+=4*16*dtile+user_charbase-@uchar + repeat j from 0 to 31 + y:=j + if y=>16 + y-=16 + if j==16 + soffset++ + doffset++ + pixel:=long[psrc][y//16] + pixel>>=soffset + pixel&=$1 + 'draw + if pixel + long[pdest][y//16]|=|16 + offset++ + y-=16 + p:=@font+4*16*tile + d:=long[p+user_charbase-@uchar][y//16] + d>>=offset + return (d&$1)>0 + +PRI setFontPixel(p,x,y,b)|tile,offset,d +'set (b=true) or clear (b=false) pixel in bmp @p at coordinates (x,y) + tile:=x/16 + offset:=(x//16)*2 + if y=>16 + offset++ + y-=16 + p+=4*16*tile+user_charbase-@uchar + 'd:=long[p][y//16] + if b + long[p][y//16]|=|>6 + c & $FE + +PRI uPrintBottom(c,ncol,nrow)|i,k + 'print bottom part of a character + k := color << 1 + c & 1 + i := user_charbase + (c & $FE) << 6 + k + array.word[nrow * cols + ncol] := i+$40'user_charbase + (c<<6) + color+$40'(color << 1 + c & 1) << 10 + user_charbase>>6 + c & $FE +1 + +PRI Bitmap2Bit(pBitmap, xPos, yPos, xSize, ySize, clr)|c,i,j,BmpAddress + row:=yPos + col:=xPos + c:=0 + BmpAddress:=pBitmap+user_charbase-@uchar + repeat j from 0 to (ySize-1) + repeat i from 0 to (xSize-1) + array.word[row * cols + col] := BmpAddress + (c<<6) + clr + 'Print2Bit(c,clr,pBitmap) + c++ + col++ + row++ + col:=xPos + + +PRI Bitmap1Bit(pBitmap, xPos, yPos, xSize, ySize, clr)|c,i,j,BmpAddress + row:=yPos + col:=xPos + c:=0 + BmpAddress:=pBitmap+user_charbase-@uchar + repeat j from 0 to (ySize-1) step 2 + repeat i from 0 to (xSize-1) + array.word[row * cols + col] := (clr<<1+1) + BmpAddress +c<<6 + if ySize<>1 + array.word[(row+1) * cols + col] := (clr<<1) + BmpAddress +c<<6 + c++ + col++ + row+=2 + col:=xPos + + +PRI Bitmap1BitTile(pBitmap,x,y,clr,bLower)|BmpAddress +'print just the upper or lower tile of a 2-tile bitmap + BmpAddress:=pBitmap+user_charbase-@uchar + clr:=clr<<1+1 + if bLower + clr-=1 + + array.word[y * cols + x] := clr + BmpAddress + + +DAT + vgacolors long + +'0..1: text color 0: + long $90009000 'orange on black + long $90900000 +'2..3: text color 1: + long $5c005c00 'blue on black + long $5c5c0000 +'4..5: text color 2: + long $94009400 'light red on black + long $94940000 +'6..7: text color 3: + long $98009800 'purple on black + long $98980000 +'8..9: text color 4: + long $f800f800 'yellow on black + long $f8f80000 +'10..11: text color 5: + long $84008400 'dark red on black + long $84840000 + + +'12: graphics 2: 'card edge colors + long $100000FC ''green,black,black,white +'13: graphics 3: 'red face card colors + long $F0C000FC ' yellow,red,black,white +'14: graphics 4: 'black face card colors + long $F000C0FC ''yellow,black,red,white +'15: graphics 5: button colors + long $FC54A8A8 'lt grey, dk.gray, gray, gray + + +FontTable word + word 8, 16,21,32,60,72,92,107,114,121,129,138,150,156,164,170,184,195,203,214,225,239,250,261,273,284,295,300,306,316,333,343,354,378,392 'to B + word 403,414,425,435,445,456,467,472,483,496,506,523,537,548,559,570,582,593,605,616,630,649,663,676,686,695,706,720,733,743,751 'note last two chars are dot and degree + +padding LONG 7[16] 'alignment padding for the following user defined characters + +uchar long + +corner_topleft long + file "corner_topleft.dat" '6x2 + +corner_topright long + file "corner_topright.dat" '6x2 + +corner_bottomLeft long + file "corner_bottomLeft.dat" '6x2 + +hv_break long + file "hv_break.dat" '1x2 + +hv_break2 long + file "hv_break2.dat" '1x2 + +endcap_med_left long + file "endcap_med_left.dat" '1x2 + +endcap_med_right long + file "endcap_med_right.dat" '1x2 + +endcap_small_left long + file "endcap_small_left.dat" '1x2 + +endcap_small_right long + file "endcap_small_right.dat" '1x2 + +filled_space long + file "filled_space.dat" '1x2 + +font long + file "font_29p5.dat" '47x2 + +title long 0[16*23] 'space for title 23x2 +footer long 0[16*23] 'space for footer 23x2 + +button1 long 0[16*20] 'space for button text 10x2 +button2 long 0[16*20] 'space for button text +button3 long 0[16*20] 'space for button text +button4 long 0[16*20] 'space for button text +button5 long 0[16*20] 'space for button text +button6 long 0[16*20] 'space for button text 10x2 +button7 long 0[16*20] 'space for button text +button8 long 0[16*20] 'space for button text +button9 long 0[16*20] 'space for button text \ No newline at end of file diff --git a/zubehör/startracker/source/bellatrix-code/stkeyb.spin b/zubehör/startracker/source/bellatrix-code/stkeyb.spin new file mode 100644 index 0000000..dad7275 Binary files /dev/null and b/zubehör/startracker/source/bellatrix-code/stkeyb.spin differ diff --git a/zubehör/startracker/source/bellatrix-code/stmouse.spin b/zubehör/startracker/source/bellatrix-code/stmouse.spin new file mode 100644 index 0000000..a5518dc --- /dev/null +++ b/zubehör/startracker/source/bellatrix-code/stmouse.spin @@ -0,0 +1,470 @@ +''***************************** +''* PS/2 Mouse Driver v1.1 * +''* (C) 2006 Parallax, Inc. * +''***************************** + +' v1.0 - 01 May 2006 - original version +' v1.1 - 01 Jun 2006 - bound coordinates added to simplify upper objects + + +VAR + + long cog + + long oldx, oldy, oldz 'must be followed by parameters (10 contiguous longs) + + long par_x 'absolute x read-only (7 contiguous longs) + long par_y 'absolute y read-only + long par_z 'absolute z read-only + long par_buttons 'button states read-only + long par_present 'mouse present read-only + long par_dpin 'data pin write-only + long par_cpin 'clock pin write-only + + long bx_min, by_min, bz_min 'min/max must be contiguous + long bx_max, by_max, bz_max + long bx_div, by_div, bz_div + long bx_acc, by_acc, bz_acc + + +PUB start(dpin, cpin) : okay + +'' Start mouse driver - starts a cog +'' returns false if no cog available +'' +'' dpin = data signal on PS/2 jack +'' cpin = clock signal on PS/2 jack +'' +'' use 100-ohm resistors between pins and jack +'' use 10K-ohm resistors to pull jack-side signals to VDD +'' connect jack-power to 5V, jack-gnd to VSS + + stop + par_dpin := dpin + par_cpin := cpin + okay := cog := cognew(@entry, @par_x) + 1 + + +PUB stop + +'' Stop mouse driver - frees a cog + + if cog + cogstop(cog~ - 1) + longfill(@oldx, 0, 10) + + +PUB present : type + +'' Check if mouse present - valid ~2s after start +'' returns mouse type: +'' +'' 3 = five-button scrollwheel mouse +'' 2 = three-button scrollwheel mouse +'' 1 = two-button or three-button mouse +'' 0 = no mouse connected + + type := par_present + + +PUB button(b) : state + +'' Get the state of a particular button +'' returns t|f + + state := -(par_buttons >> b & 1) + + +PUB buttons : states + +'' Get the states of all buttons +'' returns buttons: +'' +'' bit4 = right-side button +'' bit3 = left-side button +'' bit2 = center/scrollwheel button +'' bit1 = right button +'' bit0 = left button + + states := par_buttons + + +PUB abs_x : x + +'' Get absolute-x + + x := par_x + + +PUB abs_y : y + +'' Get absolute-y + + y := par_y + + +PUB abs_z : z + +'' Get absolute-z (scrollwheel) + + z := par_z + + +PUB delta_reset + +'' Reset deltas + + oldx := par_x + oldy := par_y + oldz := par_z + + +PUB delta_x : x | newx + +'' Get delta-x + + newx := par_x + x := newx - oldx + oldx := newx + + +PUB delta_y : y | newy + +'' Get delta-y + + newy := par_y + y := newy - oldy + oldy := newy + + +PUB delta_z : z | newz + +'' Get delta-z (scrollwheel) + + newz := par_z + z := newz - oldz + oldz := newz + + +PUB bound_limits(xmin, ymin, zmin, xmax, ymax, zmax) | i + +'' Set bounding limits + + longmove(@bx_min, @xmin, 6) + + +PUB bound_scales(x_scale, y_scale, z_scale) + +'' Set bounding scales (usually +/-1's, bigger values divide) + + longmove(@bx_div, @x_scale, 3) + + +PUB bound_preset(x, y, z) | i, d + +'' Preset bound coordinates + + repeat i from 0 to 2 + d := ||bx_div[i] + bx_acc[i] := (x[i] - bx_min[i]) * d + d >> 1 + + +PUB bound_x : x + +'' Get bound-x + + x := bound(0, delta_x) + + +PUB bound_y : y + +'' Get bound-y + + y := bound(1, delta_y) + + +PUB bound_z : z + +'' Get bound-z + + z := bound(2, delta_z) + + +PRI bound(i, delta) : b | d + + d := bx_div[i] + b := bx_min[i] + (bx_acc[i] := bx_acc[i] + delta * (d < 0) | 1 #> 0 <# (bx_max[i] - bx_min[i] + 1) * ||d - 1) / ||d + + +DAT + +'*************************************** +'* Assembly language PS/2 mouse driver * +'*************************************** + + org +' +' +' Entry +' +entry mov p,par 'load input parameters: + add p,#5*4 '_dpin/_cpin + rdlong _dpin,p + add p,#4 + rdlong _cpin,p + + mov dmask,#1 'set pin masks + shl dmask,_dpin + mov cmask,#1 + shl cmask,_cpin + + test _dpin,#$20 wc 'modify port registers within code + muxc _d1,dlsb + muxc _d2,dlsb + muxc _d3,#1 + muxc _d4,#1 + test _cpin,#$20 wc + muxc _c1,dlsb + muxc _c2,dlsb + muxc _c3,#1 + + movd :par,#_x 'reset output parameters: + mov p,#5 '_x/_y/_z/_buttons/_present +:par mov 0,#0 + add :par,dlsb + djnz p,#:par +' +' +' Reset mouse +' +reset mov dira,#0 'reset directions + mov dirb,#0 + + mov stat,#1 'set reset flag +' +' +' Update parameters +' +update movd :par,#_x 'update output parameters: + mov p,par '_x/_y/_z/_buttons/_present + mov q,#5 +:par wrlong 0,p + add :par,dlsb + add p,#4 + djnz q,#:par + + test stat,#1 wc 'if reset flag, transmit reset command + if_c mov data,#$FF + if_c call #transmit +' +' +' Get data packet +' + mov stat,#0 'reset state + + call #receive 'receive first byte + + cmp data,#$AA wz 'powerup/reset? + if_z jmp #init + + mov _buttons,data 'data packet, save buttons + + call #receive 'receive second byte + + test _buttons,#$10 wc 'adjust _x + muxc data,signext + add _x,data + + call #receive 'receive third byte + + test _buttons,#$20 wc 'adjust _y + muxc data,signext + add _y,data + + and _buttons,#%111 'trim buttons + + cmp _present,#2 wc 'if not scrollwheel mouse, update parameters + if_c jmp #update + + + call #receive 'scrollwheel mouse, receive fourth byte + + cmp _present,#3 wz 'if 5-button mouse, handle two extra buttons + if_z test data,#$10 wc + if_z_and_c or _buttons,#%01000 + if_z test data,#$20 wc + if_z_and_c or _buttons,#%10000 + + shl data,#28 'adjust _z + sar data,#28 + sub _z,data + + jmp #update 'update parameters +' +' +' Initialize mouse +' +init call #receive '$AA received, receive id + + movs crate,#100 'try to enable 3-button scrollwheel type + call #checktype + movs crate,#200 'try to enable 5-button scrollwheel type + call #checktype + shr data,#1 'if neither, 3-button type + add data,#1 + mov _present,data + + movs srate,#200 'set 200 samples per second + call #setrate + + mov data,#$F4 'enable data reporting + call #transmit + + jmp #update +' +' +' Check mouse type +' +checktype movs srate,#200 'perform "knock" sequence to enable + call #setrate '..scrollwheel and extra buttons + +crate movs srate,#200/100 + call #setrate + + movs srate,#80 + call #setrate + + mov data,#$F2 'read type + call #transmit + call #receive + +checktype_ret ret +' +' +' Set sample rate +' +setrate mov data,#$F3 + call #transmit +srate mov data,#0 + call #transmit + +setrate_ret ret +' +' +' Transmit byte to mouse +' +transmit +_c1 or dira,cmask 'pull clock low + movs napshr,#13 'hold clock for ~128us (must be >100us) + call #nap +_d1 or dira,dmask 'pull data low + movs napshr,#18 'hold data for ~4us + call #nap +_c2 xor dira,cmask 'release clock + + test data,#$0FF wc 'append parity and stop bits to byte + muxnc data,#$100 + or data,dlsb + + mov p,#10 'ready 10 bits +transmit_bit call #wait_c0 'wait until clock low + shr data,#1 wc 'output data bit +_d2 muxnc dira,dmask + mov wcond,c1 'wait until clock high + call #wait + djnz p,#transmit_bit 'another bit? + + mov wcond,c0d0 'wait until clock and data low + call #wait + mov wcond,c1d1 'wait until clock and data high + call #wait + + call #receive_ack 'receive ack byte with timed wait + cmp data,#$FA wz 'if ack error, reset mouse + if_nz jmp #reset + +transmit_ret ret +' +' +' Receive byte from mouse +' +receive test _cpin,#$20 wc 'wait indefinitely for initial clock low + waitpne cmask,cmask +receive_ack + mov p,#11 'ready 11 bits +receive_bit call #wait_c0 'wait until clock low + movs napshr,#16 'pause ~16us + call #nap +_d3 test dmask,ina wc 'input data bit + rcr data,#1 + mov wcond,c1 'wait until clock high + call #wait + djnz p,#receive_bit 'another bit? + + shr data,#22 'align byte + test data,#$1FF wc 'if parity error, reset mouse + if_nc jmp #reset + and data,#$FF 'isolate byte + +receive_ack_ret +receive_ret ret +' +' +' Wait for clock/data to be in required state(s) +' +wait_c0 mov wcond,c0 '(wait until clock low) + +wait mov q,tenms 'set timeout to 10ms + +wloop movs napshr,#18 'nap ~4us + call #nap +_c3 test cmask,ina wc 'check required state(s) +_d4 test dmask,ina wz 'loop until got state(s) or timeout +wcond if_never djnz q,#wloop '(replaced with c0/c1/c0d0/c1d1) + + tjz q,#reset 'if timeout, reset mouse +wait_ret +wait_c0_ret ret + + +c0 if_c djnz q,#wloop '(if_never replacements) +c1 if_nc djnz q,#wloop +c0d0 if_c_or_nz djnz q,#wloop +c1d1 if_nc_or_z djnz q,#wloop +' +' +' Nap +' +nap rdlong t,#0 'get clkfreq +napshr shr t,#18/16/13 'shr scales time + min t,#3 'ensure waitcnt won't snag + add t,cnt 'add cnt to time + waitcnt t,#0 'wait until time elapses (nap) + +nap_ret ret +' +' +' Initialized data +' +dlsb long 1 << 9 +tenms long 10_000 / 4 +signext long $FFFFFF00 +' +' +' Uninitialized data +' +dmask res 1 +cmask res 1 +stat res 1 +data res 1 +p res 1 +q res 1 +t res 1 + +_x res 1 'write-only +_y res 1 'write-only +_z res 1 'write-only +_buttons res 1 'write-only +_present res 1 'write-only +_dpin res 1 'read-only +_cpin res 1 'read-only \ No newline at end of file diff --git a/zubehör/startracker/source/bellatrix-code/stvga.spin b/zubehör/startracker/source/bellatrix-code/stvga.spin new file mode 100644 index 0000000..9acf513 Binary files /dev/null and b/zubehör/startracker/source/bellatrix-code/stvga.spin differ diff --git a/zubehör/startracker/source/regnatix-code/readme.rtf b/zubehör/startracker/source/regnatix-code/readme.rtf new file mode 100644 index 0000000..c32f7e0 Binary files /dev/null and b/zubehör/startracker/source/regnatix-code/readme.rtf differ diff --git a/zubehör/startracker/source/regnatix-code/stplay.spin b/zubehör/startracker/source/regnatix-code/stplay.spin new file mode 100644 index 0000000..9f6d040 Binary files /dev/null and b/zubehör/startracker/source/regnatix-code/stplay.spin differ diff --git a/zubehör/vecdem/vecdem1-bel.spin b/zubehör/vecdem/vecdem1-bel.spin new file mode 100644 index 0000000..1cf2601 Binary files /dev/null and b/zubehör/vecdem/vecdem1-bel.spin differ diff --git a/zubehör/vecdem/vectron-1-asm.spin b/zubehör/vecdem/vectron-1-asm.spin new file mode 100644 index 0000000..b21d780 Binary files /dev/null and b/zubehör/vecdem/vectron-1-asm.spin differ diff --git a/zubehör/vecdem/vectron-1-drv.spin b/zubehör/vecdem/vectron-1-drv.spin new file mode 100644 index 0000000..f9d067d --- /dev/null +++ b/zubehör/vecdem/vectron-1-drv.spin @@ -0,0 +1,250 @@ +''******************************************** +''* VGA 512x384 2-Color Bitmap Driver v1.0 * +''* (C) 2006 Parallax, Inc. * +''******************************************** +'' +'' This object generates a 512x384 pixel bitmap, signaled as 1024x768 VGA. +'' Each pixel is one bit, so the entire bitmap requires 512 x 384 / 32 longs, +'' or 6,144 longs (24KB). Color words comprised of two byte fields provide +'' unique colors for every 32x32 pixel group. These color words require 512/32 +'' * 384/32 words, or 192 words. Pixel memory and color memory are arranged +'' left-to-right then top-to-bottom. +'' +'' A sync indicator signals each time the screen is drawn (you may ignore). +'' +'' You must provide buffers for the colors, pixels, and sync. Once started, +'' all interfacing is done via memory. To this object, all buffers are read- +'' only, with the exception of the sync indicator which gets written with a +'' non-0 value. You may freely write all buffers to affect screen appearance. +'' + +{{ +notizen: + + + +}} +CON + +' 512x384 settings - signals as 1024 x 768 @ 67Hz + + hp = 512 'horizontal pixels + vp = 384 'vertical pixels + hf = 8 'horizontal front porch pixels + hs = 48 'horizontal sync pixels + hb = 88 'horizontal back porch pixels + vf = 1 'vertical front porch lines + vs = 3 'vertical sync lines + vb = 28 'vertical back porch lines + +' änderung wegen synchronisationsproblemen bei board r13 +' hn = 1 'horizontal normal sync state (0|1) +' vn = 1 'vertical normal sync state (0|1) + hn = 0 'horizontal normal sync state (0|1) + vn = 0 'vertical normal sync state (0|1) + + pr = 35 'pixel rate in MHz at 80MHz system clock (5MHz granularity) + +' Tiles + + xtiles = hp / 32 'xtiles 16 + ytiles = vp / 32 'ytiles 12 + +' H/V inactive states + + hv_inactive = (hn << 1 + vn) * $0101 + + +VAR long cog + +PUB start(BasePin, ColorPtr, PixelPtr, SyncPtr) : okay | i, j + +'' Start VGA driver - starts a COG +'' returns false if no COG available +'' +'' BasePin = VGA starting pin (0, 8, 16, 24, etc.) +'' +'' ColorPtr = Pointer to 192 words which define the "0" and "1" colors for +'' each 32x32 pixel group. The lower byte of each word contains +'' the "0" bit RGB data while the upper byte of each word contains +'' the "1" bit RGB data for the associated group. The RGB +'' data in each byte is arranged as %RRGGBB00 (4 levels each). +'' +'' color word example: %%0020_3300 = "0" = gold, "1" = blue +'' +'' PixelPtr = Pointer to 6,144 longs containing pixels that make up the 512 x +'' 384 pixel bitmap. Longs' LSBs appear left on the screen, while +'' MSBs appear right. The longs are arranged in sequence from left- +'' to-right, then top-to-bottom. +'' +'' SyncPtr = Pointer to long which gets written with non-0 upon each screen +'' refresh. May be used to time writes/scrolls, so that chopiness +'' can be avoided. You must clear it each time if you want to see +'' it re-trigger. + + 'if driver is already running, stop it + stop + + 'implant pin settings and pointers, then launch COG + ' %1111_1111_1111_1111_1111_1111_1111_1111 + ' 2 0 0 0 0 0 F F + ' 0010_0000_0000_0000_0000_0000_1111_1111 + ' || ||| VGroup + ' || |||| |||| VPins Video an allen 8 Pins - VGA + ' || --> 01 VMode VGA-Mode + ' | --> 0 CMode 2-Farbmodus + reg_vcfg := $200000FF + (BasePin & %111000) << 6 'schreibt VGroup in das Konfigurationsregister + i := $FF << (BasePin & %011000) 'acht Bits in der Maske bis zur BasePin-Position verschieben + j := BasePin & %100000 == 0 + reg_dira := i & j + reg_dirb := i & !j + + clrflag := 1 '1 - bildschirm wird bei jedem durchlauf gelöscht + clrline := 2 'tilezeile ab der gelöscht wird + + longmove(@color_base, @ColorPtr, 2) 'kopiert 2 parameter von color_ptr in den asm-bereich color_base + 'color_ptr --> color_base + 'pixel_pointer --> pixel_base + if (cog := cognew(@init, SyncPtr) + 1) + return true + + +PUB stop | i + +'' Stop VGA driver - frees a COG + + if cog + cogstop(cog~ - 1) + + +DAT + +'*********************************************** +'* Assembly language VGA 2-color bitmap driver * +'*********************************************** + + org 'set origin to $000 for start of program + +' Initialization code - init I/O + +init mov dira,reg_dira 'i/o-register konfigurieren + mov dirb,reg_dirb + + movi ctra,#%00001_101 'enable PLL in ctra (VCO runs at 4x) + '25..23 PLLDIV = 101 --> VCO / 4 + '31..26 CTRMODE = 00001 --> PLL intern (Video Mode) + movi frqa,#(pr / 5) << 3 'set pixel rate + ' (35 MHz / 5) << 3 = 56 = 111000 + + mov vcfg,reg_vcfg 'set video configuration + +' Main loop, display field and do invisible sync lines + +field mov color_ptr,color_base 'reset color pointer 'color-pointer auf anfangswert setzen + mov pixel_ptr,pixel_base 'reset pixel pointer 'pixel-pointer auf anfangswert setzen + mov y,#ytiles 'set y tiles +:ytile mov yl,#32 'set y lines per tile +:yline mov yx,#2 'set y expansion +:yexpand mov x,#xtiles 'set x tiles + mov vscl,vscl_pixel 'set pixel vscl + +:xtile rdword color,color_ptr 'get color word 'color <-- (color_ptr) + and color,colormask 'clear h/v bits + or color,hv 'set h/v inactive states + rdlong pixel,pixel_ptr 'get pixel long 'pixel <-- (pixel_ptr) + + '----------------------------------------------------- + +' cmpsub clrline,y wc 'clrline - y +' if_c jmp #:noclr + + and clrflag,clrflag wz 'clrflag = 1 '1 --> pixelspeicher bei jedem durchlauf löschen + if_nz wrlong reg_a,pixel_ptr 'pixelspeicher löschen 'reg_a --> (pixel_ptr) + + '----------------------------------------------------- + +:noclr waitvid color,pixel 'farb- und pixelwerte (32bit) ausgeben + add color_ptr,#2 'point to next color word 'farbe nur zwei byte, also ein word + add pixel_ptr,#4 'point to next pixel long 'pixel vier byte, also ein long + djnz x,#:xtile 'another x tile? 'schleife x * 32bit-pixelwerte + + sub color_ptr,#xtiles * 2 'farbzeiger auf zeilenanfang rücksetzen + sub pixel_ptr,#xtiles * 4 'pixelzeiger auf zeilenanfang rücksetzen + + mov x,#1 'zeilensynchronimpuls + call #hsync + + '----------------------------------------------------- VIDEOZEILEN + + djnz yx,#:yexpand 'y expand? + + '----------------------------------------------------- PIXELZEILEN + + add pixel_ptr,#xtiles * 4 'pixelzeiger auf nächsten zeilenanfang setzen + djnz yl,#:yline 'another y line in same tile? 'schleife y-tilezeilen + + '----------------------------------------------------- TILEZEILEN + + add color_ptr,#xtiles * 2 'farbzeiger auf nächsten zeilenanfang setzen + djnz y,#:ytile 'another y tile? + + '----------------------------------------------------- BILDSCHIRM + + wrlong colormask,par 'ende sichtbarer bereich, sync für software erzeugen + + mov x,#vf 'leerzeilen (vf - vertical front) + call #blank + mov x,#vs 'bildsynchonisation (x zeilen) + call #vsync + mov x,#vb 'do vertical back porch lines + call #vsync + + jmp #field 'field done, loop + + +' Subroutine - do blank lines + +vsync xor hvsync,#$101 'flip vertical sync bits + +blank mov vscl,hvis 'do blank pixels + waitvid hvsync,#0 +hsync mov vscl,#hf 'do horizontal front porch pixels + waitvid hvsync,#0 + mov vscl,#hs 'do horizontal sync pixels + waitvid hvsync,#1 + mov vscl,#hb 'do horizontal back porch pixels + waitvid hvsync,#0 + djnz x,#blank 'another line? +hsync_ret +blank_ret +vsync_ret ret + + +' Data + +reg_dira long 0 'set at runtime +reg_dirb long 0 'set at runtime +reg_vcfg long 0 'set at runtime + +color_base long 0 'set at runtime (2 contiguous longs) +pixel_base long 0 'set at runtime + +vscl_pixel long 1 << 12 + 32 '1 pixel per clock and 32 pixels per set +colormask long $FCFC 'mask to isolate R,G,B bits from H,V +hvis long hp 'visible pixels per scan line +hv long hv_inactive '-H,-V states +hvsync long hv_inactive ^ $200 '+/-H,-V states +reg_a long 0 'temp. register +clrflag long 0 '1 - screen bei darstellung löschen +clrline long 0 'tilezeile ab der gelöscht wird + +' Uninitialized data + +color_ptr res 1 +pixel_ptr res 1 +color res 1 +pixel res 1 +x res 1 +y res 1 +yl res 1 +yx res 1 \ No newline at end of file diff --git a/zubehör/vecdem/vectron-1-keyb.spin b/zubehör/vecdem/vectron-1-keyb.spin new file mode 100644 index 0000000..dad7275 Binary files /dev/null and b/zubehör/vecdem/vectron-1-keyb.spin differ