{ "info": { "author": "Nathan Fraser", "author_email": "ndf@metarace.com.au", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Environment :: Console", "License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)", "Programming Language :: Python", "Topic :: Software Development :: Assemblers" ], "description": "# asfv1\n\nAlternate Assembler for Spin Semi FV-1\n\nCopyright (C) 2017-2019 Nathan Fraser\n\nAn alternate assembler for the Spin Semiconductor FV-1 DSP. This\nassembler aims to replicate some of the behaviour of the Spin FV-1\nassembler in standard Python, for developers who are unable or\nunwilling to use the Spin provided IDE.\n\n## Requirements\n\n- Python \\>= 2.6\n\n## Installation\n\nMake sure your system has a python interpreter\n(preferably python3), then install from the\n[Python Package Index](https://pypi.org/)\nusing the\n[pip](https://pip.pypa.io/en/stable/)\ncommand:\n\n\t$ pip3 install asfv1\n\nor\n\n\t$ pip install asfv1\n\nFor system-specific installation instructions see\n[System Specific Installation](#system-specific-installation)\nbelow.\n\n## Description\n\nasfv1 reads a single FV-1 DSP program then parses and assembles it.\nIf no errors are encountered, machine code is written to an output\nfile. If the output filename ends with 'hex', an Intel hex\nencoded output is produced, otherwise raw binary data is written.\n\n\tusage: asfv1 [-h] [-q] [-v] [-c] [-s] [-p {0,1,2,3,4,5,6,7}] [-b]\n \tinfile outfile\n\n - `infile` : Filename for an ASCII, utf-8 or utf-16 encoded text file\n containing FV-1 assembly (see [Assembly Program Syntax](#assembly-program-syntax) below)\n\n - `outfile` : Filename for assembled output. If filename ends with 'hex',\n an Intel hex file is written.\n\n - `-h`, `--help` : Show a help message and exit\n\n - `-q`, `--quiet` : Suppress warning messages \n\n - `-v`, `--version` : Print program version and exit\n\n - `-c`, `--clamp` : Clamp out of range instruction operand values without error.\n A warning message is printed for each clamped operand.\n\n - `-s`, `--spinreals` : Interpret integer literals `1` and `2` as 1.0 and 2.0\n respectively. This option should be used with SpinASM assembly.\n\n - `-p {0,1,2,3,4,5,6,7}` : Nominate one of the eight available program\n slots on an FV-1 eeprom as the target. When this option is used with\n binary output, machine code is offset appropriately in the target\n file, allowing for assembly into an existing binary bank file. When\n Intel HEX output is requested, the output file will include a single\n program and relevant offset information for the target program.\n\n - `-b`, `--binary` : Force output in binary format, even if `outfile`\n ends with 'hex'.\n\n## Assembly Program Syntax\n\nAn FV-1 assembly program recognised by asfv1 closely resembles\nthe [SpinIDE](http://spinsemi.com/products.html) (.spn) format.\nInput is an ASCII, utf-8 or utf-16 encoded\ntext file containing zero to 128 FV-1\n[instructions](#instructions) with optional\n[targets](#jump-targets), [labels](#label-assignment),\n[comments](#comments) and [assembly directives](#memory-allocation).\nAll text is matched case-insensitively and runs of whitespace characters\n(newline, tab, space) are condensed.\nEach of the input instructions is assembled into a single 32 bit\nmachine code. If less than 128 assembly instructions are input,\nthe unallocated program space is padded with 'NOP' instructions\n(0x00000011).\n\nFor [example](example.asm):\n\n\t; A complete, but useless FV-1 assembly program\n\tMEM\tdelay\tint(32767*3/5)\t; ~0.6 sec delay\n\tEQU\tinput\tADCL\t\t; use ADCL for input\n\tEQU\toutput\tDACL\t\t; use DACL for output\n\tEQU\tvol\tREG0\t\t; use REG0 for volume\n\tstart:\tskp\tRUN,main\t; skip to main after first sample\n\t\tldax\tPOT0\t\t; read from POT0\n\t\twrax\tvol,0.0\t\t; write volume to register\n\tmain:\tldax\tinput\t\t; read from input\n\t\tmulx\tvol\t\t; scale by volume\n\t\twra\tdelay,0.0\t; write to delay\n\t\trda\tdelay^,0.5\t; read from delay midpoint\n\t\trda\tdelay#,0.5\t; read from delay end\n\t\twrax\toutput,0.0\t; write to output\n\nWhen assembled with asfv1, the resulting machine code contains\n9 instructions and padding with NOP instructions:\n\n\t$ asfv1 -q example.asm example.bin\n\t$ hd example.bin \n\t00000000 80 40 00 11 00 00 02 05 00 00 04 06 00 00 02 85 |.@..............|\n\t00000010 00 00 04 0a 00 00 00 02 20 04 cc c0 20 09 99 80 |........ ... ...|\n\t00000020 00 00 02 c6 00 00 00 11 00 00 00 11 00 00 00 11 |................|\n\t00000030 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 |................|\n\t*\n\t00000200\n\n### Comments \n\nA semicolon character ';' starts comment text. The assembler will\nignore all text including the ';' up to the end of a line.\nExamples:\n\n\t; Comment out a whole line\n\ttarget:\tor\t0xffffff\t; comment to end of line\n\ttrget2:\t\t; comment between target and instruction\n\t\tand\t0x000000\t; comment follows instruction\n\t\t; xor 0xa5a5a5\t\t; instruction commented out\n\t; excessive commenting:\n\taddr02: cho\t\t\t; op=0x14 interpolated memory access\n\t\t\trdal,\t\t; type=0x3 read offset(LFO) into ACC\n\t\t\tSIN1,\t\t; lfo=0x1 use SIN1 LFO\n\t\t\tCOS|REG\t\t; flags=0xb register LFO and use COS output\n\n### Label Assignment\n\n\tEQU\tLABEL\tEXPRESSION\n\nDirective 'EQU' assigns the constant value resulting from the\nevaluation of 'EXPRESSION' (see\n[Operand Expressions](#operand-expressions)\nbelow) to the text label 'LABEL'.\nLABEL must begin with one alphabetic character in the set [A-Z,a-z]\nfollowed by any number of alphanumeric characters or underscores:\n[A-Z,a-z,0-9,_].\nEXPRESSION can contain any previously assigned labels, including\nthose pre-defined by the assembler (see\n[Pre-defined Labels](#pre-defined-labels) below). For\ncompatibility with SpinASM, the order of 'EQU' and 'LABEL'\nmay be swapped. Examples:\n\n\tEQU\tinput\tADCL\t\t; assign value of ADCL (0x14) to 'input'\n\tEQU\tr3_7\t3/7\t\t; assign the value 3/7 to 'r3_7'\n\tinve\tEQU\t1/r3_7\t\t; assign the inverse of 'r3_7' to 'inve'\n\nEQU does not generate any code in the program, it merely reserves\nthe name for subsequent use. The parser evaluates all expressions\nin-place so a label must be declared before it is used:\n\n\t\tor\tmissing\t\t; error\n\tEQU\tmissing\t123\t\t; missing is used before definition\n\n\tparse error: Undefined label missing on line ...\n\nRe-defining an already assigned label is allowed, but will generate \na warning message:\n\n\tEQU\tPOT0\tPOT1\t\t; point POT0 to POT1\n\n\twarning: Label POT0 re-defined on line ...\n\nLabels, mnemonics and operators are matched case insensitively:\n\n\tEQU\tLabel_One\t-1.0\t; assign 1.0 to 'LABEL_ONE'\n\teQu\tlABEL_oNE\t-1.0\t; assign 1.0 to 'LABEL_ONE' again\n\t\tOr\tlabel_one\t; or -1.0\n\t\toR\tLABEL_ONE\t; or -1.0\n\t\tOR\tLABEL_ONE\t; or -1.0\n\t\tor\tlAbEl_OnE\t; or -1.0\n\n### Memory Allocation\n\n\tMEM\tLABEL\tEXPRESSION\n\nAddresses in the FV-1's 32768 sample circular buffer can be assigned\nby the assembler using the 'MEM' directive. MEM reserves a portion\nof memory that represents a delay of 'EXPRESSION' samples between\nthe start point and end point, and assigns three labels:\n\n\tLABEL\tstart of delay segment\n\tLABEL^\tmidpoint of delay segment\n\tLABEL#\tend of delay segment\n\nEXPRESSION must define an integer number of samples\nor a parse error will be generated:\n\n\tMEM\tinvalid\t123.4556\t; invalid memory definition\n\n\tMemory INVALID length 123.4556 not integer on line 42\n\n\tMEM\tthird\t32767//3\t; valid due to integer divide\n\tMEM\td0_13\tint(0.13*32767)\t; valid due to explicit type cast\n\nLABEL has the same requirements as for [EQU](#label-assignment), and\nthe assigned labels can be used in any expression. Eg:\n\n\tMEM\tDel_A\t375\t\t; declare a 375 sample delay called 'DEL_A'\n\t\twra\tDEL_A,0.0\t; write to start of delay, DEL_A=0\n\t\trda\tdel_a^,0.5\t; read 0.5*midpoint of delay, DEL_A^=187\n\t\trda\tDeL_A#,0.5\t; add to 0.5*end of delay, DEL_A#=375\n\nThe assembler keeps track of allocated memory, placing each new\nsegment immediately after those previously defined. Each segment \nwith a delay of LENGTH, will consume LENGTH+1 samples of memory.\nAn attempt to use more than the available space will trigger\na parse error:\n\n\tMEM\tlong\t0x7f00\t\t; long:0 long#:0x7f00\n\tMEM\tshort\t0x00ff\t\t; short:0x7f01 short#:0x8000 (error)\n\n\tparse error: Delay exhausted: requested 255 exceeds 254 available on line ...\n\nThe caret character '^' is also used in expressions as\nthe bitwise XOR operator, so expressions which reference\na delay may need to be explicitly parenthesised if used with '^':\n\n\t\tor\tdelay^0xffff\t; parse error - delay label takes caret\n\n\tparse error: Unexpected INTEGER 0xffff on line ...\n\n\t\tor\t(delay)^0xffff\t; OK - parentheses enforce ordering\n\t\tor\tdelay^^0xffff\t; OK \n\n### Jump Targets\n\nJump targets label a particular address in the program output\nand can be placed between instructions anywhere in a source file.\nA jump target is a text label followed by a colon ':' character:\n\n\t\t\tskp\t1,TARGET1\t; skip offset is 3\n\t\t\tskp\t2,TARGET2\t; skip offset is 2\n\t\t\tskp\t4,TARGET3\t; skip offset is 1\n\t\t\tor\t0xff\tTarget1:\t; target after instr\n\tTARGET2:\t\t\t; target on its own line\n\ttarGET3:\tand\t0x12\t; all three targets point to this instruction\n\nUse of an already defined label for a target will result in a parse error:\n\n\tEQU\terror\t-1\n\terror:\tor\t0x800000\n\n\tparse error: Target ERROR already assigned on line ...\n\nTarget labels are not assigned values until parsing is complete\nand they can only be used as a destination for a\n[skip instruction](#skp-conditions-offset). For example, \nthe following attempt to offset from a target generates a\nparse error:\n\n\t\tskp\tNEG,target\t; skip to target if negative\n\t\tskp\t0,target+1\t; error - invalid expression\n\ttarget:\tclr\t\t\t; clear ACC\n\t\twrax\tDACL,0.0\t; output only positive\n\n\tparse error: Unexpected OPERATOR + on line ...\n\nTo achieve the desired if/else behaviour, use a second target:\n\n\t\tskp\tNEG,ifpart\t; skip to target if negative\n\t\tskp\t0,elsept\t; else, skip ahead\n\tifpart:\tclr\t\t\t; clear ACC\n\telsept:\twrax\tDACL,0.0\t; output >= 0\n\n\n### Instructions\n\nAn instruction is represented by a mnemonic text followed by zero \nor more [operand expressions](#operand-expressions) separated by commas:\n\nMnemonic | Operands | Description\n--- | --- | ---\n[rda](#rda-address-multiplier)\t|\tADDRESS,MULTIPLIER\t| multiply delay[ADDRESS] and accumulate\n[rmpa](#rmpa-multiplier)\t|\tMULTIPLER\t\t| multiply delay[(*ADDR_PTR)] and accumulate\n[wra](#wra-address-multiplier)\t|\tADDRESS,MULTIPLIER\t| write delay[ADDRESS] and multiply\n[wrap](#wrap-address-multiplier)\t|\tADDRESS,MULTIPLIER\t| write delay[ADDRESS], multiply and add LR\n[rdax](#rdax-register-multiplier)\t|\tREGISTER,MULTIPLIER\t| multiply (*REGISTER) and accumulate\n[rdfx](#rdfx-register-multiplier)\t|\tREGISTER,MULTIPLIER\t| subtract (*REGISTER), multiply and add (*REGISTER)\n[ldax](#ldax-register)\t|\tREGISTER\t\t| load (*REGISTER)\n[wrax](#wrax-register-multiplier)\t|\tREGISTER,MULTIPLIER\t| write (*REGISTER) and multiply\n[wrhx](#wrhx-register-multiplier)\t|\tREGISTER,MULTIPLIER\t| write (*REGISTER) and highpass shelf\n[wrlx](#wrlx-register-multiplier)\t|\tREGISTER,MULTIPLIER\t| write (*REGISTER) and lowpass shelf\n[maxx](#maxx-register-multiplier)\t|\tREGISTER,MULTIPLIER\t| load maximum of absolute values\n[absa](#absa)\t|\t\t\t\t| load absolute value of ACC\n[mulx](#mulx-register)\t|\tREGISTER\t\t| multiply by (*REGISTER)\n[log](#log-multiplier-offset)\t|\tMULTIPLIER,OFFSET\t| log2(ACC), multiply and offset\n[exp](#exp-multiplier-offset)\t|\tMULTIPLIER,OFFSET\t| 2\\*\\*(ACC), multiply and offset\n[sof](#sof-multiplier-offset)\t|\tMULTIPLIER,OFFSET\t| multiply and offset\n[and](#and-value)\t|\tVALUE\t\t\t| bitwise AND\n[clr](#clr)\t|\t\t\t\t| clear ACC\n[or](#or-value)\t|\tVALUE\t\t\t| bitwise OR\n[xor](#xor-value)\t|\tVALUE\t\t\t| bitwise XOR\n[not](#not)\t|\t\t\t\t| bitwise negation\n[skp](#skp-conditions-offset)\t|\tCONDITIONS,OFFSET\t| skip offset instructions if all conditions met\n[jmp](#jmp-offset)\t|\tOFFSET\t| jump offset instructions\n[nop](#nop)\t|\t\t\t\t| no operation\n[wlds](#wlds-lfo-frequency-amplitude)\t|\tLFO,FREQUENCY,AMPLITUDE\t| ajdust SIN LFO\n[wldr](#wldr-lfo-frequency-amplitude)\t|\tLFO,FREQUENCY,AMPLITUDE\t| adjust RMP LFO\n[jam](#jam-lfo)\t|\tLFO\t\t\t| reset LFO\n[cho](#cho-rda-lfo-flags-address)\t|\tTYPE,LFO,FLAGS,ADDRESS\t| interpolated memory access\n[raw](#raw-u32)\t|\tU32\t\t\t| insert U32 opcode\n\nEach operand must evaluate to a single constant numeric\nvalue. The sizes and types are specific to each instruction\n(see [Instruction Reference](#instruction-reference) below).\n\n### Operand Expressions\n\nOperand expressions are any valid combination\nof labels, numbers, parentheses and the following\noperators, listed from highest to lowest precedence. Operators\non the same line have the same precedence, and are evaluated\nleft to right - except for '**' (power) which works \n[as in the python intepreter](https://docs.python.org/3/reference/expressions.html#the-power-operator).\n\nOperator | Function | Note\n--- | --- | ---\n`\\|`\t|\tbitwise or\t| valid for integers only\n`^`\t|\tbitwise xor\t| valid for integers only\n`&`\t|\tbitwise and\t| valid for integers only\n`<< >>` |\tshift left, shift right\t| valid for integers only\n`+ -`\t|\tadd, subtract\t|\n`* // /` |\tmultiply, divide\t| `//` forces integer divide\n`+ - ~ int`\t|\tunary plus, minus, invert bits, integer cast\t| `!` is an alias for `~`\n`**`\t|\tpower\t| Binds right: `-10**-2` = `-0.01`\n\nThe following numeric entry formats are recognised:\n\nLiteral\t| Value | Type\n--- | --- | ---\n`123`\t| 123 | Decimal integer\n`0x123`\t| 291 | Hexadecimal integer\n`$123`\t| 291 | Hexadecimal integer\n`0b1010_1111`\t| 175 | Binary integer\n`%0101_1111`\t| 175 | Binary integer ('_' is ignored)\n`1.124`\t| 1.124 | Floating point number\n`1.124e-3`\t| 0.001124 | Floating point number with exponent\n\nThe final value of an expression will be either an\ninteger, which is used for the instruction operand\nunchanged or a floating point value which is later converted\nto the closest fixed-point integer of the required size\n(see [Fixed Point Conversion](#fixed-point-conversion) below).\nThe unary `int` operator will force a floating-point value\nto be rounded and converted to the nearest integer:\n\n\tMEM\td0_23\tint(0.23*0x8000) ; ~0.23 second delay = 7537 samples\n\nIf the result of the expression is a complex number, or if the\nexpression cannot be evaluated, a parse error is generated:\n\n\tEQU\tj\t(-1)**(1/2)\t; j=sqrt(-1)\n\n\tparse error: Expression result (6.123233995736766e-17+1j) invalid type on line ...\n\n\tEQU\tns\t1024<<(-1)\t; impossible negative shift\n\n\tparse error: negative shift count on line ...\n\n\tEQU\ttms\t(1024/13)&0x123\t; type mismatch\n\n\tparse error: unsupported operand type(s) for &: 'float' and 'int' on line ...\n\nMore formally, a valid operand expression matches the\nfollowing grammar:\n\n\texpression ::= or_expr\n\tor_expr ::= xor_expr | or_expr \"|\" xor_expr\n\txor_expr ::= and_expr | xor_expr \"^\" and_expr\n\tand_expr ::= shift_expr | and_expr \"&\" shift_expr\n\tshift_expr ::= a_expr | shift_expr \"<<\" a_expr | shift_expr \">>\" a_expr\n\ta_expr ::= m_expr | a_expr \"+\" m_expr | a_expr \"-\" m_expr\n\tm_expr ::= u_expr | m_expr \"*\" u_expr | m_expr \"//\" u_expr | m_expr \"/\" u_expr\n\tu_expr ::= power | \"-\" u_expr | \"+\" u_expr | \"~\" u_expr | \"int\" u_expr\n\tpower ::= atom [\"**\" u_expr]\n\tatom ::= label | literal | \"(\" expression \")\"\n\nWhere label is a text label, and literal is a number. Expressions \nare parsed and evaluated in-place by asfv1. All labels must be defined\nbefore they are referenced in an expression.\n\n### Fixed Point Conversion\n\nFor instructions that require fixed-point real values as\ninput, asfv1 automatically converts real expression results\nfrom an intermediate floating-point value to the nearest\nequivalent signed fixed-point integer. This value is then\nmasked to the correct number of bits and placed in machine\ncode. The conversion is performed for all types by computing\nthe multiplication:\n\n\tfixed = int(round(floating * REFERENCE)) & MASK\n\nWhere REFERENCE is the equivalent integer value of +1.0 in the \ndesired number format and floating is the saturated intermediate\nfloating-point value. The following table lists the sizes and range\nof each of the FV-1 number formats. \n\n\tName\tBits\tRefval\tMinval\tMaxval\n\tS4_6\t11\t64\t-16.0\t15.984375\n\tS1_9\t11\t512\t-2.0\t1.998046875\n\tS_10\t11\t1024\t-1.0\t0.9990234375\n\tS1_14\t16\t16384\t-2.0\t1.99993896484375\n\tS_15\t16\t32768\t-1.0\t0.999969482421875\n\tS_23\t24\t8388608\t-1.0\t0.9999998807907104\n\nFor example, the following entries all generate the same\ncode:\n\n\t\tor\t-0.4335784912109375\t\t; S_23 real value\n\t\tor\t-0x377f80&0xffffff\t\t; signed 23bit int to unsigned 24 bit int\n\t\tor\t0xc88080\t\t\t; unsigned 24bit int in hexadecimal\n\t\tor\t13140096\t\t\t; unsigned 24bit int in decimal\n\t\tor\t1<<23|2**22|1<<19|2**15|1<<7\t; unsigned 24bit int by bitwise or\n\t\tor\t0b110010001000000010000000\t; unsigned 24bit int in binary\n\t\tor\tint(-0.4335784912109375*2**23)&0xffffff\t; S_23 to unsigned 24bit conversion\n\n### Pre-defined Labels\n\nThe following text labels are pre-defined by asfv1.\nRefer to the FV-1 datasheet for information on the \nfunction of registers.\n\nLabel | Value | Description\n--- | --- | ---\n`SIN0_RATE`\t|\t`0x00`\t|\tSIN0 rate control register\n`SIN0_RANGE`\t|\t`0x01`\t|\tSIN0 range control register\n`SIN1_RATE`\t|\t`0x02`\t|\tSIN1 rate control register\n`SIN1_RANGE`\t|\t`0x03`\t|\tSIN1 range control register\n`RMP0_RATE`\t|\t`0x04`\t|\tRMP0 rate control register\n`RMP0_RANGE`\t|\t`0x05`\t|\tRMP0 range control register\n`RMP1_RATE`\t|\t`0x06`\t|\tRMP1 rate control register\n`RMP1_RANGE`\t|\t`0x07`\t|\tRMP1 range control register\n`POT0`\t|\t`0x10`\t|\tPOT0 input register\n`POT1`\t|\t`0x11`\t|\tPOT1 input register\n`POT2`\t|\t`0x12`\t|\tPOT2 input register\n`ADCL`\t|\t`0x14`\t|\tLeft AD input register\n`ADCR`\t|\t`0x15`\t|\tRight AD input register\n`DACL`\t|\t`0x16`\t|\tLeft DA output register\n`DACR`\t|\t`0x17`\t|\tRight DA output register\n`ADDR_PTR`\t|\t`0x18`\t|\tDelay address pointer\n`REG0` - `REG31`\t|\t`0x20` - `0x3f`\t|\tGeneral purpose registers\n`SIN0`\t|\t`0x00`\t|\tSIN0 LFO selector\n`SIN1`\t|\t`0x01`\t|\tSIN1 LFO selector\n`RMP0`\t|\t`0x02`\t|\tRMP0 LFO selector\n`RMP1`\t|\t`0x03`\t|\tRMP1 LFO selector\n`RDA`\t|\t`0x00`\t|\tCHO type selector\n`SOF`\t|\t`0x02`\t|\tCHO type selector\n`RDAL`\t|\t`0x03`\t|\tCHO type selector\n`SIN`\t|\t`0x00`\t|\tCHO flag\n`COS`\t|\t`0x01`\t|\tCHO flag\n`REG`\t|\t`0x02`\t|\tCHO flag\n`COMPC`\t|\t`0x04`\t|\tCHO flag\n`COMPA`\t|\t`0x08`\t|\tCHO flag\n`RPTR2`\t|\t`0x10`\t|\tCHO flag\n`NA`\t|\t`0x20`\t|\tCHO flag\n`RUN`\t|\t`0x10`\t|\tSKP condition flag\n`ZRC`\t|\t`0x08`\t|\tSKP condition flag\n`ZRO`\t|\t`0x04`\t|\tSKP condition flag\n`GEZ`\t|\t`0x02`\t|\tSKP condition flag\n`NEG`\t|\t`0x01`\t|\tSKP condition flag\n\nPre-defined labels may be re-defined within a source file, \nhowever, the re-defined value only applies to label references\n*following* the assignment. Any re-definition will issue a\nwarning message:\n\n\t\tldax\tPOT0\t; load POT0 (0x10)\n\tEQU\tPOT0\tADCL\t; re-define POT0 to be 0x14\n\t\tldax\tPOT0\t; load from ADCL (0x14)\n\n\twarning: Label POT0 re-defined on line ...\n\n## Instruction Reference\n\n### rda ADDRESS, MULTIPLIER\n\nMultiply and accumulate a sample from delay memory.\n\n\tADDRESS:\tReal S_15 or Unsigned 15bit integer delay address\n\tMULTIPLIER:\tReal S1_9 or Unsigned 11bit integer\n\tAssembly:\tMULTIPLIER<<21 | ADDRESS<<5 | 0b00000\n\nAction:\n\n\tACC <- ACC + MULTIPLIER * delay[ADDRESS]\n\tPACC <- ACC\n\tLR <- delay[ADDRESS]\n\nExample:\t\n\n\t\trda\tpdel^+324,0.1\t; add 0.1 * delay[pdel^+324] to ACC\n\t\trda\tpdel#,0.3\t; add 0.3 * delay[pdel#] to ACC\n\t\trda\t0.3,0.5\t\t; add 0.5 * delay[0x2666] to ACC\n\n### rmpa MULTIPLIER\n\nMultiply and accumulate a sample from the delay memory, using\nthe contents of ADDR_PTR as the delay address.\n\n\tMULTIPLIER:\tReal S1_9 or Unsigned 11bit integer\n\tAssembly:\tMULTIPLIER<<21 | 0b00001\n\nAction:\n\n\tACC <- ACC + MULTIPLIER * delay[(*ADDR_PTR)>>8]\n\tPACC <- ACC\n\tLR <- delay[(*ADDR_PTR)>>8]\n\nNotes:\n\n - 15 bit delay addresses in ADDR_PTR are left shifted 8 bits,\n so they can be accessed using the real S_23 value 0->0.9999 or\n directly by multiplying the desired integer delay address by 256.\n\nExample:\t\n\n\t\tor\t1234<<8\t\t; load 1234*256 into ACC\n\t\twrax\tADDR_PTR,0.0\t; save to ADDR_PTR and clear ACC\n\t\trmpa\t0.25\t\t; add 0.25 * delay[1234] to ACC\n\t\tclr\n\t\tor\t0.5\t\t; load 0.5 into ACC\n\t\twrax\tADDR_PTR,0.0\t; save the address pointer\n\t\trmpa\t0.7\t\t; add 0.7 * delay[0x4000]\n\n### wra ADDRESS, MULTIPLIER\n\nWrite ACC to delay memory and scale by multiplier.\n\n\tADDRESS:\tReal S_15 or Unsigned 15bit integer delay address\n\tMULTIPLIER:\tReal S1_9 or Unsigned 11bit integer\n\tAssembly:\tMULTIPLIER<<21 | ADDRESS<<5 | 0b00010\n\nAction:\n\n\tdelay[ADDRESS] <- ACC\n\tPACC <- ACC\n\tACC <- MULTIPLIER * ACC\n\nExample:\t\n\n\t\twra\tpdel^+324,0.25\t; write ACC to delay[pdel^+324] scale ACC by 0.25\n\t\twra\tpdel#,0.0\t; write ACC to delay[pdel#] clear ACC\n\n### wrap ADDRESS, MULTIPLIER\n\nWrite ACC to delay memory, multiply ACC, add to LR and save to ACC.\n\n\tADDRESS:\tReal S_15 or Unsigned 15bit integer delay address\n\tMULTIPLIER:\tReal S1_9 or Unsigned 11bit integer\n\tAssembly:\tMULTIPLIER<<21 | ADDRESS<<5 | 0b00011\n\nAction:\n\n\tdelay[ADDRESS] <- ACC\n\tACC <- LR + MULTIPLIER * ACC\n\tPACC <- ACC\n\nExample:\t\n\n\t\tldax\tADCL\t\t; read from left input\n\t\twrap\t0x1000,0.3\t; write ACC to delay[0x1000] scale ACC by 0.3 add to LR\n\n### rdax REGISTER, MULTIPLIER\n\nMultiply and accumulate contents of register.\n\n\tREGISTER:\tUnsigned 6bit integer register address\n\tMULTIPLIER:\tReal S1_14 or Unsigned 16bit integer\n\tAssembly:\tMULTIPLIER<<16 | REGISTER<<5 | 0b00100\n\nAction:\n\n\tACC <- ACC + MULTIPLIER * (*REGISTER)\n\tPACC <- ACC\n\nExample:\t\n\n\t\trdax\tPOT0,0.11\t; add 0.11*POT0 to ACC\n\t\trdax\tREG8,-0.66\t; subtract 0.66*REG8 from ACC\n\n### rdfx REGISTER, MULTIPLIER\n\nSubtract register content from ACC, multiply and add to register content.\n\n\tREGISTER:\tUnsigned 6bit integer register address\n\tMULTIPLIER:\tReal S1_14 or Unsigned 16bit integer\n\tAssembly:\tMULTIPLIER<<16 | REGISTER<<5 | 0b00101\n\nAction:\n\n\tACC <- (*REGISTER) + MULTIPLIER * (ACC - (*REGISTER))\n\tPACC <- ACC\n\nExample:\t\n\n\t\trdfx\tADCL,0.0\t; transfer ADCL content to ACC\n\t\trdfx\tREG0,0.3\t; average using temp reg\n\t\twrlx\tREG0,0.0\t; infinite shelf LPF\n\n### ldax REGISTER\n\nCopy register content to ACC. Assembles to rdax with a multiplier\nof 0.0.\n\n\tREGISTER:\tUnsigned 6bit integer register address\n\tAssembly:\tREGISTER<<5 | 0b00101\n\nAction:\n\n\tACC <- (*REGISTER)\n\tPACC <- ACC\n\nExample:\t\n\n\t\tldax\tADCL\t\t; load ADCL content into ACC\n\t\twrax\tDACL,0.0\t; write ACC to DACL\n\n### wrax REGISTER, MULTIPLIER\n\nCopy ACC to REGISTER, and multiply ACC.\n\n\tREGISTER:\tUnsigned 6bit integer register address\n\tMULTIPLIER:\tReal S1_14 or Unsigned 16bit integer\n\tAssembly:\tMULTIPLIER<<16 | REGISTER<<5 | 0b00110\n\nAction:\n\n\t(*REGISTER) <- ACC\n\tACC <- MULTIPLIER * ACC\n\tPACC <- ACC\n\nExample:\t\n\n\t\twrax\tREG0,-1.0\t; copy ACC into REG0 and invert ACC\n\t\twrax\tDACL,0.0\t; copy ACC into DAC and clear ACC\n\n### wrhx REGISTER, MULTIPLIER\n\nCopy ACC to REGISTER, multiply ACC and add to PACC.\n\n\tREGISTER:\tUnsigned 6bit integer register address\n\tMULTIPLIER:\tReal S1_14 or Unsigned 16bit integer\n\tAssembly:\tMULTIPLIER<<16 | REGISTER<<5 | 0b00111\n\nAction:\n\n\t(*REGISTER) <- ACC\n\tACC <- PACC + MULTIPLIER * ACC\n\tPACC <- ACC\n\nExample:\t\n\n\t\trdfx\tREG0,0.3\t; average using temp reg\n\t\twrhx\tREG0,-0.5\t; -6dB shelf highpass filter\n\t\twrhx\tREG1,0.0\t; swap PACC and ACC\n\n### wrlx REGISTER, MULTIPLIER\n\nCopy ACC to REGISTER, subtract ACC from PACC, multiply and add to PACC.\n\n\tREGISTER:\tUnsigned 6bit integer register address\n\tMULTIPLIER:\tReal S1_14 or Unsigned 16bit integer\n\tAssembly:\tMULTIPLIER<<16 | REGISTER<<5 | 0b01000\n\nAction:\n\n\t(*REGISTER) <- ACC\n\tACC <- PACC + MULTIPLIER * (PACC - ACC)\n\tPACC <- ACC\n\nExample:\t\n\n\t\trdfx\tREG0,0.3\t; average using temp reg\n\t\twrlx\tREG0,-0.5\t; -6dB shelf lowpass filter\n\t\twrlx\tREG1,0.0\t; swap PACC and ACC\n\n### maxx REGISTER, MULTIPLIER\n\nCopy the maximum of the absolute value of ACC and the \nabsolute value of REGISTER content times MULTIPLIER into ACC.\n\n\tREGISTER:\tUnsigned 6bit integer register address\n\tMULTIPLIER:\tReal S1_14 or Unsigned 16bit integer\n\tAssembly:\tMULTIPLIER<<16 | REGISTER<<5 | 0b01001\n\nAction:\n\n\tACC <- maximum (abs (ACC), abs (MULTIPLIER * (*REGISTER)))\n\tPACC <- ACC\n\nExample:\t\n\n\t\tldax\tADCL\t\t; copy ADCL to ACC\n\t\tmaxx\tADCR,1.0\t; copy max of left and right to ACC\n\t\tmaxx\t0,0\t\t; absolute value of ACC\n\n### absa\n\nCopy the absolute value of ACC back into ACC. Assembles to maxx\nwith null register and zero multiplier.\n\n\tAssembly:\t0b01001\n\nAction:\n\n\tACC <- abs (ACC)\n\tPACC <- ACC\n\nExample:\t\n\n\t\tldax\tADCL\t\t; copy ADCL to ACC\n\t\tabsa\t\t\t; absolute value of ACC\n\n### mulx REGISTER\n\nMultiply ACC by the content of REGISTER.\n\n\tREGISTER:\tUnsigned 6bit integer register address\n\tAssembly:\tREGISTER<<5 | 0b01010\n\nAction:\n\n\tACC <- ACC * (*REGISTER)\n\tPACC <- ACC\n\nExample:\t\n\n\t\tldax\tADCL\t\t; copy ADCL to ACC\n\t\tmulx\tPOT0\t\t; scale input by POT0\n\n### log MULTIPLIER, OFFSET\n\nCompute the base 2 log of the absolute value of ACC,\nmultiply and then add offset. Input ACC is S_23,\nresult ACC is S4_19.\n\n\tMULTIPLIER:\tReal S1_14 or Unsigned 16bit integer\n\tOFFSET:\t\tReal S_10 or Unsigned 11bit integer\n\tAssembly:\tMULTIPLIER<<16 | OFFSET<<5 | 0b01011\n\nAction:\n\n\tACC <- OFFSET + MULTIPLIER * log2 (abs (ACC))\n\tPACC <- ACC\n\nNotes:\n\n - OFFSET is input as a real S_10 value, however it represents\n an S4_6 offset of the accumulator, which is in S4_19 after the log.\n\nExample:\t\n\n\t\tlog\t0.5,0.0\t\t; 2*log2(a) = log2(a**2)\n\t\texp\t1.0,0.0\t\t; a = 2**(0.5 * log2(a**2))\t[square root]\n\n### exp MULTIPLIER, OFFSET\n\nRaise 2 to the power of ACC, multiply and add OFFSET.\nInput ACC is S4_16, result ACC is S_23.\n\n\tMULTIPLIER:\tReal S1_14 or Unsigned 16bit integer\n\tOFFSET:\t\tReal S_10 or Unsigned 11bit integer\n\tAssembly:\tMULTIPLIER<<16 | OFFSET<<5 | 0b01100\n\nAction:\n\n\tACC <- OFFSET + MULTIPLIER * 2**ACC\n\tPACC <- ACC\n\nExample:\t\n\n\t\tlog\t1.0,4.0\t\t; log2(16*a) = log2(16) + log2(a)\n\t\texp\t1.0,0.0\t\t; 16*a = 2**(4+log2(a))\t[x16 gain]\n\n### sof MULTIPLIER, OFFSET\n\nScale ACC and then add an offset.\n\n\tMULTIPLIER:\tReal S1_14 or Unsigned 16bit integer\n\tOFFSET:\t\tReal S_10 or Unsigned 11bit integer\n\tAssembly:\tMULTIPLIER<<16 | OFFSET<<5 | 0b01101\n\nAction:\n\n\tACC <- OFFSET + MULTIPLIER * ACC\n\tPACC <- ACC\n\nExample:\t\n\n\t\tsof\t1.5,-0.4\t; multiply acc by 1.5 and subtract 0.4\n\n### and VALUE\n\nPerform a bitwise AND of ACC and VALUE\n\n\tVALUE:\t\tReal S_23 or Unsigned 24bit integer\n\tAssembly:\tVALUE<<8 | 0b01110\n\nAction:\n\n\tACC <- ACC & VALUE\n\tPACC <- ACC\n\nExample:\t\n\n\t\tldax\tPOT0\t\t; load POT0 into ACC\n\t\tand\t0x700000\t; mask pot to 8 steps\n\t\tand\t0\t\t; clear ACC\n\n### clr\n\nPerform a bitwise AND of ACC with zero - clearing ACC\n\n\tAssembly:\t0b01110\n\nAction:\n\n\tACC <- 0\n\tPACC <- ACC\n\nExample:\t\n\n\t\tclr\t\t\t; clear ACC\n\t\trda\t1234,1.0\t; load delay[1234]\n\n### or VALUE\n\nPerform a bitwise OR of ACC and VALUE\n\n\tVALUE:\t\tReal S_23 or Unsigned 24bit integer\n\tAssembly:\tVALUE<<8 | 0b01111\n\nAction:\n\n\tACC <- ACC | VALUE\n\tPACC <- ACC\n\nExample:\t\n\n\t\tclr\t\t\t; clear ACC\n\t\tor\t-2.3427e-4\t; load an immediate value into ACC\n\t\tor\t0x0a40f1\t; set specific bits in ACC\n\n### xor VALUE\n\nPerform a bitwise XOR of ACC and VALUE\n\n\tVALUE:\t\tReal S_23 or Unsigned 24bit integer\n\tAssembly:\tVALUE<<8 | 0b10000\n\nAction:\n\n\tACC <- ACC ^ VALUE\n\tPACC <- ACC\n\nExample:\t\n\n\t\tldax\tPOT0\t\t; load POT0\n\t\tand\t0x7f0000\t; mask off lower bits\n\t\txor\t0x150000\t; compare with 0x150000\n\t\tskp\tZRO,equal\t; if same, skip to equal\n\t\txor\t0x150000\t; else restore original value\n\n### not\n\nPerform a bitwise negation of ACC by XOR with 0xffffff.\n\n\tAssembly:\t0xffffff<<8 | 0b10000\n\nAction:\n\n\tACC <- ~ACC\n\tPACC <- ACC\n\nExample:\t\n\n\t\tldax\tPOT0\t\t; load POT0\n\t\tnot\t\t\t; invert all bits\n\n### skp CONDITIONS, OFFSET\n\nSkip over OFFSET instructions if all flagged CONDITIONS are met.\n\n\tCONDITIONS:\tUnsigned 5bit flags\n\tOFFSET:\t\tUnsigned 6bit integer or target label\n\tAssembly:\tCONDITIONS<<27 | OFFSET<<21 | 0b10001\n\nCondition Flags:\n\n\tNEG\t0x01\tACC is less than zero\n\tGEZ\t0x02\tACC is greater than or equal to zero\n\tZRO\t0x04\tACC is zero\n\tZRC\t0x08\tsign of ACC and PACC differ\n\tRUN\t0x10\tProgram has completed at least one iteration\n\nNotes:\n\n - if no condition flags are set, the skip is always performed.\n\n - if OFFSET starts with a label, it is assumed to be a jump target,\n which should be present later in the program. An attempt to skip\n backward will raise an error:\n\n\t\tstart:\tclr\n\t\t\tskp\t0,start\t\t; try to skip backward\n\n\t\tparse error: Target START does not follow SKP on line ...\n\n - the maximum possible skip offset is 63, an error will be generated if\n the named target is out of range:\n\n\t\t\tskp\t0,target\n\t\t\t[>63 instructions]\n\t\ttarget: clr\n\n\t\tparse error: Offset from SKP to TARGET (0x40) too large on line ...\n\n - To force computation of an offset, wrap an expression in parentheses:\n\n\t\tEQU\tthree\t3\n\t\t\tskp\t0,three+3\t; error - three is not a target\n\n\t\tparse error: Unexpected OPERATOR + on line ...\n\t\tparse error: Undefined target THREE for SKP on line ...\n\n\t\t\tskp\t0,(three+3)\t; ok, offset is evaluated as expression\n\n - if mutually exclusive conditions are specified, the skip is\n assembled but never performed, turning the instruction into NOP:\n\n\t\t\tskp\tNEG|ZRO,target\t; ACC cannot be negative AND zero\n\nExample:\t\n\n\t\tskp\t0,target\t; unconditionally skip to target\n\t\tldax\tADCL\t\t; read in ADCL\n\t\tldax\tREG0\t\t; load a previous value\n\t\tskp\tZRC|NEG,target\t; skip to target on positive zero crossing\n\t\tskp\tRUN,1\t\t; skip 1 instruction except on first run\n\n### jmp OFFSET\n\nPerform an unconditional skip over OFFSET instructions.\n\n\tOFFSET:\t\tUnsigned 6bit integer or target label\n\tAssembly:\tOFFSET<<21 | 0b10001\n\nNotes:\n\n - jmp is assembled as skp 0,OFFSET. See skp above for details on \n specifying jmp targets.\n\nExample:\t\n\n\t\tjmp\ttarget\t\t; unconditionally skip to target\n\t\tjmp\t3\t\t; always skip over 3 instructions\n\n### nop\n\nNo operation, equivalent to skp 0,0. Use for padding, or blocking.\n\n\tAssembly:\t0b10001\n\nExample:\t\n\n\t\tnop nop nop nop\t\t; reserve 4 instruction slots\n\n### wlds LFO, FREQUENCY, AMPLITUDE\n\nAdjust SIN LFO with coefficients FREQUENCY and AMPLITUDE.\n\n\tLFO:\t\t1bit integer (0 = SIN0 or 1 = SIN1)\n\tFREQUENCY:\tUnsigned 9bit integer\n\tAMPLITUDE:\tReal S_15 or Unsigned 15bit integer\n\tAssembly:\tLFO<<29 | FREQUENCY<<20 | AMPLITUDE<<5 | 0b10010\n\nNotes:\n\n - FREQUENCY coefficient is related to LFO rate (f) in Hz\n by the following:\n\n\t\tFREQUENCY = int (2**18 * pi * f / Fs)\n\t\tf = FREQUENCY * Fs / (2**18 * pi)\n\n Where Fs is the sample rate. For a 32768Hz crystal, the SIN \n LFO ranges from 0Hz up to about 20Hz.\n\n - AMPLITUDE coefficient specifies the peak-to-peak amplitude\n of the LFO in delay samples, and may be entered using a real\n value. Negative amplitudes work as with SINx_RANGE register.\n\n - The frequency and amplitude of SIN LFOs can also be set\n by writing to registers: SIN0_RATE, SIN0_RANGE, SIN1_RATE,\n and SIN1_RANGE. \n\nExample:\t\n\n\t\twlds\tSIN0,511,1\t; Set SIN0 to 20Hz, amplitude 1 sample\n\t\twlds\tSIN1,1,0x7fff\t; Set SIN1 to 0.04Hz and full delay length\n\t\tor\t0.5\n\t\twrax\tSIN0_RATE,0.0\t; Set SIN0 to ~10Hz\n\t\tldax\tPOT0\n\t\twrax\tSIN0_RANGE,0.0\t; Set SIN0 range from POT0\n\n### wldr LFO, FREQUENCY, AMPLITUDE\n\nAdjust RMP LFO with coefficients FREQUENCY and AMPLITUDE.\n\n\tLFO:\t\t1bit integer (0 = RMP0 or 1 = RMP1)\n\tFREQUENCY:\tReal S_15 or Signed 16bit integer\n\tAMPLITUDE:\t2bit integer (0=4096, 1=2048, 2=1024, 3=512)\n\tAssembly:\t(LFO|0x2)<<29 | FREQUENCY<<13 | AMPLITUDE<<5 | 0b10010\n\nNotes:\n\n - LFO may also be set using pre-defined labels RMP0 and RMP1.\n\n - AMPLITUDE may also be set by entering one of the specific\n integer values: 4096, 2048, 1024 or 512.\n\n - FREQUENCY may be entered using a real value, which has the same\n interpretation as the RMPx_RATE register.\n\n - The frequency and amplitude of RMP LFOs can also be set\n by writing to registers: RMP0_RATE, RMP0_RANGE, RMP1_RATE,\n and RMP1_RANGE. \n\nExample:\t\n\n\t\twldr\tRMP0,32767,0\t; Set RMP0 to max rate, 4096 amplitude\n\t\twldr\tRMP1,-1923,512\t; Set RMP1 to 512 and a negative frequency\n\n### jam LFO\n\nReset specified ramp LFO to start.\n\n\tLFO:\t\t1bit integer (0 = RMP0 or 1 = RMP1)\n\tAssembly:\t(LFO|0x2)<<6 | 0b10011\n\nNote:\n\n- LFO may also be set using pre-defined labels RMP0 and RMP1.\n\nExample:\t\n\n\t\tjam\tRMP0\t\t; reset RMP0 lfo\n\n### cho rda, LFO, FLAGS, ADDRESS\n\nRead from delay memory at ADDRESS + offset (LFO) according to\nFLAGS, multiply the result by coeff (LFO) and accumulate.\n\n\tLFO:\t\t2bit integer (SIN0, SIN1, RMP0 or RMP1)\n\tFLAGS:\t\t6bit integer flags\n\tADDRESS:\tReal S_15 or Unsigned 16bit integer\n\tAssembly:\tFLAGS<<24 | LFO<<21 | ADDRESS<<5 | 0x10100\n\nAction:\n\n\tACC <- ACC + coeff (LFO) * delay[ADDRESS + offset (LFO)]\n\tPACC <- ACC\n\nFlags:\n\n\tCOS\t0x01\tuse cosine output of SIN LFO \n\tREG\t0x02\t'register' LFO state (see note below)\n\tCOMPC\t0x04\tcomplement coefficient: 1 - coeff (LFO) \n\tCOMPA\t0x08\tcomplement address offset: 1 - offset (LFO)\n\tRPTR2\t0x10\tuse second, half-off ramp \n\tNA\t0x20\toffset (LFO) = 0.0, coeff (LFO) = crossfade coefficient\n\nNotes:\n\n - offset (LFO) is the coarse LFO delay offset, based on flag settings\n to a whole sample\n\n - coeff (LFO) is an interpolation coefficient, based on flag settings\n and the LFO fine position between whole samples\n\n - the first use of cho in a program with any LFO must include the\n REG flag in order to 'register' the LFO state and get valid data\n\n - flags that are not relevant for the chosen LFO or cho mode are ignored\n\nExample:\n\n\t\tcho\trda,SIN0,REG|COMPC,20\t; load first half of interpolation\n\t\tcho\trda,SIN0,0,21\t\t; add second half of interpolation\n\n### cho sof, LFO, FLAGS, OFFSET\n\nMultiply ACC by coeff (LFO), and add OFFSET.\n\n\tLFO:\t\t2bit integer (SIN0, SIN1, RMP0 or RMP1)\n\tFLAGS:\t\t6bit integer flags (see cho rda)\n\tOFFSET:\t\tReal S_15 or Unsigned 16bit integer\n\tAssembly:\t0x2<<30 | FLAGS<<24 | LFO<<21 | OFFSET<<5 | 0x10100\n\nAction:\n\n\tACC <- coeff (LFO) * ACC + OFFSET\n\tPACC <- ACC\n\nExample:\n\n\t\tldax\tADCL\t\t\t; load AD\n\t\tcho\tsof,RMP0,REG|COMPC|NA,0\t; tremolo - scale ACC by RMP0 xfade\n\n### cho rdal, LFO [, FLAGS]\n\nRead the specified LFO address offset value into ACC\naccording to optional FLAGS. If FLAGS are omitted, a default\nvalue of REG (0x2) is assembled.\n\n\tLFO:\t\t2bit integer (SIN0, SIN1, RMP0 or RMP1)\n\tFLAGS:\t\t6bit integer flags (see cho rda and notes)\n\tAssembly:\t0x3<<30 | FLAGS<<24 | LFO<<21 | 0x10100\n\nAction:\n\n\tACC <- ACC + offset (LFO)\n\tPACC <- ACC\n\nNotes:\n\n - REG flag must be set in order to get a meaningful value in ACC\n value (this is the default if FLAGS are omitted)\n\n - Only COS flag has any affect on the instruction, and only when used with\n SIN LFO. \n\nExample:\n\n\t\tcho\trdal,SIN0,REG\t; load the SIN value and 'register' LFO\n\t\twrax\tDACL,0.0\t; output to left channel\n\t\tcho\trdal,SIN0,COS\t; load the COS value\n\t\twrax\tDACR,0.0\t; output to right channel\n\n### raw U32\n\nCopy the unsigned 32 bit value in U32 directly to the output program.\n\n\tU32:\t\tUnsigned 32bit integer\n\tAssembly:\tU32\n\nExample:\n\n\t\traw\t0x4000000f\t; manually assemble \"or 0.5\"\n\t\tskp\t0,1\t\t; skip over the next instruction\n\t\traw\t0xa899fbda\t; place a signature in the binary\n\n## System Specific Installation\n\nThe preferred method for installation is to use your system's\npackaged pip3 command to fetch and install asfv1 from\n[PyPi](https://pypi.org/) and set it up to work with a python3\ninterpreter.\n\n### Linux with apt (Debian, Ubuntu)\n\n\t$ sudo apt install python3-venv python3-pip\n\t$ pip3 install asfv1\n\n### Linux with yum (Fedora 21)\n\n\t$ sudo yum install python3 python3-wheel\n\t$ pip3 install asfv1\n\n### Linux with dnf (Fedora 22)\n\n\t$ sudo dnf install python3 python3-wheel\n\t$ pip3 install asfv1\n\n### Arch Linux\n\n\t$ sudo pacman -S python-pip\n\t$ pip install asfv1\n\n### MacOS\n\nDownload a copy of the "Latest Python 3 Release"\nfor Mac OS from\n[python.org](https://www.python.org/downloads/mac-osx/).\nInstall the package, then open a terminal and run:\n\n\t$ pip3 install asfv1\n\n### Windows\n\nDownload a copy of the "Latest Python 3 Release"\nfor Windows from\n[python.org](https://www.python.org/downloads/windows/).\nInstall the package, then open a command prompt and run:\n\n\tC:\\> pip3 install asfv1\n\nFor more detailed information, please refer to the \n[Python package installation documentation](https://packaging.python.org/tutorials/installing-packages/)\nand\n[installing pip with packaging managers](https://packaging.python.org/guides/installing-using-linux-tools/#installing-pip-setuptools-wheel-with-linux-package-managers)\nat\n[packaging.python.org](https://packaging.python.org/).\n\n### Install from Source\n\nIf you would prefer to not use pip, or if your system is provided with\nand older version of Python (eg MacOS), asfv1 can be installed using\nthe included setup.py script. Fetch a copy of the latest source package,\nunpack it and then run the installer as root:\n\n\t$ sudo python ./setup.py install\n\nAlternatively, the main source file can be run directly with a python\ninterpreter without the need to install any files:\n\n\t$ python ./asfv1.py infile.asm outfile.bin\n\n## Links\n\n- FV-1 disassembler: \n- FV-1 test suite: \n- Dervish eurorack FV-1 module: \n- Spin FV-1 website: \n- Datasheet: \n- AN0001: \n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/ndf-zz/asfv1", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "asfv1", "package_url": "https://pypi.org/project/asfv1/", "platform": "", "project_url": "https://pypi.org/project/asfv1/", "project_urls": { "Homepage": "https://github.com/ndf-zz/asfv1" }, "release_url": "https://pypi.org/project/asfv1/1.2.7/", "requires_dist": null, "requires_python": ">=2.6", "summary": "Alternate FV-1 Assembler", "version": "1.2.7" }, "last_serial": 5915809, "releases": { "1.1.2": [ { "comment_text": "", "digests": { "md5": "4c9c996edeb2dbc1528f8018fef2ebb0", "sha256": "8bfcf3879837296158dcc79a6acef6566f4a39d199e10a8567cb592210cd2362" }, "downloads": -1, "filename": "asfv1-1.1.2-py3-none-any.whl", "has_sig": false, "md5_digest": "4c9c996edeb2dbc1528f8018fef2ebb0", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3", "size": 25060, "upload_time": "2019-06-23T14:04:20", "url": "https://files.pythonhosted.org/packages/a9/c8/57489ec653902179ae9e1a83011a4c334b866635222a54f05c35dee60a9f/asfv1-1.1.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "07524bbd6d6b66626b0491a28db1eb16", "sha256": "46758cb12908cd5c2f25940a7950c5c4d895d625c1446cb310f3c0b60579d89c" }, "downloads": -1, "filename": "asfv1-1.1.2.tar.gz", "has_sig": false, "md5_digest": "07524bbd6d6b66626b0491a28db1eb16", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 13092, "upload_time": "2019-06-23T14:04:22", "url": "https://files.pythonhosted.org/packages/8a/b1/8a8700accf3ed6a59aecdbda529f81bb6ea1f615cfb1e8010eb096c0b5a8/asfv1-1.1.2.tar.gz" } ], "1.2.4": [ { "comment_text": "", "digests": { "md5": "74839c6a846772e272c31139967fe22d", "sha256": "cb841b0b05c3862f919717f9d3681a357dbd00afe9738d67c864cde83aa98e9b" }, "downloads": -1, "filename": "asfv1-1.2.4-py3-none-any.whl", "has_sig": false, "md5_digest": "74839c6a846772e272c31139967fe22d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.6", "size": 35321, "upload_time": "2019-07-23T15:15:34", "url": "https://files.pythonhosted.org/packages/90/7c/a2cdc632ba0eee26067ee238b041e79ab06f0a91d5ecaaf94b814646b01c/asfv1-1.2.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "d13d16cb0154f6ed2c36d9ca9050c035", "sha256": "28efd211ac9b7a3675476eae6cdb56fa16d1028af268fee48c63ee240f941201" }, "downloads": -1, "filename": "asfv1-1.2.4.tar.gz", "has_sig": false, "md5_digest": "d13d16cb0154f6ed2c36d9ca9050c035", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.6", "size": 44685, "upload_time": "2019-07-23T15:15:36", "url": "https://files.pythonhosted.org/packages/a8/5f/f7fdc3b7b14868d0d4c78be4726dac2219a6ab20949059ee9f993695903c/asfv1-1.2.4.tar.gz" } ], "1.2.5": [ { "comment_text": "", "digests": { "md5": "fc9eb412ca84687bcabb0c4b720f292c", "sha256": "fbec0361ee42fd5bcdd3a9b9d43cf4f764b1308231da5a17ae37d3e9e542e03d" }, "downloads": -1, "filename": "asfv1-1.2.5-py3-none-any.whl", "has_sig": false, "md5_digest": "fc9eb412ca84687bcabb0c4b720f292c", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.6", "size": 35595, "upload_time": "2019-07-26T13:47:12", "url": "https://files.pythonhosted.org/packages/a1/f7/465becaff5bfdb0447e806fd7ba84c7795522bde525a5e427fa011b3d245/asfv1-1.2.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "d925c146db1bb35012e9436ac6901926", "sha256": "838f81a4104b7be8c7d711164bbf6de1c7e2a4830603af6dc52439bd0b49e899" }, "downloads": -1, "filename": "asfv1-1.2.5.tar.gz", "has_sig": false, "md5_digest": "d925c146db1bb35012e9436ac6901926", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.6", "size": 45066, "upload_time": "2019-07-26T13:47:14", "url": "https://files.pythonhosted.org/packages/55/5b/7e26b7f9d78b9bc8dbf9f7ac22df550764459112c3fc0f56171b6d273132/asfv1-1.2.5.tar.gz" } ], "1.2.6": [ { "comment_text": "", "digests": { "md5": "d75932c230a4d8bfce7173dbd927ff34", "sha256": "c7906e7ab90c3bd621e5841fd7ce0c6180c1b13747d6597c1ecc17c6eec8fc9e" }, "downloads": -1, "filename": "asfv1-1.2.6-py3-none-any.whl", "has_sig": false, "md5_digest": "d75932c230a4d8bfce7173dbd927ff34", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.6", "size": 36640, "upload_time": "2019-09-28T14:25:31", "url": "https://files.pythonhosted.org/packages/84/2d/ba4091a25ed17cda4533cf85214ae1c28796ee9c724d4f846fa5229dbe4f/asfv1-1.2.6-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "99f952e49d39118483f7a2d471b3156a", "sha256": "b4adf9c1f1efbcd10194f92441ebce347835f53821d9c66af1af74ff1a7c18be" }, "downloads": -1, "filename": "asfv1-1.2.6.tar.gz", "has_sig": false, "md5_digest": "99f952e49d39118483f7a2d471b3156a", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.6", "size": 48196, "upload_time": "2019-09-28T14:25:34", "url": "https://files.pythonhosted.org/packages/45/ec/6e86f35b418f5277d1bcf28b92549ddd773a2b3b09ddb879c343349c5fc3/asfv1-1.2.6.tar.gz" } ], "1.2.7": [ { "comment_text": "", "digests": { "md5": "e11265736b983422d9bcc59f9e15b251", "sha256": "68c4bb412f9456313f9a57d90b3d565b0ea48f260af9929179db6fbc6ca2d693" }, "downloads": -1, "filename": "asfv1-1.2.7-py3-none-any.whl", "has_sig": false, "md5_digest": "e11265736b983422d9bcc59f9e15b251", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.6", "size": 36737, "upload_time": "2019-10-02T03:06:41", "url": "https://files.pythonhosted.org/packages/86/0e/ebf954bc6bd1f57a8fab335632442d823e4f78ad0c183ca0631bbdcf0a87/asfv1-1.2.7-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "43e170cc7dd8572b1069bcaf0cd595d6", "sha256": "d89565365501a13ecde45f4e604d9ac462938445f7624fe787ec9e4ca2ae442a" }, "downloads": -1, "filename": "asfv1-1.2.7.tar.gz", "has_sig": false, "md5_digest": "43e170cc7dd8572b1069bcaf0cd595d6", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.6", "size": 48280, "upload_time": "2019-10-02T03:06:43", "url": "https://files.pythonhosted.org/packages/a0/05/073362d213f7c356bf034fca4873431b92b7eb584ab3eec3b23151a9f82b/asfv1-1.2.7.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "e11265736b983422d9bcc59f9e15b251", "sha256": "68c4bb412f9456313f9a57d90b3d565b0ea48f260af9929179db6fbc6ca2d693" }, "downloads": -1, "filename": "asfv1-1.2.7-py3-none-any.whl", "has_sig": false, "md5_digest": "e11265736b983422d9bcc59f9e15b251", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.6", "size": 36737, "upload_time": "2019-10-02T03:06:41", "url": "https://files.pythonhosted.org/packages/86/0e/ebf954bc6bd1f57a8fab335632442d823e4f78ad0c183ca0631bbdcf0a87/asfv1-1.2.7-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "43e170cc7dd8572b1069bcaf0cd595d6", "sha256": "d89565365501a13ecde45f4e604d9ac462938445f7624fe787ec9e4ca2ae442a" }, "downloads": -1, "filename": "asfv1-1.2.7.tar.gz", "has_sig": false, "md5_digest": "43e170cc7dd8572b1069bcaf0cd595d6", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.6", "size": 48280, "upload_time": "2019-10-02T03:06:43", "url": "https://files.pythonhosted.org/packages/a0/05/073362d213f7c356bf034fca4873431b92b7eb584ab3eec3b23151a9f82b/asfv1-1.2.7.tar.gz" } ] }