+
+There is also a Makefile available for compiling the ATS source code into
+an excutable for testing. One should be able to encounter a deadlock after
+running the simulation for a while.
+
+
+
+This article is written by Hongwei Xi.
+
+
+
+
+%{
+implement main () = fprint_filsub (stdout_ref, "main_atxt.txt")
+%}
diff --git a/samples/Agda/NatCat.agda b/samples/Agda/NatCat.agda
new file mode 100644
index 00000000..6169a085
--- /dev/null
+++ b/samples/Agda/NatCat.agda
@@ -0,0 +1,39 @@
+module NatCat where
+
+open import Relation.Binary.PropositionalEquality
+
+-- If you can show that a relation only ever has one inhabitant
+-- you get the category laws for free
+module
+ EasyCategory
+ (obj : Set)
+ (_⟶_ : obj → obj → Set)
+ (_∘_ : ∀ {x y z} → x ⟶ y → y ⟶ z → x ⟶ z)
+ (id : ∀ x → x ⟶ x)
+ (single-inhabitant : (x y : obj) (r s : x ⟶ y) → r ≡ s)
+ where
+
+ idʳ : ∀ x y (r : x ⟶ y) → r ∘ id y ≡ r
+ idʳ x y r = single-inhabitant x y (r ∘ id y) r
+
+ idˡ : ∀ x y (r : x ⟶ y) → id x ∘ r ≡ r
+ idˡ x y r = single-inhabitant x y (id x ∘ r) r
+
+ ∘-assoc : ∀ w x y z (r : w ⟶ x) (s : x ⟶ y) (t : y ⟶ z) → (r ∘ s) ∘ t ≡ r ∘ (s ∘ t)
+ ∘-assoc w x y z r s t = single-inhabitant w z ((r ∘ s) ∘ t) (r ∘ (s ∘ t))
+
+open import Data.Nat
+
+same : (x y : ℕ) (r s : x ≤ y) → r ≡ s
+same .0 y z≤n z≤n = refl
+same .(suc m) .(suc n) (s≤s {m} {n} r) (s≤s s) = cong s≤s (same m n r s)
+
+≤-trans : ∀ x y z → x ≤ y → y ≤ z → x ≤ z
+≤-trans .0 y z z≤n s = z≤n
+≤-trans .(suc m) .(suc n) .(suc n₁) (s≤s {m} {n} r) (s≤s {.n} {n₁} s) = s≤s (≤-trans m n n₁ r s)
+
+≤-refl : ∀ x → x ≤ x
+≤-refl zero = z≤n
+≤-refl (suc x) = s≤s (≤-refl x)
+
+module Nat-EasyCategory = EasyCategory ℕ _≤_ (λ {x}{y}{z} → ≤-trans x y z) ≤-refl same
diff --git a/samples/Alloy/file_system.als b/samples/Alloy/file_system.als
new file mode 100644
index 00000000..60fd959b
--- /dev/null
+++ b/samples/Alloy/file_system.als
@@ -0,0 +1,59 @@
+module examples/systems/file_system
+
+/*
+ * Model of a generic file system.
+ */
+
+abstract sig Object {}
+
+sig Name {}
+
+sig File extends Object {} { some d: Dir | this in d.entries.contents }
+
+sig Dir extends Object {
+ entries: set DirEntry,
+ parent: lone Dir
+} {
+ parent = this.~@contents.~@entries
+ all e1, e2 : entries | e1.name = e2.name => e1 = e2
+ this !in this.^@parent
+ this != Root => Root in this.^@parent
+}
+
+one sig Root extends Dir {} { no parent }
+
+lone sig Cur extends Dir {}
+
+sig DirEntry {
+ name: Name,
+ contents: Object
+} {
+ one this.~entries
+}
+
+
+/**
+ * all directories besides root have one parent
+ */
+pred OneParent_buggyVersion {
+ all d: Dir - Root | one d.parent
+}
+
+/**
+ * all directories besides root have one parent
+ */
+pred OneParent_correctVersion {
+ all d: Dir - Root | (one d.parent && one contents.d)
+}
+
+/**
+ * Only files may be linked (that is, have more than one entry)
+ * That is, all directories are the contents of at most one directory entry
+ */
+pred NoDirAliases {
+ all o: Dir | lone o.~contents
+}
+
+check { OneParent_buggyVersion => NoDirAliases } for 5 expect 1
+
+check { OneParent_correctVersion => NoDirAliases } for 5 expect 0
diff --git a/samples/Alloy/marksweepgc.als b/samples/Alloy/marksweepgc.als
new file mode 100644
index 00000000..b8081e3f
--- /dev/null
+++ b/samples/Alloy/marksweepgc.als
@@ -0,0 +1,83 @@
+module examples/systems/marksweepgc
+
+/*
+ * Model of mark and sweep garbage collection.
+ */
+
+// a node in the heap
+sig Node {}
+
+sig HeapState {
+ left, right : Node -> lone Node,
+ marked : set Node,
+ freeList : lone Node
+}
+
+pred clearMarks[hs, hs' : HeapState] {
+ // clear marked set
+ no hs'.marked
+ // left and right fields are unchanged
+ hs'.left = hs.left
+ hs'.right = hs.right
+}
+
+/**
+ * simulate the recursion of the mark() function using transitive closure
+ */
+fun reachable[hs: HeapState, n: Node] : set Node {
+ n + n.^(hs.left + hs.right)
+}
+
+pred mark[hs: HeapState, from : Node, hs': HeapState] {
+ hs'.marked = hs.reachable[from]
+ hs'.left = hs.left
+ hs'.right = hs.right
+}
+
+/**
+ * complete hack to simulate behavior of code to set freeList
+ */
+pred setFreeList[hs, hs': HeapState] {
+ // especially hackish
+ hs'.freeList.*(hs'.left) in (Node - hs.marked)
+ all n: Node |
+ (n !in hs.marked) => {
+ no hs'.right[n]
+ hs'.left[n] in (hs'.freeList.*(hs'.left))
+ n in hs'.freeList.*(hs'.left)
+ } else {
+ hs'.left[n] = hs.left[n]
+ hs'.right[n] = hs.right[n]
+ }
+ hs'.marked = hs.marked
+}
+
+pred GC[hs: HeapState, root : Node, hs': HeapState] {
+ some hs1, hs2: HeapState |
+ hs.clearMarks[hs1] && hs1.mark[root, hs2] && hs2.setFreeList[hs']
+}
+
+assert Soundness1 {
+ all h, h' : HeapState, root : Node |
+ h.GC[root, h'] =>
+ (all live : h.reachable[root] | {
+ h'.left[live] = h.left[live]
+ h'.right[live] = h.right[live]
+ })
+}
+
+assert Soundness2 {
+ all h, h' : HeapState, root : Node |
+ h.GC[root, h'] =>
+ no h'.reachable[root] & h'.reachable[h'.freeList]
+}
+
+assert Completeness {
+ all h, h' : HeapState, root : Node |
+ h.GC[root, h'] =>
+ (Node - h'.reachable[root]) in h'.reachable[h'.freeList]
+}
+
+check Soundness1 for 3 expect 0
+check Soundness2 for 3 expect 0
+check Completeness for 3 expect 0
diff --git a/samples/Alloy/views.als b/samples/Alloy/views.als
new file mode 100644
index 00000000..3a5ab82b
--- /dev/null
+++ b/samples/Alloy/views.als
@@ -0,0 +1,217 @@
+module examples/systems/views
+
+/*
+ * Model of views in object-oriented programming.
+ *
+ * Two object references, called the view and the backing,
+ * are related by a view mechanism when changes to the
+ * backing are automatically propagated to the view. Note
+ * that the state of a view need not be a projection of the
+ * state of the backing; the keySet method of Map, for
+ * example, produces two view relationships, and for the
+ * one in which the map is modified by changes to the key
+ * set, the value of the new map cannot be determined from
+ * the key set. Note that in the iterator view mechanism,
+ * the iterator is by this definition the backing object,
+ * since changes are propagated from iterator to collection
+ * and not vice versa. Oddly, a reference may be a view of
+ * more than one backing: there can be two iterators on the
+ * same collection, eg. A reference cannot be a view under
+ * more than one view type.
+ *
+ * A reference is made dirty when it is a backing for a view
+ * with which it is no longer related by the view invariant.
+ * This usually happens when a view is modified, either
+ * directly or via another backing. For example, changing a
+ * collection directly when it has an iterator invalidates
+ * it, as does changing the collection through one iterator
+ * when there are others.
+ *
+ * More work is needed if we want to model more closely the
+ * failure of an iterator when its collection is invalidated.
+ *
+ * As a terminological convention, when there are two
+ * complementary view relationships, we will give them types
+ * t and t'. For example, KeySetView propagates from map to
+ * set, and KeySetView' propagates from set to map.
+ *
+ * author: Daniel Jackson
+ */
+
+open util/ordering[State] as so
+open util/relation as rel
+
+sig Ref {}
+sig Object {}
+
+-- t->b->v in views when v is view of type t of backing b
+-- dirty contains refs that have been invalidated
+sig State {
+ refs: set Ref,
+ obj: refs -> one Object,
+ views: ViewType -> refs -> refs,
+ dirty: set refs
+-- , anyviews: Ref -> Ref -- for visualization
+ }
+-- {anyviews = ViewType.views}
+
+sig Map extends Object {
+ keys: set Ref,
+ map: keys -> one Ref
+ }{all s: State | keys + Ref.map in s.refs}
+sig MapRef extends Ref {}
+fact {State.obj[MapRef] in Map}
+
+sig Iterator extends Object {
+ left, done: set Ref,
+ lastRef: lone done
+ }{all s: State | done + left + lastRef in s.refs}
+sig IteratorRef extends Ref {}
+fact {State.obj[IteratorRef] in Iterator}
+
+sig Set extends Object {
+ elts: set Ref
+ }{all s: State | elts in s.refs}
+sig SetRef extends Ref {}
+fact {State.obj[SetRef] in Set}
+
+abstract sig ViewType {}
+one sig KeySetView, KeySetView', IteratorView extends ViewType {}
+fact ViewTypes {
+ State.views[KeySetView] in MapRef -> SetRef
+ State.views[KeySetView'] in SetRef -> MapRef
+ State.views[IteratorView] in IteratorRef -> SetRef
+ all s: State | s.views[KeySetView] = ~(s.views[KeySetView'])
+ }
+
+/**
+ * mods is refs modified directly or by view mechanism
+ * doesn't handle possibility of modifying an object and its view at once?
+ * should we limit frame conds to non-dirty refs?
+ */
+pred modifies [pre, post: State, rs: set Ref] {
+ let vr = pre.views[ViewType], mods = rs.*vr {
+ all r: pre.refs - mods | pre.obj[r] = post.obj[r]
+ all b: mods, v: pre.refs, t: ViewType |
+ b->v in pre.views[t] => viewFrame [t, pre.obj[v], post.obj[v], post.obj[b]]
+ post.dirty = pre.dirty +
+ {b: pre.refs | some v: Ref, t: ViewType |
+ b->v in pre.views[t] && !viewFrame [t, pre.obj[v], post.obj[v], post.obj[b]]
+ }
+ }
+ }
+
+pred allocates [pre, post: State, rs: set Ref] {
+ no rs & pre.refs
+ post.refs = pre.refs + rs
+ }
+
+/**
+ * models frame condition that limits change to view object from v to v' when backing object changes to b'
+ */
+pred viewFrame [t: ViewType, v, v', b': Object] {
+ t in KeySetView => v'.elts = dom [b'.map]
+ t in KeySetView' => b'.elts = dom [v'.map]
+ t in KeySetView' => (b'.elts) <: (v.map) = (b'.elts) <: (v'.map)
+ t in IteratorView => v'.elts = b'.left + b'.done
+ }
+
+pred MapRef.keySet [pre, post: State, setRefs: SetRef] {
+ post.obj[setRefs].elts = dom [pre.obj[this].map]
+ modifies [pre, post, none]
+ allocates [pre, post, setRefs]
+ post.views = pre.views + KeySetView->this->setRefs + KeySetView'->setRefs->this
+ }
+
+pred MapRef.put [pre, post: State, k, v: Ref] {
+ post.obj[this].map = pre.obj[this].map ++ k->v
+ modifies [pre, post, this]
+ allocates [pre, post, none]
+ post.views = pre.views
+ }
+
+pred SetRef.iterator [pre, post: State, iterRef: IteratorRef] {
+ let i = post.obj[iterRef] {
+ i.left = pre.obj[this].elts
+ no i.done + i.lastRef
+ }
+ modifies [pre,post,none]
+ allocates [pre, post, iterRef]
+ post.views = pre.views + IteratorView->iterRef->this
+ }
+
+pred IteratorRef.remove [pre, post: State] {
+ let i = pre.obj[this], i' = post.obj[this] {
+ i'.left = i.left
+ i'.done = i.done - i.lastRef
+ no i'.lastRef
+ }
+ modifies [pre,post,this]
+ allocates [pre, post, none]
+ pre.views = post.views
+ }
+
+pred IteratorRef.next [pre, post: State, ref: Ref] {
+ let i = pre.obj[this], i' = post.obj[this] {
+ ref in i.left
+ i'.left = i.left - ref
+ i'.done = i.done + ref
+ i'.lastRef = ref
+ }
+ modifies [pre, post, this]
+ allocates [pre, post, none]
+ pre.views = post.views
+ }
+
+pred IteratorRef.hasNext [s: State] {
+ some s.obj[this].left
+ }
+
+assert zippishOK {
+ all
+ ks, vs: SetRef,
+ m: MapRef,
+ ki, vi: IteratorRef,
+ k, v: Ref |
+ let s0=so/first,
+ s1=so/next[s0],
+ s2=so/next[s1],
+ s3=so/next[s2],
+ s4=so/next[s3],
+ s5=so/next[s4],
+ s6=so/next[s5],
+ s7=so/next[s6] |
+ ({
+ precondition [s0, ks, vs, m]
+ no s0.dirty
+ ks.iterator [s0, s1, ki]
+ vs.iterator [s1, s2, vi]
+ ki.hasNext [s2]
+ vi.hasNext [s2]
+ ki.this/next [s2, s3, k]
+ vi.this/next [s3, s4, v]
+ m.put [s4, s5, k, v]
+ ki.remove [s5, s6]
+ vi.remove [s6, s7]
+ } => no State.dirty)
+ }
+
+pred precondition [pre: State, ks, vs, m: Ref] {
+ // all these conditions and other errors discovered in scope of 6 but 8,3
+ // in initial state, must have view invariants hold
+ (all t: ViewType, b, v: pre.refs |
+ b->v in pre.views[t] => viewFrame [t, pre.obj[v], pre.obj[v], pre.obj[b]])
+ // sets are not aliases
+-- ks != vs
+ // sets are not views of map
+-- no (ks+vs)->m & ViewType.pre.views
+ // no iterator currently on either set
+-- no Ref->(ks+vs) & ViewType.pre.views
+ }
+
+check zippishOK for 6 but 8 State, 3 ViewType expect 1
+
+/**
+ * experiment with controlling heap size
+ */
+fact {all s: State | #s.obj < 5}
diff --git a/samples/AsciiDoc/encoding.asciidoc b/samples/AsciiDoc/encoding.asciidoc
new file mode 100644
index 00000000..8cf1b761
--- /dev/null
+++ b/samples/AsciiDoc/encoding.asciidoc
@@ -0,0 +1,13 @@
+Gregory Romé has written an AsciiDoc plugin for the Redmine project management application.
+
+https://github.com/foo-users/foo
+へと `vicmd` キーマップを足してみている試み、
+アニメーションgifです。
+
+tag::romé[]
+Gregory Romé has written an AsciiDoc plugin for the Redmine project management application.
+end::romé[]
+
+== Überschrift
+
+* Codierungen sind verrückt auf älteren Versionen von Ruby
\ No newline at end of file
diff --git a/samples/AsciiDoc/list.asc b/samples/AsciiDoc/list.asc
new file mode 100644
index 00000000..066d14fc
--- /dev/null
+++ b/samples/AsciiDoc/list.asc
@@ -0,0 +1,10 @@
+AsciiDoc Home Page
+==================
+
+Example Articles
+~~~~~~~~~~~~~~~~
+- Item 1
+
+- Item 2
+
+- Item 3
diff --git a/samples/AsciiDoc/sample.adoc b/samples/AsciiDoc/sample.adoc
new file mode 100644
index 00000000..51e1e45e
--- /dev/null
+++ b/samples/AsciiDoc/sample.adoc
@@ -0,0 +1,25 @@
+Document Title
+==============
+Doc Writer
+:idprefix: id_
+
+Preamble paragraph.
+
+NOTE: This is test, only a test.
+
+== Section A
+
+*Section A* paragraph.
+
+=== Section A Subsection
+
+*Section A* 'subsection' paragraph.
+
+== Section B
+
+*Section B* paragraph.
+
+.Section B list
+* Item 1
+* Item 2
+* Item 3
diff --git a/samples/AspectJ/CacheAspect.aj b/samples/AspectJ/CacheAspect.aj
new file mode 100644
index 00000000..bfab7bc4
--- /dev/null
+++ b/samples/AspectJ/CacheAspect.aj
@@ -0,0 +1,41 @@
+package com.blogspot.miguelinlas3.aspectj.cache;
+
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import org.aspectj.lang.JoinPoint;
+
+import com.blogspot.miguelinlas3.aspectj.cache.marker.Cachable;
+
+/**
+ * This simple aspect simulates the behaviour of a very simple cache
+ *
+ * @author migue
+ *
+ */
+public aspect CacheAspect {
+
+ public pointcut cache(Cachable cachable): execution(@Cachable * * (..)) && @annotation(cachable);
+
+ Object around(Cachable cachable): cache(cachable){
+
+ String evaluatedKey = this.evaluateKey(cachable.scriptKey(), thisJoinPoint);
+
+ if(cache.containsKey(evaluatedKey)){
+ System.out.println("Cache hit for key " + evaluatedKey);
+ return this.cache.get(evaluatedKey);
+ }
+
+ System.out.println("Cache miss for key " + evaluatedKey);
+ Object value = proceed(cachable);
+ cache.put(evaluatedKey, value);
+ return value;
+ }
+
+ protected String evaluateKey(String key, JoinPoint joinPoint) {
+ // TODO add some smart staff to allow simple scripting in @Cachable annotation
+ return key;
+ }
+
+ protected Map cache = new WeakHashMap();
+}
diff --git a/samples/AspectJ/OptimizeRecursionCache.aj b/samples/AspectJ/OptimizeRecursionCache.aj
new file mode 100644
index 00000000..ed1e8695
--- /dev/null
+++ b/samples/AspectJ/OptimizeRecursionCache.aj
@@ -0,0 +1,50 @@
+package aspects.caching;
+
+import java.util.Map;
+
+/**
+ * Cache aspect for optimize recursive functions.
+ *
+ * @author Migueli
+ * @date 05/11/2013
+ * @version 1.0
+ *
+ */
+public abstract aspect OptimizeRecursionCache {
+
+ @SuppressWarnings("rawtypes")
+ private Map _cache;
+
+ public OptimizeRecursionCache() {
+ _cache = getCache();
+ }
+
+ @SuppressWarnings("rawtypes")
+ abstract public Map getCache();
+
+ abstract public pointcut operation(Object o);
+
+ pointcut topLevelOperation(Object o): operation(o) && !cflowbelow(operation(Object));
+
+ before(Object o) : topLevelOperation(o) {
+ System.out.println("Seeking value for " + o);
+ }
+
+ Object around(Object o) : operation(o) {
+ Object cachedValue = _cache.get(o);
+ if (cachedValue != null) {
+ System.out.println("Found cached value for " + o + ": " + cachedValue);
+ return cachedValue;
+ }
+ return proceed(o);
+ }
+
+ @SuppressWarnings("unchecked")
+ after(Object o) returning(Object result) : topLevelOperation(o) {
+ _cache.put(o, result);
+ }
+
+ after(Object o) returning(Object result) : topLevelOperation(o) {
+ System.out.println("cache size: " + _cache.size());
+ }
+}
diff --git a/samples/Assembly/ASSEMBLE.inc b/samples/Assembly/ASSEMBLE.inc
new file mode 100644
index 00000000..c4ffdae3
--- /dev/null
+++ b/samples/Assembly/ASSEMBLE.inc
@@ -0,0 +1,2048 @@
+
+; flat assembler core
+; Copyright (c) 1999-2014, Tomasz Grysztar.
+; All rights reserved.
+
+assembler:
+ xor eax,eax
+ mov [stub_size],eax
+ mov [current_pass],ax
+ mov [resolver_flags],eax
+ mov [number_of_sections],eax
+ mov [actual_fixups_size],eax
+ assembler_loop:
+ mov eax,[labels_list]
+ mov [tagged_blocks],eax
+ mov eax,[additional_memory]
+ mov [free_additional_memory],eax
+ mov eax,[additional_memory_end]
+ mov [structures_buffer],eax
+ mov esi,[source_start]
+ mov edi,[code_start]
+ xor eax,eax
+ mov dword [adjustment],eax
+ mov dword [adjustment+4],eax
+ mov [addressing_space],eax
+ mov [error_line],eax
+ mov [counter],eax
+ mov [format_flags],eax
+ mov [number_of_relocations],eax
+ mov [undefined_data_end],eax
+ mov [file_extension],eax
+ mov [next_pass_needed],al
+ mov [output_format],al
+ mov [adjustment_sign],al
+ mov [code_type],16
+ call init_addressing_space
+ pass_loop:
+ call assemble_line
+ jnc pass_loop
+ mov eax,[additional_memory_end]
+ cmp eax,[structures_buffer]
+ je pass_done
+ sub eax,18h
+ mov eax,[eax+4]
+ mov [current_line],eax
+ jmp missing_end_directive
+ pass_done:
+ call close_pass
+ mov eax,[labels_list]
+ check_symbols:
+ cmp eax,[memory_end]
+ jae symbols_checked
+ test byte [eax+8],8
+ jz symbol_defined_ok
+ mov cx,[current_pass]
+ cmp cx,[eax+18]
+ jne symbol_defined_ok
+ test byte [eax+8],1
+ jz symbol_defined_ok
+ sub cx,[eax+16]
+ cmp cx,1
+ jne symbol_defined_ok
+ and byte [eax+8],not 1
+ or [next_pass_needed],-1
+ symbol_defined_ok:
+ test byte [eax+8],10h
+ jz use_prediction_ok
+ mov cx,[current_pass]
+ and byte [eax+8],not 10h
+ test byte [eax+8],20h
+ jnz check_use_prediction
+ cmp cx,[eax+18]
+ jne use_prediction_ok
+ test byte [eax+8],8
+ jz use_prediction_ok
+ jmp use_misprediction
+ check_use_prediction:
+ test byte [eax+8],8
+ jz use_misprediction
+ cmp cx,[eax+18]
+ je use_prediction_ok
+ use_misprediction:
+ or [next_pass_needed],-1
+ use_prediction_ok:
+ test byte [eax+8],40h
+ jz check_next_symbol
+ and byte [eax+8],not 40h
+ test byte [eax+8],4
+ jnz define_misprediction
+ mov cx,[current_pass]
+ test byte [eax+8],80h
+ jnz check_define_prediction
+ cmp cx,[eax+16]
+ jne check_next_symbol
+ test byte [eax+8],1
+ jz check_next_symbol
+ jmp define_misprediction
+ check_define_prediction:
+ test byte [eax+8],1
+ jz define_misprediction
+ cmp cx,[eax+16]
+ je check_next_symbol
+ define_misprediction:
+ or [next_pass_needed],-1
+ check_next_symbol:
+ add eax,LABEL_STRUCTURE_SIZE
+ jmp check_symbols
+ symbols_checked:
+ cmp [next_pass_needed],0
+ jne next_pass
+ mov eax,[error_line]
+ or eax,eax
+ jz assemble_ok
+ mov [current_line],eax
+ cmp [error],undefined_symbol
+ jne error_confirmed
+ mov eax,[error_info]
+ or eax,eax
+ jz error_confirmed
+ test byte [eax+8],1
+ jnz next_pass
+ error_confirmed:
+ call error_handler
+ error_handler:
+ mov eax,[error]
+ sub eax,error_handler
+ add [esp],eax
+ ret
+ next_pass:
+ inc [current_pass]
+ mov ax,[current_pass]
+ cmp ax,[passes_limit]
+ je code_cannot_be_generated
+ jmp assembler_loop
+ assemble_ok:
+ ret
+
+create_addressing_space:
+ mov ebx,[addressing_space]
+ test ebx,ebx
+ jz init_addressing_space
+ test byte [ebx+0Ah],1
+ jnz illegal_instruction
+ mov eax,edi
+ sub eax,[ebx+18h]
+ mov [ebx+1Ch],eax
+ init_addressing_space:
+ mov ebx,[tagged_blocks]
+ mov dword [ebx-4],10h
+ mov dword [ebx-8],20h
+ sub ebx,8+20h
+ cmp ebx,edi
+ jbe out_of_memory
+ mov [tagged_blocks],ebx
+ mov [addressing_space],ebx
+ xor eax,eax
+ mov [ebx],edi
+ mov [ebx+4],eax
+ mov [ebx+8],eax
+ mov [ebx+10h],eax
+ mov [ebx+14h],eax
+ mov [ebx+18h],edi
+ mov [ebx+1Ch],eax
+ ret
+
+assemble_line:
+ mov eax,[tagged_blocks]
+ sub eax,100h
+ cmp edi,eax
+ ja out_of_memory
+ lods byte [esi]
+ cmp al,1
+ je assemble_instruction
+ jb source_end
+ cmp al,3
+ jb define_label
+ je define_constant
+ cmp al,4
+ je label_addressing_space
+ cmp al,0Fh
+ je new_line
+ cmp al,13h
+ je code_type_setting
+ cmp al,10h
+ jne illegal_instruction
+ lods byte [esi]
+ jmp segment_prefix
+ code_type_setting:
+ lods byte [esi]
+ mov [code_type],al
+ jmp instruction_assembled
+ new_line:
+ lods dword [esi]
+ mov [current_line],eax
+ mov [prefixed_instruction],0
+ cmp [symbols_file],0
+ je continue_line
+ cmp [next_pass_needed],0
+ jne continue_line
+ mov ebx,[tagged_blocks]
+ mov dword [ebx-4],1
+ mov dword [ebx-8],14h
+ sub ebx,8+14h
+ cmp ebx,edi
+ jbe out_of_memory
+ mov [tagged_blocks],ebx
+ mov [ebx],eax
+ mov [ebx+4],edi
+ mov eax,[addressing_space]
+ mov [ebx+8],eax
+ mov al,[code_type]
+ mov [ebx+10h],al
+ continue_line:
+ cmp byte [esi],0Fh
+ je line_assembled
+ jmp assemble_line
+ define_label:
+ lods dword [esi]
+ cmp eax,0Fh
+ jb invalid_use_of_symbol
+ je reserved_word_used_as_symbol
+ mov ebx,eax
+ lods byte [esi]
+ mov [label_size],al
+ call make_label
+ jmp continue_line
+ make_label:
+ mov eax,edi
+ xor edx,edx
+ xor cl,cl
+ mov ebp,[addressing_space]
+ sub eax,[ds:ebp]
+ sbb edx,[ds:ebp+4]
+ sbb cl,[ds:ebp+8]
+ jp label_value_ok
+ call recoverable_overflow
+ label_value_ok:
+ mov [address_sign],cl
+ test byte [ds:ebp+0Ah],1
+ jnz make_virtual_label
+ or byte [ebx+9],1
+ xchg eax,[ebx]
+ xchg edx,[ebx+4]
+ mov ch,[ebx+9]
+ shr ch,1
+ and ch,1
+ neg ch
+ sub eax,[ebx]
+ sbb edx,[ebx+4]
+ sbb ch,cl
+ mov dword [adjustment],eax
+ mov dword [adjustment+4],edx
+ mov [adjustment_sign],ch
+ or al,ch
+ or eax,edx
+ setnz ah
+ jmp finish_label
+ make_virtual_label:
+ and byte [ebx+9],not 1
+ cmp eax,[ebx]
+ mov [ebx],eax
+ setne ah
+ cmp edx,[ebx+4]
+ mov [ebx+4],edx
+ setne al
+ or ah,al
+ finish_label:
+ mov ebp,[addressing_space]
+ mov ch,[ds:ebp+9]
+ mov cl,[label_size]
+ mov edx,[ds:ebp+14h]
+ mov ebp,[ds:ebp+10h]
+ finish_label_symbol:
+ mov al,[address_sign]
+ xor al,[ebx+9]
+ and al,10b
+ or ah,al
+ xor [ebx+9],al
+ cmp cl,[ebx+10]
+ mov [ebx+10],cl
+ setne al
+ or ah,al
+ cmp ch,[ebx+11]
+ mov [ebx+11],ch
+ setne al
+ or ah,al
+ cmp ebp,[ebx+12]
+ mov [ebx+12],ebp
+ setne al
+ or ah,al
+ or ch,ch
+ jz label_symbol_ok
+ cmp edx,[ebx+20]
+ mov [ebx+20],edx
+ setne al
+ or ah,al
+ label_symbol_ok:
+ mov cx,[current_pass]
+ xchg [ebx+16],cx
+ mov edx,[current_line]
+ mov [ebx+28],edx
+ and byte [ebx+8],not 2
+ test byte [ebx+8],1
+ jz new_label
+ cmp cx,[ebx+16]
+ je symbol_already_defined
+ btr dword [ebx+8],10
+ jc requalified_label
+ inc cx
+ sub cx,[ebx+16]
+ setnz al
+ or ah,al
+ jz label_made
+ test byte [ebx+8],8
+ jz label_made
+ mov cx,[current_pass]
+ cmp cx,[ebx+18]
+ jne label_made
+ requalified_label:
+ or [next_pass_needed],-1
+ label_made:
+ ret
+ new_label:
+ or byte [ebx+8],1
+ ret
+ define_constant:
+ lods dword [esi]
+ inc esi
+ cmp eax,0Fh
+ jb invalid_use_of_symbol
+ je reserved_word_used_as_symbol
+ mov edx,[eax+8]
+ push edx
+ cmp [current_pass],0
+ je get_constant_value
+ test dl,4
+ jnz get_constant_value
+ mov cx,[current_pass]
+ cmp cx,[eax+16]
+ je get_constant_value
+ or dl,4
+ mov [eax+8],dl
+ get_constant_value:
+ push eax
+ mov al,byte [esi-1]
+ push eax
+ or [size_override],-1
+ call get_value
+ pop ebx
+ mov ch,bl
+ pop ebx
+ pop ecx
+ test cl,4
+ jnz constant_referencing_mode_ok
+ and byte [ebx+8],not 4
+ constant_referencing_mode_ok:
+ xor cl,cl
+ mov ch,[value_type]
+ cmp ch,3
+ je invalid_use_of_symbol
+ make_constant:
+ and byte [ebx+9],not 1
+ cmp eax,[ebx]
+ mov [ebx],eax
+ setne ah
+ cmp edx,[ebx+4]
+ mov [ebx+4],edx
+ setne al
+ or ah,al
+ mov al,[value_sign]
+ xor al,[ebx+9]
+ and al,10b
+ or ah,al
+ xor [ebx+9],al
+ cmp cl,[ebx+10]
+ mov [ebx+10],cl
+ setne al
+ or ah,al
+ cmp ch,[ebx+11]
+ mov [ebx+11],ch
+ setne al
+ or ah,al
+ xor edx,edx
+ cmp edx,[ebx+12]
+ mov [ebx+12],edx
+ setne al
+ or ah,al
+ or ch,ch
+ jz constant_symbol_ok
+ mov edx,[symbol_identifier]
+ cmp edx,[ebx+20]
+ mov [ebx+20],edx
+ setne al
+ or ah,al
+ constant_symbol_ok:
+ mov cx,[current_pass]
+ xchg [ebx+16],cx
+ mov edx,[current_line]
+ mov [ebx+28],edx
+ test byte [ebx+8],1
+ jz new_constant
+ cmp cx,[ebx+16]
+ jne redeclare_constant
+ test byte [ebx+8],2
+ jz symbol_already_defined
+ or byte [ebx+8],4
+ and byte [ebx+9],not 4
+ jmp instruction_assembled
+ redeclare_constant:
+ btr dword [ebx+8],10
+ jc requalified_constant
+ inc cx
+ sub cx,[ebx+16]
+ setnz al
+ or ah,al
+ jz instruction_assembled
+ test byte [ebx+8],4
+ jnz instruction_assembled
+ test byte [ebx+8],8
+ jz instruction_assembled
+ mov cx,[current_pass]
+ cmp cx,[ebx+18]
+ jne instruction_assembled
+ requalified_constant:
+ or [next_pass_needed],-1
+ jmp instruction_assembled
+ new_constant:
+ or byte [ebx+8],1+2
+ jmp instruction_assembled
+ label_addressing_space:
+ lods dword [esi]
+ cmp eax,0Fh
+ jb invalid_use_of_symbol
+ je reserved_word_used_as_symbol
+ mov cx,[current_pass]
+ test byte [eax+8],1
+ jz make_addressing_space_label
+ cmp cx,[eax+16]
+ je symbol_already_defined
+ test byte [eax+9],4
+ jnz make_addressing_space_label
+ or [next_pass_needed],-1
+ make_addressing_space_label:
+ mov dx,[eax+8]
+ and dx,not (2 or 100h)
+ or dx,1 or 4 or 400h
+ mov [eax+8],dx
+ mov [eax+16],cx
+ mov edx,[current_line]
+ mov [eax+28],edx
+ mov ebx,[addressing_space]
+ mov [eax],ebx
+ or byte [ebx+0Ah],2
+ jmp continue_line
+ assemble_instruction:
+; mov [operand_size],0
+; mov [size_override],0
+; mov [operand_prefix],0
+; mov [opcode_prefix],0
+ and dword [operand_size],0
+; mov [rex_prefix],0
+; mov [vex_required],0
+; mov [vex_register],0
+; mov [immediate_size],0
+ and dword [rex_prefix],0
+ call instruction_handler
+ instruction_handler:
+ movzx ebx,word [esi]
+ mov al,[esi+2]
+ add esi,3
+ add [esp],ebx
+ ret
+ instruction_assembled:
+ mov al,[esi]
+ cmp al,0Fh
+ je line_assembled
+ or al,al
+ jnz extra_characters_on_line
+ line_assembled:
+ clc
+ ret
+ source_end:
+ dec esi
+ stc
+ ret
+
+org_directive:
+ lods byte [esi]
+ cmp al,'('
+ jne invalid_argument
+ cmp byte [esi],'.'
+ je invalid_value
+ call get_qword_value
+ mov cl,[value_type]
+ test cl,1
+ jnz invalid_use_of_symbol
+ push eax
+ mov ebx,[addressing_space]
+ mov eax,edi
+ sub eax,[ebx+18h]
+ mov [ebx+1Ch],eax
+ test byte [ebx+0Ah],1
+ jnz in_virtual
+ call init_addressing_space
+ jmp org_space_ok
+ in_virtual:
+ call close_virtual_addressing_space
+ call init_addressing_space
+ or byte [ebx+0Ah],1
+ org_space_ok:
+ pop eax
+ mov [ebx+9],cl
+ mov cl,[value_sign]
+ sub [ebx],eax
+ sbb [ebx+4],edx
+ sbb byte [ebx+8],cl
+ jp org_value_ok
+ call recoverable_overflow
+ org_value_ok:
+ mov edx,[symbol_identifier]
+ mov [ebx+14h],edx
+ cmp [output_format],1
+ ja instruction_assembled
+ cmp edi,[code_start]
+ jne instruction_assembled
+ cmp eax,100h
+ jne instruction_assembled
+ bts [format_flags],0
+ jmp instruction_assembled
+label_directive:
+ lods byte [esi]
+ cmp al,2
+ jne invalid_argument
+ lods dword [esi]
+ cmp eax,0Fh
+ jb invalid_use_of_symbol
+ je reserved_word_used_as_symbol
+ inc esi
+ mov ebx,eax
+ mov [label_size],0
+ lods byte [esi]
+ cmp al,':'
+ je get_label_size
+ dec esi
+ cmp al,11h
+ jne label_size_ok
+ get_label_size:
+ lods word [esi]
+ cmp al,11h
+ jne invalid_argument
+ mov [label_size],ah
+ label_size_ok:
+ cmp byte [esi],80h
+ je get_free_label_value
+ call make_label
+ jmp instruction_assembled
+ get_free_label_value:
+ inc esi
+ lods byte [esi]
+ cmp al,'('
+ jne invalid_argument
+ push ebx ecx
+ or byte [ebx+8],4
+ cmp byte [esi],'.'
+ je invalid_value
+ call get_address_value
+ or bh,bh
+ setnz ch
+ xchg ch,cl
+ mov bp,cx
+ shl ebp,16
+ xchg bl,bh
+ mov bp,bx
+ pop ecx ebx
+ and byte [ebx+8],not 4
+ mov ch,[value_type]
+ test ch,1
+ jnz invalid_use_of_symbol
+ make_free_label:
+ and byte [ebx+9],not 1
+ cmp eax,[ebx]
+ mov [ebx],eax
+ setne ah
+ cmp edx,[ebx+4]
+ mov [ebx+4],edx
+ setne al
+ or ah,al
+ mov edx,[address_symbol]
+ mov cl,[label_size]
+ call finish_label_symbol
+ jmp instruction_assembled
+load_directive:
+ lods byte [esi]
+ cmp al,2
+ jne invalid_argument
+ lods dword [esi]
+ cmp eax,0Fh
+ jb invalid_use_of_symbol
+ je reserved_word_used_as_symbol
+ inc esi
+ push eax
+ mov al,1
+ cmp byte [esi],11h
+ jne load_size_ok
+ lods byte [esi]
+ lods byte [esi]
+ load_size_ok:
+ cmp al,8
+ ja invalid_value
+ mov [operand_size],al
+ and dword [value],0
+ and dword [value+4],0
+ lods byte [esi]
+ cmp al,82h
+ jne invalid_argument
+ call get_data_point
+ jc value_loaded
+ push esi edi
+ mov esi,ebx
+ mov edi,value
+ rep movs byte [edi],[esi]
+ pop edi esi
+ value_loaded:
+ mov [value_sign],0
+ mov eax,dword [value]
+ mov edx,dword [value+4]
+ pop ebx
+ xor cx,cx
+ jmp make_constant
+ get_data_point:
+ mov ebx,[addressing_space]
+ mov ecx,edi
+ sub ecx,[ebx+18h]
+ mov [ebx+1Ch],ecx
+ lods byte [esi]
+ cmp al,'('
+ jne invalid_argument
+ cmp byte [esi],11h
+ jne get_data_address
+ cmp word [esi+1+4],'):'
+ jne get_data_address
+ inc esi
+ lods dword [esi]
+ add esi,2
+ cmp byte [esi],'('
+ jne invalid_argument
+ inc esi
+ cmp eax,0Fh
+ jbe reserved_word_used_as_symbol
+ mov edx,undefined_symbol
+ test byte [eax+8],1
+ jz addressing_space_unavailable
+ mov edx,symbol_out_of_scope
+ mov cx,[eax+16]
+ cmp cx,[current_pass]
+ jne addressing_space_unavailable
+ test byte [eax+9],4
+ jz invalid_use_of_symbol
+ mov ebx,eax
+ mov ax,[current_pass]
+ mov [ebx+18],ax
+ or byte [ebx+8],8
+ cmp [symbols_file],0
+ je get_addressing_space
+ cmp [next_pass_needed],0
+ jne get_addressing_space
+ call store_label_reference
+ get_addressing_space:
+ mov ebx,[ebx]
+ get_data_address:
+ push ebx
+ cmp byte [esi],'.'
+ je invalid_value
+ or [size_override],-1
+ call get_address_value
+ pop ebp
+ call calculate_relative_offset
+ cmp [next_pass_needed],0
+ jne data_address_type_ok
+ cmp [value_type],0
+ jne invalid_use_of_symbol
+ data_address_type_ok:
+ mov ebx,edi
+ xor ecx,ecx
+ add ebx,eax
+ adc edx,ecx
+ mov eax,ebx
+ sub eax,[ds:ebp+18h]
+ sbb edx,ecx
+ jnz bad_data_address
+ mov cl,[operand_size]
+ add eax,ecx
+ cmp eax,[ds:ebp+1Ch]
+ ja bad_data_address
+ clc
+ ret
+ addressing_space_unavailable:
+ cmp [error_line],0
+ jne get_data_address
+ push [current_line]
+ pop [error_line]
+ mov [error],edx
+ mov [error_info],eax
+ jmp get_data_address
+ bad_data_address:
+ call recoverable_overflow
+ stc
+ ret
+store_directive:
+ cmp byte [esi],11h
+ je sized_store
+ lods byte [esi]
+ cmp al,'('
+ jne invalid_argument
+ call get_byte_value
+ xor edx,edx
+ movzx eax,al
+ mov [operand_size],1
+ jmp store_value_ok
+ sized_store:
+ or [size_override],-1
+ call get_value
+ store_value_ok:
+ cmp [value_type],0
+ jne invalid_use_of_symbol
+ mov dword [value],eax
+ mov dword [value+4],edx
+ lods byte [esi]
+ cmp al,80h
+ jne invalid_argument
+ call get_data_point
+ jc instruction_assembled
+ push esi edi
+ mov esi,value
+ mov edi,ebx
+ rep movs byte [edi],[esi]
+ mov eax,edi
+ pop edi esi
+ cmp ebx,[undefined_data_end]
+ jae instruction_assembled
+ cmp eax,[undefined_data_start]
+ jbe instruction_assembled
+ mov [undefined_data_start],eax
+ jmp instruction_assembled
+
+display_directive:
+ lods byte [esi]
+ cmp al,'('
+ jne invalid_argument
+ cmp byte [esi],0
+ jne display_byte
+ inc esi
+ lods dword [esi]
+ mov ecx,eax
+ push edi
+ mov edi,[tagged_blocks]
+ sub edi,8
+ sub edi,eax
+ cmp edi,[esp]
+ jbe out_of_memory
+ mov [tagged_blocks],edi
+ rep movs byte [edi],[esi]
+ stos dword [edi]
+ xor eax,eax
+ stos dword [edi]
+ pop edi
+ inc esi
+ jmp display_next
+ display_byte:
+ call get_byte_value
+ push edi
+ mov edi,[tagged_blocks]
+ sub edi,8+1
+ mov [tagged_blocks],edi
+ stos byte [edi]
+ mov eax,1
+ stos dword [edi]
+ dec eax
+ stos dword [edi]
+ pop edi
+ display_next:
+ cmp edi,[tagged_blocks]
+ ja out_of_memory
+ lods byte [esi]
+ cmp al,','
+ je display_directive
+ dec esi
+ jmp instruction_assembled
+show_display_buffer:
+ mov eax,[tagged_blocks]
+ or eax,eax
+ jz display_done
+ mov esi,[labels_list]
+ cmp esi,eax
+ je display_done
+ display_messages:
+ sub esi,8
+ mov eax,[esi+4]
+ mov ecx,[esi]
+ sub esi,ecx
+ test eax,eax
+ jnz skip_block
+ push esi
+ call display_block
+ pop esi
+ skip_block:
+ cmp esi,[tagged_blocks]
+ jne display_messages
+ display_done:
+ ret
+
+times_directive:
+ lods byte [esi]
+ cmp al,'('
+ jne invalid_argument
+ cmp byte [esi],'.'
+ je invalid_value
+ call get_count_value
+ cmp eax,0
+ je zero_times
+ cmp byte [esi],':'
+ jne times_argument_ok
+ inc esi
+ times_argument_ok:
+ push [counter]
+ push [counter_limit]
+ mov [counter_limit],eax
+ mov [counter],1
+ times_loop:
+ mov eax,esp
+ sub eax,100h
+ jc stack_overflow
+ cmp eax,[stack_limit]
+ jb stack_overflow
+ push esi
+ or [prefixed_instruction],-1
+ call continue_line
+ mov eax,[counter_limit]
+ cmp [counter],eax
+ je times_done
+ inc [counter]
+ pop esi
+ jmp times_loop
+ times_done:
+ pop eax
+ pop [counter_limit]
+ pop [counter]
+ jmp instruction_assembled
+ zero_times:
+ call skip_symbol
+ jnc zero_times
+ jmp instruction_assembled
+
+virtual_directive:
+ lods byte [esi]
+ cmp al,80h
+ jne virtual_at_current
+ lods byte [esi]
+ cmp al,'('
+ jne invalid_argument
+ cmp byte [esi],'.'
+ je invalid_value
+ call get_address_value
+ mov ebp,[address_symbol]
+ or bh,bh
+ setnz ch
+ jmp set_virtual
+ virtual_at_current:
+ dec esi
+ mov ebp,[addressing_space]
+ mov al,[ds:ebp+9]
+ mov [value_type],al
+ mov eax,edi
+ xor edx,edx
+ xor cl,cl
+ sub eax,[ds:ebp]
+ sbb edx,[ds:ebp+4]
+ sbb cl,[ds:ebp+8]
+ mov [address_sign],cl
+ mov bx,[ds:ebp+10h]
+ mov cx,[ds:ebp+10h+2]
+ xchg bh,bl
+ xchg ch,cl
+ mov ebp,[ds:ebp+14h]
+ set_virtual:
+ xchg bl,bh
+ xchg cl,ch
+ shl ecx,16
+ mov cx,bx
+ push ecx eax
+ call allocate_structure_data
+ mov word [ebx],virtual_directive-instruction_handler
+ mov ecx,[addressing_space]
+ mov [ebx+12],ecx
+ mov [ebx+8],edi
+ mov ecx,[current_line]
+ mov [ebx+4],ecx
+ mov ebx,[addressing_space]
+ mov eax,edi
+ sub eax,[ebx+18h]
+ mov [ebx+1Ch],eax
+ call init_addressing_space
+ or byte [ebx+0Ah],1
+ pop eax
+ mov cl,[address_sign]
+ not eax
+ not edx
+ not cl
+ add eax,1
+ adc edx,0
+ adc cl,0
+ add eax,edi
+ adc edx,0
+ adc cl,0
+ mov [ebx],eax
+ mov [ebx+4],edx
+ mov [ebx+8],cl
+ pop dword [ebx+10h]
+ mov [ebx+14h],ebp
+ mov al,[value_type]
+ test al,1
+ jnz invalid_use_of_symbol
+ mov [ebx+9],al
+ jmp instruction_assembled
+ allocate_structure_data:
+ mov ebx,[structures_buffer]
+ sub ebx,18h
+ cmp ebx,[free_additional_memory]
+ jb out_of_memory
+ mov [structures_buffer],ebx
+ ret
+ find_structure_data:
+ mov ebx,[structures_buffer]
+ scan_structures:
+ cmp ebx,[additional_memory_end]
+ je no_such_structure
+ cmp ax,[ebx]
+ je structure_data_found
+ add ebx,18h
+ jmp scan_structures
+ structure_data_found:
+ ret
+ no_such_structure:
+ stc
+ ret
+ end_virtual:
+ call find_structure_data
+ jc unexpected_instruction
+ push ebx
+ call close_virtual_addressing_space
+ pop ebx
+ mov eax,[ebx+12]
+ mov [addressing_space],eax
+ mov edi,[ebx+8]
+ remove_structure_data:
+ push esi edi
+ mov ecx,ebx
+ sub ecx,[structures_buffer]
+ shr ecx,2
+ lea esi,[ebx-4]
+ lea edi,[esi+18h]
+ std
+ rep movs dword [edi],[esi]
+ cld
+ add [structures_buffer],18h
+ pop edi esi
+ ret
+ close_virtual_addressing_space:
+ mov ebx,[addressing_space]
+ mov eax,edi
+ sub eax,[ebx+18h]
+ mov [ebx+1Ch],eax
+ test byte [ebx+0Ah],2
+ jz addressing_space_closed
+ push esi edi ecx edx
+ mov ecx,eax
+ mov eax,[tagged_blocks]
+ mov dword [eax-4],11h
+ mov dword [eax-8],ecx
+ sub eax,8
+ sub eax,ecx
+ mov [tagged_blocks],eax
+ lea edi,[eax+ecx-1]
+ xchg eax,[ebx+18h]
+ lea esi,[eax+ecx-1]
+ mov eax,edi
+ sub eax,esi
+ std
+ shr ecx,1
+ jnc virtual_byte_ok
+ movs byte [edi],[esi]
+ virtual_byte_ok:
+ dec esi
+ dec edi
+ shr ecx,1
+ jnc virtual_word_ok
+ movs word [edi],[esi]
+ virtual_word_ok:
+ sub esi,2
+ sub edi,2
+ rep movs dword [edi],[esi]
+ cld
+ xor edx,edx
+ add [ebx],eax
+ adc dword [ebx+4],edx
+ adc byte [ebx+8],dl
+ pop edx ecx edi esi
+ addressing_space_closed:
+ ret
+repeat_directive:
+ cmp [prefixed_instruction],0
+ jne unexpected_instruction
+ lods byte [esi]
+ cmp al,'('
+ jne invalid_argument
+ cmp byte [esi],'.'
+ je invalid_value
+ call get_count_value
+ cmp eax,0
+ je zero_repeat
+ call allocate_structure_data
+ mov word [ebx],repeat_directive-instruction_handler
+ xchg eax,[counter_limit]
+ mov [ebx+10h],eax
+ mov eax,1
+ xchg eax,[counter]
+ mov [ebx+14h],eax
+ mov [ebx+8],esi
+ mov eax,[current_line]
+ mov [ebx+4],eax
+ jmp instruction_assembled
+ end_repeat:
+ cmp [prefixed_instruction],0
+ jne unexpected_instruction
+ call find_structure_data
+ jc unexpected_instruction
+ mov eax,[counter_limit]
+ inc [counter]
+ cmp [counter],eax
+ jbe continue_repeating
+ stop_repeat:
+ mov eax,[ebx+10h]
+ mov [counter_limit],eax
+ mov eax,[ebx+14h]
+ mov [counter],eax
+ call remove_structure_data
+ jmp instruction_assembled
+ continue_repeating:
+ mov esi,[ebx+8]
+ jmp instruction_assembled
+ zero_repeat:
+ mov al,[esi]
+ or al,al
+ jz missing_end_directive
+ cmp al,0Fh
+ jne extra_characters_on_line
+ call find_end_repeat
+ jmp instruction_assembled
+ find_end_repeat:
+ call find_structure_end
+ cmp ax,repeat_directive-instruction_handler
+ jne unexpected_instruction
+ ret
+while_directive:
+ cmp [prefixed_instruction],0
+ jne unexpected_instruction
+ call allocate_structure_data
+ mov word [ebx],while_directive-instruction_handler
+ mov eax,1
+ xchg eax,[counter]
+ mov [ebx+10h],eax
+ mov [ebx+8],esi
+ mov eax,[current_line]
+ mov [ebx+4],eax
+ do_while:
+ push ebx
+ call calculate_logical_expression
+ or al,al
+ jnz while_true
+ mov al,[esi]
+ or al,al
+ jz missing_end_directive
+ cmp al,0Fh
+ jne extra_characters_on_line
+ stop_while:
+ call find_end_while
+ pop ebx
+ mov eax,[ebx+10h]
+ mov [counter],eax
+ call remove_structure_data
+ jmp instruction_assembled
+ while_true:
+ pop ebx
+ jmp instruction_assembled
+ end_while:
+ cmp [prefixed_instruction],0
+ jne unexpected_instruction
+ call find_structure_data
+ jc unexpected_instruction
+ mov eax,[ebx+4]
+ mov [current_line],eax
+ inc [counter]
+ jz too_many_repeats
+ mov esi,[ebx+8]
+ jmp do_while
+ find_end_while:
+ call find_structure_end
+ cmp ax,while_directive-instruction_handler
+ jne unexpected_instruction
+ ret
+if_directive:
+ cmp [prefixed_instruction],0
+ jne unexpected_instruction
+ call calculate_logical_expression
+ mov dl,al
+ mov al,[esi]
+ or al,al
+ jz missing_end_directive
+ cmp al,0Fh
+ jne extra_characters_on_line
+ or dl,dl
+ jnz if_true
+ call find_else
+ jc instruction_assembled
+ mov al,[esi]
+ cmp al,1
+ jne else_true
+ cmp word [esi+1],if_directive-instruction_handler
+ jne else_true
+ add esi,4
+ jmp if_directive
+ if_true:
+ xor al,al
+ make_if_structure:
+ call allocate_structure_data
+ mov word [ebx],if_directive-instruction_handler
+ mov byte [ebx+2],al
+ mov eax,[current_line]
+ mov [ebx+4],eax
+ jmp instruction_assembled
+ else_true:
+ or al,al
+ jz missing_end_directive
+ cmp al,0Fh
+ jne extra_characters_on_line
+ or al,-1
+ jmp make_if_structure
+ else_directive:
+ cmp [prefixed_instruction],0
+ jne unexpected_instruction
+ mov ax,if_directive-instruction_handler
+ call find_structure_data
+ jc unexpected_instruction
+ cmp byte [ebx+2],0
+ jne unexpected_instruction
+ found_else:
+ mov al,[esi]
+ cmp al,1
+ jne skip_else
+ cmp word [esi+1],if_directive-instruction_handler
+ jne skip_else
+ add esi,4
+ call find_else
+ jnc found_else
+ call remove_structure_data
+ jmp instruction_assembled
+ skip_else:
+ or al,al
+ jz missing_end_directive
+ cmp al,0Fh
+ jne extra_characters_on_line
+ call find_end_if
+ call remove_structure_data
+ jmp instruction_assembled
+ end_if:
+ cmp [prefixed_instruction],0
+ jne unexpected_instruction
+ call find_structure_data
+ jc unexpected_instruction
+ call remove_structure_data
+ jmp instruction_assembled
+ find_else:
+ call find_structure_end
+ cmp ax,else_directive-instruction_handler
+ je else_found
+ cmp ax,if_directive-instruction_handler
+ jne unexpected_instruction
+ stc
+ ret
+ else_found:
+ clc
+ ret
+ find_end_if:
+ call find_structure_end
+ cmp ax,if_directive-instruction_handler
+ jne unexpected_instruction
+ ret
+ find_structure_end:
+ push [error_line]
+ mov eax,[current_line]
+ mov [error_line],eax
+ find_end_directive:
+ call skip_symbol
+ jnc find_end_directive
+ lods byte [esi]
+ cmp al,0Fh
+ jne no_end_directive
+ lods dword [esi]
+ mov [current_line],eax
+ skip_labels:
+ cmp byte [esi],2
+ jne labels_ok
+ add esi,6
+ jmp skip_labels
+ labels_ok:
+ cmp byte [esi],1
+ jne find_end_directive
+ mov ax,[esi+1]
+ cmp ax,prefix_instruction-instruction_handler
+ je find_end_directive
+ add esi,4
+ cmp ax,repeat_directive-instruction_handler
+ je skip_repeat
+ cmp ax,while_directive-instruction_handler
+ je skip_while
+ cmp ax,if_directive-instruction_handler
+ je skip_if
+ cmp ax,else_directive-instruction_handler
+ je structure_end
+ cmp ax,end_directive-instruction_handler
+ jne find_end_directive
+ cmp byte [esi],1
+ jne find_end_directive
+ mov ax,[esi+1]
+ add esi,4
+ cmp ax,repeat_directive-instruction_handler
+ je structure_end
+ cmp ax,while_directive-instruction_handler
+ je structure_end
+ cmp ax,if_directive-instruction_handler
+ jne find_end_directive
+ structure_end:
+ pop [error_line]
+ ret
+ no_end_directive:
+ mov eax,[error_line]
+ mov [current_line],eax
+ jmp missing_end_directive
+ skip_repeat:
+ call find_end_repeat
+ jmp find_end_directive
+ skip_while:
+ call find_end_while
+ jmp find_end_directive
+ skip_if:
+ call skip_if_block
+ jmp find_end_directive
+ skip_if_block:
+ call find_else
+ jc if_block_skipped
+ cmp byte [esi],1
+ jne skip_after_else
+ cmp word [esi+1],if_directive-instruction_handler
+ jne skip_after_else
+ add esi,4
+ jmp skip_if_block
+ skip_after_else:
+ call find_end_if
+ if_block_skipped:
+ ret
+end_directive:
+ lods byte [esi]
+ cmp al,1
+ jne invalid_argument
+ lods word [esi]
+ inc esi
+ cmp ax,virtual_directive-instruction_handler
+ je end_virtual
+ cmp ax,repeat_directive-instruction_handler
+ je end_repeat
+ cmp ax,while_directive-instruction_handler
+ je end_while
+ cmp ax,if_directive-instruction_handler
+ je end_if
+ cmp ax,data_directive-instruction_handler
+ je end_data
+ jmp invalid_argument
+break_directive:
+ mov ebx,[structures_buffer]
+ mov al,[esi]
+ or al,al
+ jz find_breakable_structure
+ cmp al,0Fh
+ jne extra_characters_on_line
+ find_breakable_structure:
+ cmp ebx,[additional_memory_end]
+ je unexpected_instruction
+ mov ax,[ebx]
+ cmp ax,repeat_directive-instruction_handler
+ je break_repeat
+ cmp ax,while_directive-instruction_handler
+ je break_while
+ cmp ax,if_directive-instruction_handler
+ je break_if
+ add ebx,18h
+ jmp find_breakable_structure
+ break_if:
+ push [current_line]
+ mov eax,[ebx+4]
+ mov [current_line],eax
+ call remove_structure_data
+ call skip_if_block
+ pop [current_line]
+ mov ebx,[structures_buffer]
+ jmp find_breakable_structure
+ break_repeat:
+ push ebx
+ call find_end_repeat
+ pop ebx
+ jmp stop_repeat
+ break_while:
+ push ebx
+ jmp stop_while
+
+data_bytes:
+ call define_data
+ lods byte [esi]
+ cmp al,'('
+ je get_byte
+ cmp al,'?'
+ jne invalid_argument
+ mov eax,edi
+ mov byte [edi],0
+ inc edi
+ jmp undefined_data
+ get_byte:
+ cmp byte [esi],0
+ je get_string
+ call get_byte_value
+ stos byte [edi]
+ ret
+ get_string:
+ inc esi
+ lods dword [esi]
+ mov ecx,eax
+ lea eax,[edi+ecx]
+ cmp eax,[tagged_blocks]
+ ja out_of_memory
+ rep movs byte [edi],[esi]
+ inc esi
+ ret
+ undefined_data:
+ mov ebp,[addressing_space]
+ test byte [ds:ebp+0Ah],1
+ jz mark_undefined_data
+ ret
+ mark_undefined_data:
+ cmp eax,[undefined_data_end]
+ je undefined_data_ok
+ mov [undefined_data_start],eax
+ undefined_data_ok:
+ mov [undefined_data_end],edi
+ ret
+ define_data:
+ cmp edi,[tagged_blocks]
+ jae out_of_memory
+ cmp byte [esi],'('
+ jne simple_data_value
+ mov ebx,esi
+ inc esi
+ call skip_expression
+ xchg esi,ebx
+ cmp byte [ebx],81h
+ jne simple_data_value
+ inc esi
+ call get_count_value
+ inc esi
+ or eax,eax
+ jz duplicate_zero_times
+ cmp byte [esi],'{'
+ jne duplicate_single_data_value
+ inc esi
+ duplicate_data:
+ push eax esi
+ duplicated_values:
+ cmp edi,[tagged_blocks]
+ jae out_of_memory
+ call near dword [esp+8]
+ lods byte [esi]
+ cmp al,','
+ je duplicated_values
+ cmp al,'}'
+ jne invalid_argument
+ pop ebx eax
+ dec eax
+ jz data_defined
+ mov esi,ebx
+ jmp duplicate_data
+ duplicate_single_data_value:
+ cmp edi,[tagged_blocks]
+ jae out_of_memory
+ push eax esi
+ call near dword [esp+8]
+ pop ebx eax
+ dec eax
+ jz data_defined
+ mov esi,ebx
+ jmp duplicate_single_data_value
+ duplicate_zero_times:
+ cmp byte [esi],'{'
+ jne skip_single_data_value
+ inc esi
+ skip_data_value:
+ call skip_symbol
+ jc invalid_argument
+ cmp byte [esi],'}'
+ jne skip_data_value
+ inc esi
+ jmp data_defined
+ skip_single_data_value:
+ call skip_symbol
+ jmp data_defined
+ simple_data_value:
+ cmp edi,[tagged_blocks]
+ jae out_of_memory
+ call near dword [esp]
+ data_defined:
+ lods byte [esi]
+ cmp al,','
+ je define_data
+ dec esi
+ add esp,4
+ jmp instruction_assembled
+data_unicode:
+ or [base_code],-1
+ jmp define_words
+data_words:
+ mov [base_code],0
+ define_words:
+ call define_data
+ lods byte [esi]
+ cmp al,'('
+ je get_word
+ cmp al,'?'
+ jne invalid_argument
+ mov eax,edi
+ and word [edi],0
+ scas word [edi]
+ jmp undefined_data
+ ret
+ get_word:
+ cmp [base_code],0
+ je word_data_value
+ cmp byte [esi],0
+ je word_string
+ word_data_value:
+ call get_word_value
+ call mark_relocation
+ stos word [edi]
+ ret
+ word_string:
+ inc esi
+ lods dword [esi]
+ mov ecx,eax
+ jecxz word_string_ok
+ lea eax,[edi+ecx*2]
+ cmp eax,[tagged_blocks]
+ ja out_of_memory
+ xor ah,ah
+ copy_word_string:
+ lods byte [esi]
+ stos word [edi]
+ loop copy_word_string
+ word_string_ok:
+ inc esi
+ ret
+data_dwords:
+ call define_data
+ lods byte [esi]
+ cmp al,'('
+ je get_dword
+ cmp al,'?'
+ jne invalid_argument
+ mov eax,edi
+ and dword [edi],0
+ scas dword [edi]
+ jmp undefined_data
+ get_dword:
+ push esi
+ call get_dword_value
+ pop ebx
+ cmp byte [esi],':'
+ je complex_dword
+ call mark_relocation
+ stos dword [edi]
+ ret
+ complex_dword:
+ mov esi,ebx
+ cmp byte [esi],'.'
+ je invalid_value
+ call get_word_value
+ push eax
+ inc esi
+ lods byte [esi]
+ cmp al,'('
+ jne invalid_operand
+ mov al,[value_type]
+ push eax
+ cmp byte [esi],'.'
+ je invalid_value
+ call get_word_value
+ call mark_relocation
+ stos word [edi]
+ pop eax
+ mov [value_type],al
+ pop eax
+ call mark_relocation
+ stos word [edi]
+ ret
+data_pwords:
+ call define_data
+ lods byte [esi]
+ cmp al,'('
+ je get_pword
+ cmp al,'?'
+ jne invalid_argument
+ mov eax,edi
+ and dword [edi],0
+ scas dword [edi]
+ and word [edi],0
+ scas word [edi]
+ jmp undefined_data
+ get_pword:
+ push esi
+ call get_pword_value
+ pop ebx
+ cmp byte [esi],':'
+ je complex_pword
+ call mark_relocation
+ stos dword [edi]
+ mov ax,dx
+ stos word [edi]
+ ret
+ complex_pword:
+ mov esi,ebx
+ cmp byte [esi],'.'
+ je invalid_value
+ call get_word_value
+ push eax
+ inc esi
+ lods byte [esi]
+ cmp al,'('
+ jne invalid_operand
+ mov al,[value_type]
+ push eax
+ cmp byte [esi],'.'
+ je invalid_value
+ call get_dword_value
+ call mark_relocation
+ stos dword [edi]
+ pop eax
+ mov [value_type],al
+ pop eax
+ call mark_relocation
+ stos word [edi]
+ ret
+data_qwords:
+ call define_data
+ lods byte [esi]
+ cmp al,'('
+ je get_qword
+ cmp al,'?'
+ jne invalid_argument
+ mov eax,edi
+ and dword [edi],0
+ scas dword [edi]
+ and dword [edi],0
+ scas dword [edi]
+ jmp undefined_data
+ get_qword:
+ call get_qword_value
+ call mark_relocation
+ stos dword [edi]
+ mov eax,edx
+ stos dword [edi]
+ ret
+data_twords:
+ call define_data
+ lods byte [esi]
+ cmp al,'('
+ je get_tword
+ cmp al,'?'
+ jne invalid_argument
+ mov eax,edi
+ and dword [edi],0
+ scas dword [edi]
+ and dword [edi],0
+ scas dword [edi]
+ and word [edi],0
+ scas word [edi]
+ jmp undefined_data
+ get_tword:
+ cmp byte [esi],'.'
+ jne complex_tword
+ inc esi
+ cmp word [esi+8],8000h
+ je fp_zero_tword
+ mov eax,[esi]
+ stos dword [edi]
+ mov eax,[esi+4]
+ stos dword [edi]
+ mov ax,[esi+8]
+ add ax,3FFFh
+ jo value_out_of_range
+ cmp ax,7FFFh
+ jge value_out_of_range
+ cmp ax,0
+ jg tword_exp_ok
+ mov cx,ax
+ neg cx
+ inc cx
+ cmp cx,64
+ jae value_out_of_range
+ cmp cx,32
+ ja large_shift
+ mov eax,[esi]
+ mov edx,[esi+4]
+ mov ebx,edx
+ shr edx,cl
+ shrd eax,ebx,cl
+ jmp tword_mantissa_shift_done
+ large_shift:
+ sub cx,32
+ xor edx,edx
+ mov eax,[esi+4]
+ shr eax,cl
+ tword_mantissa_shift_done:
+ jnc store_shifted_mantissa
+ add eax,1
+ adc edx,0
+ store_shifted_mantissa:
+ mov [edi-8],eax
+ mov [edi-4],edx
+ xor ax,ax
+ test edx,1 shl 31
+ jz tword_exp_ok
+ inc ax
+ tword_exp_ok:
+ mov bl,[esi+11]
+ shl bx,15
+ or ax,bx
+ stos word [edi]
+ add esi,13
+ ret
+ fp_zero_tword:
+ xor eax,eax
+ stos dword [edi]
+ stos dword [edi]
+ mov al,[esi+11]
+ shl ax,15
+ stos word [edi]
+ add esi,13
+ ret
+ complex_tword:
+ call get_word_value
+ push eax
+ cmp byte [esi],':'
+ jne invalid_operand
+ inc esi
+ lods byte [esi]
+ cmp al,'('
+ jne invalid_operand
+ mov al,[value_type]
+ push eax
+ cmp byte [esi],'.'
+ je invalid_value
+ call get_qword_value
+ call mark_relocation
+ stos dword [edi]
+ mov eax,edx
+ stos dword [edi]
+ pop eax
+ mov [value_type],al
+ pop eax
+ call mark_relocation
+ stos word [edi]
+ ret
+data_file:
+ lods word [esi]
+ cmp ax,'('
+ jne invalid_argument
+ add esi,4
+ call open_binary_file
+ mov eax,[esi-4]
+ lea esi,[esi+eax+1]
+ mov al,2
+ xor edx,edx
+ call lseek
+ push eax
+ xor edx,edx
+ cmp byte [esi],':'
+ jne position_ok
+ inc esi
+ cmp byte [esi],'('
+ jne invalid_argument
+ inc esi
+ cmp byte [esi],'.'
+ je invalid_value
+ push ebx
+ call get_count_value
+ pop ebx
+ mov edx,eax
+ sub [esp],edx
+ jc value_out_of_range
+ position_ok:
+ cmp byte [esi],','
+ jne size_ok
+ inc esi
+ cmp byte [esi],'('
+ jne invalid_argument
+ inc esi
+ cmp byte [esi],'.'
+ je invalid_value
+ push ebx edx
+ call get_count_value
+ pop edx ebx
+ cmp eax,[esp]
+ ja value_out_of_range
+ mov [esp],eax
+ size_ok:
+ xor al,al
+ call lseek
+ pop ecx
+ mov edx,edi
+ add edi,ecx
+ jc out_of_memory
+ cmp edi,[tagged_blocks]
+ ja out_of_memory
+ call read
+ jc error_reading_file
+ call close
+ lods byte [esi]
+ cmp al,','
+ je data_file
+ dec esi
+ jmp instruction_assembled
+ open_binary_file:
+ push esi
+ push edi
+ mov eax,[current_line]
+ find_current_source_path:
+ mov esi,[eax]
+ test byte [eax+7],80h
+ jz get_current_path
+ mov eax,[eax+8]
+ jmp find_current_source_path
+ get_current_path:
+ lodsb
+ stosb
+ or al,al
+ jnz get_current_path
+ cut_current_path:
+ cmp edi,[esp]
+ je current_path_ok
+ cmp byte [edi-1],'\'
+ je current_path_ok
+ cmp byte [edi-1],'/'
+ je current_path_ok
+ dec edi
+ jmp cut_current_path
+ current_path_ok:
+ mov esi,[esp+4]
+ call expand_path
+ pop edx
+ mov esi,edx
+ call open
+ jnc file_opened
+ mov edx,[include_paths]
+ search_in_include_paths:
+ push edx esi
+ mov edi,esi
+ mov esi,[esp+4]
+ call get_include_directory
+ mov [esp+4],esi
+ mov esi,[esp+8]
+ call expand_path
+ pop edx
+ mov esi,edx
+ call open
+ pop edx
+ jnc file_opened
+ cmp byte [edx],0
+ jne search_in_include_paths
+ mov edi,esi
+ mov esi,[esp]
+ push edi
+ call expand_path
+ pop edx
+ mov esi,edx
+ call open
+ jc file_not_found
+ file_opened:
+ mov edi,esi
+ pop esi
+ ret
+reserve_bytes:
+ lods byte [esi]
+ cmp al,'('
+ jne invalid_argument
+ cmp byte [esi],'.'
+ je invalid_value
+ call get_count_value
+ mov ecx,eax
+ mov edx,ecx
+ add edx,edi
+ jc out_of_memory
+ cmp edx,[tagged_blocks]
+ ja out_of_memory
+ push edi
+ cmp [next_pass_needed],0
+ je zero_bytes
+ add edi,ecx
+ jmp reserved_data
+ zero_bytes:
+ xor eax,eax
+ shr ecx,1
+ jnc bytes_stosb_ok
+ stos byte [edi]
+ bytes_stosb_ok:
+ shr ecx,1
+ jnc bytes_stosw_ok
+ stos word [edi]
+ bytes_stosw_ok:
+ rep stos dword [edi]
+ reserved_data:
+ pop eax
+ call undefined_data
+ jmp instruction_assembled
+reserve_words:
+ lods byte [esi]
+ cmp al,'('
+ jne invalid_argument
+ cmp byte [esi],'.'
+ je invalid_value
+ call get_count_value
+ mov ecx,eax
+ mov edx,ecx
+ shl edx,1
+ jc out_of_memory
+ add edx,edi
+ jc out_of_memory
+ cmp edx,[tagged_blocks]
+ ja out_of_memory
+ push edi
+ cmp [next_pass_needed],0
+ je zero_words
+ lea edi,[edi+ecx*2]
+ jmp reserved_data
+ zero_words:
+ xor eax,eax
+ shr ecx,1
+ jnc words_stosw_ok
+ stos word [edi]
+ words_stosw_ok:
+ rep stos dword [edi]
+ jmp reserved_data
+reserve_dwords:
+ lods byte [esi]
+ cmp al,'('
+ jne invalid_argument
+ cmp byte [esi],'.'
+ je invalid_value
+ call get_count_value
+ mov ecx,eax
+ mov edx,ecx
+ shl edx,1
+ jc out_of_memory
+ shl edx,1
+ jc out_of_memory
+ add edx,edi
+ jc out_of_memory
+ cmp edx,[tagged_blocks]
+ ja out_of_memory
+ push edi
+ cmp [next_pass_needed],0
+ je zero_dwords
+ lea edi,[edi+ecx*4]
+ jmp reserved_data
+ zero_dwords:
+ xor eax,eax
+ rep stos dword [edi]
+ jmp reserved_data
+reserve_pwords:
+ lods byte [esi]
+ cmp al,'('
+ jne invalid_argument
+ cmp byte [esi],'.'
+ je invalid_value
+ call get_count_value
+ mov ecx,eax
+ shl ecx,1
+ jc out_of_memory
+ add ecx,eax
+ mov edx,ecx
+ shl edx,1
+ jc out_of_memory
+ add edx,edi
+ jc out_of_memory
+ cmp edx,[tagged_blocks]
+ ja out_of_memory
+ push edi
+ cmp [next_pass_needed],0
+ je zero_words
+ lea edi,[edi+ecx*2]
+ jmp reserved_data
+reserve_qwords:
+ lods byte [esi]
+ cmp al,'('
+ jne invalid_argument
+ cmp byte [esi],'.'
+ je invalid_value
+ call get_count_value
+ mov ecx,eax
+ shl ecx,1
+ jc out_of_memory
+ mov edx,ecx
+ shl edx,1
+ jc out_of_memory
+ shl edx,1
+ jc out_of_memory
+ add edx,edi
+ jc out_of_memory
+ cmp edx,[tagged_blocks]
+ ja out_of_memory
+ push edi
+ cmp [next_pass_needed],0
+ je zero_dwords
+ lea edi,[edi+ecx*4]
+ jmp reserved_data
+reserve_twords:
+ lods byte [esi]
+ cmp al,'('
+ jne invalid_argument
+ cmp byte [esi],'.'
+ je invalid_value
+ call get_count_value
+ mov ecx,eax
+ shl ecx,2
+ jc out_of_memory
+ add ecx,eax
+ mov edx,ecx
+ shl edx,1
+ jc out_of_memory
+ add edx,edi
+ jc out_of_memory
+ cmp edx,[tagged_blocks]
+ ja out_of_memory
+ push edi
+ cmp [next_pass_needed],0
+ je zero_words
+ lea edi,[edi+ecx*2]
+ jmp reserved_data
+align_directive:
+ lods byte [esi]
+ cmp al,'('
+ jne invalid_argument
+ cmp byte [esi],'.'
+ je invalid_value
+ call get_count_value
+ mov edx,eax
+ dec edx
+ test eax,edx
+ jnz invalid_align_value
+ or eax,eax
+ jz invalid_align_value
+ cmp eax,1
+ je instruction_assembled
+ mov ecx,edi
+ mov ebp,[addressing_space]
+ sub ecx,[ds:ebp]
+ cmp dword [ds:ebp+10h],0
+ jne section_not_aligned_enough
+ cmp byte [ds:ebp+9],0
+ je make_alignment
+ cmp [output_format],3
+ je pe_alignment
+ mov ebx,[ds:ebp+14h]
+ cmp byte [ebx],0
+ jne section_not_aligned_enough
+ cmp eax,[ebx+10h]
+ jbe make_alignment
+ jmp section_not_aligned_enough
+ pe_alignment:
+ cmp eax,1000h
+ ja section_not_aligned_enough
+ make_alignment:
+ dec eax
+ and ecx,eax
+ jz instruction_assembled
+ neg ecx
+ add ecx,eax
+ inc ecx
+ mov edx,ecx
+ add edx,edi
+ jc out_of_memory
+ cmp edx,[tagged_blocks]
+ ja out_of_memory
+ push edi
+ cmp [next_pass_needed],0
+ je nops
+ add edi,ecx
+ jmp reserved_data
+ invalid_align_value:
+ cmp [error_line],0
+ jne instruction_assembled
+ mov eax,[current_line]
+ mov [error_line],eax
+ mov [error],invalid_value
+ jmp instruction_assembled
+ nops:
+ mov eax,90909090h
+ shr ecx,1
+ jnc nops_stosb_ok
+ stos byte [edi]
+ nops_stosb_ok:
+ shr ecx,1
+ jnc nops_stosw_ok
+ stos word [edi]
+ nops_stosw_ok:
+ rep stos dword [edi]
+ jmp reserved_data
+err_directive:
+ mov al,[esi]
+ cmp al,0Fh
+ je invoked_error
+ or al,al
+ jz invoked_error
+ jmp extra_characters_on_line
+assert_directive:
+ call calculate_logical_expression
+ or al,al
+ jnz instruction_assembled
+ cmp [error_line],0
+ jne instruction_assembled
+ mov eax,[current_line]
+ mov [error_line],eax
+ mov [error],assertion_failed
+ jmp instruction_assembled
diff --git a/samples/Assembly/FASM.asm b/samples/Assembly/FASM.asm
new file mode 100644
index 00000000..9a2201ae
--- /dev/null
+++ b/samples/Assembly/FASM.asm
@@ -0,0 +1,350 @@
+
+; flat assembler interface for Win32
+; Copyright (c) 1999-2014, Tomasz Grysztar.
+; All rights reserved.
+
+ format PE console
+
+section '.text' code readable executable
+
+start:
+
+ mov [con_handle],STD_OUTPUT_HANDLE
+ mov esi,_logo
+ call display_string
+
+ call get_params
+ jc information
+
+ call init_memory
+
+ mov esi,_memory_prefix
+ call display_string
+ mov eax,[memory_end]
+ sub eax,[memory_start]
+ add eax,[additional_memory_end]
+ sub eax,[additional_memory]
+ shr eax,10
+ call display_number
+ mov esi,_memory_suffix
+ call display_string
+
+ call [GetTickCount]
+ mov [start_time],eax
+
+ call preprocessor
+ call parser
+ call assembler
+ call formatter
+
+ call display_user_messages
+ movzx eax,[current_pass]
+ inc eax
+ call display_number
+ mov esi,_passes_suffix
+ call display_string
+ call [GetTickCount]
+ sub eax,[start_time]
+ xor edx,edx
+ mov ebx,100
+ div ebx
+ or eax,eax
+ jz display_bytes_count
+ xor edx,edx
+ mov ebx,10
+ div ebx
+ push edx
+ call display_number
+ mov dl,'.'
+ call display_character
+ pop eax
+ call display_number
+ mov esi,_seconds_suffix
+ call display_string
+ display_bytes_count:
+ mov eax,[written_size]
+ call display_number
+ mov esi,_bytes_suffix
+ call display_string
+ xor al,al
+ jmp exit_program
+
+information:
+ mov esi,_usage
+ call display_string
+ mov al,1
+ jmp exit_program
+
+get_params:
+ mov [input_file],0
+ mov [output_file],0
+ mov [symbols_file],0
+ mov [memory_setting],0
+ mov [passes_limit],100
+ call [GetCommandLine]
+ mov esi,eax
+ mov edi,params
+ find_command_start:
+ lodsb
+ cmp al,20h
+ je find_command_start
+ cmp al,22h
+ je skip_quoted_name
+ skip_name:
+ lodsb
+ cmp al,20h
+ je find_param
+ or al,al
+ jz all_params
+ jmp skip_name
+ skip_quoted_name:
+ lodsb
+ cmp al,22h
+ je find_param
+ or al,al
+ jz all_params
+ jmp skip_quoted_name
+ find_param:
+ lodsb
+ cmp al,20h
+ je find_param
+ cmp al,'-'
+ je option_param
+ cmp al,0Dh
+ je all_params
+ or al,al
+ jz all_params
+ cmp [input_file],0
+ jne get_output_file
+ mov [input_file],edi
+ jmp process_param
+ get_output_file:
+ cmp [output_file],0
+ jne bad_params
+ mov [output_file],edi
+ process_param:
+ cmp al,22h
+ je string_param
+ copy_param:
+ stosb
+ lodsb
+ cmp al,20h
+ je param_end
+ cmp al,0Dh
+ je param_end
+ or al,al
+ jz param_end
+ jmp copy_param
+ string_param:
+ lodsb
+ cmp al,22h
+ je string_param_end
+ cmp al,0Dh
+ je param_end
+ or al,al
+ jz param_end
+ stosb
+ jmp string_param
+ option_param:
+ lodsb
+ cmp al,'m'
+ je memory_option
+ cmp al,'M'
+ je memory_option
+ cmp al,'p'
+ je passes_option
+ cmp al,'P'
+ je passes_option
+ cmp al,'s'
+ je symbols_option
+ cmp al,'S'
+ je symbols_option
+ bad_params:
+ stc
+ ret
+ get_option_value:
+ xor eax,eax
+ mov edx,eax
+ get_option_digit:
+ lodsb
+ cmp al,20h
+ je option_value_ok
+ cmp al,0Dh
+ je option_value_ok
+ or al,al
+ jz option_value_ok
+ sub al,30h
+ jc invalid_option_value
+ cmp al,9
+ ja invalid_option_value
+ imul edx,10
+ jo invalid_option_value
+ add edx,eax
+ jc invalid_option_value
+ jmp get_option_digit
+ option_value_ok:
+ dec esi
+ clc
+ ret
+ invalid_option_value:
+ stc
+ ret
+ memory_option:
+ lodsb
+ cmp al,20h
+ je memory_option
+ cmp al,0Dh
+ je bad_params
+ or al,al
+ jz bad_params
+ dec esi
+ call get_option_value
+ or edx,edx
+ jz bad_params
+ cmp edx,1 shl (32-10)
+ jae bad_params
+ mov [memory_setting],edx
+ jmp find_param
+ passes_option:
+ lodsb
+ cmp al,20h
+ je passes_option
+ cmp al,0Dh
+ je bad_params
+ or al,al
+ jz bad_params
+ dec esi
+ call get_option_value
+ or edx,edx
+ jz bad_params
+ cmp edx,10000h
+ ja bad_params
+ mov [passes_limit],dx
+ jmp find_param
+ symbols_option:
+ mov [symbols_file],edi
+ find_symbols_file_name:
+ lodsb
+ cmp al,20h
+ jne process_param
+ jmp find_symbols_file_name
+ param_end:
+ dec esi
+ string_param_end:
+ xor al,al
+ stosb
+ jmp find_param
+ all_params:
+ cmp [input_file],0
+ je bad_params
+ clc
+ ret
+
+include 'system.inc'
+
+include '..\errors.inc'
+include '..\symbdump.inc'
+include '..\preproce.inc'
+include '..\parser.inc'
+include '..\exprpars.inc'
+include '..\assemble.inc'
+include '..\exprcalc.inc'
+include '..\formats.inc'
+include '..\x86_64.inc'
+include '..\avx.inc'
+
+include '..\tables.inc'
+include '..\messages.inc'
+
+section '.data' data readable writeable
+
+include '..\version.inc'
+
+_copyright db 'Copyright (c) 1999-2014, Tomasz Grysztar',0Dh,0Ah,0
+
+_logo db 'flat assembler version ',VERSION_STRING,0
+_usage db 0Dh,0Ah
+ db 'usage: fasm [output]',0Dh,0Ah
+ db 'optional settings:',0Dh,0Ah
+ db ' -m set the limit in kilobytes for the available memory',0Dh,0Ah
+ db ' -p set the maximum allowed number of passes',0Dh,0Ah
+ db ' -s dump symbolic information for debugging',0Dh,0Ah
+ db 0
+_memory_prefix db ' (',0
+_memory_suffix db ' kilobytes memory)',0Dh,0Ah,0
+_passes_suffix db ' passes, ',0
+_seconds_suffix db ' seconds, ',0
+_bytes_suffix db ' bytes.',0Dh,0Ah,0
+
+align 4
+
+include '..\variable.inc'
+
+con_handle dd ?
+memory_setting dd ?
+start_time dd ?
+bytes_count dd ?
+displayed_count dd ?
+character db ?
+last_displayed rb 2
+
+params rb 1000h
+options rb 1000h
+buffer rb 4000h
+
+stack 10000h
+
+section '.idata' import data readable writeable
+
+ dd 0,0,0,rva kernel_name,rva kernel_table
+ dd 0,0,0,0,0
+
+ kernel_table:
+ ExitProcess dd rva _ExitProcess
+ CreateFile dd rva _CreateFileA
+ ReadFile dd rva _ReadFile
+ WriteFile dd rva _WriteFile
+ CloseHandle dd rva _CloseHandle
+ SetFilePointer dd rva _SetFilePointer
+ GetCommandLine dd rva _GetCommandLineA
+ GetEnvironmentVariable dd rva _GetEnvironmentVariable
+ GetStdHandle dd rva _GetStdHandle
+ VirtualAlloc dd rva _VirtualAlloc
+ VirtualFree dd rva _VirtualFree
+ GetTickCount dd rva _GetTickCount
+ GetSystemTime dd rva _GetSystemTime
+ GlobalMemoryStatus dd rva _GlobalMemoryStatus
+ dd 0
+
+ kernel_name db 'KERNEL32.DLL',0
+
+ _ExitProcess dw 0
+ db 'ExitProcess',0
+ _CreateFileA dw 0
+ db 'CreateFileA',0
+ _ReadFile dw 0
+ db 'ReadFile',0
+ _WriteFile dw 0
+ db 'WriteFile',0
+ _CloseHandle dw 0
+ db 'CloseHandle',0
+ _SetFilePointer dw 0
+ db 'SetFilePointer',0
+ _GetCommandLineA dw 0
+ db 'GetCommandLineA',0
+ _GetEnvironmentVariable dw 0
+ db 'GetEnvironmentVariableA',0
+ _GetStdHandle dw 0
+ db 'GetStdHandle',0
+ _VirtualAlloc dw 0
+ db 'VirtualAlloc',0
+ _VirtualFree dw 0
+ db 'VirtualFree',0
+ _GetTickCount dw 0
+ db 'GetTickCount',0
+ _GetSystemTime dw 0
+ db 'GetSystemTime',0
+ _GlobalMemoryStatus dw 0
+ db 'GlobalMemoryStatus',0
+
+section '.reloc' fixups data readable discardable
diff --git a/samples/Assembly/SYSTEM.inc b/samples/Assembly/SYSTEM.inc
new file mode 100644
index 00000000..77a61d29
--- /dev/null
+++ b/samples/Assembly/SYSTEM.inc
@@ -0,0 +1,503 @@
+
+; flat assembler interface for Win32
+; Copyright (c) 1999-2014, Tomasz Grysztar.
+; All rights reserved.
+
+CREATE_NEW = 1
+CREATE_ALWAYS = 2
+OPEN_EXISTING = 3
+OPEN_ALWAYS = 4
+TRUNCATE_EXISTING = 5
+
+FILE_SHARE_READ = 1
+FILE_SHARE_WRITE = 2
+FILE_SHARE_DELETE = 4
+
+GENERIC_READ = 80000000h
+GENERIC_WRITE = 40000000h
+
+STD_INPUT_HANDLE = 0FFFFFFF6h
+STD_OUTPUT_HANDLE = 0FFFFFFF5h
+STD_ERROR_HANDLE = 0FFFFFFF4h
+
+MEM_COMMIT = 1000h
+MEM_RESERVE = 2000h
+MEM_DECOMMIT = 4000h
+MEM_RELEASE = 8000h
+MEM_FREE = 10000h
+MEM_PRIVATE = 20000h
+MEM_MAPPED = 40000h
+MEM_RESET = 80000h
+MEM_TOP_DOWN = 100000h
+
+PAGE_NOACCESS = 1
+PAGE_READONLY = 2
+PAGE_READWRITE = 4
+PAGE_WRITECOPY = 8
+PAGE_EXECUTE = 10h
+PAGE_EXECUTE_READ = 20h
+PAGE_EXECUTE_READWRITE = 40h
+PAGE_EXECUTE_WRITECOPY = 80h
+PAGE_GUARD = 100h
+PAGE_NOCACHE = 200h
+
+init_memory:
+ xor eax,eax
+ mov [memory_start],eax
+ mov eax,esp
+ and eax,not 0FFFh
+ add eax,1000h-10000h
+ mov [stack_limit],eax
+ mov eax,[memory_setting]
+ shl eax,10
+ jnz allocate_memory
+ push buffer
+ call [GlobalMemoryStatus]
+ mov eax,dword [buffer+20]
+ mov edx,dword [buffer+12]
+ cmp eax,0
+ jl large_memory
+ cmp edx,0
+ jl large_memory
+ shr eax,2
+ add eax,edx
+ jmp allocate_memory
+ large_memory:
+ mov eax,80000000h
+ allocate_memory:
+ mov edx,eax
+ shr edx,2
+ mov ecx,eax
+ sub ecx,edx
+ mov [memory_end],ecx
+ mov [additional_memory_end],edx
+ push PAGE_READWRITE
+ push MEM_COMMIT
+ push eax
+ push 0
+ call [VirtualAlloc]
+ or eax,eax
+ jz not_enough_memory
+ mov [memory_start],eax
+ add eax,[memory_end]
+ mov [memory_end],eax
+ mov [additional_memory],eax
+ add [additional_memory_end],eax
+ ret
+ not_enough_memory:
+ mov eax,[additional_memory_end]
+ shl eax,1
+ cmp eax,4000h
+ jb out_of_memory
+ jmp allocate_memory
+
+exit_program:
+ movzx eax,al
+ push eax
+ mov eax,[memory_start]
+ test eax,eax
+ jz do_exit
+ push MEM_RELEASE
+ push 0
+ push eax
+ call [VirtualFree]
+ do_exit:
+ call [ExitProcess]
+
+get_environment_variable:
+ mov ecx,[memory_end]
+ sub ecx,edi
+ cmp ecx,4000h
+ jbe buffer_for_variable_ok
+ mov ecx,4000h
+ buffer_for_variable_ok:
+ push ecx
+ push edi
+ push esi
+ call [GetEnvironmentVariable]
+ add edi,eax
+ cmp edi,[memory_end]
+ jae out_of_memory
+ ret
+
+open:
+ push 0
+ push 0
+ push OPEN_EXISTING
+ push 0
+ push FILE_SHARE_READ
+ push GENERIC_READ
+ push edx
+ call [CreateFile]
+ cmp eax,-1
+ je file_error
+ mov ebx,eax
+ clc
+ ret
+ file_error:
+ stc
+ ret
+create:
+ push 0
+ push 0
+ push CREATE_ALWAYS
+ push 0
+ push FILE_SHARE_READ
+ push GENERIC_WRITE
+ push edx
+ call [CreateFile]
+ cmp eax,-1
+ je file_error
+ mov ebx,eax
+ clc
+ ret
+write:
+ push 0
+ push bytes_count
+ push ecx
+ push edx
+ push ebx
+ call [WriteFile]
+ or eax,eax
+ jz file_error
+ clc
+ ret
+read:
+ mov ebp,ecx
+ push 0
+ push bytes_count
+ push ecx
+ push edx
+ push ebx
+ call [ReadFile]
+ or eax,eax
+ jz file_error
+ cmp ebp,[bytes_count]
+ jne file_error
+ clc
+ ret
+close:
+ push ebx
+ call [CloseHandle]
+ ret
+lseek:
+ movzx eax,al
+ push eax
+ push 0
+ push edx
+ push ebx
+ call [SetFilePointer]
+ ret
+
+display_string:
+ push [con_handle]
+ call [GetStdHandle]
+ mov ebp,eax
+ mov edi,esi
+ or ecx,-1
+ xor al,al
+ repne scasb
+ neg ecx
+ sub ecx,2
+ push 0
+ push bytes_count
+ push ecx
+ push esi
+ push ebp
+ call [WriteFile]
+ ret
+display_character:
+ push ebx
+ mov [character],dl
+ push [con_handle]
+ call [GetStdHandle]
+ mov ebx,eax
+ push 0
+ push bytes_count
+ push 1
+ push character
+ push ebx
+ call [WriteFile]
+ pop ebx
+ ret
+display_number:
+ push ebx
+ mov ecx,1000000000
+ xor edx,edx
+ xor bl,bl
+ display_loop:
+ div ecx
+ push edx
+ cmp ecx,1
+ je display_digit
+ or bl,bl
+ jnz display_digit
+ or al,al
+ jz digit_ok
+ not bl
+ display_digit:
+ mov dl,al
+ add dl,30h
+ push ecx
+ call display_character
+ pop ecx
+ digit_ok:
+ mov eax,ecx
+ xor edx,edx
+ mov ecx,10
+ div ecx
+ mov ecx,eax
+ pop eax
+ or ecx,ecx
+ jnz display_loop
+ pop ebx
+ ret
+
+display_user_messages:
+ mov [displayed_count],0
+ call show_display_buffer
+ cmp [displayed_count],1
+ jb line_break_ok
+ je make_line_break
+ mov ax,word [last_displayed]
+ cmp ax,0A0Dh
+ je line_break_ok
+ cmp ax,0D0Ah
+ je line_break_ok
+ make_line_break:
+ mov word [buffer],0A0Dh
+ push [con_handle]
+ call [GetStdHandle]
+ push 0
+ push bytes_count
+ push 2
+ push buffer
+ push eax
+ call [WriteFile]
+ line_break_ok:
+ ret
+display_block:
+ add [displayed_count],ecx
+ cmp ecx,1
+ ja take_last_two_characters
+ jb block_displayed
+ mov al,[last_displayed+1]
+ mov ah,[esi]
+ mov word [last_displayed],ax
+ jmp block_ok
+ take_last_two_characters:
+ mov ax,[esi+ecx-2]
+ mov word [last_displayed],ax
+ block_ok:
+ push ecx
+ push [con_handle]
+ call [GetStdHandle]
+ pop ecx
+ push 0
+ push bytes_count
+ push ecx
+ push esi
+ push eax
+ call [WriteFile]
+ block_displayed:
+ ret
+
+fatal_error:
+ mov [con_handle],STD_ERROR_HANDLE
+ mov esi,error_prefix
+ call display_string
+ pop esi
+ call display_string
+ mov esi,error_suffix
+ call display_string
+ mov al,0FFh
+ jmp exit_program
+assembler_error:
+ mov [con_handle],STD_ERROR_HANDLE
+ call display_user_messages
+ push dword 0
+ mov ebx,[current_line]
+ get_error_lines:
+ mov eax,[ebx]
+ cmp byte [eax],0
+ je get_next_error_line
+ push ebx
+ test byte [ebx+7],80h
+ jz display_error_line
+ mov edx,ebx
+ find_definition_origin:
+ mov edx,[edx+12]
+ test byte [edx+7],80h
+ jnz find_definition_origin
+ push edx
+ get_next_error_line:
+ mov ebx,[ebx+8]
+ jmp get_error_lines
+ display_error_line:
+ mov esi,[ebx]
+ call display_string
+ mov esi,line_number_start
+ call display_string
+ mov eax,[ebx+4]
+ and eax,7FFFFFFFh
+ call display_number
+ mov dl,']'
+ call display_character
+ pop esi
+ cmp ebx,esi
+ je line_number_ok
+ mov dl,20h
+ call display_character
+ push esi
+ mov esi,[esi]
+ movzx ecx,byte [esi]
+ inc esi
+ call display_block
+ mov esi,line_number_start
+ call display_string
+ pop esi
+ mov eax,[esi+4]
+ and eax,7FFFFFFFh
+ call display_number
+ mov dl,']'
+ call display_character
+ line_number_ok:
+ mov esi,line_data_start
+ call display_string
+ mov esi,ebx
+ mov edx,[esi]
+ call open
+ mov al,2
+ xor edx,edx
+ call lseek
+ mov edx,[esi+8]
+ sub eax,edx
+ jz line_data_displayed
+ push eax
+ xor al,al
+ call lseek
+ mov ecx,[esp]
+ mov edx,[additional_memory]
+ lea eax,[edx+ecx]
+ cmp eax,[additional_memory_end]
+ ja out_of_memory
+ call read
+ call close
+ pop ecx
+ mov esi,[additional_memory]
+ get_line_data:
+ mov al,[esi]
+ cmp al,0Ah
+ je display_line_data
+ cmp al,0Dh
+ je display_line_data
+ cmp al,1Ah
+ je display_line_data
+ or al,al
+ jz display_line_data
+ inc esi
+ loop get_line_data
+ display_line_data:
+ mov ecx,esi
+ mov esi,[additional_memory]
+ sub ecx,esi
+ call display_block
+ line_data_displayed:
+ mov esi,cr_lf
+ call display_string
+ pop ebx
+ or ebx,ebx
+ jnz display_error_line
+ mov esi,error_prefix
+ call display_string
+ pop esi
+ call display_string
+ mov esi,error_suffix
+ call display_string
+ mov al,2
+ jmp exit_program
+
+make_timestamp:
+ push buffer
+ call [GetSystemTime]
+ movzx ecx,word [buffer]
+ mov eax,ecx
+ sub eax,1970
+ mov ebx,365
+ mul ebx
+ mov ebp,eax
+ mov eax,ecx
+ sub eax,1969
+ shr eax,2
+ add ebp,eax
+ mov eax,ecx
+ sub eax,1901
+ mov ebx,100
+ div ebx
+ sub ebp,eax
+ mov eax,ecx
+ xor edx,edx
+ sub eax,1601
+ mov ebx,400
+ div ebx
+ add ebp,eax
+ movzx ecx,word [buffer+2]
+ mov eax,ecx
+ dec eax
+ mov ebx,30
+ mul ebx
+ add ebp,eax
+ cmp ecx,8
+ jbe months_correction
+ mov eax,ecx
+ sub eax,7
+ shr eax,1
+ add ebp,eax
+ mov ecx,8
+ months_correction:
+ mov eax,ecx
+ shr eax,1
+ add ebp,eax
+ cmp ecx,2
+ jbe day_correction_ok
+ sub ebp,2
+ movzx ecx,word [buffer]
+ test ecx,11b
+ jnz day_correction_ok
+ xor edx,edx
+ mov eax,ecx
+ mov ebx,100
+ div ebx
+ or edx,edx
+ jnz day_correction
+ mov eax,ecx
+ mov ebx,400
+ div ebx
+ or edx,edx
+ jnz day_correction_ok
+ day_correction:
+ inc ebp
+ day_correction_ok:
+ movzx eax,word [buffer+6]
+ dec eax
+ add eax,ebp
+ mov ebx,24
+ mul ebx
+ movzx ecx,word [buffer+8]
+ add eax,ecx
+ mov ebx,60
+ mul ebx
+ movzx ecx,word [buffer+10]
+ add eax,ecx
+ mov ebx,60
+ mul ebx
+ movzx ecx,word [buffer+12]
+ add eax,ecx
+ adc edx,0
+ ret
+
+error_prefix db 'error: ',0
+error_suffix db '.'
+cr_lf db 0Dh,0Ah,0
+line_number_start db ' [',0
+line_data_start db ':',0Dh,0Ah,0
diff --git a/samples/Assembly/X86_64.inc b/samples/Assembly/X86_64.inc
new file mode 100644
index 00000000..28413065
--- /dev/null
+++ b/samples/Assembly/X86_64.inc
@@ -0,0 +1,7060 @@
+
+; flat assembler core
+; Copyright (c) 1999-2014, Tomasz Grysztar.
+; All rights reserved.
+
+simple_instruction_except64:
+ cmp [code_type],64
+ je illegal_instruction
+simple_instruction:
+ stos byte [edi]
+ jmp instruction_assembled
+simple_instruction_only64:
+ cmp [code_type],64
+ jne illegal_instruction
+ jmp simple_instruction
+simple_instruction_16bit_except64:
+ cmp [code_type],64
+ je illegal_instruction
+simple_instruction_16bit:
+ cmp [code_type],16
+ jne size_prefix
+ stos byte [edi]
+ jmp instruction_assembled
+ size_prefix:
+ mov ah,al
+ mov al,66h
+ stos word [edi]
+ jmp instruction_assembled
+simple_instruction_32bit_except64:
+ cmp [code_type],64
+ je illegal_instruction
+simple_instruction_32bit:
+ cmp [code_type],16
+ je size_prefix
+ stos byte [edi]
+ jmp instruction_assembled
+iret_instruction:
+ cmp [code_type],64
+ jne simple_instruction
+simple_instruction_64bit:
+ cmp [code_type],64
+ jne illegal_instruction
+ mov ah,al
+ mov al,48h
+ stos word [edi]
+ jmp instruction_assembled
+simple_extended_instruction_64bit:
+ cmp [code_type],64
+ jne illegal_instruction
+ mov byte [edi],48h
+ inc edi
+simple_extended_instruction:
+ mov ah,al
+ mov al,0Fh
+ stos word [edi]
+ jmp instruction_assembled
+prefix_instruction:
+ stos byte [edi]
+ or [prefixed_instruction],-1
+ jmp continue_line
+segment_prefix:
+ mov ah,al
+ shr ah,4
+ cmp ah,6
+ jne illegal_instruction
+ and al,1111b
+ mov [segment_register],al
+ call store_segment_prefix
+ or [prefixed_instruction],-1
+ jmp continue_line
+int_instruction:
+ lods byte [esi]
+ call get_size_operator
+ cmp ah,1
+ ja invalid_operand_size
+ cmp al,'('
+ jne invalid_operand
+ call get_byte_value
+ test eax,eax
+ jns int_imm_ok
+ call recoverable_overflow
+ int_imm_ok:
+ mov ah,al
+ mov al,0CDh
+ stos word [edi]
+ jmp instruction_assembled
+aa_instruction:
+ cmp [code_type],64
+ je illegal_instruction
+ push eax
+ mov bl,10
+ cmp byte [esi],'('
+ jne aa_store
+ inc esi
+ xor al,al
+ xchg al,[operand_size]
+ cmp al,1
+ ja invalid_operand_size
+ call get_byte_value
+ mov bl,al
+ aa_store:
+ cmp [operand_size],0
+ jne invalid_operand
+ pop eax
+ mov ah,bl
+ stos word [edi]
+ jmp instruction_assembled
+
+basic_instruction:
+ mov [base_code],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je basic_reg
+ cmp al,'['
+ jne invalid_operand
+ basic_mem:
+ call get_address
+ push edx ebx ecx
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'('
+ je basic_mem_imm
+ cmp al,10h
+ jne invalid_operand
+ basic_mem_reg:
+ lods byte [esi]
+ call convert_register
+ mov [postbyte_register],al
+ pop ecx ebx edx
+ mov al,ah
+ cmp al,1
+ je instruction_ready
+ call operand_autodetect
+ inc [base_code]
+ instruction_ready:
+ call store_instruction
+ jmp instruction_assembled
+ basic_mem_imm:
+ mov al,[operand_size]
+ cmp al,1
+ jb basic_mem_imm_nosize
+ je basic_mem_imm_8bit
+ cmp al,2
+ je basic_mem_imm_16bit
+ cmp al,4
+ je basic_mem_imm_32bit
+ cmp al,8
+ jne invalid_operand_size
+ basic_mem_imm_64bit:
+ cmp [size_declared],0
+ jne long_immediate_not_encodable
+ call operand_64bit
+ call get_simm32
+ cmp [value_type],4
+ jae long_immediate_not_encodable
+ jmp basic_mem_imm_32bit_ok
+ basic_mem_imm_nosize:
+ call recoverable_unknown_size
+ basic_mem_imm_8bit:
+ call get_byte_value
+ mov byte [value],al
+ mov al,[base_code]
+ shr al,3
+ mov [postbyte_register],al
+ pop ecx ebx edx
+ mov [base_code],80h
+ call store_instruction_with_imm8
+ jmp instruction_assembled
+ basic_mem_imm_16bit:
+ call operand_16bit
+ call get_word_value
+ mov word [value],ax
+ mov al,[base_code]
+ shr al,3
+ mov [postbyte_register],al
+ pop ecx ebx edx
+ cmp [value_type],0
+ jne basic_mem_imm_16bit_store
+ cmp [size_declared],0
+ jne basic_mem_imm_16bit_store
+ cmp word [value],80h
+ jb basic_mem_simm_8bit
+ cmp word [value],-80h
+ jae basic_mem_simm_8bit
+ basic_mem_imm_16bit_store:
+ mov [base_code],81h
+ call store_instruction_with_imm16
+ jmp instruction_assembled
+ basic_mem_simm_8bit:
+ mov [base_code],83h
+ call store_instruction_with_imm8
+ jmp instruction_assembled
+ basic_mem_imm_32bit:
+ call operand_32bit
+ call get_dword_value
+ basic_mem_imm_32bit_ok:
+ mov dword [value],eax
+ mov al,[base_code]
+ shr al,3
+ mov [postbyte_register],al
+ pop ecx ebx edx
+ cmp [value_type],0
+ jne basic_mem_imm_32bit_store
+ cmp [size_declared],0
+ jne basic_mem_imm_32bit_store
+ cmp dword [value],80h
+ jb basic_mem_simm_8bit
+ cmp dword [value],-80h
+ jae basic_mem_simm_8bit
+ basic_mem_imm_32bit_store:
+ mov [base_code],81h
+ call store_instruction_with_imm32
+ jmp instruction_assembled
+ get_simm32:
+ call get_qword_value
+ mov ecx,edx
+ cdq
+ cmp ecx,edx
+ jne value_out_of_range
+ cmp [value_type],4
+ jne get_simm32_ok
+ mov [value_type],2
+ get_simm32_ok:
+ ret
+ basic_reg:
+ lods byte [esi]
+ call convert_register
+ mov [postbyte_register],al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je basic_reg_reg
+ cmp al,'('
+ je basic_reg_imm
+ cmp al,'['
+ jne invalid_operand
+ basic_reg_mem:
+ call get_address
+ mov al,[operand_size]
+ cmp al,1
+ je basic_reg_mem_8bit
+ call operand_autodetect
+ add [base_code],3
+ jmp instruction_ready
+ basic_reg_mem_8bit:
+ add [base_code],2
+ jmp instruction_ready
+ basic_reg_reg:
+ lods byte [esi]
+ call convert_register
+ mov bl,[postbyte_register]
+ mov [postbyte_register],al
+ mov al,ah
+ cmp al,1
+ je nomem_instruction_ready
+ call operand_autodetect
+ inc [base_code]
+ nomem_instruction_ready:
+ call store_nomem_instruction
+ jmp instruction_assembled
+ basic_reg_imm:
+ mov al,[operand_size]
+ cmp al,1
+ je basic_reg_imm_8bit
+ cmp al,2
+ je basic_reg_imm_16bit
+ cmp al,4
+ je basic_reg_imm_32bit
+ cmp al,8
+ jne invalid_operand_size
+ basic_reg_imm_64bit:
+ cmp [size_declared],0
+ jne long_immediate_not_encodable
+ call operand_64bit
+ call get_simm32
+ cmp [value_type],4
+ jae long_immediate_not_encodable
+ jmp basic_reg_imm_32bit_ok
+ basic_reg_imm_8bit:
+ call get_byte_value
+ mov dl,al
+ mov bl,[base_code]
+ shr bl,3
+ xchg bl,[postbyte_register]
+ or bl,bl
+ jz basic_al_imm
+ mov [base_code],80h
+ call store_nomem_instruction
+ mov al,dl
+ stos byte [edi]
+ jmp instruction_assembled
+ basic_al_imm:
+ mov al,[base_code]
+ add al,4
+ stos byte [edi]
+ mov al,dl
+ stos byte [edi]
+ jmp instruction_assembled
+ basic_reg_imm_16bit:
+ call operand_16bit
+ call get_word_value
+ mov dx,ax
+ mov bl,[base_code]
+ shr bl,3
+ xchg bl,[postbyte_register]
+ cmp [value_type],0
+ jne basic_reg_imm_16bit_store
+ cmp [size_declared],0
+ jne basic_reg_imm_16bit_store
+ cmp dx,80h
+ jb basic_reg_simm_8bit
+ cmp dx,-80h
+ jae basic_reg_simm_8bit
+ basic_reg_imm_16bit_store:
+ or bl,bl
+ jz basic_ax_imm
+ mov [base_code],81h
+ call store_nomem_instruction
+ basic_store_imm_16bit:
+ mov ax,dx
+ call mark_relocation
+ stos word [edi]
+ jmp instruction_assembled
+ basic_reg_simm_8bit:
+ mov [base_code],83h
+ call store_nomem_instruction
+ mov al,dl
+ stos byte [edi]
+ jmp instruction_assembled
+ basic_ax_imm:
+ add [base_code],5
+ call store_instruction_code
+ jmp basic_store_imm_16bit
+ basic_reg_imm_32bit:
+ call operand_32bit
+ call get_dword_value
+ basic_reg_imm_32bit_ok:
+ mov edx,eax
+ mov bl,[base_code]
+ shr bl,3
+ xchg bl,[postbyte_register]
+ cmp [value_type],0
+ jne basic_reg_imm_32bit_store
+ cmp [size_declared],0
+ jne basic_reg_imm_32bit_store
+ cmp edx,80h
+ jb basic_reg_simm_8bit
+ cmp edx,-80h
+ jae basic_reg_simm_8bit
+ basic_reg_imm_32bit_store:
+ or bl,bl
+ jz basic_eax_imm
+ mov [base_code],81h
+ call store_nomem_instruction
+ basic_store_imm_32bit:
+ mov eax,edx
+ call mark_relocation
+ stos dword [edi]
+ jmp instruction_assembled
+ basic_eax_imm:
+ add [base_code],5
+ call store_instruction_code
+ jmp basic_store_imm_32bit
+ recoverable_unknown_size:
+ cmp [error_line],0
+ jne ignore_unknown_size
+ push [current_line]
+ pop [error_line]
+ mov [error],operand_size_not_specified
+ ignore_unknown_size:
+ ret
+single_operand_instruction:
+ mov [base_code],0F6h
+ mov [postbyte_register],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je single_reg
+ cmp al,'['
+ jne invalid_operand
+ single_mem:
+ call get_address
+ mov al,[operand_size]
+ cmp al,1
+ je single_mem_8bit
+ jb single_mem_nosize
+ call operand_autodetect
+ inc [base_code]
+ jmp instruction_ready
+ single_mem_nosize:
+ call recoverable_unknown_size
+ single_mem_8bit:
+ jmp instruction_ready
+ single_reg:
+ lods byte [esi]
+ call convert_register
+ mov bl,al
+ mov al,ah
+ cmp al,1
+ je single_reg_8bit
+ call operand_autodetect
+ inc [base_code]
+ single_reg_8bit:
+ jmp nomem_instruction_ready
+mov_instruction:
+ mov [base_code],88h
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je mov_reg
+ cmp al,'['
+ jne invalid_operand
+ mov_mem:
+ call get_address
+ push edx ebx ecx
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'('
+ je mov_mem_imm
+ cmp al,10h
+ jne invalid_operand
+ mov_mem_reg:
+ lods byte [esi]
+ cmp al,60h
+ jb mov_mem_general_reg
+ cmp al,70h
+ jb mov_mem_sreg
+ mov_mem_general_reg:
+ call convert_register
+ mov [postbyte_register],al
+ pop ecx ebx edx
+ cmp ah,1
+ je mov_mem_reg_8bit
+ mov al,ah
+ call operand_autodetect
+ mov al,[postbyte_register]
+ or al,bl
+ or al,bh
+ jz mov_mem_ax
+ inc [base_code]
+ jmp instruction_ready
+ mov_mem_reg_8bit:
+ or al,bl
+ or al,bh
+ jnz instruction_ready
+ mov_mem_al:
+ test ch,22h
+ jnz mov_mem_address16_al
+ test ch,44h
+ jnz mov_mem_address32_al
+ test ch,88h
+ jnz mov_mem_address64_al
+ or ch,ch
+ jnz invalid_address_size
+ cmp [code_type],64
+ je mov_mem_address64_al
+ cmp [code_type],32
+ je mov_mem_address32_al
+ cmp edx,10000h
+ jb mov_mem_address16_al
+ mov_mem_address32_al:
+ call store_segment_prefix_if_necessary
+ call address_32bit_prefix
+ mov [base_code],0A2h
+ store_mov_address32:
+ call store_instruction_code
+ call store_address_32bit_value
+ jmp instruction_assembled
+ mov_mem_address16_al:
+ call store_segment_prefix_if_necessary
+ call address_16bit_prefix
+ mov [base_code],0A2h
+ store_mov_address16:
+ cmp [code_type],64
+ je invalid_address
+ call store_instruction_code
+ mov eax,edx
+ stos word [edi]
+ cmp edx,10000h
+ jge value_out_of_range
+ jmp instruction_assembled
+ mov_mem_address64_al:
+ call store_segment_prefix_if_necessary
+ mov [base_code],0A2h
+ store_mov_address64:
+ call store_instruction_code
+ call store_address_64bit_value
+ jmp instruction_assembled
+ mov_mem_ax:
+ test ch,22h
+ jnz mov_mem_address16_ax
+ test ch,44h
+ jnz mov_mem_address32_ax
+ test ch,88h
+ jnz mov_mem_address64_ax
+ or ch,ch
+ jnz invalid_address_size
+ cmp [code_type],64
+ je mov_mem_address64_ax
+ cmp [code_type],32
+ je mov_mem_address32_ax
+ cmp edx,10000h
+ jb mov_mem_address16_ax
+ mov_mem_address32_ax:
+ call store_segment_prefix_if_necessary
+ call address_32bit_prefix
+ mov [base_code],0A3h
+ jmp store_mov_address32
+ mov_mem_address16_ax:
+ call store_segment_prefix_if_necessary
+ call address_16bit_prefix
+ mov [base_code],0A3h
+ jmp store_mov_address16
+ mov_mem_address64_ax:
+ call store_segment_prefix_if_necessary
+ mov [base_code],0A3h
+ jmp store_mov_address64
+ mov_mem_sreg:
+ sub al,61h
+ mov [postbyte_register],al
+ pop ecx ebx edx
+ mov ah,[operand_size]
+ or ah,ah
+ jz mov_mem_sreg_store
+ cmp ah,2
+ jne invalid_operand_size
+ mov_mem_sreg_store:
+ mov [base_code],8Ch
+ jmp instruction_ready
+ mov_mem_imm:
+ mov al,[operand_size]
+ cmp al,1
+ jb mov_mem_imm_nosize
+ je mov_mem_imm_8bit
+ cmp al,2
+ je mov_mem_imm_16bit
+ cmp al,4
+ je mov_mem_imm_32bit
+ cmp al,8
+ jne invalid_operand_size
+ mov_mem_imm_64bit:
+ cmp [size_declared],0
+ jne long_immediate_not_encodable
+ call operand_64bit
+ call get_simm32
+ cmp [value_type],4
+ jae long_immediate_not_encodable
+ jmp mov_mem_imm_32bit_store
+ mov_mem_imm_8bit:
+ call get_byte_value
+ mov byte [value],al
+ mov [postbyte_register],0
+ mov [base_code],0C6h
+ pop ecx ebx edx
+ call store_instruction_with_imm8
+ jmp instruction_assembled
+ mov_mem_imm_16bit:
+ call operand_16bit
+ call get_word_value
+ mov word [value],ax
+ mov [postbyte_register],0
+ mov [base_code],0C7h
+ pop ecx ebx edx
+ call store_instruction_with_imm16
+ jmp instruction_assembled
+ mov_mem_imm_nosize:
+ call recoverable_unknown_size
+ mov_mem_imm_32bit:
+ call operand_32bit
+ call get_dword_value
+ mov_mem_imm_32bit_store:
+ mov dword [value],eax
+ mov [postbyte_register],0
+ mov [base_code],0C7h
+ pop ecx ebx edx
+ call store_instruction_with_imm32
+ jmp instruction_assembled
+ mov_reg:
+ lods byte [esi]
+ mov ah,al
+ sub ah,10h
+ and ah,al
+ test ah,0F0h
+ jnz mov_sreg
+ call convert_register
+ mov [postbyte_register],al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ je mov_reg_mem
+ cmp al,'('
+ je mov_reg_imm
+ cmp al,10h
+ jne invalid_operand
+ mov_reg_reg:
+ lods byte [esi]
+ mov ah,al
+ sub ah,10h
+ and ah,al
+ test ah,0F0h
+ jnz mov_reg_sreg
+ call convert_register
+ mov bl,[postbyte_register]
+ mov [postbyte_register],al
+ mov al,ah
+ cmp al,1
+ je mov_reg_reg_8bit
+ call operand_autodetect
+ inc [base_code]
+ mov_reg_reg_8bit:
+ jmp nomem_instruction_ready
+ mov_reg_sreg:
+ mov bl,[postbyte_register]
+ mov ah,al
+ and al,1111b
+ mov [postbyte_register],al
+ shr ah,4
+ cmp ah,5
+ je mov_reg_creg
+ cmp ah,7
+ je mov_reg_dreg
+ ja mov_reg_treg
+ dec [postbyte_register]
+ cmp [operand_size],8
+ je mov_reg_sreg64
+ cmp [operand_size],4
+ je mov_reg_sreg32
+ cmp [operand_size],2
+ jne invalid_operand_size
+ call operand_16bit
+ jmp mov_reg_sreg_store
+ mov_reg_sreg64:
+ call operand_64bit
+ jmp mov_reg_sreg_store
+ mov_reg_sreg32:
+ call operand_32bit
+ mov_reg_sreg_store:
+ mov [base_code],8Ch
+ jmp nomem_instruction_ready
+ mov_reg_treg:
+ cmp ah,9
+ jne invalid_operand
+ mov [extended_code],24h
+ jmp mov_reg_xrx
+ mov_reg_dreg:
+ mov [extended_code],21h
+ jmp mov_reg_xrx
+ mov_reg_creg:
+ mov [extended_code],20h
+ mov_reg_xrx:
+ mov [base_code],0Fh
+ cmp [code_type],64
+ je mov_reg_xrx_64bit
+ cmp [operand_size],4
+ jne invalid_operand_size
+ cmp [postbyte_register],8
+ jne mov_reg_xrx_store
+ cmp [extended_code],20h
+ jne mov_reg_xrx_store
+ mov al,0F0h
+ stos byte [edi]
+ mov [postbyte_register],0
+ mov_reg_xrx_store:
+ jmp nomem_instruction_ready
+ mov_reg_xrx_64bit:
+ cmp [operand_size],8
+ jne invalid_operand_size
+ jmp nomem_instruction_ready
+ mov_reg_mem:
+ call get_address
+ mov al,[operand_size]
+ cmp al,1
+ je mov_reg_mem_8bit
+ call operand_autodetect
+ mov al,[postbyte_register]
+ or al,bl
+ or al,bh
+ jz mov_ax_mem
+ add [base_code],3
+ jmp instruction_ready
+ mov_reg_mem_8bit:
+ mov al,[postbyte_register]
+ or al,bl
+ or al,bh
+ jz mov_al_mem
+ add [base_code],2
+ jmp instruction_ready
+ mov_al_mem:
+ test ch,22h
+ jnz mov_al_mem_address16
+ test ch,44h
+ jnz mov_al_mem_address32
+ test ch,88h
+ jnz mov_al_mem_address64
+ or ch,ch
+ jnz invalid_address_size
+ cmp [code_type],64
+ je mov_al_mem_address64
+ cmp [code_type],32
+ je mov_al_mem_address32
+ cmp edx,10000h
+ jb mov_al_mem_address16
+ mov_al_mem_address32:
+ call store_segment_prefix_if_necessary
+ call address_32bit_prefix
+ mov [base_code],0A0h
+ jmp store_mov_address32
+ mov_al_mem_address16:
+ call store_segment_prefix_if_necessary
+ call address_16bit_prefix
+ mov [base_code],0A0h
+ jmp store_mov_address16
+ mov_al_mem_address64:
+ call store_segment_prefix_if_necessary
+ mov [base_code],0A0h
+ jmp store_mov_address64
+ mov_ax_mem:
+ test ch,22h
+ jnz mov_ax_mem_address16
+ test ch,44h
+ jnz mov_ax_mem_address32
+ test ch,88h
+ jnz mov_ax_mem_address64
+ or ch,ch
+ jnz invalid_address_size
+ cmp [code_type],64
+ je mov_ax_mem_address64
+ cmp [code_type],32
+ je mov_ax_mem_address32
+ cmp edx,10000h
+ jb mov_ax_mem_address16
+ mov_ax_mem_address32:
+ call store_segment_prefix_if_necessary
+ call address_32bit_prefix
+ mov [base_code],0A1h
+ jmp store_mov_address32
+ mov_ax_mem_address16:
+ call store_segment_prefix_if_necessary
+ call address_16bit_prefix
+ mov [base_code],0A1h
+ jmp store_mov_address16
+ mov_ax_mem_address64:
+ call store_segment_prefix_if_necessary
+ mov [base_code],0A1h
+ jmp store_mov_address64
+ mov_reg_imm:
+ mov al,[operand_size]
+ cmp al,1
+ je mov_reg_imm_8bit
+ cmp al,2
+ je mov_reg_imm_16bit
+ cmp al,4
+ je mov_reg_imm_32bit
+ cmp al,8
+ jne invalid_operand_size
+ mov_reg_imm_64bit:
+ call operand_64bit
+ call get_qword_value
+ mov ecx,edx
+ cmp [size_declared],0
+ jne mov_reg_imm_64bit_store
+ cmp [value_type],4
+ jae mov_reg_imm_64bit_store
+ cdq
+ cmp ecx,edx
+ je mov_reg_64bit_imm_32bit
+ mov_reg_imm_64bit_store:
+ push eax ecx
+ mov al,0B8h
+ call store_mov_reg_imm_code
+ pop edx eax
+ call mark_relocation
+ stos dword [edi]
+ mov eax,edx
+ stos dword [edi]
+ jmp instruction_assembled
+ mov_reg_imm_8bit:
+ call get_byte_value
+ mov dl,al
+ mov al,0B0h
+ call store_mov_reg_imm_code
+ mov al,dl
+ stos byte [edi]
+ jmp instruction_assembled
+ mov_reg_imm_16bit:
+ call get_word_value
+ mov dx,ax
+ call operand_16bit
+ mov al,0B8h
+ call store_mov_reg_imm_code
+ mov ax,dx
+ call mark_relocation
+ stos word [edi]
+ jmp instruction_assembled
+ mov_reg_imm_32bit:
+ call operand_32bit
+ call get_dword_value
+ mov edx,eax
+ mov al,0B8h
+ call store_mov_reg_imm_code
+ mov_store_imm_32bit:
+ mov eax,edx
+ call mark_relocation
+ stos dword [edi]
+ jmp instruction_assembled
+ store_mov_reg_imm_code:
+ mov ah,[postbyte_register]
+ test ah,1000b
+ jz mov_reg_imm_prefix_ok
+ or [rex_prefix],41h
+ mov_reg_imm_prefix_ok:
+ and ah,111b
+ add al,ah
+ mov [base_code],al
+ call store_instruction_code
+ ret
+ mov_reg_64bit_imm_32bit:
+ mov edx,eax
+ mov bl,[postbyte_register]
+ mov [postbyte_register],0
+ mov [base_code],0C7h
+ call store_nomem_instruction
+ jmp mov_store_imm_32bit
+ mov_sreg:
+ mov ah,al
+ and al,1111b
+ mov [postbyte_register],al
+ shr ah,4
+ cmp ah,5
+ je mov_creg
+ cmp ah,7
+ je mov_dreg
+ ja mov_treg
+ cmp al,2
+ je illegal_instruction
+ dec [postbyte_register]
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ je mov_sreg_mem
+ cmp al,10h
+ jne invalid_operand
+ mov_sreg_reg:
+ lods byte [esi]
+ call convert_register
+ or ah,ah
+ jz mov_sreg_reg_size_ok
+ cmp ah,2
+ jne invalid_operand_size
+ mov bl,al
+ mov_sreg_reg_size_ok:
+ mov [base_code],8Eh
+ jmp nomem_instruction_ready
+ mov_sreg_mem:
+ call get_address
+ mov al,[operand_size]
+ or al,al
+ jz mov_sreg_mem_size_ok
+ cmp al,2
+ jne invalid_operand_size
+ mov_sreg_mem_size_ok:
+ mov [base_code],8Eh
+ jmp instruction_ready
+ mov_treg:
+ cmp ah,9
+ jne invalid_operand
+ mov [extended_code],26h
+ jmp mov_xrx
+ mov_dreg:
+ mov [extended_code],23h
+ jmp mov_xrx
+ mov_creg:
+ mov [extended_code],22h
+ mov_xrx:
+ mov [base_code],0Fh
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ mov bl,al
+ cmp [code_type],64
+ je mov_xrx_64bit
+ cmp ah,4
+ jne invalid_operand_size
+ cmp [postbyte_register],8
+ jne mov_xrx_store
+ cmp [extended_code],22h
+ jne mov_xrx_store
+ mov al,0F0h
+ stos byte [edi]
+ mov [postbyte_register],0
+ mov_xrx_store:
+ jmp nomem_instruction_ready
+ mov_xrx_64bit:
+ cmp ah,8
+ je mov_xrx_store
+ jmp invalid_operand_size
+test_instruction:
+ mov [base_code],84h
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je test_reg
+ cmp al,'['
+ jne invalid_operand
+ test_mem:
+ call get_address
+ push edx ebx ecx
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'('
+ je test_mem_imm
+ cmp al,10h
+ jne invalid_operand
+ test_mem_reg:
+ lods byte [esi]
+ call convert_register
+ mov [postbyte_register],al
+ pop ecx ebx edx
+ mov al,ah
+ cmp al,1
+ je test_mem_reg_8bit
+ call operand_autodetect
+ inc [base_code]
+ test_mem_reg_8bit:
+ jmp instruction_ready
+ test_mem_imm:
+ mov al,[operand_size]
+ cmp al,1
+ jb test_mem_imm_nosize
+ je test_mem_imm_8bit
+ cmp al,2
+ je test_mem_imm_16bit
+ cmp al,4
+ je test_mem_imm_32bit
+ cmp al,8
+ jne invalid_operand_size
+ test_mem_imm_64bit:
+ cmp [size_declared],0
+ jne long_immediate_not_encodable
+ call operand_64bit
+ call get_simm32
+ cmp [value_type],4
+ jae long_immediate_not_encodable
+ jmp test_mem_imm_32bit_store
+ test_mem_imm_8bit:
+ call get_byte_value
+ mov byte [value],al
+ mov [postbyte_register],0
+ mov [base_code],0F6h
+ pop ecx ebx edx
+ call store_instruction_with_imm8
+ jmp instruction_assembled
+ test_mem_imm_16bit:
+ call operand_16bit
+ call get_word_value
+ mov word [value],ax
+ mov [postbyte_register],0
+ mov [base_code],0F7h
+ pop ecx ebx edx
+ call store_instruction_with_imm16
+ jmp instruction_assembled
+ test_mem_imm_nosize:
+ call recoverable_unknown_size
+ test_mem_imm_32bit:
+ call operand_32bit
+ call get_dword_value
+ test_mem_imm_32bit_store:
+ mov dword [value],eax
+ mov [postbyte_register],0
+ mov [base_code],0F7h
+ pop ecx ebx edx
+ call store_instruction_with_imm32
+ jmp instruction_assembled
+ test_reg:
+ lods byte [esi]
+ call convert_register
+ mov [postbyte_register],al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ je test_reg_mem
+ cmp al,'('
+ je test_reg_imm
+ cmp al,10h
+ jne invalid_operand
+ test_reg_reg:
+ lods byte [esi]
+ call convert_register
+ mov bl,[postbyte_register]
+ mov [postbyte_register],al
+ mov al,ah
+ cmp al,1
+ je test_reg_reg_8bit
+ call operand_autodetect
+ inc [base_code]
+ test_reg_reg_8bit:
+ jmp nomem_instruction_ready
+ test_reg_imm:
+ mov al,[operand_size]
+ cmp al,1
+ je test_reg_imm_8bit
+ cmp al,2
+ je test_reg_imm_16bit
+ cmp al,4
+ je test_reg_imm_32bit
+ cmp al,8
+ jne invalid_operand_size
+ test_reg_imm_64bit:
+ cmp [size_declared],0
+ jne long_immediate_not_encodable
+ call operand_64bit
+ call get_simm32
+ cmp [value_type],4
+ jae long_immediate_not_encodable
+ jmp test_reg_imm_32bit_store
+ test_reg_imm_8bit:
+ call get_byte_value
+ mov dl,al
+ mov bl,[postbyte_register]
+ mov [postbyte_register],0
+ mov [base_code],0F6h
+ or bl,bl
+ jz test_al_imm
+ call store_nomem_instruction
+ mov al,dl
+ stos byte [edi]
+ jmp instruction_assembled
+ test_al_imm:
+ mov [base_code],0A8h
+ call store_instruction_code
+ mov al,dl
+ stos byte [edi]
+ jmp instruction_assembled
+ test_reg_imm_16bit:
+ call operand_16bit
+ call get_word_value
+ mov dx,ax
+ mov bl,[postbyte_register]
+ mov [postbyte_register],0
+ mov [base_code],0F7h
+ or bl,bl
+ jz test_ax_imm
+ call store_nomem_instruction
+ mov ax,dx
+ call mark_relocation
+ stos word [edi]
+ jmp instruction_assembled
+ test_ax_imm:
+ mov [base_code],0A9h
+ call store_instruction_code
+ mov ax,dx
+ stos word [edi]
+ jmp instruction_assembled
+ test_reg_imm_32bit:
+ call operand_32bit
+ call get_dword_value
+ test_reg_imm_32bit_store:
+ mov edx,eax
+ mov bl,[postbyte_register]
+ mov [postbyte_register],0
+ mov [base_code],0F7h
+ or bl,bl
+ jz test_eax_imm
+ call store_nomem_instruction
+ mov eax,edx
+ call mark_relocation
+ stos dword [edi]
+ jmp instruction_assembled
+ test_eax_imm:
+ mov [base_code],0A9h
+ call store_instruction_code
+ mov eax,edx
+ stos dword [edi]
+ jmp instruction_assembled
+ test_reg_mem:
+ call get_address
+ mov al,[operand_size]
+ cmp al,1
+ je test_reg_mem_8bit
+ call operand_autodetect
+ inc [base_code]
+ test_reg_mem_8bit:
+ jmp instruction_ready
+xchg_instruction:
+ mov [base_code],86h
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je xchg_reg
+ cmp al,'['
+ jne invalid_operand
+ xchg_mem:
+ call get_address
+ push edx ebx ecx
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je test_mem_reg
+ jmp invalid_operand
+ xchg_reg:
+ lods byte [esi]
+ call convert_register
+ mov [postbyte_register],al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ je test_reg_mem
+ cmp al,10h
+ jne invalid_operand
+ xchg_reg_reg:
+ lods byte [esi]
+ call convert_register
+ mov bl,al
+ mov al,ah
+ cmp al,1
+ je xchg_reg_reg_8bit
+ call operand_autodetect
+ cmp [postbyte_register],0
+ je xchg_ax_reg
+ or bl,bl
+ jnz xchg_reg_reg_store
+ mov bl,[postbyte_register]
+ xchg_ax_reg:
+ cmp [code_type],64
+ jne xchg_ax_reg_ok
+ cmp ah,4
+ jne xchg_ax_reg_ok
+ or bl,bl
+ jz xchg_reg_reg_store
+ xchg_ax_reg_ok:
+ test bl,1000b
+ jz xchg_ax_reg_store
+ or [rex_prefix],41h
+ and bl,111b
+ xchg_ax_reg_store:
+ add bl,90h
+ mov [base_code],bl
+ call store_instruction_code
+ jmp instruction_assembled
+ xchg_reg_reg_store:
+ inc [base_code]
+ xchg_reg_reg_8bit:
+ jmp nomem_instruction_ready
+push_instruction:
+ mov [push_size],al
+ push_next:
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je push_reg
+ cmp al,'('
+ je push_imm
+ cmp al,'['
+ jne invalid_operand
+ push_mem:
+ call get_address
+ mov al,[operand_size]
+ mov ah,[push_size]
+ cmp al,2
+ je push_mem_16bit
+ cmp al,4
+ je push_mem_32bit
+ cmp al,8
+ je push_mem_64bit
+ or al,al
+ jnz invalid_operand_size
+ cmp ah,2
+ je push_mem_16bit
+ cmp ah,4
+ je push_mem_32bit
+ cmp ah,8
+ je push_mem_64bit
+ call recoverable_unknown_size
+ jmp push_mem_store
+ push_mem_16bit:
+ test ah,not 2
+ jnz invalid_operand_size
+ call operand_16bit
+ jmp push_mem_store
+ push_mem_32bit:
+ test ah,not 4
+ jnz invalid_operand_size
+ cmp [code_type],64
+ je illegal_instruction
+ call operand_32bit
+ jmp push_mem_store
+ push_mem_64bit:
+ test ah,not 8
+ jnz invalid_operand_size
+ cmp [code_type],64
+ jne illegal_instruction
+ push_mem_store:
+ mov [base_code],0FFh
+ mov [postbyte_register],110b
+ call store_instruction
+ jmp push_done
+ push_reg:
+ lods byte [esi]
+ mov ah,al
+ sub ah,10h
+ and ah,al
+ test ah,0F0h
+ jnz push_sreg
+ call convert_register
+ test al,1000b
+ jz push_reg_ok
+ or [rex_prefix],41h
+ and al,111b
+ push_reg_ok:
+ add al,50h
+ mov [base_code],al
+ mov al,ah
+ mov ah,[push_size]
+ cmp al,2
+ je push_reg_16bit
+ cmp al,4
+ je push_reg_32bit
+ cmp al,8
+ jne invalid_operand_size
+ push_reg_64bit:
+ test ah,not 8
+ jnz invalid_operand_size
+ cmp [code_type],64
+ jne illegal_instruction
+ jmp push_reg_store
+ push_reg_32bit:
+ test ah,not 4
+ jnz invalid_operand_size
+ cmp [code_type],64
+ je illegal_instruction
+ call operand_32bit
+ jmp push_reg_store
+ push_reg_16bit:
+ test ah,not 2
+ jnz invalid_operand_size
+ call operand_16bit
+ push_reg_store:
+ call store_instruction_code
+ jmp push_done
+ push_sreg:
+ mov bl,al
+ mov dl,[operand_size]
+ mov dh,[push_size]
+ cmp dl,2
+ je push_sreg16
+ cmp dl,4
+ je push_sreg32
+ cmp dl,8
+ je push_sreg64
+ or dl,dl
+ jnz invalid_operand_size
+ cmp dh,2
+ je push_sreg16
+ cmp dh,4
+ je push_sreg32
+ cmp dh,8
+ je push_sreg64
+ jmp push_sreg_store
+ push_sreg16:
+ test dh,not 2
+ jnz invalid_operand_size
+ call operand_16bit
+ jmp push_sreg_store
+ push_sreg32:
+ test dh,not 4
+ jnz invalid_operand_size
+ cmp [code_type],64
+ je illegal_instruction
+ call operand_32bit
+ jmp push_sreg_store
+ push_sreg64:
+ test dh,not 8
+ jnz invalid_operand_size
+ cmp [code_type],64
+ jne illegal_instruction
+ push_sreg_store:
+ mov al,bl
+ cmp al,70h
+ jae invalid_operand
+ sub al,61h
+ jc invalid_operand
+ cmp al,4
+ jae push_sreg_386
+ shl al,3
+ add al,6
+ mov [base_code],al
+ cmp [code_type],64
+ je illegal_instruction
+ jmp push_reg_store
+ push_sreg_386:
+ sub al,4
+ shl al,3
+ add al,0A0h
+ mov [extended_code],al
+ mov [base_code],0Fh
+ jmp push_reg_store
+ push_imm:
+ mov al,[operand_size]
+ mov ah,[push_size]
+ or al,al
+ je push_imm_size_ok
+ or ah,ah
+ je push_imm_size_ok
+ cmp al,ah
+ jne invalid_operand_size
+ push_imm_size_ok:
+ cmp al,2
+ je push_imm_16bit
+ cmp al,4
+ je push_imm_32bit
+ cmp al,8
+ je push_imm_64bit
+ cmp ah,2
+ je push_imm_optimized_16bit
+ cmp ah,4
+ je push_imm_optimized_32bit
+ cmp ah,8
+ je push_imm_optimized_64bit
+ or al,al
+ jnz invalid_operand_size
+ cmp [code_type],16
+ je push_imm_optimized_16bit
+ cmp [code_type],32
+ je push_imm_optimized_32bit
+ push_imm_optimized_64bit:
+ cmp [code_type],64
+ jne illegal_instruction
+ call get_simm32
+ mov edx,eax
+ cmp [value_type],0
+ jne push_imm_32bit_store
+ cmp eax,-80h
+ jl push_imm_32bit_store
+ cmp eax,80h
+ jge push_imm_32bit_store
+ jmp push_imm_8bit
+ push_imm_optimized_32bit:
+ cmp [code_type],64
+ je illegal_instruction
+ call get_dword_value
+ mov edx,eax
+ call operand_32bit
+ cmp [value_type],0
+ jne push_imm_32bit_store
+ cmp eax,-80h
+ jl push_imm_32bit_store
+ cmp eax,80h
+ jge push_imm_32bit_store
+ jmp push_imm_8bit
+ push_imm_optimized_16bit:
+ call get_word_value
+ mov dx,ax
+ call operand_16bit
+ cmp [value_type],0
+ jne push_imm_16bit_store
+ cmp ax,-80h
+ jl push_imm_16bit_store
+ cmp ax,80h
+ jge push_imm_16bit_store
+ push_imm_8bit:
+ mov ah,al
+ mov [base_code],6Ah
+ call store_instruction_code
+ mov al,ah
+ stos byte [edi]
+ jmp push_done
+ push_imm_16bit:
+ call get_word_value
+ mov dx,ax
+ call operand_16bit
+ push_imm_16bit_store:
+ mov [base_code],68h
+ call store_instruction_code
+ mov ax,dx
+ call mark_relocation
+ stos word [edi]
+ jmp push_done
+ push_imm_64bit:
+ cmp [code_type],64
+ jne illegal_instruction
+ call get_simm32
+ mov edx,eax
+ jmp push_imm_32bit_store
+ push_imm_32bit:
+ cmp [code_type],64
+ je illegal_instruction
+ call get_dword_value
+ mov edx,eax
+ call operand_32bit
+ push_imm_32bit_store:
+ mov [base_code],68h
+ call store_instruction_code
+ mov eax,edx
+ call mark_relocation
+ stos dword [edi]
+ push_done:
+ lods byte [esi]
+ dec esi
+ cmp al,0Fh
+ je instruction_assembled
+ or al,al
+ jz instruction_assembled
+ mov [operand_size],0
+ mov [size_override],0
+ mov [operand_prefix],0
+ mov [rex_prefix],0
+ jmp push_next
+pop_instruction:
+ mov [push_size],al
+ pop_next:
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je pop_reg
+ cmp al,'['
+ jne invalid_operand
+ pop_mem:
+ call get_address
+ mov al,[operand_size]
+ mov ah,[push_size]
+ cmp al,2
+ je pop_mem_16bit
+ cmp al,4
+ je pop_mem_32bit
+ cmp al,8
+ je pop_mem_64bit
+ or al,al
+ jnz invalid_operand_size
+ cmp ah,2
+ je pop_mem_16bit
+ cmp ah,4
+ je pop_mem_32bit
+ cmp ah,8
+ je pop_mem_64bit
+ call recoverable_unknown_size
+ jmp pop_mem_store
+ pop_mem_16bit:
+ test ah,not 2
+ jnz invalid_operand_size
+ call operand_16bit
+ jmp pop_mem_store
+ pop_mem_32bit:
+ test ah,not 4
+ jnz invalid_operand_size
+ cmp [code_type],64
+ je illegal_instruction
+ call operand_32bit
+ jmp pop_mem_store
+ pop_mem_64bit:
+ test ah,not 8
+ jnz invalid_operand_size
+ cmp [code_type],64
+ jne illegal_instruction
+ pop_mem_store:
+ mov [base_code],08Fh
+ mov [postbyte_register],0
+ call store_instruction
+ jmp pop_done
+ pop_reg:
+ lods byte [esi]
+ mov ah,al
+ sub ah,10h
+ and ah,al
+ test ah,0F0h
+ jnz pop_sreg
+ call convert_register
+ test al,1000b
+ jz pop_reg_ok
+ or [rex_prefix],41h
+ and al,111b
+ pop_reg_ok:
+ add al,58h
+ mov [base_code],al
+ mov al,ah
+ mov ah,[push_size]
+ cmp al,2
+ je pop_reg_16bit
+ cmp al,4
+ je pop_reg_32bit
+ cmp al,8
+ je pop_reg_64bit
+ jmp invalid_operand_size
+ pop_reg_64bit:
+ test ah,not 8
+ jnz invalid_operand_size
+ cmp [code_type],64
+ jne illegal_instruction
+ jmp pop_reg_store
+ pop_reg_32bit:
+ test ah,not 4
+ jnz invalid_operand_size
+ cmp [code_type],64
+ je illegal_instruction
+ call operand_32bit
+ jmp pop_reg_store
+ pop_reg_16bit:
+ test ah,not 2
+ jnz invalid_operand_size
+ call operand_16bit
+ pop_reg_store:
+ call store_instruction_code
+ pop_done:
+ lods byte [esi]
+ dec esi
+ cmp al,0Fh
+ je instruction_assembled
+ or al,al
+ jz instruction_assembled
+ mov [operand_size],0
+ mov [size_override],0
+ mov [operand_prefix],0
+ mov [rex_prefix],0
+ jmp pop_next
+ pop_sreg:
+ mov dl,[operand_size]
+ mov dh,[push_size]
+ cmp al,62h
+ je pop_cs
+ mov bl,al
+ cmp dl,2
+ je pop_sreg16
+ cmp dl,4
+ je pop_sreg32
+ cmp dl,8
+ je pop_sreg64
+ or dl,dl
+ jnz invalid_operand_size
+ cmp dh,2
+ je pop_sreg16
+ cmp dh,4
+ je pop_sreg32
+ cmp dh,8
+ je pop_sreg64
+ jmp pop_sreg_store
+ pop_sreg16:
+ test dh,not 2
+ jnz invalid_operand_size
+ call operand_16bit
+ jmp pop_sreg_store
+ pop_sreg32:
+ test dh,not 4
+ jnz invalid_operand_size
+ cmp [code_type],64
+ je illegal_instruction
+ call operand_32bit
+ jmp pop_sreg_store
+ pop_sreg64:
+ test dh,not 8
+ jnz invalid_operand_size
+ cmp [code_type],64
+ jne illegal_instruction
+ pop_sreg_store:
+ mov al,bl
+ cmp al,70h
+ jae invalid_operand
+ sub al,61h
+ jc invalid_operand
+ cmp al,4
+ jae pop_sreg_386
+ shl al,3
+ add al,7
+ mov [base_code],al
+ cmp [code_type],64
+ je illegal_instruction
+ jmp pop_reg_store
+ pop_cs:
+ cmp [code_type],16
+ jne illegal_instruction
+ cmp dl,2
+ je pop_cs_store
+ or dl,dl
+ jnz invalid_operand_size
+ cmp dh,2
+ je pop_cs_store
+ or dh,dh
+ jnz illegal_instruction
+ pop_cs_store:
+ test dh,not 2
+ jnz invalid_operand_size
+ mov al,0Fh
+ stos byte [edi]
+ jmp pop_done
+ pop_sreg_386:
+ sub al,4
+ shl al,3
+ add al,0A1h
+ mov [extended_code],al
+ mov [base_code],0Fh
+ jmp pop_reg_store
+inc_instruction:
+ mov [base_code],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je inc_reg
+ cmp al,'['
+ je inc_mem
+ jne invalid_operand
+ inc_mem:
+ call get_address
+ mov al,[operand_size]
+ cmp al,1
+ je inc_mem_8bit
+ jb inc_mem_nosize
+ call operand_autodetect
+ mov al,0FFh
+ xchg al,[base_code]
+ mov [postbyte_register],al
+ jmp instruction_ready
+ inc_mem_nosize:
+ call recoverable_unknown_size
+ inc_mem_8bit:
+ mov al,0FEh
+ xchg al,[base_code]
+ mov [postbyte_register],al
+ jmp instruction_ready
+ inc_reg:
+ lods byte [esi]
+ call convert_register
+ mov bl,al
+ mov al,0FEh
+ xchg al,[base_code]
+ mov [postbyte_register],al
+ mov al,ah
+ cmp al,1
+ je inc_reg_8bit
+ call operand_autodetect
+ cmp [code_type],64
+ je inc_reg_long_form
+ mov al,[postbyte_register]
+ shl al,3
+ add al,bl
+ add al,40h
+ mov [base_code],al
+ call store_instruction_code
+ jmp instruction_assembled
+ inc_reg_long_form:
+ inc [base_code]
+ inc_reg_8bit:
+ jmp nomem_instruction_ready
+set_instruction:
+ mov [base_code],0Fh
+ mov [extended_code],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je set_reg
+ cmp al,'['
+ jne invalid_operand
+ set_mem:
+ call get_address
+ cmp [operand_size],1
+ ja invalid_operand_size
+ mov [postbyte_register],0
+ jmp instruction_ready
+ set_reg:
+ lods byte [esi]
+ call convert_register
+ cmp ah,1
+ jne invalid_operand_size
+ mov bl,al
+ mov [postbyte_register],0
+ jmp nomem_instruction_ready
+arpl_instruction:
+ cmp [code_type],64
+ je illegal_instruction
+ mov [base_code],63h
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je arpl_reg
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ mov [postbyte_register],al
+ cmp ah,2
+ jne invalid_operand_size
+ jmp instruction_ready
+ arpl_reg:
+ lods byte [esi]
+ call convert_register
+ cmp ah,2
+ jne invalid_operand_size
+ mov bl,al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ mov [postbyte_register],al
+ jmp nomem_instruction_ready
+bound_instruction:
+ cmp [code_type],64
+ je illegal_instruction
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ mov [postbyte_register],al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ mov al,[operand_size]
+ cmp al,2
+ je bound_store
+ cmp al,4
+ jne invalid_operand_size
+ bound_store:
+ call operand_autodetect
+ mov [base_code],62h
+ jmp instruction_ready
+enter_instruction:
+ lods byte [esi]
+ call get_size_operator
+ cmp ah,2
+ je enter_imm16_size_ok
+ or ah,ah
+ jnz invalid_operand_size
+ enter_imm16_size_ok:
+ cmp al,'('
+ jne invalid_operand
+ call get_word_value
+ cmp [next_pass_needed],0
+ jne enter_imm16_ok
+ cmp [value_type],0
+ jne invalid_use_of_symbol
+ test eax,eax
+ js value_out_of_range
+ enter_imm16_ok:
+ push eax
+ mov [operand_size],0
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp ah,1
+ je enter_imm8_size_ok
+ or ah,ah
+ jnz invalid_operand_size
+ enter_imm8_size_ok:
+ cmp al,'('
+ jne invalid_operand
+ call get_byte_value
+ cmp [next_pass_needed],0
+ jne enter_imm8_ok
+ test eax,eax
+ js value_out_of_range
+ enter_imm8_ok:
+ mov dl,al
+ pop ebx
+ mov al,0C8h
+ stos byte [edi]
+ mov ax,bx
+ stos word [edi]
+ mov al,dl
+ stos byte [edi]
+ jmp instruction_assembled
+ret_instruction_only64:
+ cmp [code_type],64
+ jne illegal_instruction
+ jmp ret_instruction
+ret_instruction_32bit_except64:
+ cmp [code_type],64
+ je illegal_instruction
+ret_instruction_32bit:
+ call operand_32bit
+ jmp ret_instruction
+ret_instruction_16bit:
+ call operand_16bit
+ jmp ret_instruction
+retf_instruction:
+ cmp [code_type],64
+ jne ret_instruction
+ret_instruction_64bit:
+ call operand_64bit
+ret_instruction:
+ mov [base_code],al
+ lods byte [esi]
+ dec esi
+ or al,al
+ jz simple_ret
+ cmp al,0Fh
+ je simple_ret
+ lods byte [esi]
+ call get_size_operator
+ or ah,ah
+ jz ret_imm
+ cmp ah,2
+ je ret_imm
+ jmp invalid_operand_size
+ ret_imm:
+ cmp al,'('
+ jne invalid_operand
+ call get_word_value
+ cmp [next_pass_needed],0
+ jne ret_imm_ok
+ cmp [value_type],0
+ jne invalid_use_of_symbol
+ test eax,eax
+ js value_out_of_range
+ ret_imm_ok:
+ cmp [size_declared],0
+ jne ret_imm_store
+ or ax,ax
+ jz simple_ret
+ ret_imm_store:
+ mov dx,ax
+ call store_instruction_code
+ mov ax,dx
+ stos word [edi]
+ jmp instruction_assembled
+ simple_ret:
+ inc [base_code]
+ call store_instruction_code
+ jmp instruction_assembled
+lea_instruction:
+ mov [base_code],8Dh
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ mov [postbyte_register],al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ xor al,al
+ xchg al,[operand_size]
+ push eax
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_operand
+ mov [size_override],-1
+ call get_address
+ pop eax
+ mov [operand_size],al
+ call operand_autodetect
+ jmp instruction_ready
+ls_instruction:
+ or al,al
+ jz les_instruction
+ cmp al,3
+ jz lds_instruction
+ add al,0B0h
+ mov [extended_code],al
+ mov [base_code],0Fh
+ jmp ls_code_ok
+ les_instruction:
+ mov [base_code],0C4h
+ jmp ls_short_code
+ lds_instruction:
+ mov [base_code],0C5h
+ ls_short_code:
+ cmp [code_type],64
+ je illegal_instruction
+ ls_code_ok:
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ mov [postbyte_register],al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ add [operand_size],2
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ mov al,[operand_size]
+ cmp al,4
+ je ls_16bit
+ cmp al,6
+ je ls_32bit
+ cmp al,10
+ je ls_64bit
+ jmp invalid_operand_size
+ ls_16bit:
+ call operand_16bit
+ jmp instruction_ready
+ ls_32bit:
+ call operand_32bit
+ jmp instruction_ready
+ ls_64bit:
+ call operand_64bit
+ jmp instruction_ready
+sh_instruction:
+ mov [postbyte_register],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je sh_reg
+ cmp al,'['
+ jne invalid_operand
+ sh_mem:
+ call get_address
+ push edx ebx ecx
+ mov al,[operand_size]
+ push eax
+ mov [operand_size],0
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'('
+ je sh_mem_imm
+ cmp al,10h
+ jne invalid_operand
+ sh_mem_reg:
+ lods byte [esi]
+ cmp al,11h
+ jne invalid_operand
+ pop eax ecx ebx edx
+ cmp al,1
+ je sh_mem_cl_8bit
+ jb sh_mem_cl_nosize
+ call operand_autodetect
+ mov [base_code],0D3h
+ jmp instruction_ready
+ sh_mem_cl_nosize:
+ call recoverable_unknown_size
+ sh_mem_cl_8bit:
+ mov [base_code],0D2h
+ jmp instruction_ready
+ sh_mem_imm:
+ mov al,[operand_size]
+ or al,al
+ jz sh_mem_imm_size_ok
+ cmp al,1
+ jne invalid_operand_size
+ sh_mem_imm_size_ok:
+ call get_byte_value
+ mov byte [value],al
+ pop eax ecx ebx edx
+ cmp al,1
+ je sh_mem_imm_8bit
+ jb sh_mem_imm_nosize
+ call operand_autodetect
+ cmp byte [value],1
+ je sh_mem_1
+ mov [base_code],0C1h
+ call store_instruction_with_imm8
+ jmp instruction_assembled
+ sh_mem_1:
+ mov [base_code],0D1h
+ jmp instruction_ready
+ sh_mem_imm_nosize:
+ call recoverable_unknown_size
+ sh_mem_imm_8bit:
+ cmp byte [value],1
+ je sh_mem_1_8bit
+ mov [base_code],0C0h
+ call store_instruction_with_imm8
+ jmp instruction_assembled
+ sh_mem_1_8bit:
+ mov [base_code],0D0h
+ jmp instruction_ready
+ sh_reg:
+ lods byte [esi]
+ call convert_register
+ mov bx,ax
+ mov [operand_size],0
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'('
+ je sh_reg_imm
+ cmp al,10h
+ jne invalid_operand
+ sh_reg_reg:
+ lods byte [esi]
+ cmp al,11h
+ jne invalid_operand
+ mov al,bh
+ cmp al,1
+ je sh_reg_cl_8bit
+ call operand_autodetect
+ mov [base_code],0D3h
+ jmp nomem_instruction_ready
+ sh_reg_cl_8bit:
+ mov [base_code],0D2h
+ jmp nomem_instruction_ready
+ sh_reg_imm:
+ mov al,[operand_size]
+ or al,al
+ jz sh_reg_imm_size_ok
+ cmp al,1
+ jne invalid_operand_size
+ sh_reg_imm_size_ok:
+ push ebx
+ call get_byte_value
+ mov dl,al
+ pop ebx
+ mov al,bh
+ cmp al,1
+ je sh_reg_imm_8bit
+ call operand_autodetect
+ cmp dl,1
+ je sh_reg_1
+ mov [base_code],0C1h
+ call store_nomem_instruction
+ mov al,dl
+ stos byte [edi]
+ jmp instruction_assembled
+ sh_reg_1:
+ mov [base_code],0D1h
+ jmp nomem_instruction_ready
+ sh_reg_imm_8bit:
+ cmp dl,1
+ je sh_reg_1_8bit
+ mov [base_code],0C0h
+ call store_nomem_instruction
+ mov al,dl
+ stos byte [edi]
+ jmp instruction_assembled
+ sh_reg_1_8bit:
+ mov [base_code],0D0h
+ jmp nomem_instruction_ready
+shd_instruction:
+ mov [base_code],0Fh
+ mov [extended_code],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je shd_reg
+ cmp al,'['
+ jne invalid_operand
+ shd_mem:
+ call get_address
+ push edx ebx ecx
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ mov [postbyte_register],al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ mov al,ah
+ mov [operand_size],0
+ push eax
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'('
+ je shd_mem_reg_imm
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ cmp al,11h
+ jne invalid_operand
+ pop eax ecx ebx edx
+ call operand_autodetect
+ inc [extended_code]
+ jmp instruction_ready
+ shd_mem_reg_imm:
+ mov al,[operand_size]
+ or al,al
+ jz shd_mem_reg_imm_size_ok
+ cmp al,1
+ jne invalid_operand_size
+ shd_mem_reg_imm_size_ok:
+ call get_byte_value
+ mov byte [value],al
+ pop eax ecx ebx edx
+ call operand_autodetect
+ call store_instruction_with_imm8
+ jmp instruction_assembled
+ shd_reg:
+ lods byte [esi]
+ call convert_register
+ mov [postbyte_register],al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ mov bl,[postbyte_register]
+ mov [postbyte_register],al
+ mov al,ah
+ push eax ebx
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ mov [operand_size],0
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'('
+ je shd_reg_reg_imm
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ cmp al,11h
+ jne invalid_operand
+ pop ebx eax
+ call operand_autodetect
+ inc [extended_code]
+ jmp nomem_instruction_ready
+ shd_reg_reg_imm:
+ mov al,[operand_size]
+ or al,al
+ jz shd_reg_reg_imm_size_ok
+ cmp al,1
+ jne invalid_operand_size
+ shd_reg_reg_imm_size_ok:
+ call get_byte_value
+ mov dl,al
+ pop ebx eax
+ call operand_autodetect
+ call store_nomem_instruction
+ mov al,dl
+ stos byte [edi]
+ jmp instruction_assembled
+movx_instruction:
+ mov [base_code],0Fh
+ mov [extended_code],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ mov [postbyte_register],al
+ mov al,ah
+ push eax
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ mov [operand_size],0
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je movx_reg
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ pop eax
+ mov ah,[operand_size]
+ or ah,ah
+ jz movx_unknown_size
+ cmp ah,al
+ jae invalid_operand_size
+ cmp ah,1
+ je movx_mem_store
+ cmp ah,2
+ jne invalid_operand_size
+ inc [extended_code]
+ movx_mem_store:
+ call operand_autodetect
+ jmp instruction_ready
+ movx_unknown_size:
+ call recoverable_unknown_size
+ jmp movx_mem_store
+ movx_reg:
+ lods byte [esi]
+ call convert_register
+ pop ebx
+ xchg bl,al
+ cmp ah,al
+ jae invalid_operand_size
+ cmp ah,1
+ je movx_reg_8bit
+ cmp ah,2
+ je movx_reg_16bit
+ jmp invalid_operand_size
+ movx_reg_8bit:
+ call operand_autodetect
+ jmp nomem_instruction_ready
+ movx_reg_16bit:
+ call operand_autodetect
+ inc [extended_code]
+ jmp nomem_instruction_ready
+movsxd_instruction:
+ mov [base_code],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ mov [postbyte_register],al
+ cmp ah,8
+ jne invalid_operand_size
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ mov [operand_size],0
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je movsxd_reg
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ cmp [operand_size],4
+ je movsxd_mem_store
+ cmp [operand_size],0
+ jne invalid_operand_size
+ movsxd_mem_store:
+ call operand_64bit
+ jmp instruction_ready
+ movsxd_reg:
+ lods byte [esi]
+ call convert_register
+ cmp ah,4
+ jne invalid_operand_size
+ mov bl,al
+ call operand_64bit
+ jmp nomem_instruction_ready
+bt_instruction:
+ mov [postbyte_register],al
+ shl al,3
+ add al,83h
+ mov [extended_code],al
+ mov [base_code],0Fh
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je bt_reg
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ push eax ebx ecx
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ cmp byte [esi],'('
+ je bt_mem_imm
+ cmp byte [esi],11h
+ jne bt_mem_reg
+ cmp byte [esi+2],'('
+ je bt_mem_imm
+ bt_mem_reg:
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ mov [postbyte_register],al
+ pop ecx ebx edx
+ mov al,ah
+ call operand_autodetect
+ jmp instruction_ready
+ bt_mem_imm:
+ xor al,al
+ xchg al,[operand_size]
+ push eax
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'('
+ jne invalid_operand
+ mov al,[operand_size]
+ or al,al
+ jz bt_mem_imm_size_ok
+ cmp al,1
+ jne invalid_operand_size
+ bt_mem_imm_size_ok:
+ call get_byte_value
+ mov byte [value],al
+ pop eax
+ or al,al
+ jz bt_mem_imm_nosize
+ call operand_autodetect
+ bt_mem_imm_store:
+ pop ecx ebx edx
+ mov [extended_code],0BAh
+ call store_instruction_with_imm8
+ jmp instruction_assembled
+ bt_mem_imm_nosize:
+ call recoverable_unknown_size
+ jmp bt_mem_imm_store
+ bt_reg:
+ lods byte [esi]
+ call convert_register
+ mov bl,al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ cmp byte [esi],'('
+ je bt_reg_imm
+ cmp byte [esi],11h
+ jne bt_reg_reg
+ cmp byte [esi+2],'('
+ je bt_reg_imm
+ bt_reg_reg:
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ mov [postbyte_register],al
+ mov al,ah
+ call operand_autodetect
+ jmp nomem_instruction_ready
+ bt_reg_imm:
+ xor al,al
+ xchg al,[operand_size]
+ push eax ebx
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'('
+ jne invalid_operand
+ mov al,[operand_size]
+ or al,al
+ jz bt_reg_imm_size_ok
+ cmp al,1
+ jne invalid_operand_size
+ bt_reg_imm_size_ok:
+ call get_byte_value
+ mov byte [value],al
+ pop ebx eax
+ call operand_autodetect
+ bt_reg_imm_store:
+ mov [extended_code],0BAh
+ call store_nomem_instruction
+ mov al,byte [value]
+ stos byte [edi]
+ jmp instruction_assembled
+bs_instruction:
+ mov [extended_code],al
+ mov [base_code],0Fh
+ call get_reg_mem
+ jc bs_reg_reg
+ mov al,[operand_size]
+ call operand_autodetect
+ jmp instruction_ready
+ bs_reg_reg:
+ mov al,ah
+ call operand_autodetect
+ jmp nomem_instruction_ready
+ get_reg_mem:
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ mov [postbyte_register],al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je get_reg_reg
+ cmp al,'['
+ jne invalid_argument
+ call get_address
+ clc
+ ret
+ get_reg_reg:
+ lods byte [esi]
+ call convert_register
+ mov bl,al
+ stc
+ ret
+
+imul_instruction:
+ mov [base_code],0F6h
+ mov [postbyte_register],5
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je imul_reg
+ cmp al,'['
+ jne invalid_operand
+ imul_mem:
+ call get_address
+ mov al,[operand_size]
+ cmp al,1
+ je imul_mem_8bit
+ jb imul_mem_nosize
+ call operand_autodetect
+ inc [base_code]
+ jmp instruction_ready
+ imul_mem_nosize:
+ call recoverable_unknown_size
+ imul_mem_8bit:
+ jmp instruction_ready
+ imul_reg:
+ lods byte [esi]
+ call convert_register
+ cmp byte [esi],','
+ je imul_reg_
+ mov bl,al
+ mov al,ah
+ cmp al,1
+ je imul_reg_8bit
+ call operand_autodetect
+ inc [base_code]
+ imul_reg_8bit:
+ jmp nomem_instruction_ready
+ imul_reg_:
+ mov [postbyte_register],al
+ inc esi
+ cmp byte [esi],'('
+ je imul_reg_imm
+ cmp byte [esi],11h
+ jne imul_reg_noimm
+ cmp byte [esi+2],'('
+ je imul_reg_imm
+ imul_reg_noimm:
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je imul_reg_reg
+ cmp al,'['
+ jne invalid_operand
+ imul_reg_mem:
+ call get_address
+ push edx ebx ecx
+ cmp byte [esi],','
+ je imul_reg_mem_imm
+ mov al,[operand_size]
+ call operand_autodetect
+ pop ecx ebx edx
+ mov [base_code],0Fh
+ mov [extended_code],0AFh
+ jmp instruction_ready
+ imul_reg_mem_imm:
+ inc esi
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'('
+ jne invalid_operand
+ mov al,[operand_size]
+ cmp al,2
+ je imul_reg_mem_imm_16bit
+ cmp al,4
+ je imul_reg_mem_imm_32bit
+ cmp al,8
+ jne invalid_operand_size
+ imul_reg_mem_imm_64bit:
+ cmp [size_declared],0
+ jne long_immediate_not_encodable
+ call operand_64bit
+ call get_simm32
+ cmp [value_type],4
+ jae long_immediate_not_encodable
+ jmp imul_reg_mem_imm_32bit_ok
+ imul_reg_mem_imm_16bit:
+ call operand_16bit
+ call get_word_value
+ mov word [value],ax
+ cmp [value_type],0
+ jne imul_reg_mem_imm_16bit_store
+ cmp [size_declared],0
+ jne imul_reg_mem_imm_16bit_store
+ cmp ax,-80h
+ jl imul_reg_mem_imm_16bit_store
+ cmp ax,80h
+ jl imul_reg_mem_imm_8bit_store
+ imul_reg_mem_imm_16bit_store:
+ pop ecx ebx edx
+ mov [base_code],69h
+ call store_instruction_with_imm16
+ jmp instruction_assembled
+ imul_reg_mem_imm_32bit:
+ call operand_32bit
+ call get_dword_value
+ imul_reg_mem_imm_32bit_ok:
+ mov dword [value],eax
+ cmp [value_type],0
+ jne imul_reg_mem_imm_32bit_store
+ cmp [size_declared],0
+ jne imul_reg_mem_imm_32bit_store
+ cmp eax,-80h
+ jl imul_reg_mem_imm_32bit_store
+ cmp eax,80h
+ jl imul_reg_mem_imm_8bit_store
+ imul_reg_mem_imm_32bit_store:
+ pop ecx ebx edx
+ mov [base_code],69h
+ call store_instruction_with_imm32
+ jmp instruction_assembled
+ imul_reg_mem_imm_8bit_store:
+ pop ecx ebx edx
+ mov [base_code],6Bh
+ call store_instruction_with_imm8
+ jmp instruction_assembled
+ imul_reg_imm:
+ mov bl,[postbyte_register]
+ dec esi
+ jmp imul_reg_reg_imm
+ imul_reg_reg:
+ lods byte [esi]
+ call convert_register
+ mov bl,al
+ cmp byte [esi],','
+ je imul_reg_reg_imm
+ mov al,ah
+ call operand_autodetect
+ mov [base_code],0Fh
+ mov [extended_code],0AFh
+ jmp nomem_instruction_ready
+ imul_reg_reg_imm:
+ inc esi
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'('
+ jne invalid_operand
+ mov al,[operand_size]
+ cmp al,2
+ je imul_reg_reg_imm_16bit
+ cmp al,4
+ je imul_reg_reg_imm_32bit
+ cmp al,8
+ jne invalid_operand_size
+ imul_reg_reg_imm_64bit:
+ cmp [size_declared],0
+ jne long_immediate_not_encodable
+ call operand_64bit
+ push ebx
+ call get_simm32
+ cmp [value_type],4
+ jae long_immediate_not_encodable
+ jmp imul_reg_reg_imm_32bit_ok
+ imul_reg_reg_imm_16bit:
+ call operand_16bit
+ push ebx
+ call get_word_value
+ pop ebx
+ mov dx,ax
+ cmp [value_type],0
+ jne imul_reg_reg_imm_16bit_store
+ cmp [size_declared],0
+ jne imul_reg_reg_imm_16bit_store
+ cmp ax,-80h
+ jl imul_reg_reg_imm_16bit_store
+ cmp ax,80h
+ jl imul_reg_reg_imm_8bit_store
+ imul_reg_reg_imm_16bit_store:
+ mov [base_code],69h
+ call store_nomem_instruction
+ mov ax,dx
+ call mark_relocation
+ stos word [edi]
+ jmp instruction_assembled
+ imul_reg_reg_imm_32bit:
+ call operand_32bit
+ push ebx
+ call get_dword_value
+ imul_reg_reg_imm_32bit_ok:
+ pop ebx
+ mov edx,eax
+ cmp [value_type],0
+ jne imul_reg_reg_imm_32bit_store
+ cmp [size_declared],0
+ jne imul_reg_reg_imm_32bit_store
+ cmp eax,-80h
+ jl imul_reg_reg_imm_32bit_store
+ cmp eax,80h
+ jl imul_reg_reg_imm_8bit_store
+ imul_reg_reg_imm_32bit_store:
+ mov [base_code],69h
+ call store_nomem_instruction
+ mov eax,edx
+ call mark_relocation
+ stos dword [edi]
+ jmp instruction_assembled
+ imul_reg_reg_imm_8bit_store:
+ mov [base_code],6Bh
+ call store_nomem_instruction
+ mov al,dl
+ stos byte [edi]
+ jmp instruction_assembled
+in_instruction:
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ or al,al
+ jnz invalid_operand
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ mov al,ah
+ push eax
+ mov [operand_size],0
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'('
+ je in_imm
+ cmp al,10h
+ je in_reg
+ jmp invalid_operand
+ in_reg:
+ lods byte [esi]
+ cmp al,22h
+ jne invalid_operand
+ pop eax
+ cmp al,1
+ je in_al_dx
+ cmp al,2
+ je in_ax_dx
+ cmp al,4
+ jne invalid_operand_size
+ in_ax_dx:
+ call operand_autodetect
+ mov [base_code],0EDh
+ call store_instruction_code
+ jmp instruction_assembled
+ in_al_dx:
+ mov al,0ECh
+ stos byte [edi]
+ jmp instruction_assembled
+ in_imm:
+ mov al,[operand_size]
+ or al,al
+ jz in_imm_size_ok
+ cmp al,1
+ jne invalid_operand_size
+ in_imm_size_ok:
+ call get_byte_value
+ mov dl,al
+ pop eax
+ cmp al,1
+ je in_al_imm
+ cmp al,2
+ je in_ax_imm
+ cmp al,4
+ jne invalid_operand_size
+ in_ax_imm:
+ call operand_autodetect
+ mov [base_code],0E5h
+ call store_instruction_code
+ mov al,dl
+ stos byte [edi]
+ jmp instruction_assembled
+ in_al_imm:
+ mov al,0E4h
+ stos byte [edi]
+ mov al,dl
+ stos byte [edi]
+ jmp instruction_assembled
+out_instruction:
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'('
+ je out_imm
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ cmp al,22h
+ jne invalid_operand
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ mov [operand_size],0
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ or al,al
+ jnz invalid_operand
+ mov al,ah
+ cmp al,1
+ je out_dx_al
+ cmp al,2
+ je out_dx_ax
+ cmp al,4
+ jne invalid_operand_size
+ out_dx_ax:
+ call operand_autodetect
+ mov [base_code],0EFh
+ call store_instruction_code
+ jmp instruction_assembled
+ out_dx_al:
+ mov al,0EEh
+ stos byte [edi]
+ jmp instruction_assembled
+ out_imm:
+ mov al,[operand_size]
+ or al,al
+ jz out_imm_size_ok
+ cmp al,1
+ jne invalid_operand_size
+ out_imm_size_ok:
+ call get_byte_value
+ mov dl,al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ mov [operand_size],0
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ or al,al
+ jnz invalid_operand
+ mov al,ah
+ cmp al,1
+ je out_imm_al
+ cmp al,2
+ je out_imm_ax
+ cmp al,4
+ jne invalid_operand_size
+ out_imm_ax:
+ call operand_autodetect
+ mov [base_code],0E7h
+ call store_instruction_code
+ mov al,dl
+ stos byte [edi]
+ jmp instruction_assembled
+ out_imm_al:
+ mov al,0E6h
+ stos byte [edi]
+ mov al,dl
+ stos byte [edi]
+ jmp instruction_assembled
+
+call_instruction:
+ mov [postbyte_register],10b
+ mov [base_code],0E8h
+ mov [extended_code],9Ah
+ jmp process_jmp
+jmp_instruction:
+ mov [postbyte_register],100b
+ mov [base_code],0E9h
+ mov [extended_code],0EAh
+ process_jmp:
+ lods byte [esi]
+ call get_jump_operator
+ call get_size_operator
+ cmp al,'('
+ je jmp_imm
+ mov [base_code],0FFh
+ cmp al,10h
+ je jmp_reg
+ cmp al,'['
+ jne invalid_operand
+ jmp_mem:
+ cmp [jump_type],1
+ je illegal_instruction
+ call get_address
+ mov edx,eax
+ mov al,[operand_size]
+ or al,al
+ jz jmp_mem_size_not_specified
+ cmp al,2
+ je jmp_mem_16bit
+ cmp al,4
+ je jmp_mem_32bit
+ cmp al,6
+ je jmp_mem_48bit
+ cmp al,8
+ je jmp_mem_64bit
+ cmp al,10
+ je jmp_mem_80bit
+ jmp invalid_operand_size
+ jmp_mem_size_not_specified:
+ cmp [jump_type],3
+ je jmp_mem_far
+ cmp [jump_type],2
+ je jmp_mem_near
+ call recoverable_unknown_size
+ jmp_mem_near:
+ cmp [code_type],16
+ je jmp_mem_16bit
+ cmp [code_type],32
+ je jmp_mem_near_32bit
+ jmp_mem_64bit:
+ cmp [jump_type],3
+ je invalid_operand_size
+ cmp [code_type],64
+ jne illegal_instruction
+ jmp instruction_ready
+ jmp_mem_far:
+ cmp [code_type],16
+ je jmp_mem_far_32bit
+ jmp_mem_48bit:
+ call operand_32bit
+ jmp_mem_far_store:
+ cmp [jump_type],2
+ je invalid_operand_size
+ inc [postbyte_register]
+ jmp instruction_ready
+ jmp_mem_80bit:
+ call operand_64bit
+ jmp jmp_mem_far_store
+ jmp_mem_far_32bit:
+ call operand_16bit
+ jmp jmp_mem_far_store
+ jmp_mem_32bit:
+ cmp [jump_type],3
+ je jmp_mem_far_32bit
+ cmp [jump_type],2
+ je jmp_mem_near_32bit
+ cmp [code_type],16
+ je jmp_mem_far_32bit
+ jmp_mem_near_32bit:
+ cmp [code_type],64
+ je illegal_instruction
+ call operand_32bit
+ jmp instruction_ready
+ jmp_mem_16bit:
+ cmp [jump_type],3
+ je invalid_operand_size
+ call operand_16bit
+ jmp instruction_ready
+ jmp_reg:
+ test [jump_type],1
+ jnz invalid_operand
+ lods byte [esi]
+ call convert_register
+ mov bl,al
+ mov al,ah
+ cmp al,2
+ je jmp_reg_16bit
+ cmp al,4
+ je jmp_reg_32bit
+ cmp al,8
+ jne invalid_operand_size
+ jmp_reg_64bit:
+ cmp [code_type],64
+ jne illegal_instruction
+ jmp nomem_instruction_ready
+ jmp_reg_32bit:
+ cmp [code_type],64
+ je illegal_instruction
+ call operand_32bit
+ jmp nomem_instruction_ready
+ jmp_reg_16bit:
+ call operand_16bit
+ jmp nomem_instruction_ready
+ jmp_imm:
+ cmp byte [esi],'.'
+ je invalid_value
+ mov ebx,esi
+ dec esi
+ call skip_symbol
+ xchg esi,ebx
+ cmp byte [ebx],':'
+ je jmp_far
+ cmp [jump_type],3
+ je invalid_operand
+ jmp_near:
+ mov al,[operand_size]
+ cmp al,2
+ je jmp_imm_16bit
+ cmp al,4
+ je jmp_imm_32bit
+ cmp al,8
+ je jmp_imm_64bit
+ or al,al
+ jnz invalid_operand_size
+ cmp [code_type],16
+ je jmp_imm_16bit
+ cmp [code_type],64
+ je jmp_imm_64bit
+ jmp_imm_32bit:
+ cmp [code_type],64
+ je invalid_operand_size
+ call get_address_dword_value
+ cmp [code_type],16
+ jne jmp_imm_32bit_prefix_ok
+ mov byte [edi],66h
+ inc edi
+ jmp_imm_32bit_prefix_ok:
+ call calculate_jump_offset
+ cdq
+ call check_for_short_jump
+ jc jmp_short
+ jmp_imm_32bit_store:
+ mov edx,eax
+ sub edx,3
+ jno jmp_imm_32bit_ok
+ cmp [code_type],64
+ je relative_jump_out_of_range
+ jmp_imm_32bit_ok:
+ mov al,[base_code]
+ stos byte [edi]
+ mov eax,edx
+ call mark_relocation
+ stos dword [edi]
+ jmp instruction_assembled
+ jmp_imm_64bit:
+ cmp [code_type],64
+ jne invalid_operand_size
+ call get_address_qword_value
+ call calculate_jump_offset
+ mov ecx,edx
+ cdq
+ cmp edx,ecx
+ jne relative_jump_out_of_range
+ call check_for_short_jump
+ jnc jmp_imm_32bit_store
+ jmp_short:
+ mov ah,al
+ mov al,0EBh
+ stos word [edi]
+ jmp instruction_assembled
+ jmp_imm_16bit:
+ call get_address_word_value
+ cmp [code_type],16
+ je jmp_imm_16bit_prefix_ok
+ mov byte [edi],66h
+ inc edi
+ jmp_imm_16bit_prefix_ok:
+ call calculate_jump_offset
+ cwde
+ cdq
+ call check_for_short_jump
+ jc jmp_short
+ cmp [value_type],0
+ jne invalid_use_of_symbol
+ mov edx,eax
+ dec edx
+ mov al,[base_code]
+ stos byte [edi]
+ mov eax,edx
+ stos word [edi]
+ jmp instruction_assembled
+ calculate_jump_offset:
+ add edi,2
+ mov ebp,[addressing_space]
+ call calculate_relative_offset
+ sub edi,2
+ ret
+ check_for_short_jump:
+ cmp [jump_type],1
+ je forced_short
+ ja no_short_jump
+ cmp [base_code],0E8h
+ je no_short_jump
+ cmp [value_type],0
+ jne no_short_jump
+ cmp eax,80h
+ jb short_jump
+ cmp eax,-80h
+ jae short_jump
+ no_short_jump:
+ clc
+ ret
+ forced_short:
+ cmp [base_code],0E8h
+ je illegal_instruction
+ cmp [next_pass_needed],0
+ jne jmp_short_value_type_ok
+ cmp [value_type],0
+ jne invalid_use_of_symbol
+ jmp_short_value_type_ok:
+ cmp eax,-80h
+ jae short_jump
+ cmp eax,80h
+ jae jump_out_of_range
+ short_jump:
+ stc
+ ret
+ jump_out_of_range:
+ cmp [error_line],0
+ jne instruction_assembled
+ mov eax,[current_line]
+ mov [error_line],eax
+ mov [error],relative_jump_out_of_range
+ jmp instruction_assembled
+ jmp_far:
+ cmp [jump_type],2
+ je invalid_operand
+ cmp [code_type],64
+ je illegal_instruction
+ mov al,[extended_code]
+ mov [base_code],al
+ call get_word_value
+ push eax
+ inc esi
+ lods byte [esi]
+ cmp al,'('
+ jne invalid_operand
+ mov al,[value_type]
+ push eax [symbol_identifier]
+ cmp byte [esi],'.'
+ je invalid_value
+ mov al,[operand_size]
+ cmp al,4
+ je jmp_far_16bit
+ cmp al,6
+ je jmp_far_32bit
+ or al,al
+ jnz invalid_operand_size
+ cmp [code_type],16
+ jne jmp_far_32bit
+ jmp_far_16bit:
+ call get_word_value
+ mov ebx,eax
+ call operand_16bit
+ call store_instruction_code
+ mov ax,bx
+ call mark_relocation
+ stos word [edi]
+ jmp_far_segment:
+ pop [symbol_identifier] eax
+ mov [value_type],al
+ pop eax
+ call mark_relocation
+ stos word [edi]
+ jmp instruction_assembled
+ jmp_far_32bit:
+ call get_dword_value
+ mov ebx,eax
+ call operand_32bit
+ call store_instruction_code
+ mov eax,ebx
+ call mark_relocation
+ stos dword [edi]
+ jmp jmp_far_segment
+conditional_jump:
+ mov [base_code],al
+ lods byte [esi]
+ call get_jump_operator
+ cmp [jump_type],3
+ je invalid_operand
+ call get_size_operator
+ cmp al,'('
+ jne invalid_operand
+ cmp byte [esi],'.'
+ je invalid_value
+ mov al,[operand_size]
+ cmp al,2
+ je conditional_jump_16bit
+ cmp al,4
+ je conditional_jump_32bit
+ cmp al,8
+ je conditional_jump_64bit
+ or al,al
+ jnz invalid_operand_size
+ cmp [code_type],16
+ je conditional_jump_16bit
+ cmp [code_type],64
+ je conditional_jump_64bit
+ conditional_jump_32bit:
+ cmp [code_type],64
+ je invalid_operand_size
+ call get_address_dword_value
+ cmp [code_type],16
+ jne conditional_jump_32bit_prefix_ok
+ mov byte [edi],66h
+ inc edi
+ conditional_jump_32bit_prefix_ok:
+ call calculate_jump_offset
+ cdq
+ call check_for_short_jump
+ jc conditional_jump_short
+ conditional_jump_32bit_store:
+ mov edx,eax
+ sub edx,4
+ jno conditional_jump_32bit_range_ok
+ cmp [code_type],64
+ je relative_jump_out_of_range
+ conditional_jump_32bit_range_ok:
+ mov ah,[base_code]
+ add ah,10h
+ mov al,0Fh
+ stos word [edi]
+ mov eax,edx
+ call mark_relocation
+ stos dword [edi]
+ jmp instruction_assembled
+ conditional_jump_64bit:
+ cmp [code_type],64
+ jne invalid_operand_size
+ call get_address_qword_value
+ call calculate_jump_offset
+ mov ecx,edx
+ cdq
+ cmp edx,ecx
+ jne relative_jump_out_of_range
+ call check_for_short_jump
+ jnc conditional_jump_32bit_store
+ conditional_jump_short:
+ mov ah,al
+ mov al,[base_code]
+ stos word [edi]
+ jmp instruction_assembled
+ conditional_jump_16bit:
+ call get_address_word_value
+ cmp [code_type],16
+ je conditional_jump_16bit_prefix_ok
+ mov byte [edi],66h
+ inc edi
+ conditional_jump_16bit_prefix_ok:
+ call calculate_jump_offset
+ cwde
+ cdq
+ call check_for_short_jump
+ jc conditional_jump_short
+ cmp [value_type],0
+ jne invalid_use_of_symbol
+ mov edx,eax
+ sub dx,2
+ mov ah,[base_code]
+ add ah,10h
+ mov al,0Fh
+ stos word [edi]
+ mov eax,edx
+ stos word [edi]
+ jmp instruction_assembled
+loop_instruction_16bit:
+ cmp [code_type],64
+ je illegal_instruction
+ cmp [code_type],16
+ je loop_instruction
+ mov [operand_prefix],67h
+ jmp loop_instruction
+loop_instruction_32bit:
+ cmp [code_type],32
+ je loop_instruction
+ mov [operand_prefix],67h
+ jmp loop_instruction
+loop_instruction_64bit:
+ cmp [code_type],64
+ jne illegal_instruction
+loop_instruction:
+ mov [base_code],al
+ lods byte [esi]
+ call get_jump_operator
+ cmp [jump_type],1
+ ja invalid_operand
+ call get_size_operator
+ cmp al,'('
+ jne invalid_operand
+ cmp byte [esi],'.'
+ je invalid_value
+ mov al,[operand_size]
+ cmp al,2
+ je loop_jump_16bit
+ cmp al,4
+ je loop_jump_32bit
+ cmp al,8
+ je loop_jump_64bit
+ or al,al
+ jnz invalid_operand_size
+ cmp [code_type],16
+ je loop_jump_16bit
+ cmp [code_type],64
+ je loop_jump_64bit
+ loop_jump_32bit:
+ cmp [code_type],64
+ je invalid_operand_size
+ call get_address_dword_value
+ cmp [code_type],16
+ jne loop_jump_32bit_prefix_ok
+ mov byte [edi],66h
+ inc edi
+ loop_jump_32bit_prefix_ok:
+ call loop_counter_size
+ call calculate_jump_offset
+ cdq
+ make_loop_jump:
+ call check_for_short_jump
+ jc conditional_jump_short
+ scas word [edi]
+ jmp jump_out_of_range
+ loop_counter_size:
+ cmp [operand_prefix],0
+ je loop_counter_size_ok
+ push eax
+ mov al,[operand_prefix]
+ stos byte [edi]
+ pop eax
+ loop_counter_size_ok:
+ ret
+ loop_jump_64bit:
+ cmp [code_type],64
+ jne invalid_operand_size
+ call get_address_qword_value
+ call loop_counter_size
+ call calculate_jump_offset
+ mov ecx,edx
+ cdq
+ cmp edx,ecx
+ jne relative_jump_out_of_range
+ jmp make_loop_jump
+ loop_jump_16bit:
+ call get_address_word_value
+ cmp [code_type],16
+ je loop_jump_16bit_prefix_ok
+ mov byte [edi],66h
+ inc edi
+ loop_jump_16bit_prefix_ok:
+ call loop_counter_size
+ call calculate_jump_offset
+ cwde
+ cdq
+ jmp make_loop_jump
+
+movs_instruction:
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ or eax,eax
+ jnz invalid_address
+ or bl,ch
+ jnz invalid_address
+ cmp [segment_register],1
+ ja invalid_address
+ push ebx
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ pop edx
+ or eax,eax
+ jnz invalid_address
+ or bl,ch
+ jnz invalid_address
+ mov al,dh
+ mov ah,bh
+ shr al,4
+ shr ah,4
+ cmp al,ah
+ jne address_sizes_do_not_agree
+ and bh,111b
+ and dh,111b
+ cmp bh,6
+ jne invalid_address
+ cmp dh,7
+ jne invalid_address
+ cmp al,2
+ je movs_address_16bit
+ cmp al,4
+ je movs_address_32bit
+ cmp [code_type],64
+ jne invalid_address_size
+ jmp movs_store
+ movs_address_32bit:
+ call address_32bit_prefix
+ jmp movs_store
+ movs_address_16bit:
+ cmp [code_type],64
+ je invalid_address_size
+ call address_16bit_prefix
+ movs_store:
+ xor ebx,ebx
+ call store_segment_prefix_if_necessary
+ mov al,0A4h
+ movs_check_size:
+ mov bl,[operand_size]
+ cmp bl,1
+ je simple_instruction
+ inc al
+ cmp bl,2
+ je simple_instruction_16bit
+ cmp bl,4
+ je simple_instruction_32bit
+ cmp bl,8
+ je simple_instruction_64bit
+ or bl,bl
+ jnz invalid_operand_size
+ call recoverable_unknown_size
+ jmp simple_instruction
+lods_instruction:
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ or eax,eax
+ jnz invalid_address
+ or bl,ch
+ jnz invalid_address
+ cmp bh,26h
+ je lods_address_16bit
+ cmp bh,46h
+ je lods_address_32bit
+ cmp bh,86h
+ jne invalid_address
+ cmp [code_type],64
+ jne invalid_address_size
+ jmp lods_store
+ lods_address_32bit:
+ call address_32bit_prefix
+ jmp lods_store
+ lods_address_16bit:
+ cmp [code_type],64
+ je invalid_address_size
+ call address_16bit_prefix
+ lods_store:
+ xor ebx,ebx
+ call store_segment_prefix_if_necessary
+ mov al,0ACh
+ jmp movs_check_size
+stos_instruction:
+ mov [base_code],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ or eax,eax
+ jnz invalid_address
+ or bl,ch
+ jnz invalid_address
+ cmp bh,27h
+ je stos_address_16bit
+ cmp bh,47h
+ je stos_address_32bit
+ cmp bh,87h
+ jne invalid_address
+ cmp [code_type],64
+ jne invalid_address_size
+ jmp stos_store
+ stos_address_32bit:
+ call address_32bit_prefix
+ jmp stos_store
+ stos_address_16bit:
+ cmp [code_type],64
+ je invalid_address_size
+ call address_16bit_prefix
+ stos_store:
+ cmp [segment_register],1
+ ja invalid_address
+ mov al,[base_code]
+ jmp movs_check_size
+cmps_instruction:
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ or eax,eax
+ jnz invalid_address
+ or bl,ch
+ jnz invalid_address
+ mov al,[segment_register]
+ push eax ebx
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ or eax,eax
+ jnz invalid_address
+ or bl,ch
+ jnz invalid_address
+ pop edx eax
+ cmp [segment_register],1
+ ja invalid_address
+ mov [segment_register],al
+ mov al,dh
+ mov ah,bh
+ shr al,4
+ shr ah,4
+ cmp al,ah
+ jne address_sizes_do_not_agree
+ and bh,111b
+ and dh,111b
+ cmp bh,7
+ jne invalid_address
+ cmp dh,6
+ jne invalid_address
+ cmp al,2
+ je cmps_address_16bit
+ cmp al,4
+ je cmps_address_32bit
+ cmp [code_type],64
+ jne invalid_address_size
+ jmp cmps_store
+ cmps_address_32bit:
+ call address_32bit_prefix
+ jmp cmps_store
+ cmps_address_16bit:
+ cmp [code_type],64
+ je invalid_address_size
+ call address_16bit_prefix
+ cmps_store:
+ xor ebx,ebx
+ call store_segment_prefix_if_necessary
+ mov al,0A6h
+ jmp movs_check_size
+ins_instruction:
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ or eax,eax
+ jnz invalid_address
+ or bl,ch
+ jnz invalid_address
+ cmp bh,27h
+ je ins_address_16bit
+ cmp bh,47h
+ je ins_address_32bit
+ cmp bh,87h
+ jne invalid_address
+ cmp [code_type],64
+ jne invalid_address_size
+ jmp ins_store
+ ins_address_32bit:
+ call address_32bit_prefix
+ jmp ins_store
+ ins_address_16bit:
+ cmp [code_type],64
+ je invalid_address_size
+ call address_16bit_prefix
+ ins_store:
+ cmp [segment_register],1
+ ja invalid_address
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ cmp al,22h
+ jne invalid_operand
+ mov al,6Ch
+ ins_check_size:
+ cmp [operand_size],8
+ jne movs_check_size
+ jmp invalid_operand_size
+outs_instruction:
+ lods byte [esi]
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ cmp al,22h
+ jne invalid_operand
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ or eax,eax
+ jnz invalid_address
+ or bl,ch
+ jnz invalid_address
+ cmp bh,26h
+ je outs_address_16bit
+ cmp bh,46h
+ je outs_address_32bit
+ cmp bh,86h
+ jne invalid_address
+ cmp [code_type],64
+ jne invalid_address_size
+ jmp outs_store
+ outs_address_32bit:
+ call address_32bit_prefix
+ jmp outs_store
+ outs_address_16bit:
+ cmp [code_type],64
+ je invalid_address_size
+ call address_16bit_prefix
+ outs_store:
+ xor ebx,ebx
+ call store_segment_prefix_if_necessary
+ mov al,6Eh
+ jmp ins_check_size
+xlat_instruction:
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ or eax,eax
+ jnz invalid_address
+ or bl,ch
+ jnz invalid_address
+ cmp bh,23h
+ je xlat_address_16bit
+ cmp bh,43h
+ je xlat_address_32bit
+ cmp bh,83h
+ jne invalid_address
+ cmp [code_type],64
+ jne invalid_address_size
+ jmp xlat_store
+ xlat_address_32bit:
+ call address_32bit_prefix
+ jmp xlat_store
+ xlat_address_16bit:
+ cmp [code_type],64
+ je invalid_address_size
+ call address_16bit_prefix
+ xlat_store:
+ call store_segment_prefix_if_necessary
+ mov al,0D7h
+ cmp [operand_size],1
+ jbe simple_instruction
+ jmp invalid_operand_size
+
+pm_word_instruction:
+ mov ah,al
+ shr ah,4
+ and al,111b
+ mov [base_code],0Fh
+ mov [extended_code],ah
+ mov [postbyte_register],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je pm_reg
+ pm_mem:
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ mov al,[operand_size]
+ cmp al,2
+ je pm_mem_store
+ or al,al
+ jnz invalid_operand_size
+ pm_mem_store:
+ jmp instruction_ready
+ pm_reg:
+ lods byte [esi]
+ call convert_register
+ mov bl,al
+ cmp ah,2
+ jne invalid_operand_size
+ jmp nomem_instruction_ready
+pm_store_word_instruction:
+ mov ah,al
+ shr ah,4
+ and al,111b
+ mov [base_code],0Fh
+ mov [extended_code],ah
+ mov [postbyte_register],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne pm_mem
+ lods byte [esi]
+ call convert_register
+ mov bl,al
+ mov al,ah
+ call operand_autodetect
+ jmp nomem_instruction_ready
+lgdt_instruction:
+ mov [base_code],0Fh
+ mov [extended_code],1
+ mov [postbyte_register],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ mov al,[operand_size]
+ cmp al,6
+ je lgdt_mem_48bit
+ cmp al,10
+ je lgdt_mem_80bit
+ or al,al
+ jnz invalid_operand_size
+ jmp lgdt_mem_store
+ lgdt_mem_80bit:
+ cmp [code_type],64
+ jne illegal_instruction
+ jmp lgdt_mem_store
+ lgdt_mem_48bit:
+ cmp [code_type],64
+ je illegal_instruction
+ cmp [postbyte_register],2
+ jb lgdt_mem_store
+ call operand_32bit
+ lgdt_mem_store:
+ jmp instruction_ready
+lar_instruction:
+ mov [extended_code],al
+ mov [base_code],0Fh
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ mov [postbyte_register],al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ xor al,al
+ xchg al,[operand_size]
+ call operand_autodetect
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je lar_reg_reg
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ mov al,[operand_size]
+ or al,al
+ jz lar_reg_mem
+ cmp al,2
+ jne invalid_operand_size
+ lar_reg_mem:
+ jmp instruction_ready
+ lar_reg_reg:
+ lods byte [esi]
+ call convert_register
+ cmp ah,2
+ jne invalid_operand_size
+ mov bl,al
+ jmp nomem_instruction_ready
+invlpg_instruction:
+ mov [base_code],0Fh
+ mov [extended_code],1
+ mov [postbyte_register],7
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ jmp instruction_ready
+swapgs_instruction:
+ cmp [code_type],64
+ jne illegal_instruction
+rdtscp_instruction:
+ mov [base_code],0Fh
+ mov [extended_code],1
+ mov [postbyte_register],7
+ mov bl,al
+ jmp nomem_instruction_ready
+
+basic_486_instruction:
+ mov [base_code],0Fh
+ mov [extended_code],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je basic_486_reg
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ push edx ebx ecx
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ mov [postbyte_register],al
+ pop ecx ebx edx
+ mov al,ah
+ cmp al,1
+ je basic_486_mem_reg_8bit
+ call operand_autodetect
+ inc [extended_code]
+ basic_486_mem_reg_8bit:
+ jmp instruction_ready
+ basic_486_reg:
+ lods byte [esi]
+ call convert_register
+ mov [postbyte_register],al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ mov bl,[postbyte_register]
+ mov [postbyte_register],al
+ mov al,ah
+ cmp al,1
+ je basic_486_reg_reg_8bit
+ call operand_autodetect
+ inc [extended_code]
+ basic_486_reg_reg_8bit:
+ jmp nomem_instruction_ready
+bswap_instruction:
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ test al,1000b
+ jz bswap_reg_code_ok
+ or [rex_prefix],41h
+ and al,111b
+ bswap_reg_code_ok:
+ add al,0C8h
+ mov [extended_code],al
+ mov [base_code],0Fh
+ cmp ah,8
+ je bswap_reg64
+ cmp ah,4
+ jne invalid_operand_size
+ call operand_32bit
+ call store_instruction_code
+ jmp instruction_assembled
+ bswap_reg64:
+ call operand_64bit
+ call store_instruction_code
+ jmp instruction_assembled
+cmpxchgx_instruction:
+ mov [base_code],0Fh
+ mov [extended_code],0C7h
+ mov [postbyte_register],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ mov ah,1
+ xchg [postbyte_register],ah
+ mov al,[operand_size]
+ or al,al
+ jz cmpxchgx_size_ok
+ cmp al,ah
+ jne invalid_operand_size
+ cmpxchgx_size_ok:
+ cmp ah,16
+ jne cmpxchgx_store
+ call operand_64bit
+ cmpxchgx_store:
+ jmp instruction_ready
+nop_instruction:
+ mov ah,[esi]
+ cmp ah,10h
+ je extended_nop
+ cmp ah,11h
+ je extended_nop
+ cmp ah,'['
+ je extended_nop
+ stos byte [edi]
+ jmp instruction_assembled
+ extended_nop:
+ mov [base_code],0Fh
+ mov [extended_code],1Fh
+ mov [postbyte_register],0
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je extended_nop_reg
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ mov al,[operand_size]
+ or al,al
+ jz extended_nop_store
+ call operand_autodetect
+ extended_nop_store:
+ jmp instruction_ready
+ extended_nop_reg:
+ lods byte [esi]
+ call convert_register
+ mov bl,al
+ mov al,ah
+ call operand_autodetect
+ jmp nomem_instruction_ready
+
+basic_fpu_instruction:
+ mov [postbyte_register],al
+ mov [base_code],0D8h
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je basic_fpu_streg
+ cmp al,'['
+ je basic_fpu_mem
+ dec esi
+ mov ah,[postbyte_register]
+ cmp ah,2
+ jb invalid_operand
+ cmp ah,3
+ ja invalid_operand
+ mov bl,1
+ jmp nomem_instruction_ready
+ basic_fpu_mem:
+ call get_address
+ mov al,[operand_size]
+ cmp al,4
+ je basic_fpu_mem_32bit
+ cmp al,8
+ je basic_fpu_mem_64bit
+ or al,al
+ jnz invalid_operand_size
+ call recoverable_unknown_size
+ basic_fpu_mem_32bit:
+ jmp instruction_ready
+ basic_fpu_mem_64bit:
+ mov [base_code],0DCh
+ jmp instruction_ready
+ basic_fpu_streg:
+ lods byte [esi]
+ call convert_fpu_register
+ mov bl,al
+ mov ah,[postbyte_register]
+ cmp ah,2
+ je basic_fpu_single_streg
+ cmp ah,3
+ je basic_fpu_single_streg
+ or al,al
+ jz basic_fpu_st0
+ test ah,110b
+ jz basic_fpu_streg_st0
+ xor [postbyte_register],1
+ basic_fpu_streg_st0:
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_fpu_register
+ or al,al
+ jnz invalid_operand
+ mov [base_code],0DCh
+ jmp nomem_instruction_ready
+ basic_fpu_st0:
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_fpu_register
+ mov bl,al
+ basic_fpu_single_streg:
+ mov [base_code],0D8h
+ jmp nomem_instruction_ready
+simple_fpu_instruction:
+ mov ah,al
+ or ah,11000000b
+ mov al,0D9h
+ stos word [edi]
+ jmp instruction_assembled
+fi_instruction:
+ mov [postbyte_register],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ mov al,[operand_size]
+ cmp al,2
+ je fi_mem_16bit
+ cmp al,4
+ je fi_mem_32bit
+ or al,al
+ jnz invalid_operand_size
+ call recoverable_unknown_size
+ fi_mem_32bit:
+ mov [base_code],0DAh
+ jmp instruction_ready
+ fi_mem_16bit:
+ mov [base_code],0DEh
+ jmp instruction_ready
+fld_instruction:
+ mov [postbyte_register],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je fld_streg
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ mov al,[operand_size]
+ cmp al,4
+ je fld_mem_32bit
+ cmp al,8
+ je fld_mem_64bit
+ cmp al,10
+ je fld_mem_80bit
+ or al,al
+ jnz invalid_operand_size
+ call recoverable_unknown_size
+ fld_mem_32bit:
+ mov [base_code],0D9h
+ jmp instruction_ready
+ fld_mem_64bit:
+ mov [base_code],0DDh
+ jmp instruction_ready
+ fld_mem_80bit:
+ mov al,[postbyte_register]
+ cmp al,0
+ je fld_mem_80bit_store
+ dec [postbyte_register]
+ cmp al,3
+ je fld_mem_80bit_store
+ jmp invalid_operand_size
+ fld_mem_80bit_store:
+ add [postbyte_register],5
+ mov [base_code],0DBh
+ jmp instruction_ready
+ fld_streg:
+ lods byte [esi]
+ call convert_fpu_register
+ mov bl,al
+ cmp [postbyte_register],2
+ jae fst_streg
+ mov [base_code],0D9h
+ jmp nomem_instruction_ready
+ fst_streg:
+ mov [base_code],0DDh
+ jmp nomem_instruction_ready
+fild_instruction:
+ mov [postbyte_register],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ mov al,[operand_size]
+ cmp al,2
+ je fild_mem_16bit
+ cmp al,4
+ je fild_mem_32bit
+ cmp al,8
+ je fild_mem_64bit
+ or al,al
+ jnz invalid_operand_size
+ call recoverable_unknown_size
+ fild_mem_32bit:
+ mov [base_code],0DBh
+ jmp instruction_ready
+ fild_mem_16bit:
+ mov [base_code],0DFh
+ jmp instruction_ready
+ fild_mem_64bit:
+ mov al,[postbyte_register]
+ cmp al,1
+ je fisttp_64bit_store
+ jb fild_mem_64bit_store
+ dec [postbyte_register]
+ cmp al,3
+ je fild_mem_64bit_store
+ jmp invalid_operand_size
+ fild_mem_64bit_store:
+ add [postbyte_register],5
+ mov [base_code],0DFh
+ jmp instruction_ready
+ fisttp_64bit_store:
+ mov [base_code],0DDh
+ jmp instruction_ready
+fbld_instruction:
+ mov [postbyte_register],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ mov al,[operand_size]
+ or al,al
+ jz fbld_mem_80bit
+ cmp al,10
+ je fbld_mem_80bit
+ jmp invalid_operand_size
+ fbld_mem_80bit:
+ mov [base_code],0DFh
+ jmp instruction_ready
+faddp_instruction:
+ mov [postbyte_register],al
+ mov [base_code],0DEh
+ mov edx,esi
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je faddp_streg
+ mov esi,edx
+ mov bl,1
+ jmp nomem_instruction_ready
+ faddp_streg:
+ lods byte [esi]
+ call convert_fpu_register
+ mov bl,al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_fpu_register
+ or al,al
+ jnz invalid_operand
+ jmp nomem_instruction_ready
+fcompp_instruction:
+ mov ax,0D9DEh
+ stos word [edi]
+ jmp instruction_assembled
+fucompp_instruction:
+ mov ax,0E9DAh
+ stos word [edi]
+ jmp instruction_assembled
+fxch_instruction:
+ mov dx,01D9h
+ jmp fpu_single_operand
+ffreep_instruction:
+ mov dx,00DFh
+ jmp fpu_single_operand
+ffree_instruction:
+ mov dl,0DDh
+ mov dh,al
+ fpu_single_operand:
+ mov ebx,esi
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je fpu_streg
+ or dh,dh
+ jz invalid_operand
+ mov esi,ebx
+ shl dh,3
+ or dh,11000001b
+ mov ax,dx
+ stos word [edi]
+ jmp instruction_assembled
+ fpu_streg:
+ lods byte [esi]
+ call convert_fpu_register
+ shl dh,3
+ or dh,al
+ or dh,11000000b
+ mov ax,dx
+ stos word [edi]
+ jmp instruction_assembled
+
+fstenv_instruction:
+ mov byte [edi],9Bh
+ inc edi
+fldenv_instruction:
+ mov [base_code],0D9h
+ jmp fpu_mem
+fstenv_instruction_16bit:
+ mov byte [edi],9Bh
+ inc edi
+fldenv_instruction_16bit:
+ call operand_16bit
+ jmp fldenv_instruction
+fstenv_instruction_32bit:
+ mov byte [edi],9Bh
+ inc edi
+fldenv_instruction_32bit:
+ call operand_32bit
+ jmp fldenv_instruction
+fsave_instruction_32bit:
+ mov byte [edi],9Bh
+ inc edi
+fnsave_instruction_32bit:
+ call operand_32bit
+ jmp fnsave_instruction
+fsave_instruction_16bit:
+ mov byte [edi],9Bh
+ inc edi
+fnsave_instruction_16bit:
+ call operand_16bit
+ jmp fnsave_instruction
+fsave_instruction:
+ mov byte [edi],9Bh
+ inc edi
+fnsave_instruction:
+ mov [base_code],0DDh
+ fpu_mem:
+ mov [postbyte_register],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ cmp [operand_size],0
+ jne invalid_operand_size
+ jmp instruction_ready
+fstcw_instruction:
+ mov byte [edi],9Bh
+ inc edi
+fldcw_instruction:
+ mov [postbyte_register],al
+ mov [base_code],0D9h
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ mov al,[operand_size]
+ or al,al
+ jz fldcw_mem_16bit
+ cmp al,2
+ je fldcw_mem_16bit
+ jmp invalid_operand_size
+ fldcw_mem_16bit:
+ jmp instruction_ready
+fstsw_instruction:
+ mov al,9Bh
+ stos byte [edi]
+fnstsw_instruction:
+ mov [base_code],0DDh
+ mov [postbyte_register],7
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je fstsw_reg
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ mov al,[operand_size]
+ or al,al
+ jz fstsw_mem_16bit
+ cmp al,2
+ je fstsw_mem_16bit
+ jmp invalid_operand_size
+ fstsw_mem_16bit:
+ jmp instruction_ready
+ fstsw_reg:
+ lods byte [esi]
+ call convert_register
+ cmp ax,0200h
+ jne invalid_operand
+ mov ax,0E0DFh
+ stos word [edi]
+ jmp instruction_assembled
+finit_instruction:
+ mov byte [edi],9Bh
+ inc edi
+fninit_instruction:
+ mov ah,al
+ mov al,0DBh
+ stos word [edi]
+ jmp instruction_assembled
+fcmov_instruction:
+ mov dh,0DAh
+ jmp fcomi_streg
+fcomi_instruction:
+ mov dh,0DBh
+ jmp fcomi_streg
+fcomip_instruction:
+ mov dh,0DFh
+ fcomi_streg:
+ mov dl,al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_fpu_register
+ mov ah,al
+ cmp byte [esi],','
+ je fcomi_st0_streg
+ add ah,dl
+ mov al,dh
+ stos word [edi]
+ jmp instruction_assembled
+ fcomi_st0_streg:
+ or ah,ah
+ jnz invalid_operand
+ inc esi
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_fpu_register
+ mov ah,al
+ add ah,dl
+ mov al,dh
+ stos word [edi]
+ jmp instruction_assembled
+
+basic_mmx_instruction:
+ mov [base_code],0Fh
+ mov [extended_code],al
+ mmx_instruction:
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_mmx_register
+ call make_mmx_prefix
+ mov [postbyte_register],al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je mmx_mmreg_mmreg
+ cmp al,'['
+ jne invalid_operand
+ mmx_mmreg_mem:
+ call get_address
+ jmp instruction_ready
+ mmx_mmreg_mmreg:
+ lods byte [esi]
+ call convert_mmx_register
+ mov bl,al
+ jmp nomem_instruction_ready
+mmx_bit_shift_instruction:
+ mov [base_code],0Fh
+ mov [extended_code],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_mmx_register
+ call make_mmx_prefix
+ mov [postbyte_register],al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ mov [operand_size],0
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je mmx_mmreg_mmreg
+ cmp al,'('
+ je mmx_ps_mmreg_imm8
+ cmp al,'['
+ je mmx_mmreg_mem
+ jmp invalid_operand
+ mmx_ps_mmreg_imm8:
+ call get_byte_value
+ mov byte [value],al
+ test [operand_size],not 1
+ jnz invalid_value
+ mov bl,[extended_code]
+ mov al,bl
+ shr bl,4
+ and al,1111b
+ add al,70h
+ mov [extended_code],al
+ sub bl,0Ch
+ shl bl,1
+ xchg bl,[postbyte_register]
+ call store_nomem_instruction
+ mov al,byte [value]
+ stos byte [edi]
+ jmp instruction_assembled
+pmovmskb_instruction:
+ mov [base_code],0Fh
+ mov [extended_code],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ cmp ah,4
+ je pmovmskb_reg_size_ok
+ cmp [code_type],64
+ jne invalid_operand_size
+ cmp ah,8
+ jnz invalid_operand_size
+ pmovmskb_reg_size_ok:
+ mov [postbyte_register],al
+ mov [operand_size],0
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_mmx_register
+ mov bl,al
+ call make_mmx_prefix
+ cmp [extended_code],0C5h
+ je mmx_nomem_imm8
+ jmp nomem_instruction_ready
+ mmx_imm8:
+ push ebx ecx edx
+ xor cl,cl
+ xchg cl,[operand_size]
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ test ah,not 1
+ jnz invalid_operand_size
+ mov [operand_size],cl
+ cmp al,'('
+ jne invalid_operand
+ call get_byte_value
+ mov byte [value],al
+ pop edx ecx ebx
+ call store_instruction_with_imm8
+ jmp instruction_assembled
+ mmx_nomem_imm8:
+ call store_nomem_instruction
+ call append_imm8
+ jmp instruction_assembled
+ append_imm8:
+ mov [operand_size],0
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ test ah,not 1
+ jnz invalid_operand_size
+ cmp al,'('
+ jne invalid_operand
+ call get_byte_value
+ stosb
+ ret
+pinsrw_instruction:
+ mov [extended_code],al
+ mov [base_code],0Fh
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_mmx_register
+ call make_mmx_prefix
+ mov [postbyte_register],al
+ mov [operand_size],0
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je pinsrw_mmreg_reg
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ cmp [operand_size],0
+ je mmx_imm8
+ cmp [operand_size],2
+ jne invalid_operand_size
+ jmp mmx_imm8
+ pinsrw_mmreg_reg:
+ lods byte [esi]
+ call convert_register
+ cmp ah,4
+ jne invalid_operand_size
+ mov bl,al
+ jmp mmx_nomem_imm8
+pshufw_instruction:
+ mov [mmx_size],8
+ mov [opcode_prefix],al
+ jmp pshuf_instruction
+pshufd_instruction:
+ mov [mmx_size],16
+ mov [opcode_prefix],al
+ pshuf_instruction:
+ mov [base_code],0Fh
+ mov [extended_code],70h
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_mmx_register
+ cmp ah,[mmx_size]
+ jne invalid_operand_size
+ mov [postbyte_register],al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je pshuf_mmreg_mmreg
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ jmp mmx_imm8
+ pshuf_mmreg_mmreg:
+ lods byte [esi]
+ call convert_mmx_register
+ mov bl,al
+ jmp mmx_nomem_imm8
+movd_instruction:
+ mov [base_code],0Fh
+ mov [extended_code],7Eh
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je movd_reg
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ test [operand_size],not 4
+ jnz invalid_operand_size
+ mov [operand_size],0
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_mmx_register
+ call make_mmx_prefix
+ mov [postbyte_register],al
+ jmp instruction_ready
+ movd_reg:
+ lods byte [esi]
+ cmp al,0B0h
+ jae movd_mmreg
+ call convert_register
+ cmp ah,4
+ jne invalid_operand_size
+ mov [operand_size],0
+ mov bl,al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_mmx_register
+ mov [postbyte_register],al
+ call make_mmx_prefix
+ jmp nomem_instruction_ready
+ movd_mmreg:
+ mov [extended_code],6Eh
+ call convert_mmx_register
+ call make_mmx_prefix
+ mov [postbyte_register],al
+ mov [operand_size],0
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je movd_mmreg_reg
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ test [operand_size],not 4
+ jnz invalid_operand_size
+ jmp instruction_ready
+ movd_mmreg_reg:
+ lods byte [esi]
+ call convert_register
+ cmp ah,4
+ jne invalid_operand_size
+ mov bl,al
+ jmp nomem_instruction_ready
+ make_mmx_prefix:
+ cmp [vex_required],0
+ jne mmx_prefix_for_vex
+ cmp [operand_size],16
+ jne no_mmx_prefix
+ mov [operand_prefix],66h
+ no_mmx_prefix:
+ ret
+ mmx_prefix_for_vex:
+ cmp [operand_size],16
+ jne invalid_operand
+ mov [opcode_prefix],66h
+ ret
+movq_instruction:
+ mov [base_code],0Fh
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je movq_reg
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ test [operand_size],not 8
+ jnz invalid_operand_size
+ mov [operand_size],0
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_mmx_register
+ mov [postbyte_register],al
+ cmp ah,16
+ je movq_mem_xmmreg
+ mov [extended_code],7Fh
+ jmp instruction_ready
+ movq_mem_xmmreg:
+ mov [extended_code],0D6h
+ mov [opcode_prefix],66h
+ jmp instruction_ready
+ movq_reg:
+ lods byte [esi]
+ cmp al,0B0h
+ jae movq_mmreg
+ call convert_register
+ cmp ah,8
+ jne invalid_operand_size
+ mov bl,al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ mov [operand_size],0
+ lods byte [esi]
+ call convert_mmx_register
+ mov [postbyte_register],al
+ call make_mmx_prefix
+ mov [extended_code],7Eh
+ call operand_64bit
+ jmp nomem_instruction_ready
+ movq_mmreg:
+ call convert_mmx_register
+ mov [postbyte_register],al
+ mov [extended_code],6Fh
+ mov [mmx_size],ah
+ cmp ah,16
+ jne movq_mmreg_
+ mov [extended_code],7Eh
+ mov [opcode_prefix],0F3h
+ movq_mmreg_:
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ mov [operand_size],0
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je movq_mmreg_reg
+ call get_address
+ test [operand_size],not 8
+ jnz invalid_operand_size
+ jmp instruction_ready
+ movq_mmreg_reg:
+ lods byte [esi]
+ cmp al,0B0h
+ jae movq_mmreg_mmreg
+ mov [operand_size],0
+ call convert_register
+ cmp ah,8
+ jne invalid_operand_size
+ mov [extended_code],6Eh
+ mov [opcode_prefix],0
+ mov bl,al
+ cmp [mmx_size],16
+ jne movq_mmreg_reg_store
+ mov [opcode_prefix],66h
+ movq_mmreg_reg_store:
+ call operand_64bit
+ jmp nomem_instruction_ready
+ movq_mmreg_mmreg:
+ call convert_mmx_register
+ cmp ah,[mmx_size]
+ jne invalid_operand_size
+ mov bl,al
+ jmp nomem_instruction_ready
+movdq_instruction:
+ mov [opcode_prefix],al
+ mov [base_code],0Fh
+ mov [extended_code],6Fh
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je movdq_mmreg
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_xmm_register
+ mov [postbyte_register],al
+ mov [extended_code],7Fh
+ jmp instruction_ready
+ movdq_mmreg:
+ lods byte [esi]
+ call convert_xmm_register
+ mov [postbyte_register],al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je movdq_mmreg_mmreg
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ jmp instruction_ready
+ movdq_mmreg_mmreg:
+ lods byte [esi]
+ call convert_xmm_register
+ mov bl,al
+ jmp nomem_instruction_ready
+lddqu_instruction:
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_xmm_register
+ push eax
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ pop eax
+ mov [postbyte_register],al
+ mov [opcode_prefix],0F2h
+ mov [base_code],0Fh
+ mov [extended_code],0F0h
+ jmp instruction_ready
+
+movdq2q_instruction:
+ mov [opcode_prefix],0F2h
+ mov [mmx_size],8
+ jmp movq2dq_
+movq2dq_instruction:
+ mov [opcode_prefix],0F3h
+ mov [mmx_size],16
+ movq2dq_:
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_mmx_register
+ cmp ah,[mmx_size]
+ jne invalid_operand_size
+ mov [postbyte_register],al
+ mov [operand_size],0
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_mmx_register
+ xor [mmx_size],8+16
+ cmp ah,[mmx_size]
+ jne invalid_operand_size
+ mov bl,al
+ mov [base_code],0Fh
+ mov [extended_code],0D6h
+ jmp nomem_instruction_ready
+
+sse_ps_instruction_imm8:
+ mov [immediate_size],1
+sse_ps_instruction:
+ mov [mmx_size],16
+ jmp sse_instruction
+sse_pd_instruction_imm8:
+ mov [immediate_size],1
+sse_pd_instruction:
+ mov [mmx_size],16
+ mov [opcode_prefix],66h
+ jmp sse_instruction
+sse_ss_instruction:
+ mov [mmx_size],4
+ mov [opcode_prefix],0F3h
+ jmp sse_instruction
+sse_sd_instruction:
+ mov [mmx_size],8
+ mov [opcode_prefix],0F2h
+ jmp sse_instruction
+cmp_pd_instruction:
+ mov [opcode_prefix],66h
+cmp_ps_instruction:
+ mov [mmx_size],16
+ mov byte [value],al
+ mov al,0C2h
+ jmp sse_instruction
+cmp_ss_instruction:
+ mov [mmx_size],4
+ mov [opcode_prefix],0F3h
+ jmp cmp_sx_instruction
+cmpsd_instruction:
+ mov al,0A7h
+ mov ah,[esi]
+ or ah,ah
+ jz simple_instruction_32bit
+ cmp ah,0Fh
+ je simple_instruction_32bit
+ mov al,-1
+cmp_sd_instruction:
+ mov [mmx_size],8
+ mov [opcode_prefix],0F2h
+ cmp_sx_instruction:
+ mov byte [value],al
+ mov al,0C2h
+ jmp sse_instruction
+comiss_instruction:
+ mov [mmx_size],4
+ jmp sse_instruction
+comisd_instruction:
+ mov [mmx_size],8
+ mov [opcode_prefix],66h
+ jmp sse_instruction
+cvtdq2pd_instruction:
+ mov [opcode_prefix],0F3h
+cvtps2pd_instruction:
+ mov [mmx_size],8
+ jmp sse_instruction
+cvtpd2dq_instruction:
+ mov [mmx_size],16
+ mov [opcode_prefix],0F2h
+ jmp sse_instruction
+movshdup_instruction:
+ mov [mmx_size],16
+ mov [opcode_prefix],0F3h
+sse_instruction:
+ mov [base_code],0Fh
+ mov [extended_code],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ sse_xmmreg:
+ lods byte [esi]
+ call convert_xmm_register
+ sse_reg:
+ mov [postbyte_register],al
+ mov [operand_size],0
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je sse_xmmreg_xmmreg
+ sse_reg_mem:
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ cmp [operand_size],0
+ je sse_mem_size_ok
+ mov al,[mmx_size]
+ cmp [operand_size],al
+ jne invalid_operand_size
+ sse_mem_size_ok:
+ mov al,[extended_code]
+ mov ah,[supplemental_code]
+ cmp al,0C2h
+ je sse_cmp_mem_ok
+ cmp ax,443Ah
+ je sse_cmp_mem_ok
+ cmp [immediate_size],1
+ je mmx_imm8
+ cmp [immediate_size],-1
+ jne sse_ok
+ call take_additional_xmm0
+ mov [immediate_size],0
+ sse_ok:
+ jmp instruction_ready
+ sse_cmp_mem_ok:
+ cmp byte [value],-1
+ je mmx_imm8
+ call store_instruction_with_imm8
+ jmp instruction_assembled
+ sse_xmmreg_xmmreg:
+ cmp [operand_prefix],66h
+ jne sse_xmmreg_xmmreg_ok
+ cmp [extended_code],12h
+ je invalid_operand
+ cmp [extended_code],16h
+ je invalid_operand
+ sse_xmmreg_xmmreg_ok:
+ lods byte [esi]
+ call convert_xmm_register
+ mov bl,al
+ mov al,[extended_code]
+ mov ah,[supplemental_code]
+ cmp al,0C2h
+ je sse_cmp_nomem_ok
+ cmp ax,443Ah
+ je sse_cmp_nomem_ok
+ cmp [immediate_size],1
+ je mmx_nomem_imm8
+ cmp [immediate_size],-1
+ jne sse_nomem_ok
+ call take_additional_xmm0
+ mov [immediate_size],0
+ sse_nomem_ok:
+ jmp nomem_instruction_ready
+ sse_cmp_nomem_ok:
+ cmp byte [value],-1
+ je mmx_nomem_imm8
+ call store_nomem_instruction
+ mov al,byte [value]
+ stosb
+ jmp instruction_assembled
+ take_additional_xmm0:
+ cmp byte [esi],','
+ jne additional_xmm0_ok
+ inc esi
+ lods byte [esi]
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_xmm_register
+ test al,al
+ jnz invalid_operand
+ additional_xmm0_ok:
+ ret
+
+pslldq_instruction:
+ mov [postbyte_register],al
+ mov [opcode_prefix],66h
+ mov [base_code],0Fh
+ mov [extended_code],73h
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_xmm_register
+ mov bl,al
+ jmp mmx_nomem_imm8
+movpd_instruction:
+ mov [opcode_prefix],66h
+movps_instruction:
+ mov [base_code],0Fh
+ mov [extended_code],al
+ mov [mmx_size],16
+ jmp sse_mov_instruction
+movss_instruction:
+ mov [mmx_size],4
+ mov [opcode_prefix],0F3h
+ jmp sse_movs
+movsd_instruction:
+ mov al,0A5h
+ mov ah,[esi]
+ or ah,ah
+ jz simple_instruction_32bit
+ cmp ah,0Fh
+ je simple_instruction_32bit
+ mov [mmx_size],8
+ mov [opcode_prefix],0F2h
+ sse_movs:
+ mov [base_code],0Fh
+ mov [extended_code],10h
+ jmp sse_mov_instruction
+sse_mov_instruction:
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je sse_xmmreg
+ sse_mem:
+ cmp al,'['
+ jne invalid_operand
+ inc [extended_code]
+ call get_address
+ cmp [operand_size],0
+ je sse_mem_xmmreg
+ mov al,[mmx_size]
+ cmp [operand_size],al
+ jne invalid_operand_size
+ mov [operand_size],0
+ sse_mem_xmmreg:
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_xmm_register
+ mov [postbyte_register],al
+ jmp instruction_ready
+movlpd_instruction:
+ mov [opcode_prefix],66h
+movlps_instruction:
+ mov [base_code],0Fh
+ mov [extended_code],al
+ mov [mmx_size],8
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne sse_mem
+ lods byte [esi]
+ call convert_xmm_register
+ mov [postbyte_register],al
+ mov [operand_size],0
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ jmp sse_reg_mem
+movhlps_instruction:
+ mov [base_code],0Fh
+ mov [extended_code],al
+ mov [mmx_size],0
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_xmm_register
+ mov [postbyte_register],al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je sse_xmmreg_xmmreg_ok
+ jmp invalid_operand
+maskmovq_instruction:
+ mov cl,8
+ jmp maskmov_instruction
+maskmovdqu_instruction:
+ mov cl,16
+ mov [opcode_prefix],66h
+ maskmov_instruction:
+ mov [base_code],0Fh
+ mov [extended_code],0F7h
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_mmx_register
+ cmp ah,cl
+ jne invalid_operand_size
+ mov [postbyte_register],al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_mmx_register
+ mov bl,al
+ jmp nomem_instruction_ready
+movmskpd_instruction:
+ mov [opcode_prefix],66h
+movmskps_instruction:
+ mov [base_code],0Fh
+ mov [extended_code],50h
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ mov [postbyte_register],al
+ cmp ah,4
+ je movmskps_reg_ok
+ cmp ah,8
+ jne invalid_operand_size
+ cmp [code_type],64
+ jne invalid_operand
+ movmskps_reg_ok:
+ mov [operand_size],0
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je sse_xmmreg_xmmreg_ok
+ jmp invalid_operand
+
+cvtpi2pd_instruction:
+ mov [opcode_prefix],66h
+cvtpi2ps_instruction:
+ mov [base_code],0Fh
+ mov [extended_code],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_xmm_register
+ mov [postbyte_register],al
+ mov [operand_size],0
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je cvtpi_xmmreg_xmmreg
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ cmp [operand_size],0
+ je cvtpi_size_ok
+ cmp [operand_size],8
+ jne invalid_operand_size
+ cvtpi_size_ok:
+ jmp instruction_ready
+ cvtpi_xmmreg_xmmreg:
+ lods byte [esi]
+ call convert_mmx_register
+ cmp ah,8
+ jne invalid_operand_size
+ mov bl,al
+ jmp nomem_instruction_ready
+cvtsi2ss_instruction:
+ mov [opcode_prefix],0F3h
+ jmp cvtsi_instruction
+cvtsi2sd_instruction:
+ mov [opcode_prefix],0F2h
+ cvtsi_instruction:
+ mov [base_code],0Fh
+ mov [extended_code],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_xmm_register
+ mov [postbyte_register],al
+ cvtsi_xmmreg:
+ mov [operand_size],0
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je cvtsi_xmmreg_reg
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ cmp [operand_size],0
+ je cvtsi_size_ok
+ cmp [operand_size],4
+ je cvtsi_size_ok
+ cmp [operand_size],8
+ jne invalid_operand_size
+ call operand_64bit
+ cvtsi_size_ok:
+ jmp instruction_ready
+ cvtsi_xmmreg_reg:
+ lods byte [esi]
+ call convert_register
+ cmp ah,4
+ je cvtsi_xmmreg_reg_store
+ cmp ah,8
+ jne invalid_operand_size
+ call operand_64bit
+ cvtsi_xmmreg_reg_store:
+ mov bl,al
+ jmp nomem_instruction_ready
+cvtps2pi_instruction:
+ mov [mmx_size],8
+ jmp cvtpd_instruction
+cvtpd2pi_instruction:
+ mov [opcode_prefix],66h
+ mov [mmx_size],16
+ cvtpd_instruction:
+ mov [base_code],0Fh
+ mov [extended_code],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_mmx_register
+ cmp ah,8
+ jne invalid_operand_size
+ mov [operand_size],0
+ jmp sse_reg
+cvtss2si_instruction:
+ mov [opcode_prefix],0F3h
+ mov [mmx_size],4
+ jmp cvt2si_instruction
+cvtsd2si_instruction:
+ mov [opcode_prefix],0F2h
+ mov [mmx_size],8
+ cvt2si_instruction:
+ mov [extended_code],al
+ mov [base_code],0Fh
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ mov [operand_size],0
+ cmp ah,4
+ je sse_reg
+ cmp ah,8
+ jne invalid_operand_size
+ call operand_64bit
+ jmp sse_reg
+
+ssse3_instruction:
+ mov [base_code],0Fh
+ mov [extended_code],38h
+ mov [supplemental_code],al
+ jmp mmx_instruction
+palignr_instruction:
+ mov [base_code],0Fh
+ mov [extended_code],3Ah
+ mov [supplemental_code],0Fh
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_mmx_register
+ call make_mmx_prefix
+ mov [postbyte_register],al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je palignr_mmreg_mmreg
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ jmp mmx_imm8
+ palignr_mmreg_mmreg:
+ lods byte [esi]
+ call convert_mmx_register
+ mov bl,al
+ jmp mmx_nomem_imm8
+amd3dnow_instruction:
+ mov [base_code],0Fh
+ mov [extended_code],0Fh
+ mov byte [value],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_mmx_register
+ cmp ah,8
+ jne invalid_operand_size
+ mov [postbyte_register],al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je amd3dnow_mmreg_mmreg
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ call store_instruction_with_imm8
+ jmp instruction_assembled
+ amd3dnow_mmreg_mmreg:
+ lods byte [esi]
+ call convert_mmx_register
+ cmp ah,8
+ jne invalid_operand_size
+ mov bl,al
+ call store_nomem_instruction
+ mov al,byte [value]
+ stos byte [edi]
+ jmp instruction_assembled
+
+sse4_instruction_38_xmm0:
+ mov [immediate_size],-1
+sse4_instruction_38:
+ mov [mmx_size],16
+ mov [opcode_prefix],66h
+ mov [supplemental_code],al
+ mov al,38h
+ jmp sse_instruction
+sse4_ss_instruction_3a_imm8:
+ mov [immediate_size],1
+ mov [mmx_size],4
+ jmp sse4_instruction_3a_setup
+sse4_sd_instruction_3a_imm8:
+ mov [immediate_size],1
+ mov [mmx_size],8
+ jmp sse4_instruction_3a_setup
+sse4_instruction_3a_imm8:
+ mov [immediate_size],1
+ mov [mmx_size],16
+ sse4_instruction_3a_setup:
+ mov [opcode_prefix],66h
+ mov [supplemental_code],al
+ mov al,3Ah
+ jmp sse_instruction
+pclmulqdq_instruction:
+ mov byte [value],al
+ mov [mmx_size],16
+ mov al,44h
+ jmp sse4_instruction_3a_setup
+extractps_instruction:
+ mov [opcode_prefix],66h
+ mov [base_code],0Fh
+ mov [extended_code],3Ah
+ mov [supplemental_code],17h
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je extractps_reg
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ cmp [operand_size],4
+ je extractps_size_ok
+ cmp [operand_size],0
+ jne invalid_operand_size
+ extractps_size_ok:
+ push edx ebx ecx
+ mov [operand_size],0
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_xmm_register
+ mov [postbyte_register],al
+ pop ecx ebx edx
+ jmp mmx_imm8
+ extractps_reg:
+ lods byte [esi]
+ call convert_register
+ push eax
+ mov [operand_size],0
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_xmm_register
+ mov [postbyte_register],al
+ pop ebx
+ mov al,bh
+ cmp al,4
+ je mmx_nomem_imm8
+ cmp al,8
+ jne invalid_operand_size
+ call operand_64bit
+ jmp mmx_nomem_imm8
+insertps_instruction:
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_xmm_register
+ mov [postbyte_register],al
+ insertps_xmmreg:
+ mov [opcode_prefix],66h
+ mov [base_code],0Fh
+ mov [extended_code],3Ah
+ mov [supplemental_code],21h
+ mov [operand_size],0
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je insertps_xmmreg_reg
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ cmp [operand_size],4
+ je insertps_size_ok
+ cmp [operand_size],0
+ jne invalid_operand_size
+ insertps_size_ok:
+ jmp mmx_imm8
+ insertps_xmmreg_reg:
+ lods byte [esi]
+ call convert_mmx_register
+ mov bl,al
+ jmp mmx_nomem_imm8
+pextrq_instruction:
+ mov [mmx_size],8
+ jmp pextr_instruction
+pextrd_instruction:
+ mov [mmx_size],4
+ jmp pextr_instruction
+pextrw_instruction:
+ mov [mmx_size],2
+ jmp pextr_instruction
+pextrb_instruction:
+ mov [mmx_size],1
+ pextr_instruction:
+ mov [opcode_prefix],66h
+ mov [base_code],0Fh
+ mov [extended_code],3Ah
+ mov [supplemental_code],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je pextr_reg
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ mov al,[mmx_size]
+ cmp al,[operand_size]
+ je pextr_size_ok
+ cmp [operand_size],0
+ jne invalid_operand_size
+ pextr_size_ok:
+ cmp al,8
+ jne pextr_prefix_ok
+ call operand_64bit
+ pextr_prefix_ok:
+ push edx ebx ecx
+ mov [operand_size],0
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_xmm_register
+ mov [postbyte_register],al
+ pop ecx ebx edx
+ jmp mmx_imm8
+ pextr_reg:
+ lods byte [esi]
+ call convert_register
+ cmp [mmx_size],4
+ ja pextrq_reg
+ cmp ah,4
+ je pextr_reg_size_ok
+ cmp [code_type],64
+ jne pextr_invalid_size
+ cmp ah,8
+ je pextr_reg_size_ok
+ pextr_invalid_size:
+ jmp invalid_operand_size
+ pextrq_reg:
+ cmp ah,8
+ jne pextr_invalid_size
+ call operand_64bit
+ pextr_reg_size_ok:
+ mov [operand_size],0
+ push eax
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_mmx_register
+ mov ebx,eax
+ pop eax
+ mov [postbyte_register],al
+ mov al,ah
+ cmp [mmx_size],2
+ jne pextr_reg_store
+ mov [opcode_prefix],0
+ mov [extended_code],0C5h
+ call make_mmx_prefix
+ jmp mmx_nomem_imm8
+ pextr_reg_store:
+ cmp bh,16
+ jne invalid_operand_size
+ xchg bl,[postbyte_register]
+ call operand_autodetect
+ jmp mmx_nomem_imm8
+pinsrb_instruction:
+ mov [mmx_size],1
+ jmp pinsr_instruction
+pinsrd_instruction:
+ mov [mmx_size],4
+ jmp pinsr_instruction
+pinsrq_instruction:
+ mov [mmx_size],8
+ call operand_64bit
+ pinsr_instruction:
+ mov [opcode_prefix],66h
+ mov [base_code],0Fh
+ mov [extended_code],3Ah
+ mov [supplemental_code],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_xmm_register
+ mov [postbyte_register],al
+ pinsr_xmmreg:
+ mov [operand_size],0
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je pinsr_xmmreg_reg
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ cmp [operand_size],0
+ je mmx_imm8
+ mov al,[mmx_size]
+ cmp al,[operand_size]
+ je mmx_imm8
+ jmp invalid_operand_size
+ pinsr_xmmreg_reg:
+ lods byte [esi]
+ call convert_register
+ mov bl,al
+ cmp [mmx_size],8
+ je pinsrq_xmmreg_reg
+ cmp ah,4
+ je mmx_nomem_imm8
+ jmp invalid_operand_size
+ pinsrq_xmmreg_reg:
+ cmp ah,8
+ je mmx_nomem_imm8
+ jmp invalid_operand_size
+pmovsxbw_instruction:
+ mov [mmx_size],8
+ jmp pmovsx_instruction
+pmovsxbd_instruction:
+ mov [mmx_size],4
+ jmp pmovsx_instruction
+pmovsxbq_instruction:
+ mov [mmx_size],2
+ jmp pmovsx_instruction
+pmovsxwd_instruction:
+ mov [mmx_size],8
+ jmp pmovsx_instruction
+pmovsxwq_instruction:
+ mov [mmx_size],4
+ jmp pmovsx_instruction
+pmovsxdq_instruction:
+ mov [mmx_size],8
+ pmovsx_instruction:
+ mov [opcode_prefix],66h
+ mov [base_code],0Fh
+ mov [extended_code],38h
+ mov [supplemental_code],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_xmm_register
+ mov [postbyte_register],al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ mov [operand_size],0
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je pmovsx_xmmreg_reg
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ cmp [operand_size],0
+ je instruction_ready
+ mov al,[mmx_size]
+ cmp al,[operand_size]
+ jne invalid_operand_size
+ jmp instruction_ready
+ pmovsx_xmmreg_reg:
+ lods byte [esi]
+ call convert_xmm_register
+ mov bl,al
+ jmp nomem_instruction_ready
+
+fxsave_instruction_64bit:
+ call operand_64bit
+fxsave_instruction:
+ mov [extended_code],0AEh
+ mov [base_code],0Fh
+ mov [postbyte_register],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ mov ah,[operand_size]
+ or ah,ah
+ jz fxsave_size_ok
+ mov al,[postbyte_register]
+ cmp al,111b
+ je clflush_size_check
+ cmp al,10b
+ jb invalid_operand_size
+ cmp al,11b
+ ja invalid_operand_size
+ cmp ah,4
+ jne invalid_operand_size
+ jmp fxsave_size_ok
+ clflush_size_check:
+ cmp ah,1
+ jne invalid_operand_size
+ fxsave_size_ok:
+ jmp instruction_ready
+prefetch_instruction:
+ mov [extended_code],18h
+ prefetch_mem_8bit:
+ mov [base_code],0Fh
+ mov [postbyte_register],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_operand
+ or ah,ah
+ jz prefetch_size_ok
+ cmp ah,1
+ jne invalid_operand_size
+ prefetch_size_ok:
+ call get_address
+ jmp instruction_ready
+amd_prefetch_instruction:
+ mov [extended_code],0Dh
+ jmp prefetch_mem_8bit
+fence_instruction:
+ mov bl,al
+ mov ax,0AE0Fh
+ stos word [edi]
+ mov al,bl
+ stos byte [edi]
+ jmp instruction_assembled
+pause_instruction:
+ mov ax,90F3h
+ stos word [edi]
+ jmp instruction_assembled
+movntq_instruction:
+ mov [mmx_size],8
+ jmp movnt_instruction
+movntpd_instruction:
+ mov [opcode_prefix],66h
+movntps_instruction:
+ mov [mmx_size],16
+ movnt_instruction:
+ mov [extended_code],al
+ mov [base_code],0Fh
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_mmx_register
+ cmp ah,[mmx_size]
+ jne invalid_operand_size
+ mov [postbyte_register],al
+ jmp instruction_ready
+
+movntsd_instruction:
+ mov [opcode_prefix],0F2h
+ mov [mmx_size],8
+ jmp movnts_instruction
+movntss_instruction:
+ mov [opcode_prefix],0F3h
+ mov [mmx_size],4
+ movnts_instruction:
+ mov [extended_code],al
+ mov [base_code],0Fh
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ mov al,[operand_size]
+ cmp al,[mmx_size]
+ je movnts_size_ok
+ test al,al
+ jnz invalid_operand_size
+ movnts_size_ok:
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ mov [operand_size],0
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_xmm_register
+ mov [postbyte_register],al
+ jmp instruction_ready
+
+movnti_instruction:
+ mov [base_code],0Fh
+ mov [extended_code],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ cmp ah,4
+ je movnti_store
+ cmp ah,8
+ jne invalid_operand_size
+ call operand_64bit
+ movnti_store:
+ mov [postbyte_register],al
+ jmp instruction_ready
+monitor_instruction:
+ mov [postbyte_register],al
+ cmp byte [esi],0
+ je monitor_instruction_store
+ cmp byte [esi],0Fh
+ je monitor_instruction_store
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ cmp ax,0400h
+ jne invalid_operand
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ cmp ax,0401h
+ jne invalid_operand
+ cmp [postbyte_register],0C8h
+ jne monitor_instruction_store
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ cmp ax,0402h
+ jne invalid_operand
+ monitor_instruction_store:
+ mov ax,010Fh
+ stos word [edi]
+ mov al,[postbyte_register]
+ stos byte [edi]
+ jmp instruction_assembled
+movntdqa_instruction:
+ mov [opcode_prefix],66h
+ mov [base_code],0Fh
+ mov [extended_code],38h
+ mov [supplemental_code],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_xmm_register
+ mov [postbyte_register],al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ jmp instruction_ready
+
+extrq_instruction:
+ mov [opcode_prefix],66h
+ mov [base_code],0Fh
+ mov [extended_code],78h
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_xmm_register
+ mov [postbyte_register],al
+ mov [operand_size],0
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je extrq_xmmreg_xmmreg
+ test ah,not 1
+ jnz invalid_operand_size
+ cmp al,'('
+ jne invalid_operand
+ xor bl,bl
+ xchg bl,[postbyte_register]
+ call store_nomem_instruction
+ call get_byte_value
+ stosb
+ call append_imm8
+ jmp instruction_assembled
+ extrq_xmmreg_xmmreg:
+ inc [extended_code]
+ lods byte [esi]
+ call convert_xmm_register
+ mov bl,al
+ jmp nomem_instruction_ready
+insertq_instruction:
+ mov [opcode_prefix],0F2h
+ mov [base_code],0Fh
+ mov [extended_code],78h
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_xmm_register
+ mov [postbyte_register],al
+ mov [operand_size],0
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_xmm_register
+ mov bl,al
+ cmp byte [esi],','
+ je insertq_with_imm
+ inc [extended_code]
+ jmp nomem_instruction_ready
+ insertq_with_imm:
+ call store_nomem_instruction
+ call append_imm8
+ call append_imm8
+ jmp instruction_assembled
+
+crc32_instruction:
+ mov [opcode_prefix],0F2h
+ mov [base_code],0Fh
+ mov [extended_code],38h
+ mov [supplemental_code],0F0h
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ mov [postbyte_register],al
+ cmp ah,8
+ je crc32_reg64
+ cmp ah,4
+ jne invalid_operand
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ mov [operand_size],0
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je crc32_reg32_reg
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ mov al,[operand_size]
+ test al,al
+ jz crc32_unknown_size
+ cmp al,1
+ je crc32_reg32_mem_store
+ cmp al,4
+ ja invalid_operand_size
+ inc [supplemental_code]
+ call operand_autodetect
+ crc32_reg32_mem_store:
+ jmp instruction_ready
+ crc32_unknown_size:
+ call recoverable_unknown_size
+ jmp crc32_reg32_mem_store
+ crc32_reg32_reg:
+ lods byte [esi]
+ call convert_register
+ mov bl,al
+ mov al,ah
+ cmp al,1
+ je crc32_reg32_reg_store
+ cmp al,4
+ ja invalid_operand_size
+ inc [supplemental_code]
+ call operand_autodetect
+ crc32_reg32_reg_store:
+ jmp nomem_instruction_ready
+ crc32_reg64:
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ mov [operand_size],0
+ call operand_64bit
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je crc32_reg64_reg
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ mov ah,[operand_size]
+ mov al,8
+ test ah,ah
+ jz crc32_unknown_size
+ cmp ah,1
+ je crc32_reg32_mem_store
+ cmp ah,al
+ jne invalid_operand_size
+ inc [supplemental_code]
+ jmp crc32_reg32_mem_store
+ crc32_reg64_reg:
+ lods byte [esi]
+ call convert_register
+ mov bl,al
+ mov al,8
+ cmp ah,1
+ je crc32_reg32_reg_store
+ cmp ah,al
+ jne invalid_operand_size
+ inc [supplemental_code]
+ jmp crc32_reg32_reg_store
+popcnt_instruction:
+ mov [opcode_prefix],0F3h
+ jmp bs_instruction
+movbe_instruction:
+ mov [supplemental_code],al
+ mov [extended_code],38h
+ mov [base_code],0Fh
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ je movbe_mem
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ mov [postbyte_register],al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_argument
+ call get_address
+ mov al,[operand_size]
+ call operand_autodetect
+ jmp instruction_ready
+ movbe_mem:
+ inc [supplemental_code]
+ call get_address
+ push edx ebx ecx
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ mov [postbyte_register],al
+ pop ecx ebx edx
+ mov al,[operand_size]
+ call operand_autodetect
+ jmp instruction_ready
+adx_instruction:
+ mov [base_code],0Fh
+ mov [extended_code],38h
+ mov [supplemental_code],0F6h
+ mov [operand_prefix],al
+ call get_reg_mem
+ jc adx_reg_reg
+ mov al,[operand_size]
+ cmp al,4
+ je instruction_ready
+ cmp al,8
+ jne invalid_operand_size
+ call operand_64bit
+ jmp instruction_ready
+ adx_reg_reg:
+ cmp ah,4
+ je nomem_instruction_ready
+ cmp ah,8
+ jne invalid_operand_size
+ call operand_64bit
+ jmp nomem_instruction_ready
+
+simple_vmx_instruction:
+ mov ah,al
+ mov al,0Fh
+ stos byte [edi]
+ mov al,1
+ stos word [edi]
+ jmp instruction_assembled
+vmclear_instruction:
+ mov [opcode_prefix],66h
+ jmp vmx_instruction
+vmxon_instruction:
+ mov [opcode_prefix],0F3h
+vmx_instruction:
+ mov [postbyte_register],al
+ mov [extended_code],0C7h
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ mov al,[operand_size]
+ or al,al
+ jz vmx_size_ok
+ cmp al,8
+ jne invalid_operand_size
+ vmx_size_ok:
+ mov [base_code],0Fh
+ jmp instruction_ready
+vmread_instruction:
+ mov [extended_code],78h
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je vmread_nomem
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ mov [postbyte_register],al
+ call vmread_check_size
+ jmp vmx_size_ok
+ vmread_nomem:
+ lods byte [esi]
+ call convert_register
+ push eax
+ call vmread_check_size
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ mov [postbyte_register],al
+ call vmread_check_size
+ pop ebx
+ mov [base_code],0Fh
+ jmp nomem_instruction_ready
+ vmread_check_size:
+ cmp [code_type],64
+ je vmread_long
+ cmp [operand_size],4
+ jne invalid_operand_size
+ ret
+ vmread_long:
+ cmp [operand_size],8
+ jne invalid_operand_size
+ ret
+vmwrite_instruction:
+ mov [extended_code],79h
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ mov [postbyte_register],al
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ je vmwrite_nomem
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ call vmread_check_size
+ jmp vmx_size_ok
+ vmwrite_nomem:
+ lods byte [esi]
+ call convert_register
+ mov bl,al
+ mov [base_code],0Fh
+ jmp nomem_instruction_ready
+vmx_inv_instruction:
+ mov [opcode_prefix],66h
+ mov [extended_code],38h
+ mov [supplemental_code],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ mov [postbyte_register],al
+ call vmread_check_size
+ mov [operand_size],0
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,'['
+ jne invalid_operand
+ call get_address
+ mov al,[operand_size]
+ or al,al
+ jz vmx_size_ok
+ cmp al,16
+ jne invalid_operand_size
+ jmp vmx_size_ok
+simple_svm_instruction:
+ push eax
+ mov [base_code],0Fh
+ mov [extended_code],1
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ or al,al
+ jnz invalid_operand
+ simple_svm_detect_size:
+ cmp ah,2
+ je simple_svm_16bit
+ cmp ah,4
+ je simple_svm_32bit
+ cmp [code_type],64
+ jne invalid_operand_size
+ jmp simple_svm_store
+ simple_svm_16bit:
+ cmp [code_type],16
+ je simple_svm_store
+ cmp [code_type],64
+ je invalid_operand_size
+ jmp prefixed_svm_store
+ simple_svm_32bit:
+ cmp [code_type],32
+ je simple_svm_store
+ prefixed_svm_store:
+ mov al,67h
+ stos byte [edi]
+ simple_svm_store:
+ call store_instruction_code
+ pop eax
+ stos byte [edi]
+ jmp instruction_assembled
+skinit_instruction:
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ cmp ax,0400h
+ jne invalid_operand
+ mov al,0DEh
+ jmp simple_vmx_instruction
+invlpga_instruction:
+ push eax
+ mov [base_code],0Fh
+ mov [extended_code],1
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ or al,al
+ jnz invalid_operand
+ mov bl,ah
+ mov [operand_size],0
+ lods byte [esi]
+ cmp al,','
+ jne invalid_operand
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ cmp ax,0401h
+ jne invalid_operand
+ mov ah,bl
+ jmp simple_svm_detect_size
+
+rdrand_instruction:
+ mov [base_code],0Fh
+ mov [extended_code],0C7h
+ mov [postbyte_register],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ mov bl,al
+ mov al,ah
+ call operand_autodetect
+ jmp nomem_instruction_ready
+rdfsbase_instruction:
+ cmp [code_type],64
+ jne illegal_instruction
+ mov [opcode_prefix],0F3h
+ mov [base_code],0Fh
+ mov [extended_code],0AEh
+ mov [postbyte_register],al
+ lods byte [esi]
+ call get_size_operator
+ cmp al,10h
+ jne invalid_operand
+ lods byte [esi]
+ call convert_register
+ mov bl,al
+ mov al,ah
+ cmp ah,2
+ je invalid_operand_size
+ call operand_autodetect
+ jmp nomem_instruction_ready
+
+xabort_instruction:
+ lods byte [esi]
+ call get_size_operator
+ cmp ah,1
+ ja invalid_operand_size
+ cmp al,'('
+ jne invalid_operand
+ call get_byte_value
+ mov dl,al
+ mov ax,0F8C6h
+ stos word [edi]
+ mov al,dl
+ stos byte [edi]
+ jmp instruction_assembled
+xbegin_instruction:
+ lods byte [esi]
+ cmp al,'('
+ jne invalid_operand
+ mov al,[code_type]
+ cmp al,64
+ je xbegin_64bit
+ cmp al,32
+ je xbegin_32bit
+ xbegin_16bit:
+ call get_address_word_value
+ add edi,4
+ mov ebp,[addressing_space]
+ call calculate_relative_offset
+ sub edi,4
+ shl eax,16
+ mov ax,0F8C7h
+ stos dword [edi]
+ jmp instruction_assembled
+ xbegin_32bit:
+ call get_address_dword_value
+ jmp xbegin_address_ok
+ xbegin_64bit:
+ call get_address_qword_value
+ xbegin_address_ok:
+ add edi,5
+ mov ebp,[addressing_space]
+ call calculate_relative_offset
+ sub edi,5
+ mov edx,eax
+ cwde
+ cmp eax,edx
+ jne xbegin_rel32
+ mov al,66h
+ stos byte [edi]
+ mov eax,edx
+ shl eax,16
+ mov ax,0F8C7h
+ stos dword [edi]
+ jmp instruction_assembled
+ xbegin_rel32:
+ sub edx,1
+ jno xbegin_rel32_ok
+ cmp [code_type],64
+ je relative_jump_out_of_range
+ xbegin_rel32_ok:
+ mov ax,0F8C7h
+ stos word [edi]
+ mov eax,edx
+ stos dword [edi]
+ jmp instruction_assembled
+
+convert_register:
+ mov ah,al
+ shr ah,4
+ and al,0Fh
+ cmp ah,8
+ je match_register_size
+ cmp ah,4
+ ja invalid_operand
+ cmp ah,1
+ ja match_register_size
+ cmp al,4
+ jb match_register_size
+ or ah,ah
+ jz high_byte_register
+ or [rex_prefix],40h
+ match_register_size:
+ cmp ah,[operand_size]
+ je register_size_ok
+ cmp [operand_size],0
+ jne operand_sizes_do_not_match
+ mov [operand_size],ah
+ register_size_ok:
+ ret
+ high_byte_register:
+ mov ah,1
+ or [rex_prefix],80h
+ jmp match_register_size
+convert_fpu_register:
+ mov ah,al
+ shr ah,4
+ and al,111b
+ cmp ah,10
+ jne invalid_operand
+ jmp match_register_size
+convert_mmx_register:
+ mov ah,al
+ shr ah,4
+ cmp ah,0Ch
+ je xmm_register
+ ja invalid_operand
+ and al,111b
+ cmp ah,0Bh
+ jne invalid_operand
+ mov ah,8
+ cmp [vex_required],0
+ jne invalid_operand
+ jmp match_register_size
+ xmm_register:
+ and al,0Fh
+ mov ah,16
+ cmp al,8
+ jb match_register_size
+ cmp [code_type],64
+ jne invalid_operand
+ jmp match_register_size
+convert_xmm_register:
+ mov ah,al
+ shr ah,4
+ cmp ah,0Ch
+ je xmm_register
+ jmp invalid_operand
+get_size_operator:
+ xor ah,ah
+ cmp al,11h
+ jne no_size_operator
+ mov [size_declared],1
+ lods word [esi]
+ xchg al,ah
+ mov [size_override],1
+ cmp ah,[operand_size]
+ je size_operator_ok
+ cmp [operand_size],0
+ jne operand_sizes_do_not_match
+ mov [operand_size],ah
+ size_operator_ok:
+ ret
+ no_size_operator:
+ mov [size_declared],0
+ cmp al,'['
+ jne size_operator_ok
+ mov [size_override],0
+ ret
+get_jump_operator:
+ mov [jump_type],0
+ cmp al,12h
+ jne jump_operator_ok
+ lods word [esi]
+ mov [jump_type],al
+ mov al,ah
+ jump_operator_ok:
+ ret
+get_address:
+ mov [segment_register],0
+ mov [address_size],0
+ mov [free_address_range],0
+ mov al,[code_type]
+ shr al,3
+ mov [value_size],al
+ mov al,[esi]
+ and al,11110000b
+ cmp al,60h
+ jne get_size_prefix
+ lods byte [esi]
+ sub al,60h
+ mov [segment_register],al
+ mov al,[esi]
+ and al,11110000b
+ get_size_prefix:
+ cmp al,70h
+ jne address_size_prefix_ok
+ lods byte [esi]
+ sub al,70h
+ cmp al,2
+ jb invalid_address_size
+ cmp al,8
+ ja invalid_address_size
+ mov [address_size],al
+ mov [value_size],al
+ address_size_prefix_ok:
+ call calculate_address
+ cmp byte [esi-1],']'
+ jne invalid_address
+ mov [address_high],edx
+ mov edx,eax
+ cmp [code_type],64
+ jne address_ok
+ or bx,bx
+ jnz address_ok
+ test ch,0Fh
+ jnz address_ok
+ calculate_relative_address:
+ mov edx,[address_symbol]
+ mov [symbol_identifier],edx
+ mov edx,[address_high]
+ mov ebp,[addressing_space]
+ call calculate_relative_offset
+ mov [address_high],edx
+ cdq
+ cmp edx,[address_high]
+ je address_high_ok
+ call recoverable_overflow
+ address_high_ok:
+ mov edx,eax
+ ror ecx,16
+ mov cl,[value_type]
+ rol ecx,16
+ mov bx,0FF00h
+ address_ok:
+ ret
+operand_16bit:
+ cmp [code_type],16
+ je size_prefix_ok
+ mov [operand_prefix],66h
+ ret
+operand_32bit:
+ cmp [code_type],16
+ jne size_prefix_ok
+ mov [operand_prefix],66h
+ size_prefix_ok:
+ ret
+operand_64bit:
+ cmp [code_type],64
+ jne illegal_instruction
+ or [rex_prefix],48h
+ ret
+operand_autodetect:
+ cmp al,2
+ je operand_16bit
+ cmp al,4
+ je operand_32bit
+ cmp al,8
+ je operand_64bit
+ jmp invalid_operand_size
+store_segment_prefix_if_necessary:
+ mov al,[segment_register]
+ or al,al
+ jz segment_prefix_ok
+ cmp al,4
+ ja segment_prefix_386
+ cmp [code_type],64
+ je segment_prefix_ok
+ cmp al,3
+ je ss_prefix
+ jb segment_prefix_86
+ cmp bl,25h
+ je segment_prefix_86
+ cmp bh,25h
+ je segment_prefix_86
+ cmp bh,45h
+ je segment_prefix_86
+ cmp bh,44h
+ je segment_prefix_86
+ ret
+ ss_prefix:
+ cmp bl,25h
+ je segment_prefix_ok
+ cmp bh,25h
+ je segment_prefix_ok
+ cmp bh,45h
+ je segment_prefix_ok
+ cmp bh,44h
+ je segment_prefix_ok
+ jmp segment_prefix_86
+store_segment_prefix:
+ mov al,[segment_register]
+ or al,al
+ jz segment_prefix_ok
+ cmp al,5
+ jae segment_prefix_386
+ segment_prefix_86:
+ dec al
+ shl al,3
+ add al,26h
+ stos byte [edi]
+ jmp segment_prefix_ok
+ segment_prefix_386:
+ add al,64h-5
+ stos byte [edi]
+ segment_prefix_ok:
+ ret
+store_instruction_code:
+ cmp [vex_required],0
+ jne store_vex_instruction_code
+ mov al,[operand_prefix]
+ or al,al
+ jz operand_prefix_ok
+ stos byte [edi]
+ operand_prefix_ok:
+ mov al,[opcode_prefix]
+ or al,al
+ jz opcode_prefix_ok
+ stos byte [edi]
+ opcode_prefix_ok:
+ mov al,[rex_prefix]
+ test al,40h
+ jz rex_prefix_ok
+ cmp [code_type],64
+ jne invalid_operand
+ test al,0B0h
+ jnz disallowed_combination_of_registers
+ stos byte [edi]
+ rex_prefix_ok:
+ mov al,[base_code]
+ stos byte [edi]
+ cmp al,0Fh
+ jne instruction_code_ok
+ store_extended_code:
+ mov al,[extended_code]
+ stos byte [edi]
+ cmp al,38h
+ je store_supplemental_code
+ cmp al,3Ah
+ je store_supplemental_code
+ instruction_code_ok:
+ ret
+ store_supplemental_code:
+ mov al,[supplemental_code]
+ stos byte [edi]
+ ret
+store_nomem_instruction:
+ test [postbyte_register],1000b
+ jz nomem_reg_code_ok
+ or [rex_prefix],44h
+ and [postbyte_register],111b
+ nomem_reg_code_ok:
+ test bl,1000b
+ jz nomem_rm_code_ok
+ or [rex_prefix],41h
+ and bl,111b
+ nomem_rm_code_ok:
+ call store_instruction_code
+ mov al,[postbyte_register]
+ shl al,3
+ or al,bl
+ or al,11000000b
+ stos byte [edi]
+ ret
+store_instruction:
+ mov [current_offset],edi
+ test [postbyte_register],1000b
+ jz reg_code_ok
+ or [rex_prefix],44h
+ and [postbyte_register],111b
+ reg_code_ok:
+ cmp [code_type],64
+ jne address_value_ok
+ xor eax,eax
+ bt edx,31
+ sbb eax,[address_high]
+ jz address_value_ok
+ cmp [address_high],0
+ jne address_value_out_of_range
+ test ch,44h
+ jnz address_value_ok
+ test bx,8080h
+ jz address_value_ok
+ address_value_out_of_range:
+ call recoverable_overflow
+ address_value_ok:
+ call store_segment_prefix_if_necessary
+ test [vex_required],4
+ jnz address_vsib
+ or bx,bx
+ jz address_immediate
+ cmp bx,0F800h
+ je address_rip_based
+ cmp bx,0F400h
+ je address_eip_based
+ cmp bx,0FF00h
+ je address_relative
+ mov al,bl
+ or al,bh
+ and al,11110000b
+ cmp al,80h
+ je postbyte_64bit
+ cmp al,40h
+ je postbyte_32bit
+ cmp al,20h
+ jne invalid_address
+ cmp [code_type],64
+ je invalid_address_size
+ call address_16bit_prefix
+ call store_instruction_code
+ cmp bl,bh
+ jbe determine_16bit_address
+ xchg bl,bh
+ determine_16bit_address:
+ cmp bx,2600h
+ je address_si
+ cmp bx,2700h
+ je address_di
+ cmp bx,2300h
+ je address_bx
+ cmp bx,2500h
+ je address_bp
+ cmp bx,2625h
+ je address_bp_si
+ cmp bx,2725h
+ je address_bp_di
+ cmp bx,2723h
+ je address_bx_di
+ cmp bx,2623h
+ jne invalid_address
+ address_bx_si:
+ xor al,al
+ jmp postbyte_16bit
+ address_bx_di:
+ mov al,1
+ jmp postbyte_16bit
+ address_bp_si:
+ mov al,10b
+ jmp postbyte_16bit
+ address_bp_di:
+ mov al,11b
+ jmp postbyte_16bit
+ address_si:
+ mov al,100b
+ jmp postbyte_16bit
+ address_di:
+ mov al,101b
+ jmp postbyte_16bit
+ address_bx:
+ mov al,111b
+ jmp postbyte_16bit
+ address_bp:
+ mov al,110b
+ postbyte_16bit:
+ test ch,22h
+ jnz address_16bit_value
+ or ch,ch
+ jnz address_sizes_do_not_agree
+ cmp edx,10000h
+ jge value_out_of_range
+ cmp edx,-8000h
+ jl value_out_of_range
+ or dx,dx
+ jz address
+ cmp dx,80h
+ jb address_8bit_value
+ cmp dx,-80h
+ jae address_8bit_value
+ address_16bit_value:
+ or al,10000000b
+ mov cl,[postbyte_register]
+ shl cl,3
+ or al,cl
+ stos byte [edi]
+ mov eax,edx
+ stos word [edi]
+ ret
+ address_8bit_value:
+ or al,01000000b
+ mov cl,[postbyte_register]
+ shl cl,3
+ or al,cl
+ stos byte [edi]
+ mov al,dl
+ stos byte [edi]
+ cmp dx,80h
+ jge value_out_of_range
+ cmp dx,-80h
+ jl value_out_of_range
+ ret
+ address:
+ cmp al,110b
+ je address_8bit_value
+ mov cl,[postbyte_register]
+ shl cl,3
+ or al,cl
+ stos byte [edi]
+ ret
+ address_vsib:
+ mov al,bl
+ shr al,4
+ cmp al,0Ch
+ je vector_index_ok
+ cmp al,0Dh
+ jne invalid_address
+ vector_index_ok:
+ mov al,bh
+ shr al,4
+ cmp al,4
+ je postbyte_32bit
+ cmp [code_type],64
+ je address_prefix_ok
+ test al,al
+ jnz invalid_address
+ postbyte_32bit:
+ call address_32bit_prefix
+ jmp address_prefix_ok
+ postbyte_64bit:
+ cmp [code_type],64
+ jne invalid_address_size
+ address_prefix_ok:
+ cmp bl,44h
+ je invalid_address
+ cmp bl,84h
+ je invalid_address
+ test bh,1000b
+ jz base_code_ok
+ or [rex_prefix],41h
+ base_code_ok:
+ test bl,1000b
+ jz index_code_ok
+ or [rex_prefix],42h
+ index_code_ok:
+ call store_instruction_code
+ or cl,cl
+ jz only_base_register
+ base_and_index:
+ mov al,100b
+ xor ah,ah
+ cmp cl,1
+ je scale_ok
+ cmp cl,2
+ je scale_1
+ cmp cl,4
+ je scale_2
+ or ah,11000000b
+ jmp scale_ok
+ scale_2:
+ or ah,10000000b
+ jmp scale_ok
+ scale_1:
+ or ah,01000000b
+ scale_ok:
+ or bh,bh
+ jz only_index_register
+ and bl,111b
+ shl bl,3
+ or ah,bl
+ and bh,111b
+ or ah,bh
+ sib_ready:
+ test ch,44h
+ jnz sib_address_32bit_value
+ test ch,88h
+ jnz sib_address_32bit_value
+ or ch,ch
+ jnz address_sizes_do_not_agree
+ cmp bh,5
+ je address_value
+ or edx,edx
+ jz sib_address
+ address_value:
+ cmp edx,80h
+ jb sib_address_8bit_value
+ cmp edx,-80h
+ jae sib_address_8bit_value
+ sib_address_32bit_value:
+ or al,10000000b
+ mov cl,[postbyte_register]
+ shl cl,3
+ or al,cl
+ stos word [edi]
+ jmp store_address_32bit_value
+ sib_address_8bit_value:
+ or al,01000000b
+ mov cl,[postbyte_register]
+ shl cl,3
+ or al,cl
+ stos word [edi]
+ mov al,dl
+ stos byte [edi]
+ cmp edx,80h
+ jge value_out_of_range
+ cmp edx,-80h
+ jl value_out_of_range
+ ret
+ sib_address:
+ mov cl,[postbyte_register]
+ shl cl,3
+ or al,cl
+ stos word [edi]
+ ret
+ only_index_register:
+ or ah,101b
+ and bl,111b
+ shl bl,3
+ or ah,bl
+ mov cl,[postbyte_register]
+ shl cl,3
+ or al,cl
+ stos word [edi]
+ test ch,44h
+ jnz store_address_32bit_value
+ test ch,88h
+ jnz store_address_32bit_value
+ or ch,ch
+ jnz invalid_address_size
+ jmp store_address_32bit_value
+ zero_index_register:
+ mov bl,4
+ mov cl,1
+ jmp base_and_index
+ only_base_register:
+ mov al,bh
+ and al,111b
+ cmp al,4
+ je zero_index_register
+ test ch,44h
+ jnz simple_address_32bit_value
+ test ch,88h
+ jnz simple_address_32bit_value
+ or ch,ch
+ jnz address_sizes_do_not_agree
+ or edx,edx
+ jz simple_address
+ cmp edx,80h
+ jb simple_address_8bit_value
+ cmp edx,-80h
+ jae simple_address_8bit_value
+ simple_address_32bit_value:
+ or al,10000000b
+ mov cl,[postbyte_register]
+ shl cl,3
+ or al,cl
+ stos byte [edi]
+ jmp store_address_32bit_value
+ simple_address_8bit_value:
+ or al,01000000b
+ mov cl,[postbyte_register]
+ shl cl,3
+ or al,cl
+ stos byte [edi]
+ mov al,dl
+ stos byte [edi]
+ cmp edx,80h
+ jge value_out_of_range
+ cmp edx,-80h
+ jl value_out_of_range
+ ret
+ simple_address:
+ cmp al,5
+ je simple_address_8bit_value
+ mov cl,[postbyte_register]
+ shl cl,3
+ or al,cl
+ stos byte [edi]
+ ret
+ address_immediate:
+ cmp [code_type],64
+ je address_immediate_sib
+ test ch,44h
+ jnz address_immediate_32bit
+ test ch,88h
+ jnz address_immediate_32bit
+ test ch,22h
+ jnz address_immediate_16bit
+ or ch,ch
+ jnz invalid_address_size
+ cmp [code_type],16
+ je addressing_16bit
+ address_immediate_32bit:
+ call address_32bit_prefix
+ call store_instruction_code
+ store_immediate_address:
+ mov al,101b
+ mov cl,[postbyte_register]
+ shl cl,3
+ or al,cl
+ stos byte [edi]
+ store_address_32bit_value:
+ test ch,0F0h
+ jz address_32bit_relocation_ok
+ mov eax,ecx
+ shr eax,16
+ cmp al,4
+ jne address_32bit_relocation
+ mov al,2
+ address_32bit_relocation:
+ xchg [value_type],al
+ mov ebx,[address_symbol]
+ xchg ebx,[symbol_identifier]
+ call mark_relocation
+ mov [value_type],al
+ mov [symbol_identifier],ebx
+ address_32bit_relocation_ok:
+ mov eax,edx
+ stos dword [edi]
+ ret
+ store_address_64bit_value:
+ test ch,0F0h
+ jz address_64bit_relocation_ok
+ mov eax,ecx
+ shr eax,16
+ xchg [value_type],al
+ mov ebx,[address_symbol]
+ xchg ebx,[symbol_identifier]
+ call mark_relocation
+ mov [value_type],al
+ mov [symbol_identifier],ebx
+ address_64bit_relocation_ok:
+ mov eax,edx
+ stos dword [edi]
+ mov eax,[address_high]
+ stos dword [edi]
+ ret
+ address_immediate_sib:
+ test ch,44h
+ jnz address_immediate_sib_32bit
+ test ch,not 88h
+ jnz invalid_address_size
+ address_immediate_sib_store:
+ call store_instruction_code
+ mov al,100b
+ mov ah,100101b
+ mov cl,[postbyte_register]
+ shl cl,3
+ or al,cl
+ stos word [edi]
+ jmp store_address_32bit_value
+ address_immediate_sib_32bit:
+ test ecx,0FF0000h
+ jnz address_immediate_sib_nosignextend
+ test edx,80000000h
+ jz address_immediate_sib_store
+ address_immediate_sib_nosignextend:
+ call address_32bit_prefix
+ jmp address_immediate_sib_store
+ address_eip_based:
+ mov al,67h
+ stos byte [edi]
+ address_rip_based:
+ cmp [code_type],64
+ jne invalid_address
+ call store_instruction_code
+ jmp store_immediate_address
+ address_relative:
+ call store_instruction_code
+ movzx eax,[immediate_size]
+ add eax,edi
+ sub eax,[current_offset]
+ add eax,5
+ sub edx,eax
+ jo value_out_of_range
+ mov al,101b
+ mov cl,[postbyte_register]
+ shl cl,3
+ or al,cl
+ stos byte [edi]
+ shr ecx,16
+ xchg [value_type],cl
+ mov ebx,[address_symbol]
+ xchg ebx,[symbol_identifier]
+ mov eax,edx
+ call mark_relocation
+ mov [value_type],cl
+ mov [symbol_identifier],ebx
+ stos dword [edi]
+ ret
+ addressing_16bit:
+ cmp edx,10000h
+ jge address_immediate_32bit
+ cmp edx,-8000h
+ jl address_immediate_32bit
+ movzx edx,dx
+ address_immediate_16bit:
+ call address_16bit_prefix
+ call store_instruction_code
+ mov al,110b
+ mov cl,[postbyte_register]
+ shl cl,3
+ or al,cl
+ stos byte [edi]
+ mov eax,edx
+ stos word [edi]
+ cmp edx,10000h
+ jge value_out_of_range
+ cmp edx,-8000h
+ jl value_out_of_range
+ ret
+ address_16bit_prefix:
+ cmp [code_type],16
+ je instruction_prefix_ok
+ mov al,67h
+ stos byte [edi]
+ ret
+ address_32bit_prefix:
+ cmp [code_type],32
+ je instruction_prefix_ok
+ mov al,67h
+ stos byte [edi]
+ instruction_prefix_ok:
+ ret
+store_instruction_with_imm8:
+ mov [immediate_size],1
+ call store_instruction
+ mov al,byte [value]
+ stos byte [edi]
+ ret
+store_instruction_with_imm16:
+ mov [immediate_size],2
+ call store_instruction
+ mov ax,word [value]
+ call mark_relocation
+ stos word [edi]
+ ret
+store_instruction_with_imm32:
+ mov [immediate_size],4
+ call store_instruction
+ mov eax,dword [value]
+ call mark_relocation
+ stos dword [edi]
+ ret
diff --git a/samples/BlitzBasic/HalfAndDouble.bb b/samples/BlitzBasic/HalfAndDouble.bb
new file mode 100644
index 00000000..6b8aa0d3
--- /dev/null
+++ b/samples/BlitzBasic/HalfAndDouble.bb
@@ -0,0 +1,147 @@
+
+Local bk = CreateBank(8)
+PokeFloat bk, 0, -1
+Print Bin(PeekInt(bk, 0))
+Print %1000000000000000
+Print Bin(1 Shl 31)
+Print $1f
+Print $ff
+Print $1f + (127 - 15)
+Print Hex(%01111111100000000000000000000000)
+Print Hex(~%11111111100000000000000000000000)
+
+Print Bin(FloatToHalf(-2.5))
+Print HalfToFloat(FloatToHalf(-200000000000.0))
+
+Print Bin(FToI(-2.5))
+
+WaitKey
+End
+
+
+; Half-precision (16-bit) arithmetic library
+;============================================
+
+Global Half_CBank_
+
+Function FToI(f#)
+ If Half_CBank_ = 0 Then Half_CBank_ = CreateBank(4)
+ PokeFloat Half_CBank_, 0, f
+ Return PeekInt(Half_CBank_, 0)
+End Function
+
+Function HalfToFloat#(h)
+ Local signBit, exponent, fraction, fBits
+
+ signBit = (h And 32768) <> 0
+ exponent = (h And %0111110000000000) Shr 10
+ fraction = (h And %0000001111111111)
+
+ If exponent = $1F Then exponent = $FF : ElseIf exponent Then exponent = (exponent - 15) + 127
+ fBits = (signBit Shl 31) Or (exponent Shl 23) Or (fraction Shl 13)
+
+ If Half_CBank_ = 0 Then Half_CBank_ = CreateBank(4)
+ PokeInt Half_CBank_, 0, fBits
+ Return PeekFloat(Half_CBank_, 0)
+End Function
+
+Function FloatToHalf(f#)
+ Local signBit, exponent, fraction, fBits
+
+ If Half_CBank_ = 0 Then Half_CBank_ = CreateBank(4)
+ PokeFloat Half_CBank_, 0, f
+ fBits = PeekInt(Half_CBank_, 0)
+
+ signBit = (fBits And (1 Shl 31)) <> 0
+ exponent = (fBits And $7F800000) Shr 23
+ fraction = fBits And $007FFFFF
+
+ If exponent
+ exponent = exponent - 127
+ If Abs(exponent) > $1F
+ If exponent <> ($FF - 127) Then fraction = 0
+ exponent = $1F * Sgn(exponent)
+ Else
+ exponent = exponent + 15
+ EndIf
+ exponent = exponent And %11111
+ EndIf
+ fraction = fraction Shr 13
+
+ Return (signBit Shl 15) Or (exponent Shl 10) Or fraction
+End Function
+
+Function HalfAdd(l, r)
+
+End Function
+
+Function HalfSub(l, r)
+
+End Function
+
+Function HalfMul(l, r)
+
+End Function
+
+Function HalfDiv(l, r)
+
+End Function
+
+Function HalfLT(l, r)
+
+End Function
+
+Function HalfGT(l, r)
+
+End Function
+
+
+; Double-precision (64-bit) arithmetic library)
+;===============================================
+
+Global DoubleOut[1], Double_CBank_
+
+Function DoubleToFloat#(d[1])
+
+End Function
+
+Function FloatToDouble(f#)
+
+End Function
+
+Function IntToDouble(i)
+
+End Function
+
+Function SefToDouble(s, e, f)
+
+End Function
+
+Function DoubleAdd(l, r)
+
+End Function
+
+Function DoubleSub(l, r)
+
+End Function
+
+Function DoubleMul(l, r)
+
+End Function
+
+Function DoubleDiv(l, r)
+
+End Function
+
+Function DoubleLT(l, r)
+
+End Function
+
+Function DoubleGT(l, r)
+
+End Function
+
+
+;~IDEal Editor Parameters:
+;~F#1A#20#2F
+;~C#Blitz3D
\ No newline at end of file
diff --git a/samples/BlitzBasic/LList.bb b/samples/BlitzBasic/LList.bb
new file mode 100644
index 00000000..49bf4eaa
--- /dev/null
+++ b/samples/BlitzBasic/LList.bb
@@ -0,0 +1,369 @@
+
+; Double-linked list container class
+;====================================
+
+; with thanks to MusicianKool, for concept and issue fixes
+
+
+Type LList
+ Field head_.ListNode
+ Field tail_.ListNode
+End Type
+
+Type ListNode
+ Field pv_.ListNode
+ Field nx_.ListNode
+ Field Value
+End Type
+
+Type Iterator
+ Field Value
+ Field l_.LList
+ Field cn_.ListNode, cni_
+End Type
+
+
+;Create a new LList object
+Function CreateList.LList()
+ Local l.LList = New LList
+
+ l\head_ = New ListNode
+ l\tail_ = New ListNode
+
+ l\head_\nx_ = l\tail_ ;End caps
+ l\head_\pv_ = l\head_ ;These make it more or less safe to iterate freely
+ l\head_\Value = 0
+
+ l\tail_\nx_ = l\tail_
+ l\tail_\pv_ = l\head_
+ l\tail_\Value = 0
+
+ Return l
+End Function
+
+;Free a list and all elements (not any values)
+Function FreeList(l.LList)
+ ClearList l
+ Delete l\head_
+ Delete l\tail_
+ Delete l
+End Function
+
+;Remove all the elements from a list (does not free values)
+Function ClearList(l.LList)
+ Local n.ListNode = l\head_\nx_
+ While n <> l\tail_
+ Local nx.ListNode = n\nx_
+ Delete n
+ n = nx
+ Wend
+ l\head_\nx_ = l\tail_
+ l\tail_\pv_ = l\head_
+End Function
+
+;Count the number of elements in a list (slow)
+Function ListLength(l.LList)
+ Local i.Iterator = GetIterator(l), elems
+ While EachIn(i)
+ elems = elems + 1
+ Wend
+ Return elems
+End Function
+
+;Return True if a list contains a given value
+Function ListContains(l.LList, Value)
+ Return (ListFindNode(l, Value) <> Null)
+End Function
+
+;Create a linked list from the intvalues in a bank (slow)
+Function ListFromBank.LList(bank)
+ Local l.LList = CreateList()
+ Local size = BankSize(bank), p
+
+ For p = 0 To size - 4 Step 4
+ ListAddLast l, PeekInt(bank, p)
+ Next
+
+ Return l
+End Function
+
+;Create a bank containing all the values in a list (slow)
+Function ListToBank(l.LList)
+ Local size = ListLength(l) * 4
+ Local bank = CreateBank(size)
+
+ Local i.Iterator = GetIterator(l), p = 0
+ While EachIn(i)
+ PokeInt bank, p, i\Value
+ p = p + 4
+ Wend
+
+ Return bank
+End Function
+
+;Swap the contents of two list objects
+Function SwapLists(l1.LList, l2.LList)
+ Local tempH.ListNode = l1\head_, tempT.ListNode = l1\tail_
+ l1\head_ = l2\head_
+ l1\tail_ = l2\tail_
+ l2\head_ = tempH
+ l2\tail_ = tempT
+End Function
+
+;Create a new list containing the same values as the first
+Function CopyList.LList(lo.LList)
+ Local ln.LList = CreateList()
+ Local i.Iterator = GetIterator(lo) : While EachIn(i)
+ ListAddLast ln, i\Value
+ Wend
+ Return ln
+End Function
+
+;Reverse the order of elements of a list
+Function ReverseList(l.LList)
+ Local n1.ListNode, n2.ListNode, tmp.ListNode
+
+ n1 = l\head_
+ n2 = l\head_\nx_
+
+ While n1 <> l\tail_
+ n1\pv_ = n2
+ tmp = n2\nx_
+ n2\nx_ = n1
+ n1 = n2
+ n2 = tmp
+ Wend
+
+ tmp = l\head_
+ l\head_ = l\tail_
+ l\tail_ = tmp
+
+ l\head_\pv_ = l\head_
+ l\tail_\nx_ = l\tail_
+End Function
+
+;Search a list to retrieve the first node with the given value
+Function ListFindNode.ListNode(l.LList, Value)
+ Local n.ListNode = l\head_\nx_
+
+ While n <> l\tail_
+ If n\Value = Value Then Return n
+ n = n\nx_
+ Wend
+
+ Return Null
+End Function
+
+;Append a value to the end of a list (fast) and return the node
+Function ListAddLast.ListNode(l.LList, Value)
+ Local n.ListNode = New ListNode
+
+ n\pv_ = l\tail_\pv_
+ n\nx_ = l\tail_
+ n\Value = Value
+
+ l\tail_\pv_ = n
+ n\pv_\nx_ = n
+
+ Return n
+End Function
+
+;Attach a value to the start of a list (fast) and return the node
+Function ListAddFirst.ListNode(l.LList, Value)
+ Local n.ListNode = New ListNode
+
+ n\pv_ = l\head_
+ n\nx_ = l\head_\nx_
+ n\Value = Value
+
+ l\head_\nx_ = n
+ n\nx_\pv_ = n
+
+ Return n
+End Function
+
+;Remove the first occurence of the given value from a list
+Function ListRemove(l.LList, Value)
+ Local n.ListNode = ListFindNode(l, Value)
+ If n <> Null Then RemoveListNode n
+End Function
+
+;Remove a node from a list
+Function RemoveListNode(n.ListNode)
+ n\pv_\nx_ = n\nx_
+ n\nx_\pv_ = n\pv_
+ Delete n
+End Function
+
+;Return the value of the element at the given position from the start of the list,
+;or backwards from the end of the list for a negative index
+Function ValueAtIndex(l.LList, index)
+ Local n.ListNode = ListNodeAtIndex(l, index)
+ If n <> Null Then Return n\Value : Else Return 0
+End Function
+
+;Return the ListNode at the given position from the start of the list, or backwards
+;from the end of the list for a negative index, or Null if invalid
+Function ListNodeAtIndex.ListNode(l.LList, index)
+ Local e, n.ListNode
+
+ If index >= 0
+ n = l\head_
+ For e = 0 To index
+ n = n\nx_
+ Next
+ If n = l\tail_ Then n = Null ;Beyond the end of the list - not valid
+
+ Else ;Negative index - count backward
+ n = l\tail_
+ For e = 0 To index Step -1
+ n = n\pv_
+ Next
+ If n = l\head_ Then n = Null ;Before the start of the list - not valid
+
+ EndIf
+
+ Return n
+End Function
+
+;Replace a value at the given position (added by MusicianKool)
+Function ReplaceValueAtIndex(l.LList,index,value)
+ Local n.ListNode = ListNodeAtIndex(l,index)
+ If n <> Null Then n\Value = value:Else Return 0
+End Function
+
+;Remove and return a value at the given position (added by MusicianKool)
+Function RemoveNodeAtIndex(l.LList,index)
+ Local n.ListNode = ListNodeAtIndex(l,index),tval
+ If n <> Null Then tval = n\Value:RemoveListNode(n):Return tval:Else Return 0
+End Function
+
+;Retrieve the first value from a list
+Function ListFirst(l.LList)
+ If l\head_\nx_ <> l\tail_ Then Return l\head_\nx_\Value
+End Function
+
+;Retrieve the last value from a list
+Function ListLast(l.LList)
+ If l\tail_\pv_ <> l\head_ Then Return l\tail_\pv_\Value
+End Function
+
+;Remove the first element from a list, and return its value
+Function ListRemoveFirst(l.LList)
+ Local val
+ If l\head_\nx_ <> l\tail_
+ val = l\head_\nx_\Value
+ RemoveListNode l\head_\nx_
+ EndIf
+ Return val
+End Function
+
+;Remove the last element from a list, and return its value
+Function ListRemoveLast(l.LList)
+ Local val
+ If l\tail_\pv_ <> l\head_
+ val = l\tail_\pv_\Value
+ RemoveListNode l\tail_\pv_
+ EndIf
+ Return val
+End Function
+
+;Insert a value into a list before the specified node, and return the new node
+Function InsertBeforeNode.ListNode(Value, n.ListNode)
+ Local bef.ListNode = New ListNode
+
+ bef\pv_ = n\pv_
+ bef\nx_ = n
+ bef\Value = Value
+
+ n\pv_ = bef
+ bef\pv_\nx_ = bef
+
+ Return bef
+End Function
+
+;Insert a value into a list after the specified node, and return then new node
+Function InsertAfterNode.ListNode(Value, n.ListNode)
+ Local aft.ListNode = New ListNode
+
+ aft\nx_ = n\nx_
+ aft\pv_ = n
+ aft\Value = Value
+
+ n\nx_ = aft
+ aft\nx_\pv_ = aft
+
+ Return aft
+End Function
+
+;Get an iterator object to use with a loop
+;This function means that most programs won't have to think about deleting iterators manually
+;(in general only a small, constant number will be created)
+Function GetIterator.Iterator(l.LList)
+ Local i.Iterator
+
+ If l = Null Then RuntimeError "Cannot create Iterator for Null"
+
+ For i = Each Iterator ;See if there's an available iterator at the moment
+ If i\l_ = Null Then Exit
+ Next
+
+ If i = Null Then i = New Iterator ;If there wasn't, create one
+
+ i\l_ = l
+ i\cn_ = l\head_
+ i\cni_ = -1
+ i\Value = 0 ;No especial reason why this has to be anything, but meh
+
+ Return i
+End Function
+
+;Use as the argument to While to iterate over the members of a list
+Function EachIn(i.Iterator)
+
+ i\cn_ = i\cn_\nx_
+
+ If i\cn_ <> i\l_\tail_ ;Still items in the list
+ i\Value = i\cn_\Value
+ i\cni_ = i\cni_ + 1
+ Return True
+
+ Else
+ i\l_ = Null ;Disconnect from the list, having reached the end
+ i\cn_ = Null
+ i\cni_ = -1
+ Return False
+
+ EndIf
+End Function
+
+;Remove from the containing list the element currently pointed to by an iterator
+Function IteratorRemove(i.Iterator)
+ If (i\cn_ <> i\l_\head_) And (i\cn_ <> i\l_\tail_)
+ Local temp.ListNode = i\cn_
+
+ i\cn_ = i\cn_\pv_
+ i\cni_ = i\cni_ - 1
+ i\Value = 0
+
+ RemoveListNode temp
+
+ Return True
+ Else
+ Return False
+ EndIf
+End Function
+
+;Call this before breaking out of an EachIn loop, to disconnect the iterator from the list
+Function IteratorBreak(i.Iterator)
+ i\l_ = Null
+ i\cn_ = Null
+ i\cni_ = -1
+ i\Value = 0
+End Function
+
+
+;~IDEal Editor Parameters:
+;~F#5#A#10#18#2A#32#3E#47#4C#58#66#6F#78#8F#9B#A9#B7#BD#C5#CC
+;~F#E3#E9#EF#F4#F9#103#10D#11B#12B#13F#152#163
+;~C#Blitz3D
\ No newline at end of file
diff --git a/samples/BlitzBasic/PObj.bb b/samples/BlitzBasic/PObj.bb
new file mode 100644
index 00000000..2989f98e
--- /dev/null
+++ b/samples/BlitzBasic/PObj.bb
@@ -0,0 +1,66 @@
+
+Local i, start, result
+
+Local s.Sum3Obj = New Sum3Obj
+
+For i = 1 To 100000
+ s = New Sum3Obj
+ result = Handle Before s
+ Delete s
+Next
+
+start = MilliSecs()
+For i = 1 To 1000000
+ result = Sum3_(MakeSum3Obj(i, i, i))
+Next
+start = MilliSecs() - start
+Print start
+
+start = MilliSecs()
+For i = 1 To 1000000
+ result = Sum3(i, i, i)
+Next
+start = MilliSecs() - start
+Print start
+
+WaitKey
+End
+
+
+Function Sum3(a, b, c)
+ Return a + b + c
+End Function
+
+
+Type Sum3Obj
+ Field isActive
+ Field a, b, c
+End Type
+
+Function MakeSum3Obj(a, b, c)
+ Local s.Sum3Obj = Last Sum3Obj
+ If s\isActive Then s = New Sum3Obj
+ s\isActive = True
+ s\a = a
+ s\b = b
+ s\c = c
+
+ Restore label
+ Read foo
+
+ Return Handle(s)
+End Function
+
+.label
+Data (10 + 2), 12, 14
+:
+Function Sum3_(a_)
+ Local a.Sum3Obj = Object.Sum3Obj a_
+ Local return_ = a\a + a\b + a\c
+ Insert a Before First Sum3Obj :: a\isActive = False
+ Return return_
+End Function
+
+
+;~IDEal Editor Parameters:
+;~C#Blitz3D
\ No newline at end of file
diff --git a/samples/Bluespec/TL.bsv b/samples/Bluespec/TL.bsv
new file mode 100644
index 00000000..2d6af5c1
--- /dev/null
+++ b/samples/Bluespec/TL.bsv
@@ -0,0 +1,167 @@
+package TL;
+
+interface TL;
+ method Action ped_button_push();
+
+ (* always_enabled *)
+ method Action set_car_state_N(Bool x);
+ (* always_enabled *)
+ method Action set_car_state_S(Bool x);
+ (* always_enabled *)
+ method Action set_car_state_E(Bool x);
+ (* always_enabled *)
+ method Action set_car_state_W(Bool x);
+
+ method Bool lampRedNS();
+ method Bool lampAmberNS();
+ method Bool lampGreenNS();
+
+ method Bool lampRedE();
+ method Bool lampAmberE();
+ method Bool lampGreenE();
+
+ method Bool lampRedW();
+ method Bool lampAmberW();
+ method Bool lampGreenW();
+
+ method Bool lampRedPed();
+ method Bool lampAmberPed();
+ method Bool lampGreenPed();
+endinterface: TL
+
+typedef enum {
+ AllRed,
+ GreenNS, AmberNS,
+ GreenE, AmberE,
+ GreenW, AmberW,
+ GreenPed, AmberPed} TLstates deriving (Eq, Bits);
+
+typedef UInt#(5) Time32;
+typedef UInt#(20) CtrSize;
+
+(* synthesize *)
+module sysTL(TL);
+ Time32 allRedDelay = 2;
+ Time32 amberDelay = 4;
+ Time32 nsGreenDelay = 20;
+ Time32 ewGreenDelay = 10;
+ Time32 pedGreenDelay = 10;
+ Time32 pedAmberDelay = 6;
+
+ CtrSize clocks_per_sec = 100;
+
+ Reg#(TLstates) state <- mkReg(AllRed);
+ Reg#(TLstates) next_green <- mkReg(GreenNS);
+ Reg#(Time32) secs <- mkReg(0);
+ Reg#(Bool) ped_button_pushed <- mkReg(False);
+ Reg#(Bool) car_present_N <- mkReg(True);
+ Reg#(Bool) car_present_S <- mkReg(True);
+ Reg#(Bool) car_present_E <- mkReg(True);
+ Reg#(Bool) car_present_W <- mkReg(True);
+ Bool car_present_NS = car_present_N || car_present_S;
+ Reg#(CtrSize) cycle_ctr <- mkReg(0);
+
+ rule dec_cycle_ctr (cycle_ctr != 0);
+ cycle_ctr <= cycle_ctr - 1;
+ endrule
+
+ Rules low_priority_rule = (rules
+ rule inc_sec (cycle_ctr == 0);
+ secs <= secs + 1;
+ cycle_ctr <= clocks_per_sec;
+ endrule endrules);
+
+ function Action next_state(TLstates ns);
+ action
+ state <= ns;
+ secs <= 0;
+ endaction
+ endfunction: next_state
+
+ function TLstates green_seq(TLstates x);
+ case (x)
+ GreenNS: return (GreenE);
+ GreenE: return (GreenW);
+ GreenW: return (GreenNS);
+ endcase
+ endfunction
+
+ function Bool car_present(TLstates x);
+ case (x)
+ GreenNS: return (car_present_NS);
+ GreenE: return (car_present_E);
+ GreenW: return (car_present_W);
+ endcase
+ endfunction
+
+ function Rules make_from_green_rule(TLstates green_state, Time32 delay, Bool car_is_present, TLstates ns);
+ return (rules
+ rule from_green (state == green_state && (secs >= delay || !car_is_present));
+ next_state(ns);
+ endrule endrules);
+ endfunction: make_from_green_rule
+
+ function Rules make_from_amber_rule(TLstates amber_state, TLstates ng);
+ return (rules
+ rule from_amber (state == amber_state && secs >= amberDelay);
+ next_state(AllRed);
+ next_green <= ng;
+ endrule endrules);
+ endfunction: make_from_amber_rule
+
+ Rules hprs[7];
+
+ hprs[1] = make_from_green_rule(GreenNS, nsGreenDelay, car_present_NS, AmberNS);
+ hprs[2] = make_from_amber_rule(AmberNS, GreenE);
+ hprs[3] = make_from_green_rule(GreenE, ewGreenDelay, car_present_E, AmberE);
+ hprs[4] = make_from_amber_rule(AmberE, GreenW);
+ hprs[5] = make_from_green_rule(GreenW, ewGreenDelay, car_present_W, AmberW);
+ hprs[6] = make_from_amber_rule(AmberW, GreenNS);
+
+ hprs[0] = (rules
+ rule fromAllRed (state == AllRed && secs >= allRedDelay);
+ if (ped_button_pushed) action
+ ped_button_pushed <= False;
+ next_state(GreenPed);
+ endaction else if (car_present(next_green))
+ next_state(next_green);
+ else if (car_present(green_seq(next_green)))
+ next_state(green_seq(next_green));
+ else if (car_present(green_seq(green_seq(next_green))))
+ next_state(green_seq(green_seq(next_green)));
+ else
+ noAction;
+ endrule: fromAllRed endrules);
+
+ Rules high_priority_rules = hprs[0];
+ for (Integer i = 1; i<7; i=i+1)
+ high_priority_rules = rJoin(hprs[i], high_priority_rules);
+
+ addRules(preempts(high_priority_rules, low_priority_rule));
+
+ method Action ped_button_push();
+ ped_button_pushed <= True;
+ endmethod: ped_button_push
+
+ method Action set_car_state_N(b) ; car_present_N <= b; endmethod
+ method Action set_car_state_S(b) ; car_present_S <= b; endmethod
+ method Action set_car_state_E(b) ; car_present_E <= b; endmethod
+ method Action set_car_state_W(b) ; car_present_W <= b; endmethod
+
+ method lampRedNS() = (!(state == GreenNS || state == AmberNS));
+ method lampAmberNS() = (state == AmberNS);
+ method lampGreenNS() = (state == GreenNS);
+ method lampRedE() = (!(state == GreenE || state == AmberE));
+ method lampAmberE() = (state == AmberE);
+ method lampGreenE() = (state == GreenE);
+ method lampRedW() = (!(state == GreenW || state == AmberW));
+ method lampAmberW() = (state == AmberW);
+ method lampGreenW() = (state == GreenW);
+
+ method lampRedPed() = (!(state == GreenPed || state == AmberPed));
+ method lampAmberPed() = (state == AmberPed);
+ method lampGreenPed() = (state == GreenPed);
+
+endmodule: sysTL
+
+endpackage: TL
diff --git a/samples/Bluespec/TbTL.bsv b/samples/Bluespec/TbTL.bsv
new file mode 100644
index 00000000..d5dbabf0
--- /dev/null
+++ b/samples/Bluespec/TbTL.bsv
@@ -0,0 +1,109 @@
+package TbTL;
+
+import TL::*;
+
+interface Lamp;
+ method Bool changed;
+ method Action show_offs;
+ method Action show_ons;
+ method Action reset;
+endinterface
+
+module mkLamp#(String name, Bool lamp)(Lamp);
+ Reg#(Bool) prev <- mkReg(False);
+
+ method changed = (prev != lamp);
+
+ method Action show_offs;
+ if (prev && !lamp)
+ $write (name + " off, ");
+ endmethod
+
+ method Action show_ons;
+ if (!prev && lamp)
+ $write (name + " on, ");
+ endmethod
+
+ method Action reset;
+ prev <= lamp;
+ endmethod
+endmodule
+
+
+(* synthesize *)
+module mkTest();
+ let dut <- sysTL;
+
+ Reg#(Bit#(16)) ctr <- mkReg(0);
+
+ Reg#(Bool) carN <- mkReg(False);
+ Reg#(Bool) carS <- mkReg(False);
+ Reg#(Bool) carE <- mkReg(False);
+ Reg#(Bool) carW <- mkReg(False);
+
+ Lamp lamps[12];
+
+ lamps[0] <- mkLamp("0: NS red ", dut.lampRedNS);
+ lamps[1] <- mkLamp("1: NS amber", dut.lampAmberNS);
+ lamps[2] <- mkLamp("2: NS green", dut.lampGreenNS);
+ lamps[3] <- mkLamp("3: E red ", dut.lampRedE);
+ lamps[4] <- mkLamp("4: E amber", dut.lampAmberE);
+ lamps[5] <- mkLamp("5: E green", dut.lampGreenE);
+ lamps[6] <- mkLamp("6: W red ", dut.lampRedW);
+ lamps[7] <- mkLamp("7: W amber", dut.lampAmberW);
+ lamps[8] <- mkLamp("8: W green", dut.lampGreenW);
+
+ lamps[9] <- mkLamp("9: Ped red ", dut.lampRedPed);
+ lamps[10] <- mkLamp("10: Ped amber", dut.lampAmberPed);
+ lamps[11] <- mkLamp("11: Ped green", dut.lampGreenPed);
+
+ rule start (ctr == 0);
+ $dumpvars;
+ endrule
+
+ rule detect_cars;
+ dut.set_car_state_N(carN);
+ dut.set_car_state_S(carS);
+ dut.set_car_state_E(carE);
+ dut.set_car_state_W(carW);
+ endrule
+
+ rule go;
+ ctr <= ctr + 1;
+ if (ctr == 5000) carN <= True;
+ if (ctr == 6500) carN <= False;
+ if (ctr == 12_000) dut.ped_button_push;
+ endrule
+
+ rule stop (ctr > 32768);
+ $display("TESTS FINISHED");
+ $finish(0);
+ endrule
+
+ function do_offs(l) = l.show_offs;
+ function do_ons(l) = l.show_ons;
+ function do_reset(l) = l.reset;
+
+ function do_it(f);
+ action
+ for (Integer i=0; i<12; i=i+1)
+ f(lamps[i]);
+ endaction
+ endfunction
+
+ function any_changes();
+ Bool b = False;
+ for (Integer i=0; i<12; i=i+1)
+ b = b || lamps[i].changed;
+ return b;
+ endfunction
+
+ rule show (any_changes());
+ do_it(do_offs);
+ do_it(do_ons);
+ do_it(do_reset);
+ $display("(at time %d)", $time);
+ endrule
+endmodule
+
+endpackage
diff --git a/samples/Brightscript/SimpleGrid.brs b/samples/Brightscript/SimpleGrid.brs
new file mode 100644
index 00000000..b205d69a
--- /dev/null
+++ b/samples/Brightscript/SimpleGrid.brs
@@ -0,0 +1,305 @@
+' *********************************************************
+' ** Simple Grid Screen Demonstration App
+' ** Jun 2010
+' ** Copyright (c) 2010 Roku Inc. All Rights Reserved.
+' *********************************************************
+
+'************************************************************
+'** Application startup
+'************************************************************
+Sub Main()
+
+ 'initialize theme attributes like titles, logos and overhang color
+ initTheme()
+
+ gridstyle = "Flat-Movie"
+
+ 'set to go, time to get started
+ while gridstyle <> ""
+ print "starting grid style= ";gridstyle
+ screen=preShowGridScreen(gridstyle)
+ gridstyle = showGridScreen(screen, gridstyle)
+ end while
+
+End Sub
+
+
+'*************************************************************
+'** Set the configurable theme attributes for the application
+'**
+'** Configure the custom overhang and Logo attributes
+'** These attributes affect the branding of the application
+'** and are artwork, colors and offsets specific to the app
+'*************************************************************
+
+Sub initTheme()
+ app = CreateObject("roAppManager")
+ app.SetTheme(CreateDefaultTheme())
+End Sub
+
+'******************************************************
+'** @return The default application theme.
+'** Screens can make slight adjustments to the default
+'** theme by getting it from here and then overriding
+'** individual theme attributes.
+'******************************************************
+Function CreateDefaultTheme() as Object
+ theme = CreateObject("roAssociativeArray")
+
+ theme.ThemeType = "generic-dark"
+
+ ' All these are greyscales
+ theme.GridScreenBackgroundColor = "#363636"
+ theme.GridScreenMessageColor = "#808080"
+ theme.GridScreenRetrievingColor = "#CCCCCC"
+ theme.GridScreenListNameColor = "#FFFFFF"
+
+ ' Color values work here
+ theme.GridScreenDescriptionTitleColor = "#001090"
+ theme.GridScreenDescriptionDateColor = "#FF005B"
+ theme.GridScreenDescriptionRuntimeColor = "#5B005B"
+ theme.GridScreenDescriptionSynopsisColor = "#606000"
+
+ 'used in the Grid Screen
+ theme.CounterTextLeft = "#FF0000"
+ theme.CounterSeparator = "#00FF00"
+ theme.CounterTextRight = "#0000FF"
+
+ theme.GridScreenLogoHD = "pkg:/images/Overhang_Test_HD.png"
+
+ theme.GridScreenLogoOffsetHD_X = "0"
+ theme.GridScreenLogoOffsetHD_Y = "0"
+ theme.GridScreenOverhangHeightHD = "99"
+
+ theme.GridScreenLogoSD = "pkg:/images/Overhang_Test_SD43.png"
+ theme.GridScreenOverhangHeightSD = "66"
+ theme.GridScreenLogoOffsetSD_X = "0"
+ theme.GridScreenLogoOffsetSD_Y = "0"
+
+ ' to use your own focus ring artwork
+ 'theme.GridScreenFocusBorderSD = "pkg:/images/GridCenter_Border_Movies_SD43.png"
+ 'theme.GridScreenBorderOffsetSD = "(-26,-25)"
+ 'theme.GridScreenFocusBorderHD = "pkg:/images/GridCenter_Border_Movies_HD.png"
+ 'theme.GridScreenBorderOffsetHD = "(-28,-20)"
+
+ ' to use your own description background artwork
+ 'theme.GridScreenDescriptionImageSD = "pkg:/images/Grid_Description_Background_SD43.png"
+ 'theme.GridScreenDescriptionOffsetSD = "(125,170)"
+ 'theme.GridScreenDescriptionImageHD = "pkg:/images/Grid_Description_Background_HD.png"
+ 'theme.GridScreenDescriptionOffsetHD = "(190,255)"
+
+
+ return theme
+End Function
+
+'******************************************************
+'** Perform any startup/initialization stuff prior to
+'** initially showing the screen.
+'******************************************************
+Function preShowGridScreen(style as string) As Object
+
+ m.port=CreateObject("roMessagePort")
+ screen = CreateObject("roGridScreen")
+ screen.SetMessagePort(m.port)
+' screen.SetDisplayMode("best-fit")
+ screen.SetDisplayMode("scale-to-fill")
+
+ screen.SetGridStyle(style)
+ return screen
+
+End Function
+
+
+'******************************************************
+'** Display the gird screen and wait for events from
+'** the screen. The screen will show retreiving while
+'** we fetch and parse the feeds for the show posters
+'******************************************************
+Function showGridScreen(screen As Object, gridstyle as string) As string
+
+ print "enter showGridScreen"
+
+ categoryList = getCategoryList()
+ categoryList[0] = "GridStyle: " + gridstyle
+ screen.setupLists(categoryList.count())
+ screen.SetListNames(categoryList)
+ StyleButtons = getGridControlButtons()
+ screen.SetContentList(0, StyleButtons)
+ for i = 1 to categoryList.count()-1
+ screen.SetContentList(i, getShowsForCategoryItem(categoryList[i]))
+ end for
+ screen.Show()
+
+ while true
+ print "Waiting for message"
+ msg = wait(0, m.port)
+ 'msg = wait(0, screen.GetMessagePort()) ' getmessageport does not work on gridscreen
+ print "Got Message:";type(msg)
+ if type(msg) = "roGridScreenEvent" then
+ print "msg= "; msg.GetMessage() " , index= "; msg.GetIndex(); " data= "; msg.getData()
+ if msg.isListItemFocused() then
+ print"list item focused | current show = "; msg.GetIndex()
+ else if msg.isListItemSelected() then
+ row = msg.GetIndex()
+ selection = msg.getData()
+ print "list item selected row= "; row; " selection= "; selection
+
+ ' Did we get a selection from the gridstyle selection row?
+ if (row = 0)
+ ' yes, return so we can come back with new style
+ return StyleButtons[selection].Title
+ endif
+
+ 'm.curShow = displayShowDetailScreen(showList[msg.GetIndex()])
+ else if msg.isScreenClosed() then
+ return ""
+ end if
+ end If
+ end while
+
+
+End Function
+
+'**********************************************************
+'** When a poster on the home screen is selected, we call
+'** this function passing an roAssociativeArray with the
+'** ContentMetaData for the selected show. This data should
+'** be sufficient for the springboard to display
+'**********************************************************
+Function displayShowDetailScreen(category as Object, showIndex as Integer) As Integer
+
+ 'add code to create springboard, for now we do nothing
+ return 1
+
+End Function
+
+
+'**************************************************************
+'** Return the list of categories to display in the filter
+'** banner. The result is an roArray containing the names of
+'** all of the categories. All just static data for the example.
+'***************************************************************
+Function getCategoryList() As Object
+
+ categoryList = [ "GridStyle", "Reality", "History", "News", "Comedy", "Drama"]
+ return categoryList
+
+End Function
+
+
+'********************************************************************
+'** Given the category from the filter banner, return an array
+'** of ContentMetaData objects (roAssociativeArray's) representing
+'** the shows for the category. For this example, we just cheat and
+'** create and return a static array with just the minimal items
+'** set, but ideally, you'd go to a feed service, fetch and parse
+'** this data dynamically, so content for each category is dynamic
+'********************************************************************
+Function getShowsForCategoryItem(category As Object) As Object
+
+ print "getting shows for category "; category
+
+ showList = [
+ {
+ Title: category + ": Header",
+ releaseDate: "1976",
+ length: 3600-600,
+ Description:"This row is category " + category,
+ hdBranded: true,
+ HDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/4/43/Gold_star_on_blue.gif",
+ SDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/4/43/Gold_star_on_blue.gif",
+ Description:"Short Synopsis #1",
+ Synopsis:"Length",
+ StarRating:10,
+ }
+ {
+ Title: category + ": Beverly Hillbillies",
+ releaseDate: "1969",
+ rating: "PG",
+ Description:"Come and listen to a story about a man named Jed: Poor mountaineer, barely kept his family fed. Then one day he was shootin at some food, and up through the ground came a bubblin crude. Oil that is, black gold, Texas tea.",
+ numEpisodes:42,
+ contentType:"season",
+ HDPosterUrl:"http://upload.wikimedia.org/wikipedia/en/4/4e/The_Beverly_Hillbillies.jpg",
+ SDPosterUrl:"http://upload.wikimedia.org/wikipedia/en/4/4e/The_Beverly_Hillbillies.jpg",
+ StarRating:80,
+ UserStarRating:40
+ }
+ {
+ Title: category + ": Babylon 5",
+ releaseDate: "1996",
+ rating: "PG",
+ Description:"The show centers on the Babylon 5 space station: a focal point for politics, diplomacy, and conflict during the years 2257-2262.",
+ numEpisodes:102,
+ contentType:"season",
+ HDPosterUrl:"http://upload.wikimedia.org/wikipedia/en/9/9d/Smb5-s4.jpg",
+ SDPosterUrl:"http://upload.wikimedia.org/wikipedia/en/9/9d/Smb5-s4.jpg",
+ StarRating:80,
+ UserStarRating:40
+ }
+ {
+ Title: category + ": John F. Kennedy",
+ releaseDate: "1961",
+ rating: "PG",
+ Description:"My fellow citizens of the world: ask not what America will do for you, but what together we can do for the freedom of man.",
+ HDPosterUrl:"http://upload.wikimedia.org/wikipedia/en/5/52/Jfk_happy_birthday_1.jpg",
+ SDPosterUrl:"http://upload.wikimedia.org/wikipedia/en/5/52/Jfk_happy_birthday_1.jpg",
+ StarRating:100
+ }
+ {
+ Title: category + ": Man on the Moon",
+ releaseDate: "1969",
+ rating: "PG",
+ Description:"That's one small step for a man, one giant leap for mankind.",
+ HDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/1/1e/Apollo_11_first_step.jpg",
+ SDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/1/1e/Apollo_11_first_step.jpg",
+ StarRating:100
+ }
+ {
+ Title: category + ": I have a Dream",
+ releaseDate: "1963",
+ rating: "PG",
+ Description:"I have a dream that my four little children will one day live in a nation where they will not be judged by the color of their skin, but by the content of their character.",
+ HDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/8/81/Martin_Luther_King_-_March_on_Washington.jpg",
+ SDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/8/81/Martin_Luther_King_-_March_on_Washington.jpg",
+ StarRating:100
+ }
+ ]
+
+ return showList
+End Function
+
+function getGridControlButtons() as object
+ buttons = [
+ { Title: "Flat-Movie"
+ ReleaseDate: "HD:5x2 SD:5x2"
+ Description: "Flat-Movie (Netflix) style"
+ HDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/4/43/Gold_star_on_blue.gif"
+ SDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/4/43/Gold_star_on_blue.gif"
+ }
+ { Title: "Flat-Landscape"
+ ReleaseDate: "HD:5x3 SD:4x3"
+ Description: "Channel Store"
+ HDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/thumb/9/96/Dunkery_Hill.jpg/800px-Dunkery_Hill.jpg",
+ SDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/thumb/9/96/Dunkery_Hill.jpg/800px-Dunkery_Hill.jpg",
+ }
+ { Title: "Flat-Portrait"
+ ReleaseDate: "HD:5x2 SD:5x2"
+ Description: "3x4 style posters"
+ HDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/9/9f/Kane_George_Gurnett.jpg",
+ SDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/9/9f/Kane_George_Gurnett.jpg",
+ }
+ { Title: "Flat-Square"
+ ReleaseDate: "HD:7x3 SD:6x3"
+ Description: "1x1 style posters"
+ HDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/thumb/d/de/SQUARE_SHAPE.svg/536px-SQUARE_SHAPE.svg.png",
+ SDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/thumb/d/de/SQUARE_SHAPE.svg/536px-SQUARE_SHAPE.svg.png",
+ }
+ { Title: "Flat-16x9"
+ ReleaseDate: "HD:5x3 SD:4x3"
+ Description: "HD style posters"
+ HDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/thumb/2/22/%C3%89cran_TV_plat.svg/200px-%C3%89cran_TV_plat.svg.png",
+ SDPosterUrl:"http://upload.wikimedia.org/wikipedia/commons/thumb/2/22/%C3%89cran_TV_plat.svg/200px-%C3%89cran_TV_plat.svg.png",
+ }
+ ]
+ return buttons
+End Function
diff --git a/samples/C#/Index.cshtml b/samples/C#/Index.cshtml
new file mode 100644
index 00000000..f7aa29c6
--- /dev/null
+++ b/samples/C#/Index.cshtml
@@ -0,0 +1,45 @@
+@{
+ ViewBag.Title = "Home Page";
+}
+@section featured {
+
+
+
+
@ViewBag.Title.
+
@ViewBag.Message
+
+
+ To learn more about ASP.NET MVC visit
+ http://asp.net/mvc.
+ The page features videos, tutorials, and samples to help you get the most from ASP.NET MVC.
+ If you have any questions about ASP.NET MVC visit
+ our forums.
+
+
+
+}
+
We suggest the following:
+
+
+
Getting Started
+ ASP.NET MVC gives you a powerful, patterns-based way to build dynamic websites that
+ enables a clean separation of concerns and that gives you full control over markup
+ for enjoyable, agile development. ASP.NET MVC includes many features that enable
+ fast, TDD-friendly development for creating sophisticated applications that use
+ the latest web standards.
+ Learn more…
+
+
+
+
Add NuGet packages and jump-start your coding
+ NuGet makes it easy to install and update free libraries and tools.
+ Learn more…
+
+
+
+
Find Web Hosting
+ You can easily find a web hosting company that offers the right mix of features
+ and price for your applications.
+ Learn more…
+
+
diff --git a/samples/C#/Program.cs b/samples/C#/Program.cs
new file mode 100644
index 00000000..20e24850
--- /dev/null
+++ b/samples/C#/Program.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LittleSampleApp
+{
+ ///
+ /// Just what it says on the tin. A little sample application for Linguist to try out.
+ ///
+ ///
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ Console.WriteLine("Hello, I am a little sample application to test GitHub's Linguist module.");
+ Console.WriteLine("I also include a Razor MVC file just to prove it handles cshtml files now.");
+ }
+ }
+}
diff --git a/samples/C++/CsvStreamer.h b/samples/C++/CsvStreamer.h
new file mode 100644
index 00000000..b15e648d
--- /dev/null
+++ b/samples/C++/CsvStreamer.h
@@ -0,0 +1,42 @@
+#pragma once
+#include
+#include
+#include
+#include "util.h"
+
+using namespace std;
+
+
+#define DEFAULT_DELIMITER ','
+
+
+class CsvStreamer
+{
+ private:
+ ofstream file; // File output stream
+ vector row_buffer; // Buffer which stores a row's data before being flushed/written
+ int fields; // Number of fields (columns)
+ long rows; // Number of rows (records) including header row
+ char delimiter; // Delimiter character; comma by default
+ string sanitize(string); // Returns a string ready for output into the file
+
+ public:
+ CsvStreamer(); // Empty CSV streamer... be sure to open the file before writing!
+ CsvStreamer(string, char); // Same as open(string, char)...
+ CsvStreamer(string); // Opens an output CSV file given a file path/name
+ ~CsvStreamer(); // Ensures the output file is closed and saved
+ void open(string); // Opens an output CSV file given a file path/name (default delimiter)
+ void open(string, char); // Opens an output CSV file given a file path/name and a delimiting character (default comma)
+ void add_field(string); // If still on first line, adds a new field to the header row
+ void save_fields(); // Call this to save the header row; all new writes should be through append()
+ void append(string); // Appends the current row with this data for the next field; quoted only if needed (leading/trailing spaces are trimmed)
+ void append(string, bool); // Like append(string) but can specify whether to trim spaces at either end of the data (false to keep spaces)
+ void append(float); // Appends the current row with this number
+ void append(double); // Appends the current row with this number
+ void append(long); // Appends the current row with this number
+ void append(int); // Appends the current row with this number
+ void writeln(); // Flushes what was in the row buffer into the file (writes the row)
+ void close(); // Saves and closes the file
+ int field_count(); // Gets the number of fields (columns)
+ long row_count(); // Gets the number of records (rows) -- NOT including the header row
+};
diff --git a/samples/C++/Field.h b/samples/C++/Field.h
new file mode 100644
index 00000000..201be118
--- /dev/null
+++ b/samples/C++/Field.h
@@ -0,0 +1,32 @@
+/*****************************************************************************
+* Dwarf Mine - The 13-11 Benchmark
+*
+* Copyright (c) 2013 Bünger, Thomas; Kieschnick, Christian; Kusber,
+* Michael; Lohse, Henning; Wuttke, Nikolai; Xylander, Oliver; Yao, Gary;
+* Zimmermann, Florian
+*
+* 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.
+*****************************************************************************/
+
+#pragma once
+
+enum Field { Free, Black, White, Illegal };
+
+typedef Field Player;
diff --git a/samples/C++/Math.inl b/samples/C++/Math.inl
new file mode 100644
index 00000000..194370a3
--- /dev/null
+++ b/samples/C++/Math.inl
@@ -0,0 +1,530 @@
+/*
+===========================================================================
+The Open Game Libraries.
+Copyright (C) 2007-2010 Lusito Software
+
+Author: Santo Pfingsten (TTK-Bandit)
+Purpose: Math namespace
+-----------------------------------------
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source distribution.
+===========================================================================
+*/
+
+#ifndef __OG_MATH_INL__
+#define __OG_MATH_INL__
+
+namespace og {
+
+/*
+==============================================================================
+
+ Math
+
+==============================================================================
+*/
+
+/*
+================
+Math::Abs
+================
+*/
+OG_INLINE int Math::Abs( int i ) {
+#if 1
+ if ( i & 0x80000000 )
+ return 0x80000000 - (i & MASK_SIGNED);
+ return i;
+#else
+ int y = x >> 31;
+ return ( ( x ^ y ) - y );
+#endif
+}
+
+/*
+================
+Math::Fabs
+================
+*/
+OG_INLINE float Math::Fabs( float f ) {
+#if 1
+ uInt *pf = reinterpret_cast(&f);
+ *(pf) &= MASK_SIGNED;
+ return f;
+#else
+ return fabsf( f );
+#endif
+}
+
+/*
+================
+Math::Round
+================
+*/
+OG_INLINE float Math::Round( float f ) {
+ return floorf( f + 0.5f );
+}
+
+/*
+================
+Math::Floor
+================
+*/
+OG_INLINE float Math::Floor( float f ) {
+ return floorf( f );
+}
+
+/*
+================
+Math::Ceil
+================
+*/
+OG_INLINE float Math::Ceil( float f ) {
+ return ceilf( f );
+}
+
+/*
+================
+Math::Ftoi
+
+ok since this is SSE, why should the other ftoi be the faster one ?
+and: we might need to add a check for SSE extensions..
+because sse isn't *really* faster (I actually read that GCC does not handle
+SSE extensions perfectly. I'll find the link and send it to you when you're online)
+================
+*/
+OG_INLINE int Math::Ftoi( float f ) {
+ //! @todo needs testing
+ // note: sse function cvttss2si
+#if OG_ASM_MSVC
+ int i;
+#if defined(OG_FTOI_USE_SSE)
+ if( SysInfo::cpu.general.SSE ) {
+ __asm cvttss2si eax, f
+ __asm mov i, eax
+ return i;
+ } else
+#endif
+ {
+ __asm fld f
+ __asm fistp i
+ //__asm mov eax, i // do we need this ? O_o
+ }
+ return i;
+#elif OG_ASM_GNU
+ int i;
+#if defined(OG_FTOI_USE_SSE)
+ if( SysInfo::cpu.general.SSE ) {
+ __asm__ __volatile__( "cvttss2si %1 \n\t"
+ : "=m" (i)
+ : "m" (f)
+ );
+ } else
+#endif
+ {
+ __asm__ __volatile__( "flds %1 \n\t"
+ "fistpl %0 \n\t"
+ : "=m" (i)
+ : "m" (f)
+ );
+ }
+ return i;
+#else
+ // we use c++ cast instead of c cast (not sure why id did that)
+ return static_cast(f);
+#endif
+}
+
+/*
+================
+Math::FtoiFast
+================
+*/
+OG_INLINE int Math::FtoiFast( float f ) {
+#if OG_ASM_MSVC
+ int i;
+ __asm fld f
+ __asm fistp i
+ //__asm mov eax, i // do we need this ? O_o
+ return i;
+#elif OG_ASM_GNU
+ int i;
+ __asm__ __volatile__( "flds %1 \n\t"
+ "fistpl %0 \n\t"
+ : "=m" (i)
+ : "m" (f)
+ );
+ return i;
+#else
+ // we use c++ cast instead of c cast (not sure why id did that)
+ return static_cast(f);
+#endif
+}
+
+/*
+================
+Math::Ftol
+================
+*/
+OG_INLINE long Math::Ftol( float f ) {
+#if OG_ASM_MSVC
+ long i;
+ __asm fld f
+ __asm fistp i
+ //__asm mov eax, i // do we need this ? O_o
+ return i;
+#elif OG_ASM_GNU
+ long i;
+ __asm__ __volatile__( "flds %1 \n\t"
+ "fistpl %0 \n\t"
+ : "=m" (i)
+ : "m" (f)
+ );
+ return i;
+#else
+ // we use c++ cast instead of c cast (not sure why id did that)
+ return static_cast(f);
+#endif
+}
+
+/*
+================
+Math::Sign
+================
+*/
+OG_INLINE float Math::Sign( float f ) {
+ if ( f > 0.0f )
+ return 1.0f;
+ if ( f < 0.0f )
+ return -1.0f;
+ return 0.0f;
+}
+
+/*
+================
+Math::Fmod
+================
+*/
+OG_INLINE float Math::Fmod( float numerator, float denominator ) {
+ return fmodf( numerator, denominator );
+}
+
+/*
+================
+Math::Modf
+================
+*/
+OG_INLINE float Math::Modf( float f, float& i ) {
+ return modff( f, &i );
+}
+OG_INLINE float Math::Modf( float f ) {
+ float i;
+ return modff( f, &i );
+}
+
+/*
+================
+Math::Sqrt
+================
+*/
+OG_INLINE float Math::Sqrt( float f ) {
+ return sqrtf( f );
+}
+
+/*
+================
+Math::InvSqrt
+
+Cannot be 0.0f
+================
+*/
+OG_INLINE float Math::InvSqrt( float f ) {
+ OG_ASSERT( f != 0.0f );
+ return 1.0f / sqrtf( f );
+}
+
+/*
+================
+Math::RSqrt
+
+Can be 0.0f
+================
+*/
+OG_INLINE float Math::RSqrt( float f ) {
+ float g = 0.5f * f;
+ int i = *reinterpret_cast(&f);
+
+ // do a guess
+ i = 0x5f375a86 - ( i>>1 );
+ f = *reinterpret_cast(&i);
+
+ // Newtons calculation
+ f = f * ( 1.5f - g * f * f );
+ return f;
+}
+
+/*
+================
+Math::Log/Log2/Log10
+
+Log of 0 is bad.
+I've also heard you're not really
+supposed to do log of negatives, yet
+they work fine.
+================
+*/
+OG_INLINE float Math::Log( float f ) {
+ OG_ASSERT( f != 0.0f );
+ return logf( f );
+}
+OG_INLINE float Math::Log2( float f ) {
+ OG_ASSERT( f != 0.0f );
+ return INV_LN_2 * logf( f );
+}
+OG_INLINE float Math::Log10( float f ) {
+ OG_ASSERT( f != 0.0f );
+ return INV_LN_10 * logf( f );
+}
+
+/*
+================
+Math::Pow
+================
+*/
+OG_INLINE float Math::Pow( float base, float exp ) {
+ return powf( base, exp );
+}
+
+/*
+================
+Math::Exp
+================
+*/
+OG_INLINE float Math::Exp( float f ) {
+ return expf( f );
+}
+
+/*
+================
+Math::IsPowerOfTwo
+================
+*/
+OG_INLINE bool Math::IsPowerOfTwo( int x ) {
+ // This is the faster of the two known methods
+ // with the x > 0 check moved to the beginning
+ return x > 0 && ( x & ( x - 1 ) ) == 0;
+}
+
+/*
+================
+Math::HigherPowerOfTwo
+================
+*/
+OG_INLINE int Math::HigherPowerOfTwo( int x ) {
+ x--;
+ x |= x >> 1;
+ x |= x >> 2;
+ x |= x >> 4;
+ x |= x >> 8;
+ x |= x >> 16;
+ return x + 1;
+}
+
+/*
+================
+Math::LowerPowerOfTwo
+================
+*/
+OG_INLINE int Math::LowerPowerOfTwo( int x ) {
+ return HigherPowerOfTwo( x ) >> 1;
+}
+
+/*
+================
+Math::FloorPowerOfTwo
+================
+*/
+OG_INLINE int Math::FloorPowerOfTwo( int x ) {
+ return IsPowerOfTwo( x ) ? x : LowerPowerOfTwo( x );
+}
+
+/*
+================
+Math::CeilPowerOfTwo
+================
+*/
+OG_INLINE int Math::CeilPowerOfTwo( int x ) {
+ return IsPowerOfTwo( x ) ? x : HigherPowerOfTwo( x );
+}
+
+/*
+================
+Math::ClosestPowerOfTwo
+================
+*/
+OG_INLINE int Math::ClosestPowerOfTwo( int x ) {
+ if ( IsPowerOfTwo( x ) )
+ return x;
+ int high = HigherPowerOfTwo( x );
+ int low = high >> 1;
+ return ((high-x) < (x-low)) ? high : low;
+}
+
+/*
+================
+Math::Digits
+================
+*/
+OG_INLINE int Math::Digits( int x ) {
+ int digits = 1;
+ int step = 10;
+ while (step <= x) {
+ digits++;
+ step *= 10;
+ }
+ return digits;
+}
+
+/*
+================
+Math::Sin/ASin
+================
+*/
+OG_INLINE float Math::Sin( float f ) {
+ return sinf( f );
+}
+OG_INLINE float Math::ASin( float f ) {
+ if ( f <= -1.0f )
+ return -HALF_PI;
+ if ( f >= 1.0f )
+ return HALF_PI;
+ return asinf( f );
+}
+
+/*
+================
+Math::Cos/ACos
+================
+*/
+OG_INLINE float Math::Cos( float f ) {
+ return cosf( f );
+}
+OG_INLINE float Math::ACos( float f ) {
+ if ( f <= -1.0f )
+ return PI;
+ if ( f >= 1.0f )
+ return 0.0f;
+ return acosf( f );
+}
+
+/*
+================
+Math::Tan/ATan
+================
+*/
+OG_INLINE float Math::Tan( float f ) {
+ return tanf( f );
+}
+OG_INLINE float Math::ATan( float f ) {
+ return atanf( f );
+}
+OG_INLINE float Math::ATan( float f1, float f2 ) {
+ return atan2f( f1, f2 );
+}
+
+/*
+================
+Math::SinCos
+================
+*/
+OG_INLINE void Math::SinCos( float f, float &s, float &c ) {
+#if OG_ASM_MSVC
+ // sometimes assembler is just waaayy faster
+ _asm {
+ fld f
+ fsincos
+ mov ecx, c
+ mov edx, s
+ fstp dword ptr [ecx]
+ fstp dword ptr [edx]
+ }
+#elif OG_ASM_GNU
+ asm ("fsincos" : "=t" (c), "=u" (s) : "0" (f));
+#else
+ s = Sin(f);
+ c = Sqrt( 1.0f - s * s ); // faster than calling Cos(f)
+#endif
+}
+
+/*
+================
+Math::Deg2Rad
+================
+*/
+OG_INLINE float Math::Deg2Rad( float f ) {
+ return f * DEG_TO_RAD;
+}
+
+/*
+================
+Math::Rad2Deg
+================
+*/
+OG_INLINE float Math::Rad2Deg( float f ) {
+ return f * RAD_TO_DEG;
+}
+
+/*
+================
+Math::Square
+================
+*/
+OG_INLINE float Math::Square( float v ) {
+ return v * v;
+}
+
+/*
+================
+Math::Cube
+================
+*/
+OG_INLINE float Math::Cube( float v ) {
+ return v * v * v;
+}
+
+/*
+================
+Math::Sec2Ms
+================
+*/
+OG_INLINE int Math::Sec2Ms( int sec ) {
+ return sec * 1000;
+}
+
+/*
+================
+Math::Ms2Sec
+================
+*/
+OG_INLINE int Math::Ms2Sec( int ms ) {
+ return FtoiFast( ms * 0.001f );
+}
+
+}
+
+#endif
diff --git a/samples/C++/Types.h b/samples/C++/Types.h
new file mode 100644
index 00000000..e2675538
--- /dev/null
+++ b/samples/C++/Types.h
@@ -0,0 +1,32 @@
+/*****************************************************************************
+* Dwarf Mine - The 13-11 Benchmark
+*
+* Copyright (c) 2013 Bünger, Thomas; Kieschnick, Christian; Kusber,
+* Michael; Lohse, Henning; Wuttke, Nikolai; Xylander, Oliver; Yao, Gary;
+* Zimmermann, Florian
+*
+* 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.
+*****************************************************************************/
+
+#pragma once
+
+#include
+
+typedef uint32_t smallPrime_t;
diff --git a/samples/C++/bcm2835.h b/samples/C++/bcm2835.h
new file mode 100644
index 00000000..e5330933
--- /dev/null
+++ b/samples/C++/bcm2835.h
@@ -0,0 +1,1129 @@
+// bcm2835.h
+//
+// C and C++ support for Broadcom BCM 2835 as used in Raspberry Pi
+//
+// Author: Mike McCauley
+// Copyright (C) 2011-2013 Mike McCauley
+// $Id: bcm2835.h,v 1.8 2013/02/15 22:06:09 mikem Exp mikem $
+//
+/// \mainpage C library for Broadcom BCM 2835 as used in Raspberry Pi
+///
+/// This is a C library for Raspberry Pi (RPi). It provides access to
+/// GPIO and other IO functions on the Broadcom BCM 2835 chip,
+/// allowing access to the GPIO pins on the
+/// 26 pin IDE plug on the RPi board so you can control and interface with various external devices.
+///
+/// It provides functions for reading digital inputs and setting digital outputs, using SPI and I2C,
+/// and for accessing the system timers.
+/// Pin event detection is supported by polling (interrupts are not supported).
+///
+/// It is C++ compatible, and installs as a header file and non-shared library on
+/// any Linux-based distro (but clearly is no use except on Raspberry Pi or another board with
+/// BCM 2835).
+///
+/// The version of the package that this documentation refers to can be downloaded
+/// from http://www.airspayce.com/mikem/bcm2835/bcm2835-1.26.tar.gz
+/// You can find the latest version at http://www.airspayce.com/mikem/bcm2835
+///
+/// Several example programs are provided.
+///
+/// Based on data in http://elinux.org/RPi_Low-level_peripherals and
+/// http://www.raspberrypi.org/wp-content/uploads/2012/02/BCM2835-ARM-Peripherals.pdf
+/// and http://www.scribd.com/doc/101830961/GPIO-Pads-Control2
+///
+/// You can also find online help and discussion at http://groups.google.com/group/bcm2835
+/// Please use that group for all questions and discussions on this topic.
+/// Do not contact the author directly, unless it is to discuss commercial licensing.
+///
+/// Tested on debian6-19-04-2012, 2012-07-15-wheezy-raspbian and Occidentalisv01
+/// CAUTION: it has been observed that when detect enables such as bcm2835_gpio_len()
+/// are used and the pin is pulled LOW
+/// it can cause temporary hangs on 2012-07-15-wheezy-raspbian and Occidentalisv01.
+/// Reason for this is not yet determined, but suspect that an interrupt handler is
+/// hitting a hard loop on those OSs.
+/// If you must use bcm2835_gpio_len() and friends, make sure you disable the pins with
+/// bcm2835_gpio_cler_len() and friends after use.
+///
+/// \par Installation
+///
+/// This library consists of a single non-shared library and header file, which will be
+/// installed in the usual places by make install
+///
+/// \code
+/// # download the latest version of the library, say bcm2835-1.xx.tar.gz, then:
+/// tar zxvf bcm2835-1.xx.tar.gz
+/// cd bcm2835-1.xx
+/// ./configure
+/// make
+/// sudo make check
+/// sudo make install
+/// \endcode
+///
+/// \par Physical Addresses
+///
+/// The functions bcm2835_peri_read(), bcm2835_peri_write() and bcm2835_peri_set_bits()
+/// are low level peripheral register access functions. They are designed to use
+/// physical addresses as described in section 1.2.3 ARM physical addresses
+/// of the BCM2835 ARM Peripherals manual.
+/// Physical addresses range from 0x20000000 to 0x20FFFFFF for peripherals. The bus
+/// addresses for peripherals are set up to map onto the peripheral bus address range starting at
+/// 0x7E000000. Thus a peripheral advertised in the manual at bus address 0x7Ennnnnn is available at
+/// physical address 0x20nnnnnn.
+///
+/// The base address of the various peripheral registers are available with the following
+/// externals:
+/// bcm2835_gpio
+/// bcm2835_pwm
+/// bcm2835_clk
+/// bcm2835_pads
+/// bcm2835_spio0
+/// bcm2835_st
+/// bcm2835_bsc0
+/// bcm2835_bsc1
+///
+/// \par Pin Numbering
+///
+/// The GPIO pin numbering as used by RPi is different to and inconsistent with the underlying
+/// BCM 2835 chip pin numbering. http://elinux.org/RPi_BCM2835_GPIOs
+///
+/// RPi has a 26 pin IDE header that provides access to some of the GPIO pins on the BCM 2835,
+/// as well as power and ground pins. Not all GPIO pins on the BCM 2835 are available on the
+/// IDE header.
+///
+/// RPi Version 2 also has a P5 connector with 4 GPIO pins, 5V, 3.3V and Gnd.
+///
+/// The functions in this library are designed to be passed the BCM 2835 GPIO pin number and _not_
+/// the RPi pin number. There are symbolic definitions for each of the available pins
+/// that you should use for convenience. See \ref RPiGPIOPin.
+///
+/// \par SPI Pins
+///
+/// The bcm2835_spi_* functions allow you to control the BCM 2835 SPI0 interface,
+/// allowing you to send and received data by SPI (Serial Peripheral Interface).
+/// For more information about SPI, see http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus
+///
+/// When bcm2835_spi_begin() is called it changes the bahaviour of the SPI interface pins from their
+/// default GPIO behaviour in order to support SPI. While SPI is in use, you will not be able
+/// to control the state of the SPI pins through the usual bcm2835_spi_gpio_write().
+/// When bcm2835_spi_end() is called, the SPI pins will all revert to inputs, and can then be
+/// configured and controled with the usual bcm2835_gpio_* calls.
+///
+/// The Raspberry Pi GPIO pins used for SPI are:
+///
+/// - P1-19 (MOSI)
+/// - P1-21 (MISO)
+/// - P1-23 (CLK)
+/// - P1-24 (CE0)
+/// - P1-26 (CE1)
+///
+/// \par I2C Pins
+///
+/// The bcm2835_i2c_* functions allow you to control the BCM 2835 BSC interface,
+/// allowing you to send and received data by I2C ("eye-squared cee"; generically referred to as "two-wire interface") .
+/// For more information about I?C, see http://en.wikipedia.org/wiki/I%C2%B2C
+///
+/// The Raspberry Pi V2 GPIO pins used for I2C are:
+///
+/// - P1-03 (SDA)
+/// - P1-05 (SLC)
+///
+/// \par Real Time performance constraints
+///
+/// The bcm2835 is a library for user programs (i.e. they run in 'userland').
+/// Such programs are not part of the kernel and are usually
+/// subject to paging and swapping by the kernel while it does other things besides running your program.
+/// This means that you should not expect to get real-time performance or
+/// real-time timing constraints from such programs. In particular, there is no guarantee that the
+/// bcm2835_delay() and bcm2835_delayMicroseconds() will return after exactly the time requested.
+/// In fact, depending on other activity on the host, IO etc, you might get significantly longer delay times
+/// than the one you asked for. So please dont expect to get exactly the time delay you request.
+///
+/// Arjan reports that you can prevent swapping on Linux with the following code fragment:
+///
+/// \code
+/// struct sched_param sp;
+/// memset(&sp, 0, sizeof(sp));
+/// sp.sched_priority = sched_get_priority_max(SCHED_FIFO);
+/// sched_setscheduler(0, SCHED_FIFO, &sp);
+/// mlockall(MCL_CURRENT | MCL_FUTURE);
+/// \endcode
+///
+/// \par Open Source Licensing GPL V2
+///
+/// This is the appropriate option if you want to share the source code of your
+/// application with everyone you distribute it to, and you also want to give them
+/// the right to share who uses it. If you wish to use this software under Open
+/// Source Licensing, you must contribute all your source code to the open source
+/// community in accordance with the GPL Version 2 when your application is
+/// distributed. See http://www.gnu.org/copyleft/gpl.html and COPYING
+///
+/// \par Acknowledgements
+///
+/// Some of this code has been inspired by Dom and Gert.
+/// The I2C code has been inspired by Alan Barr.
+///
+/// \par Revision History
+///
+/// \version 1.0 Initial release
+/// \version 1.1 Minor bug fixes
+/// \version 1.2 Added support for SPI
+/// \version 1.3 Added bcm2835_spi_transfern()
+/// \version 1.4 Fixed a problem that prevented SPI CE1 being used. Reported by David Robinson.
+/// \version 1.5 Added bcm2835_close() to deinit the library. Suggested by C?sar Ortiz
+/// \version 1.6 Document testing on 2012-07-15-wheezy-raspbian and Occidentalisv01
+/// Functions bcm2835_gpio_ren(), bcm2835_gpio_fen(), bcm2835_gpio_hen()
+/// bcm2835_gpio_len(), bcm2835_gpio_aren() and bcm2835_gpio_afen() now
+/// changes only the pin specified. Other pins that were already previously
+/// enabled stay enabled.
+/// Added bcm2835_gpio_clr_ren(), bcm2835_gpio_clr_fen(), bcm2835_gpio_clr_hen()
+/// bcm2835_gpio_clr_len(), bcm2835_gpio_clr_aren(), bcm2835_gpio_clr_afen()
+/// to clear the enable for individual pins, suggested by Andreas Sundstrom.
+/// \version 1.7 Added bcm2835_spi_transfernb to support different buffers for read and write.
+/// \version 1.8 Improvements to read barrier, as suggested by maddin.
+/// \version 1.9 Improvements contributed by mikew:
+/// I noticed that it was mallocing memory for the mmaps on /dev/mem.
+/// It's not necessary to do that, you can just mmap the file directly,
+/// so I've removed the mallocs (and frees).
+/// I've also modified delayMicroseconds() to use nanosleep() for long waits,
+/// and a busy wait on a high resolution timer for the rest. This is because
+/// I've found that calling nanosleep() takes at least 100-200 us.
+/// You need to link using '-lrt' using this version.
+/// I've added some unsigned casts to the debug prints to silence compiler
+/// warnings I was getting, fixed some typos, and changed the value of
+/// BCM2835_PAD_HYSTERESIS_ENABLED to 0x08 as per Gert van Loo's doc at
+/// http://www.scribd.com/doc/101830961/GPIO-Pads-Control2
+/// Also added a define for the passwrd value that Gert says is needed to
+/// change pad control settings.
+/// \version 1.10 Changed the names of the delay functions to bcm2835_delay()
+/// and bcm2835_delayMicroseconds() to prevent collisions with wiringPi.
+/// Macros to map delay()-> bcm2835_delay() and
+/// Macros to map delayMicroseconds()-> bcm2835_delayMicroseconds(), which
+/// can be disabled by defining BCM2835_NO_DELAY_COMPATIBILITY
+/// \version 1.11 Fixed incorrect link to download file
+/// \version 1.12 New GPIO pin definitions for RPi version 2 (which has a different GPIO mapping)
+/// \version 1.13 New GPIO pin definitions for RPi version 2 plug P5
+/// Hardware base pointers are now available (after initialisation) externally as bcm2835_gpio
+/// bcm2835_pwm bcm2835_clk bcm2835_pads bcm2835_spi0.
+/// \version 1.14 Now compiles even if CLOCK_MONOTONIC_RAW is not available, uses CLOCK_MONOTONIC instead.
+/// Fixed errors in documentation of SPI divider frequencies based on 250MHz clock.
+/// Reported by Ben Simpson.
+/// \version 1.15 Added bcm2835_close() to end of examples as suggested by Mark Wolfe.
+/// \version 1.16 Added bcm2835_gpio_set_multi, bcm2835_gpio_clr_multi and bcm2835_gpio_write_multi
+/// to allow a mask of pins to be set all at once. Requested by Sebastian Loncar.
+/// \version 1.17 Added bcm2835_gpio_write_mask. Requested by Sebastian Loncar.
+/// \version 1.18 Added bcm2835_i2c_* functions. Changes to bcm2835_delayMicroseconds:
+/// now uses the RPi system timer counter, instead of clock_gettime, for improved accuracy.
+/// No need to link with -lrt now. Contributed by Arjan van Vught.
+/// \version 1.19 Removed inlines added by previous patch since they don't seem to work everywhere.
+/// Reported by olly.
+/// \version 1.20 Patch from Mark Dootson to close /dev/mem after access to the peripherals has been granted.
+/// \version 1.21 delayMicroseconds is now not susceptible to 32 bit timer overruns.
+/// Patch courtesy Jeremy Mortis.
+/// \version 1.22 Fixed incorrect definition of BCM2835_GPFEN0 which broke the ability to set
+/// falling edge events. Reported by Mark Dootson.
+/// \version 1.23 Added bcm2835_i2c_set_baudrate and bcm2835_i2c_read_register_rs.
+/// Improvements to bcm2835_i2c_read and bcm2835_i2c_write functions
+/// to fix ocasional reads not completing. Patched by Mark Dootson.
+/// \version 1.24 Mark Dootson p[atched a problem with his previously submitted code
+/// under high load from other processes.
+/// \version 1.25 Updated author and distribution location details to airspayce.com
+/// \version 1.26 Added missing unmapmem for pads in bcm2835_close to prevent a memory leak.
+/// Reported by Hartmut Henkel.
+/// \author Mike McCauley (mikem@airspayce.com) DO NOT CONTACT THE AUTHOR DIRECTLY: USE THE LISTS
+
+
+
+// Defines for BCM2835
+#ifndef BCM2835_H
+#define BCM2835_H
+
+#include
+
+/// \defgroup constants Constants for passing to and from library functions
+/// The values here are designed to be passed to various functions in the bcm2835 library.
+/// @{
+
+
+/// This means pin HIGH, true, 3.3volts on a pin.
+#define HIGH 0x1
+/// This means pin LOW, false, 0volts on a pin.
+#define LOW 0x0
+
+/// Speed of the core clock core_clk
+#define BCM2835_CORE_CLK_HZ 250000000 ///< 250 MHz
+
+// Physical addresses for various peripheral register sets
+/// Base Physical Address of the BCM 2835 peripheral registers
+#define BCM2835_PERI_BASE 0x20000000
+/// Base Physical Address of the System Timer registers
+#define BCM2835_ST_BASE (BCM2835_PERI_BASE + 0x3000)
+/// Base Physical Address of the Pads registers
+#define BCM2835_GPIO_PADS (BCM2835_PERI_BASE + 0x100000)
+/// Base Physical Address of the Clock/timer registers
+#define BCM2835_CLOCK_BASE (BCM2835_PERI_BASE + 0x101000)
+/// Base Physical Address of the GPIO registers
+#define BCM2835_GPIO_BASE (BCM2835_PERI_BASE + 0x200000)
+/// Base Physical Address of the SPI0 registers
+#define BCM2835_SPI0_BASE (BCM2835_PERI_BASE + 0x204000)
+/// Base Physical Address of the BSC0 registers
+#define BCM2835_BSC0_BASE (BCM2835_PERI_BASE + 0x205000)
+/// Base Physical Address of the PWM registers
+#define BCM2835_GPIO_PWM (BCM2835_PERI_BASE + 0x20C000)
+ /// Base Physical Address of the BSC1 registers
+#define BCM2835_BSC1_BASE (BCM2835_PERI_BASE + 0x804000)
+
+
+/// Base of the ST (System Timer) registers.
+/// Available after bcm2835_init has been called
+extern volatile uint32_t *bcm2835_st;
+
+/// Base of the GPIO registers.
+/// Available after bcm2835_init has been called
+extern volatile uint32_t *bcm2835_gpio;
+
+/// Base of the PWM registers.
+/// Available after bcm2835_init has been called
+extern volatile uint32_t *bcm2835_pwm;
+
+/// Base of the CLK registers.
+/// Available after bcm2835_init has been called
+extern volatile uint32_t *bcm2835_clk;
+
+/// Base of the PADS registers.
+/// Available after bcm2835_init has been called
+extern volatile uint32_t *bcm2835_pads;
+
+/// Base of the SPI0 registers.
+/// Available after bcm2835_init has been called
+extern volatile uint32_t *bcm2835_spi0;
+
+/// Base of the BSC0 registers.
+/// Available after bcm2835_init has been called
+extern volatile uint32_t *bcm2835_bsc0;
+
+/// Base of the BSC1 registers.
+/// Available after bcm2835_init has been called
+extern volatile uint32_t *bcm2835_bsc1;
+
+/// Size of memory page on RPi
+#define BCM2835_PAGE_SIZE (4*1024)
+/// Size of memory block on RPi
+#define BCM2835_BLOCK_SIZE (4*1024)
+
+
+// Defines for GPIO
+// The BCM2835 has 54 GPIO pins.
+// BCM2835 data sheet, Page 90 onwards.
+/// GPIO register offsets from BCM2835_GPIO_BASE. Offsets into the GPIO Peripheral block in bytes per 6.1 Register View
+#define BCM2835_GPFSEL0 0x0000 ///< GPIO Function Select 0
+#define BCM2835_GPFSEL1 0x0004 ///< GPIO Function Select 1
+#define BCM2835_GPFSEL2 0x0008 ///< GPIO Function Select 2
+#define BCM2835_GPFSEL3 0x000c ///< GPIO Function Select 3
+#define BCM2835_GPFSEL4 0x0010 ///< GPIO Function Select 4
+#define BCM2835_GPFSEL5 0x0014 ///< GPIO Function Select 5
+#define BCM2835_GPSET0 0x001c ///< GPIO Pin Output Set 0
+#define BCM2835_GPSET1 0x0020 ///< GPIO Pin Output Set 1
+#define BCM2835_GPCLR0 0x0028 ///< GPIO Pin Output Clear 0
+#define BCM2835_GPCLR1 0x002c ///< GPIO Pin Output Clear 1
+#define BCM2835_GPLEV0 0x0034 ///< GPIO Pin Level 0
+#define BCM2835_GPLEV1 0x0038 ///< GPIO Pin Level 1
+#define BCM2835_GPEDS0 0x0040 ///< GPIO Pin Event Detect Status 0
+#define BCM2835_GPEDS1 0x0044 ///< GPIO Pin Event Detect Status 1
+#define BCM2835_GPREN0 0x004c ///< GPIO Pin Rising Edge Detect Enable 0
+#define BCM2835_GPREN1 0x0050 ///< GPIO Pin Rising Edge Detect Enable 1
+#define BCM2835_GPFEN0 0x0058 ///< GPIO Pin Falling Edge Detect Enable 0
+#define BCM2835_GPFEN1 0x005c ///< GPIO Pin Falling Edge Detect Enable 1
+#define BCM2835_GPHEN0 0x0064 ///< GPIO Pin High Detect Enable 0
+#define BCM2835_GPHEN1 0x0068 ///< GPIO Pin High Detect Enable 1
+#define BCM2835_GPLEN0 0x0070 ///< GPIO Pin Low Detect Enable 0
+#define BCM2835_GPLEN1 0x0074 ///< GPIO Pin Low Detect Enable 1
+#define BCM2835_GPAREN0 0x007c ///< GPIO Pin Async. Rising Edge Detect 0
+#define BCM2835_GPAREN1 0x0080 ///< GPIO Pin Async. Rising Edge Detect 1
+#define BCM2835_GPAFEN0 0x0088 ///< GPIO Pin Async. Falling Edge Detect 0
+#define BCM2835_GPAFEN1 0x008c ///< GPIO Pin Async. Falling Edge Detect 1
+#define BCM2835_GPPUD 0x0094 ///< GPIO Pin Pull-up/down Enable
+#define BCM2835_GPPUDCLK0 0x0098 ///< GPIO Pin Pull-up/down Enable Clock 0
+#define BCM2835_GPPUDCLK1 0x009c ///< GPIO Pin Pull-up/down Enable Clock 1
+
+/// \brief bcm2835PortFunction
+/// Port function select modes for bcm2835_gpio_fsel()
+typedef enum
+{
+ BCM2835_GPIO_FSEL_INPT = 0b000, ///< Input
+ BCM2835_GPIO_FSEL_OUTP = 0b001, ///< Output
+ BCM2835_GPIO_FSEL_ALT0 = 0b100, ///< Alternate function 0
+ BCM2835_GPIO_FSEL_ALT1 = 0b101, ///< Alternate function 1
+ BCM2835_GPIO_FSEL_ALT2 = 0b110, ///< Alternate function 2
+ BCM2835_GPIO_FSEL_ALT3 = 0b111, ///< Alternate function 3
+ BCM2835_GPIO_FSEL_ALT4 = 0b011, ///< Alternate function 4
+ BCM2835_GPIO_FSEL_ALT5 = 0b010, ///< Alternate function 5
+ BCM2835_GPIO_FSEL_MASK = 0b111 ///< Function select bits mask
+} bcm2835FunctionSelect;
+
+/// \brief bcm2835PUDControl
+/// Pullup/Pulldown defines for bcm2835_gpio_pud()
+typedef enum
+{
+ BCM2835_GPIO_PUD_OFF = 0b00, ///< Off ? disable pull-up/down
+ BCM2835_GPIO_PUD_DOWN = 0b01, ///< Enable Pull Down control
+ BCM2835_GPIO_PUD_UP = 0b10 ///< Enable Pull Up control
+} bcm2835PUDControl;
+
+/// Pad control register offsets from BCM2835_GPIO_PADS
+#define BCM2835_PADS_GPIO_0_27 0x002c ///< Pad control register for pads 0 to 27
+#define BCM2835_PADS_GPIO_28_45 0x0030 ///< Pad control register for pads 28 to 45
+#define BCM2835_PADS_GPIO_46_53 0x0034 ///< Pad control register for pads 46 to 53
+
+/// Pad Control masks
+#define BCM2835_PAD_PASSWRD (0x5A << 24) ///< Password to enable setting pad mask
+#define BCM2835_PAD_SLEW_RATE_UNLIMITED 0x10 ///< Slew rate unlimited
+#define BCM2835_PAD_HYSTERESIS_ENABLED 0x08 ///< Hysteresis enabled
+#define BCM2835_PAD_DRIVE_2mA 0x00 ///< 2mA drive current
+#define BCM2835_PAD_DRIVE_4mA 0x01 ///< 4mA drive current
+#define BCM2835_PAD_DRIVE_6mA 0x02 ///< 6mA drive current
+#define BCM2835_PAD_DRIVE_8mA 0x03 ///< 8mA drive current
+#define BCM2835_PAD_DRIVE_10mA 0x04 ///< 10mA drive current
+#define BCM2835_PAD_DRIVE_12mA 0x05 ///< 12mA drive current
+#define BCM2835_PAD_DRIVE_14mA 0x06 ///< 14mA drive current
+#define BCM2835_PAD_DRIVE_16mA 0x07 ///< 16mA drive current
+
+/// \brief bcm2835PadGroup
+/// Pad group specification for bcm2835_gpio_pad()
+typedef enum
+{
+ BCM2835_PAD_GROUP_GPIO_0_27 = 0, ///< Pad group for GPIO pads 0 to 27
+ BCM2835_PAD_GROUP_GPIO_28_45 = 1, ///< Pad group for GPIO pads 28 to 45
+ BCM2835_PAD_GROUP_GPIO_46_53 = 2 ///< Pad group for GPIO pads 46 to 53
+} bcm2835PadGroup;
+
+/// \brief GPIO Pin Numbers
+///
+/// Here we define Raspberry Pin GPIO pins on P1 in terms of the underlying BCM GPIO pin numbers.
+/// These can be passed as a pin number to any function requiring a pin.
+/// Not all pins on the RPi 26 bin IDE plug are connected to GPIO pins
+/// and some can adopt an alternate function.
+/// RPi version 2 has some slightly different pinouts, and these are values RPI_V2_*.
+/// At bootup, pins 8 and 10 are set to UART0_TXD, UART0_RXD (ie the alt0 function) respectively
+/// When SPI0 is in use (ie after bcm2835_spi_begin()), pins 19, 21, 23, 24, 26 are dedicated to SPI
+/// and cant be controlled independently
+typedef enum
+{
+ RPI_GPIO_P1_03 = 0, ///< Version 1, Pin P1-03
+ RPI_GPIO_P1_05 = 1, ///< Version 1, Pin P1-05
+ RPI_GPIO_P1_07 = 4, ///< Version 1, Pin P1-07
+ RPI_GPIO_P1_08 = 14, ///< Version 1, Pin P1-08, defaults to alt function 0 UART0_TXD
+ RPI_GPIO_P1_10 = 15, ///< Version 1, Pin P1-10, defaults to alt function 0 UART0_RXD
+ RPI_GPIO_P1_11 = 17, ///< Version 1, Pin P1-11
+ RPI_GPIO_P1_12 = 18, ///< Version 1, Pin P1-12
+ RPI_GPIO_P1_13 = 21, ///< Version 1, Pin P1-13
+ RPI_GPIO_P1_15 = 22, ///< Version 1, Pin P1-15
+ RPI_GPIO_P1_16 = 23, ///< Version 1, Pin P1-16
+ RPI_GPIO_P1_18 = 24, ///< Version 1, Pin P1-18
+ RPI_GPIO_P1_19 = 10, ///< Version 1, Pin P1-19, MOSI when SPI0 in use
+ RPI_GPIO_P1_21 = 9, ///< Version 1, Pin P1-21, MISO when SPI0 in use
+ RPI_GPIO_P1_22 = 25, ///< Version 1, Pin P1-22
+ RPI_GPIO_P1_23 = 11, ///< Version 1, Pin P1-23, CLK when SPI0 in use
+ RPI_GPIO_P1_24 = 8, ///< Version 1, Pin P1-24, CE0 when SPI0 in use
+ RPI_GPIO_P1_26 = 7, ///< Version 1, Pin P1-26, CE1 when SPI0 in use
+
+ // RPi Version 2
+ RPI_V2_GPIO_P1_03 = 2, ///< Version 2, Pin P1-03
+ RPI_V2_GPIO_P1_05 = 3, ///< Version 2, Pin P1-05
+ RPI_V2_GPIO_P1_07 = 4, ///< Version 2, Pin P1-07
+ RPI_V2_GPIO_P1_08 = 14, ///< Version 2, Pin P1-08, defaults to alt function 0 UART0_TXD
+ RPI_V2_GPIO_P1_10 = 15, ///< Version 2, Pin P1-10, defaults to alt function 0 UART0_RXD
+ RPI_V2_GPIO_P1_11 = 17, ///< Version 2, Pin P1-11
+ RPI_V2_GPIO_P1_12 = 18, ///< Version 2, Pin P1-12
+ RPI_V2_GPIO_P1_13 = 27, ///< Version 2, Pin P1-13
+ RPI_V2_GPIO_P1_15 = 22, ///< Version 2, Pin P1-15
+ RPI_V2_GPIO_P1_16 = 23, ///< Version 2, Pin P1-16
+ RPI_V2_GPIO_P1_18 = 24, ///< Version 2, Pin P1-18
+ RPI_V2_GPIO_P1_19 = 10, ///< Version 2, Pin P1-19, MOSI when SPI0 in use
+ RPI_V2_GPIO_P1_21 = 9, ///< Version 2, Pin P1-21, MISO when SPI0 in use
+ RPI_V2_GPIO_P1_22 = 25, ///< Version 2, Pin P1-22
+ RPI_V2_GPIO_P1_23 = 11, ///< Version 2, Pin P1-23, CLK when SPI0 in use
+ RPI_V2_GPIO_P1_24 = 8, ///< Version 2, Pin P1-24, CE0 when SPI0 in use
+ RPI_V2_GPIO_P1_26 = 7, ///< Version 2, Pin P1-26, CE1 when SPI0 in use
+
+ // RPi Version 2, new plug P5
+ RPI_V2_GPIO_P5_03 = 28, ///< Version 2, Pin P5-03
+ RPI_V2_GPIO_P5_04 = 29, ///< Version 2, Pin P5-04
+ RPI_V2_GPIO_P5_05 = 30, ///< Version 2, Pin P5-05
+ RPI_V2_GPIO_P5_06 = 31, ///< Version 2, Pin P5-06
+
+} RPiGPIOPin;
+
+// Defines for SPI
+// GPIO register offsets from BCM2835_SPI0_BASE.
+// Offsets into the SPI Peripheral block in bytes per 10.5 SPI Register Map
+#define BCM2835_SPI0_CS 0x0000 ///< SPI Master Control and Status
+#define BCM2835_SPI0_FIFO 0x0004 ///< SPI Master TX and RX FIFOs
+#define BCM2835_SPI0_CLK 0x0008 ///< SPI Master Clock Divider
+#define BCM2835_SPI0_DLEN 0x000c ///< SPI Master Data Length
+#define BCM2835_SPI0_LTOH 0x0010 ///< SPI LOSSI mode TOH
+#define BCM2835_SPI0_DC 0x0014 ///< SPI DMA DREQ Controls
+
+// Register masks for SPI0_CS
+#define BCM2835_SPI0_CS_LEN_LONG 0x02000000 ///< Enable Long data word in Lossi mode if DMA_LEN is set
+#define BCM2835_SPI0_CS_DMA_LEN 0x01000000 ///< Enable DMA mode in Lossi mode
+#define BCM2835_SPI0_CS_CSPOL2 0x00800000 ///< Chip Select 2 Polarity
+#define BCM2835_SPI0_CS_CSPOL1 0x00400000 ///< Chip Select 1 Polarity
+#define BCM2835_SPI0_CS_CSPOL0 0x00200000 ///< Chip Select 0 Polarity
+#define BCM2835_SPI0_CS_RXF 0x00100000 ///< RXF - RX FIFO Full
+#define BCM2835_SPI0_CS_RXR 0x00080000 ///< RXR RX FIFO needs Reading ( full)
+#define BCM2835_SPI0_CS_TXD 0x00040000 ///< TXD TX FIFO can accept Data
+#define BCM2835_SPI0_CS_RXD 0x00020000 ///< RXD RX FIFO contains Data
+#define BCM2835_SPI0_CS_DONE 0x00010000 ///< Done transfer Done
+#define BCM2835_SPI0_CS_TE_EN 0x00008000 ///< Unused
+#define BCM2835_SPI0_CS_LMONO 0x00004000 ///< Unused
+#define BCM2835_SPI0_CS_LEN 0x00002000 ///< LEN LoSSI enable
+#define BCM2835_SPI0_CS_REN 0x00001000 ///< REN Read Enable
+#define BCM2835_SPI0_CS_ADCS 0x00000800 ///< ADCS Automatically Deassert Chip Select
+#define BCM2835_SPI0_CS_INTR 0x00000400 ///< INTR Interrupt on RXR
+#define BCM2835_SPI0_CS_INTD 0x00000200 ///< INTD Interrupt on Done
+#define BCM2835_SPI0_CS_DMAEN 0x00000100 ///< DMAEN DMA Enable
+#define BCM2835_SPI0_CS_TA 0x00000080 ///< Transfer Active
+#define BCM2835_SPI0_CS_CSPOL 0x00000040 ///< Chip Select Polarity
+#define BCM2835_SPI0_CS_CLEAR 0x00000030 ///< Clear FIFO Clear RX and TX
+#define BCM2835_SPI0_CS_CLEAR_RX 0x00000020 ///< Clear FIFO Clear RX
+#define BCM2835_SPI0_CS_CLEAR_TX 0x00000010 ///< Clear FIFO Clear TX
+#define BCM2835_SPI0_CS_CPOL 0x00000008 ///< Clock Polarity
+#define BCM2835_SPI0_CS_CPHA 0x00000004 ///< Clock Phase
+#define BCM2835_SPI0_CS_CS 0x00000003 ///< Chip Select
+
+/// \brief bcm2835SPIBitOrder SPI Bit order
+/// Specifies the SPI data bit ordering for bcm2835_spi_setBitOrder()
+typedef enum
+{
+ BCM2835_SPI_BIT_ORDER_LSBFIRST = 0, ///< LSB First
+ BCM2835_SPI_BIT_ORDER_MSBFIRST = 1 ///< MSB First
+}bcm2835SPIBitOrder;
+
+/// \brief SPI Data mode
+/// Specify the SPI data mode to be passed to bcm2835_spi_setDataMode()
+typedef enum
+{
+ BCM2835_SPI_MODE0 = 0, ///< CPOL = 0, CPHA = 0
+ BCM2835_SPI_MODE1 = 1, ///< CPOL = 0, CPHA = 1
+ BCM2835_SPI_MODE2 = 2, ///< CPOL = 1, CPHA = 0
+ BCM2835_SPI_MODE3 = 3, ///< CPOL = 1, CPHA = 1
+}bcm2835SPIMode;
+
+/// \brief bcm2835SPIChipSelect
+/// Specify the SPI chip select pin(s)
+typedef enum
+{
+ BCM2835_SPI_CS0 = 0, ///< Chip Select 0
+ BCM2835_SPI_CS1 = 1, ///< Chip Select 1
+ BCM2835_SPI_CS2 = 2, ///< Chip Select 2 (ie pins CS1 and CS2 are asserted)
+ BCM2835_SPI_CS_NONE = 3, ///< No CS, control it yourself
+} bcm2835SPIChipSelect;
+
+/// \brief bcm2835SPIClockDivider
+/// Specifies the divider used to generate the SPI clock from the system clock.
+/// Figures below give the divider, clock period and clock frequency.
+/// Clock divided is based on nominal base clock rate of 250MHz
+/// It is reported that (contrary to the documentation) any even divider may used.
+/// The frequencies shown for each divider have been confirmed by measurement
+typedef enum
+{
+ BCM2835_SPI_CLOCK_DIVIDER_65536 = 0, ///< 65536 = 262.144us = 3.814697260kHz
+ BCM2835_SPI_CLOCK_DIVIDER_32768 = 32768, ///< 32768 = 131.072us = 7.629394531kHz
+ BCM2835_SPI_CLOCK_DIVIDER_16384 = 16384, ///< 16384 = 65.536us = 15.25878906kHz
+ BCM2835_SPI_CLOCK_DIVIDER_8192 = 8192, ///< 8192 = 32.768us = 30/51757813kHz
+ BCM2835_SPI_CLOCK_DIVIDER_4096 = 4096, ///< 4096 = 16.384us = 61.03515625kHz
+ BCM2835_SPI_CLOCK_DIVIDER_2048 = 2048, ///< 2048 = 8.192us = 122.0703125kHz
+ BCM2835_SPI_CLOCK_DIVIDER_1024 = 1024, ///< 1024 = 4.096us = 244.140625kHz
+ BCM2835_SPI_CLOCK_DIVIDER_512 = 512, ///< 512 = 2.048us = 488.28125kHz
+ BCM2835_SPI_CLOCK_DIVIDER_256 = 256, ///< 256 = 1.024us = 976.5625MHz
+ BCM2835_SPI_CLOCK_DIVIDER_128 = 128, ///< 128 = 512ns = = 1.953125MHz
+ BCM2835_SPI_CLOCK_DIVIDER_64 = 64, ///< 64 = 256ns = 3.90625MHz
+ BCM2835_SPI_CLOCK_DIVIDER_32 = 32, ///< 32 = 128ns = 7.8125MHz
+ BCM2835_SPI_CLOCK_DIVIDER_16 = 16, ///< 16 = 64ns = 15.625MHz
+ BCM2835_SPI_CLOCK_DIVIDER_8 = 8, ///< 8 = 32ns = 31.25MHz
+ BCM2835_SPI_CLOCK_DIVIDER_4 = 4, ///< 4 = 16ns = 62.5MHz
+ BCM2835_SPI_CLOCK_DIVIDER_2 = 2, ///< 2 = 8ns = 125MHz, fastest you can get
+ BCM2835_SPI_CLOCK_DIVIDER_1 = 1, ///< 0 = 262.144us = 3.814697260kHz, same as 0/65536
+} bcm2835SPIClockDivider;
+
+// Defines for I2C
+// GPIO register offsets from BCM2835_BSC*_BASE.
+// Offsets into the BSC Peripheral block in bytes per 3.1 BSC Register Map
+#define BCM2835_BSC_C 0x0000 ///< BSC Master Control
+#define BCM2835_BSC_S 0x0004 ///< BSC Master Status
+#define BCM2835_BSC_DLEN 0x0008 ///< BSC Master Data Length
+#define BCM2835_BSC_A 0x000c ///< BSC Master Slave Address
+#define BCM2835_BSC_FIFO 0x0010 ///< BSC Master Data FIFO
+#define BCM2835_BSC_DIV 0x0014 ///< BSC Master Clock Divider
+#define BCM2835_BSC_DEL 0x0018 ///< BSC Master Data Delay
+#define BCM2835_BSC_CLKT 0x001c ///< BSC Master Clock Stretch Timeout
+
+// Register masks for BSC_C
+#define BCM2835_BSC_C_I2CEN 0x00008000 ///< I2C Enable, 0 = disabled, 1 = enabled
+#define BCM2835_BSC_C_INTR 0x00000400 ///< Interrupt on RX
+#define BCM2835_BSC_C_INTT 0x00000200 ///< Interrupt on TX
+#define BCM2835_BSC_C_INTD 0x00000100 ///< Interrupt on DONE
+#define BCM2835_BSC_C_ST 0x00000080 ///< Start transfer, 1 = Start a new transfer
+#define BCM2835_BSC_C_CLEAR_1 0x00000020 ///< Clear FIFO Clear
+#define BCM2835_BSC_C_CLEAR_2 0x00000010 ///< Clear FIFO Clear
+#define BCM2835_BSC_C_READ 0x00000001 ///< Read transfer
+
+// Register masks for BSC_S
+#define BCM2835_BSC_S_CLKT 0x00000200 ///< Clock stretch timeout
+#define BCM2835_BSC_S_ERR 0x00000100 ///< ACK error
+#define BCM2835_BSC_S_RXF 0x00000080 ///< RXF FIFO full, 0 = FIFO is not full, 1 = FIFO is full
+#define BCM2835_BSC_S_TXE 0x00000040 ///< TXE FIFO full, 0 = FIFO is not full, 1 = FIFO is full
+#define BCM2835_BSC_S_RXD 0x00000020 ///< RXD FIFO contains data
+#define BCM2835_BSC_S_TXD 0x00000010 ///< TXD FIFO can accept data
+#define BCM2835_BSC_S_RXR 0x00000008 ///< RXR FIFO needs reading (full)
+#define BCM2835_BSC_S_TXW 0x00000004 ///< TXW FIFO needs writing (full)
+#define BCM2835_BSC_S_DONE 0x00000002 ///< Transfer DONE
+#define BCM2835_BSC_S_TA 0x00000001 ///< Transfer Active
+
+#define BCM2835_BSC_FIFO_SIZE 16 ///< BSC FIFO size
+
+/// \brief bcm2835I2CClockDivider
+/// Specifies the divider used to generate the I2C clock from the system clock.
+/// Clock divided is based on nominal base clock rate of 250MHz
+typedef enum
+{
+ BCM2835_I2C_CLOCK_DIVIDER_2500 = 2500, ///< 2500 = 10us = 100 kHz
+ BCM2835_I2C_CLOCK_DIVIDER_626 = 626, ///< 622 = 2.504us = 399.3610 kHz
+ BCM2835_I2C_CLOCK_DIVIDER_150 = 150, ///< 150 = 60ns = 1.666 MHz (default at reset)
+ BCM2835_I2C_CLOCK_DIVIDER_148 = 148, ///< 148 = 59ns = 1.689 MHz
+} bcm2835I2CClockDivider;
+
+/// \brief bcm2835I2CReasonCodes
+/// Specifies the reason codes for the bcm2835_i2c_write and bcm2835_i2c_read functions.
+typedef enum
+{
+ BCM2835_I2C_REASON_OK = 0x00, ///< Success
+ BCM2835_I2C_REASON_ERROR_NACK = 0x01, ///< Received a NACK
+ BCM2835_I2C_REASON_ERROR_CLKT = 0x02, ///< Received Clock Stretch Timeout
+ BCM2835_I2C_REASON_ERROR_DATA = 0x04, ///< Not all data is sent / received
+} bcm2835I2CReasonCodes;
+
+// Defines for ST
+// GPIO register offsets from BCM2835_ST_BASE.
+// Offsets into the ST Peripheral block in bytes per 12.1 System Timer Registers
+// The System Timer peripheral provides four 32-bit timer channels and a single 64-bit free running counter.
+// BCM2835_ST_CLO is the System Timer Counter Lower bits register.
+// The system timer free-running counter lower register is a read-only register that returns the current value
+// of the lower 32-bits of the free running counter.
+// BCM2835_ST_CHI is the System Timer Counter Upper bits register.
+// The system timer free-running counter upper register is a read-only register that returns the current value
+// of the upper 32-bits of the free running counter.
+#define BCM2835_ST_CS 0x0000 ///< System Timer Control/Status
+#define BCM2835_ST_CLO 0x0004 ///< System Timer Counter Lower 32 bits
+#define BCM2835_ST_CHI 0x0008 ///< System Timer Counter Upper 32 bits
+
+/// @}
+
+
+// Defines for PWM
+#define BCM2835_PWM_CONTROL 0
+#define BCM2835_PWM_STATUS 1
+#define BCM2835_PWM0_RANGE 4
+#define BCM2835_PWM0_DATA 5
+#define BCM2835_PWM1_RANGE 8
+#define BCM2835_PWM1_DATA 9
+
+#define BCM2835_PWMCLK_CNTL 40
+#define BCM2835_PWMCLK_DIV 41
+
+#define BCM2835_PWM1_MS_MODE 0x8000 /// Run in MS mode
+#define BCM2835_PWM1_USEFIFO 0x2000 /// Data from FIFO
+#define BCM2835_PWM1_REVPOLAR 0x1000 /// Reverse polarity
+#define BCM2835_PWM1_OFFSTATE 0x0800 /// Ouput Off state
+#define BCM2835_PWM1_REPEATFF 0x0400 /// Repeat last value if FIFO empty
+#define BCM2835_PWM1_SERIAL 0x0200 /// Run in serial mode
+#define BCM2835_PWM1_ENABLE 0x0100 /// Channel Enable
+
+#define BCM2835_PWM0_MS_MODE 0x0080 /// Run in MS mode
+#define BCM2835_PWM0_USEFIFO 0x0020 /// Data from FIFO
+#define BCM2835_PWM0_REVPOLAR 0x0010 /// Reverse polarity
+#define BCM2835_PWM0_OFFSTATE 0x0008 /// Ouput Off state
+#define BCM2835_PWM0_REPEATFF 0x0004 /// Repeat last value if FIFO empty
+#define BCM2835_PWM0_SERIAL 0x0002 /// Run in serial mode
+#define BCM2835_PWM0_ENABLE 0x0001 /// Channel Enable
+
+// Historical name compatibility
+#ifndef BCM2835_NO_DELAY_COMPATIBILITY
+#define delay(x) bcm2835_delay(x)
+#define delayMicroseconds(x) bcm2835_delayMicroseconds(x)
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /// \defgroup init Library initialisation and management
+ /// These functions allow you to intialise and control the bcm2835 library
+ /// @{
+
+ /// Initialise the library by opening /dev/mem and getting pointers to the
+ /// internal memory for BCM 2835 device registers. You must call this (successfully)
+ /// before calling any other
+ /// functions in this library (except bcm2835_set_debug).
+ /// If bcm2835_init() fails by returning 0,
+ /// calling any other function may result in crashes or other failures.
+ /// Prints messages to stderr in case of errors.
+ /// \return 1 if successful else 0
+ extern int bcm2835_init(void);
+
+ /// Close the library, deallocating any allocated memory and closing /dev/mem
+ /// \return 1 if successful else 0
+ extern int bcm2835_close(void);
+
+ /// Sets the debug level of the library.
+ /// A value of 1 prevents mapping to /dev/mem, and makes the library print out
+ /// what it would do, rather than accessing the GPIO registers.
+ /// A value of 0, the default, causes normal operation.
+ /// Call this before calling bcm2835_init();
+ /// \param[in] debug The new debug level. 1 means debug
+ extern void bcm2835_set_debug(uint8_t debug);
+
+ /// @} // end of init
+
+ /// \defgroup lowlevel Low level register access
+ /// These functions provide low level register access, and should not generally
+ /// need to be used
+ ///
+ /// @{
+
+ /// Reads 32 bit value from a peripheral address
+ /// The read is done twice, and is therefore always safe in terms of
+ /// manual section 1.3 Peripheral access precautions for correct memory ordering
+ /// \param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc.
+ /// \return the value read from the 32 bit register
+ /// \sa Physical Addresses
+ extern uint32_t bcm2835_peri_read(volatile uint32_t* paddr);
+
+
+ /// Reads 32 bit value from a peripheral address without the read barrier
+ /// You should only use this when your code has previously called bcm2835_peri_read()
+ /// within the same peripheral, and no other peripheral access has occurred since.
+ /// \param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc.
+ /// \return the value read from the 32 bit register
+ /// \sa Physical Addresses
+ extern uint32_t bcm2835_peri_read_nb(volatile uint32_t* paddr);
+
+
+ /// Writes 32 bit value from a peripheral address
+ /// The write is done twice, and is therefore always safe in terms of
+ /// manual section 1.3 Peripheral access precautions for correct memory ordering
+ /// \param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc.
+ /// \param[in] value The 32 bit value to write
+ /// \sa Physical Addresses
+ extern void bcm2835_peri_write(volatile uint32_t* paddr, uint32_t value);
+
+ /// Writes 32 bit value from a peripheral address without the write barrier
+ /// You should only use this when your code has previously called bcm2835_peri_write()
+ /// within the same peripheral, and no other peripheral access has occurred since.
+ /// \param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc.
+ /// \param[in] value The 32 bit value to write
+ /// \sa Physical Addresses
+ extern void bcm2835_peri_write_nb(volatile uint32_t* paddr, uint32_t value);
+
+ /// Alters a number of bits in a 32 peripheral regsiter.
+ /// It reads the current valu and then alters the bits deines as 1 in mask,
+ /// according to the bit value in value.
+ /// All other bits that are 0 in the mask are unaffected.
+ /// Use this to alter a subset of the bits in a register.
+ /// The write is done twice, and is therefore always safe in terms of
+ /// manual section 1.3 Peripheral access precautions for correct memory ordering
+ /// \param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc.
+ /// \param[in] value The 32 bit value to write, masked in by mask.
+ /// \param[in] mask Bitmask that defines the bits that will be altered in the register.
+ /// \sa Physical Addresses
+ extern void bcm2835_peri_set_bits(volatile uint32_t* paddr, uint32_t value, uint32_t mask);
+ /// @} // end of lowlevel
+
+ /// \defgroup gpio GPIO register access
+ /// These functions allow you to control the GPIO interface. You can set the
+ /// function of each GPIO pin, read the input state and set the output state.
+ /// @{
+
+ /// Sets the Function Select register for the given pin, which configures
+ /// the pin as Input, Output or one of the 6 alternate functions.
+ /// \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from RPiGPIOPin.
+ /// \param[in] mode Mode to set the pin to, one of BCM2835_GPIO_FSEL_* from \ref bcm2835FunctionSelect
+ extern void bcm2835_gpio_fsel(uint8_t pin, uint8_t mode);
+
+ /// Sets the specified pin output to
+ /// HIGH.
+ /// \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
+ /// \sa bcm2835_gpio_write()
+ extern void bcm2835_gpio_set(uint8_t pin);
+
+ /// Sets the specified pin output to
+ /// LOW.
+ /// \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
+ /// \sa bcm2835_gpio_write()
+ extern void bcm2835_gpio_clr(uint8_t pin);
+
+ /// Sets any of the first 32 GPIO output pins specified in the mask to
+ /// HIGH.
+ /// \param[in] mask Mask of pins to affect. Use eg: (1 << RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05)
+ /// \sa bcm2835_gpio_write_multi()
+ extern void bcm2835_gpio_set_multi(uint32_t mask);
+
+ /// Sets any of the first 32 GPIO output pins specified in the mask to
+ /// LOW.
+ /// \param[in] mask Mask of pins to affect. Use eg: (1 << RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05)
+ /// \sa bcm2835_gpio_write_multi()
+ extern void bcm2835_gpio_clr_multi(uint32_t mask);
+
+ /// Reads the current level on the specified
+ /// pin and returns either HIGH or LOW. Works whether or not the pin
+ /// is an input or an output.
+ /// \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
+ /// \return the current level either HIGH or LOW
+ extern uint8_t bcm2835_gpio_lev(uint8_t pin);
+
+ /// Event Detect Status.
+ /// Tests whether the specified pin has detected a level or edge
+ /// as requested by bcm2835_gpio_ren(), bcm2835_gpio_fen(), bcm2835_gpio_hen(),
+ /// bcm2835_gpio_len(), bcm2835_gpio_aren(), bcm2835_gpio_afen().
+ /// Clear the flag for a given pin by calling bcm2835_gpio_set_eds(pin);
+ /// \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
+ /// \return HIGH if the event detect status for th given pin is true.
+ extern uint8_t bcm2835_gpio_eds(uint8_t pin);
+
+ /// Sets the Event Detect Status register for a given pin to 1,
+ /// which has the effect of clearing the flag. Use this afer seeing
+ /// an Event Detect Status on the pin.
+ /// \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
+ extern void bcm2835_gpio_set_eds(uint8_t pin);
+
+ /// Enable Rising Edge Detect Enable for the specified pin.
+ /// When a rising edge is detected, sets the appropriate pin in Event Detect Status.
+ /// The GPRENn registers use
+ /// synchronous edge detection. This means the input signal is sampled using the
+ /// system clock and then it is looking for a ?011? pattern on the sampled signal. This
+ /// has the effect of suppressing glitches.
+ /// \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
+ extern void bcm2835_gpio_ren(uint8_t pin);
+
+ /// Disable Rising Edge Detect Enable for the specified pin.
+ /// \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
+ extern void bcm2835_gpio_clr_ren(uint8_t pin);
+
+ /// Enable Falling Edge Detect Enable for the specified pin.
+ /// When a falling edge is detected, sets the appropriate pin in Event Detect Status.
+ /// The GPRENn registers use
+ /// synchronous edge detection. This means the input signal is sampled using the
+ /// system clock and then it is looking for a ?100? pattern on the sampled signal. This
+ /// has the effect of suppressing glitches.
+ /// \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
+ extern void bcm2835_gpio_fen(uint8_t pin);
+
+ /// Disable Falling Edge Detect Enable for the specified pin.
+ /// \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
+ extern void bcm2835_gpio_clr_fen(uint8_t pin);
+
+ /// Enable High Detect Enable for the specified pin.
+ /// When a HIGH level is detected on the pin, sets the appropriate pin in Event Detect Status.
+ /// \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
+ extern void bcm2835_gpio_hen(uint8_t pin);
+
+ /// Disable High Detect Enable for the specified pin.
+ /// \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
+ extern void bcm2835_gpio_clr_hen(uint8_t pin);
+
+ /// Enable Low Detect Enable for the specified pin.
+ /// When a LOW level is detected on the pin, sets the appropriate pin in Event Detect Status.
+ /// \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
+ extern void bcm2835_gpio_len(uint8_t pin);
+
+ /// Disable Low Detect Enable for the specified pin.
+ /// \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
+ extern void bcm2835_gpio_clr_len(uint8_t pin);
+
+ /// Enable Asynchronous Rising Edge Detect Enable for the specified pin.
+ /// When a rising edge is detected, sets the appropriate pin in Event Detect Status.
+ /// Asynchronous means the incoming signal is not sampled by the system clock. As such
+ /// rising edges of very short duration can be detected.
+ /// \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
+ extern void bcm2835_gpio_aren(uint8_t pin);
+
+ /// Disable Asynchronous Rising Edge Detect Enable for the specified pin.
+ /// \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
+ extern void bcm2835_gpio_clr_aren(uint8_t pin);
+
+ /// Enable Asynchronous Falling Edge Detect Enable for the specified pin.
+ /// When a falling edge is detected, sets the appropriate pin in Event Detect Status.
+ /// Asynchronous means the incoming signal is not sampled by the system clock. As such
+ /// falling edges of very short duration can be detected.
+ /// \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
+ extern void bcm2835_gpio_afen(uint8_t pin);
+
+ /// Disable Asynchronous Falling Edge Detect Enable for the specified pin.
+ /// \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
+ extern void bcm2835_gpio_clr_afen(uint8_t pin);
+
+ /// Sets the Pull-up/down register for the given pin. This is
+ /// used with bcm2835_gpio_pudclk() to set the Pull-up/down resistor for the given pin.
+ /// However, it is usually more convenient to use bcm2835_gpio_set_pud().
+ /// \param[in] pud The desired Pull-up/down mode. One of BCM2835_GPIO_PUD_* from bcm2835PUDControl
+ /// \sa bcm2835_gpio_set_pud()
+ extern void bcm2835_gpio_pud(uint8_t pud);
+
+ /// Clocks the Pull-up/down value set earlier by bcm2835_gpio_pud() into the pin.
+ /// \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
+ /// \param[in] on HIGH to clock the value from bcm2835_gpio_pud() into the pin.
+ /// LOW to remove the clock.
+ /// \sa bcm2835_gpio_set_pud()
+ extern void bcm2835_gpio_pudclk(uint8_t pin, uint8_t on);
+
+ /// Reads and returns the Pad Control for the given GPIO group.
+ /// \param[in] group The GPIO pad group number, one of BCM2835_PAD_GROUP_GPIO_*
+ /// \return Mask of bits from BCM2835_PAD_* from \ref bcm2835PadGroup
+ extern uint32_t bcm2835_gpio_pad(uint8_t group);
+
+ /// Sets the Pad Control for the given GPIO group.
+ /// \param[in] group The GPIO pad group number, one of BCM2835_PAD_GROUP_GPIO_*
+ /// \param[in] control Mask of bits from BCM2835_PAD_* from \ref bcm2835PadGroup
+ extern void bcm2835_gpio_set_pad(uint8_t group, uint32_t control);
+
+ /// Delays for the specified number of milliseconds.
+ /// Uses nanosleep(), and therefore does not use CPU until the time is up.
+ /// However, you are at the mercy of nanosleep(). From the manual for nanosleep():
+ /// If the interval specified in req is not an exact multiple of the granularity
+ /// underlying clock (see time(7)), then the interval will be
+ /// rounded up to the next multiple. Furthermore, after the sleep completes,
+ /// there may still be a delay before the CPU becomes free to once
+ /// again execute the calling thread.
+ /// \param[in] millis Delay in milliseconds
+ extern void bcm2835_delay (unsigned int millis);
+
+ /// Delays for the specified number of microseconds.
+ /// Uses a combination of nanosleep() and a busy wait loop on the BCM2835 system timers,
+ /// However, you are at the mercy of nanosleep(). From the manual for nanosleep():
+ /// If the interval specified in req is not an exact multiple of the granularity
+ /// underlying clock (see time(7)), then the interval will be
+ /// rounded up to the next multiple. Furthermore, after the sleep completes,
+ /// there may still be a delay before the CPU becomes free to once
+ /// again execute the calling thread.
+ /// For times less than about 450 microseconds, uses a busy wait on the System Timer.
+ /// It is reported that a delay of 0 microseconds on RaspberryPi will in fact
+ /// result in a delay of about 80 microseconds. Your mileage may vary.
+ /// \param[in] micros Delay in microseconds
+ extern void bcm2835_delayMicroseconds (uint64_t micros);
+
+ /// Sets the output state of the specified pin
+ /// \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
+ /// \param[in] on HIGH sets the output to HIGH and LOW to LOW.
+ extern void bcm2835_gpio_write(uint8_t pin, uint8_t on);
+
+ /// Sets any of the first 32 GPIO output pins specified in the mask to the state given by on
+ /// \param[in] mask Mask of pins to affect. Use eg: (1 << RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05)
+ /// \param[in] on HIGH sets the output to HIGH and LOW to LOW.
+ extern void bcm2835_gpio_write_multi(uint32_t mask, uint8_t on);
+
+ /// Sets the first 32 GPIO output pins specified in the mask to the value given by value
+ /// \param[in] value values required for each bit masked in by mask, eg: (1 << RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05)
+ /// \param[in] mask Mask of pins to affect. Use eg: (1 << RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05)
+ extern void bcm2835_gpio_write_mask(uint32_t value, uint32_t mask);
+
+ /// Sets the Pull-up/down mode for the specified pin. This is more convenient than
+ /// clocking the mode in with bcm2835_gpio_pud() and bcm2835_gpio_pudclk().
+ /// \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
+ /// \param[in] pud The desired Pull-up/down mode. One of BCM2835_GPIO_PUD_* from bcm2835PUDControl
+ extern void bcm2835_gpio_set_pud(uint8_t pin, uint8_t pud);
+
+ /// @}
+
+ /// \defgroup spi SPI access
+ /// These functions let you use SPI0 (Serial Peripheral Interface) to
+ /// interface with an external SPI device.
+ /// @{
+
+ /// Start SPI operations.
+ /// Forces RPi SPI0 pins P1-19 (MOSI), P1-21 (MISO), P1-23 (CLK), P1-24 (CE0) and P1-26 (CE1)
+ /// to alternate function ALT0, which enables those pins for SPI interface.
+ /// You should call bcm2835_spi_end() when all SPI funcitons are complete to return the pins to
+ /// their default functions
+ /// \sa bcm2835_spi_end()
+ extern void bcm2835_spi_begin(void);
+
+ /// End SPI operations.
+ /// SPI0 pins P1-19 (MOSI), P1-21 (MISO), P1-23 (CLK), P1-24 (CE0) and P1-26 (CE1)
+ /// are returned to their default INPUT behaviour.
+ extern void bcm2835_spi_end(void);
+
+ /// Sets the SPI bit order
+ /// NOTE: has no effect. Not supported by SPI0.
+ /// Defaults to
+ /// \param[in] order The desired bit order, one of BCM2835_SPI_BIT_ORDER_*,
+ /// see \ref bcm2835SPIBitOrder
+ extern void bcm2835_spi_setBitOrder(uint8_t order);
+
+ /// Sets the SPI clock divider and therefore the
+ /// SPI clock speed.
+ /// \param[in] divider The desired SPI clock divider, one of BCM2835_SPI_CLOCK_DIVIDER_*,
+ /// see \ref bcm2835SPIClockDivider
+ extern void bcm2835_spi_setClockDivider(uint16_t divider);
+
+ /// Sets the SPI data mode
+ /// Sets the clock polariy and phase
+ /// \param[in] mode The desired data mode, one of BCM2835_SPI_MODE*,
+ /// see \ref bcm2835SPIMode
+ extern void bcm2835_spi_setDataMode(uint8_t mode);
+
+ /// Sets the chip select pin(s)
+ /// When an bcm2835_spi_transfer() is made, the selected pin(s) will be asserted during the
+ /// transfer.
+ /// \param[in] cs Specifies the CS pins(s) that are used to activate the desired slave.
+ /// One of BCM2835_SPI_CS*, see \ref bcm2835SPIChipSelect
+ extern void bcm2835_spi_chipSelect(uint8_t cs);
+
+ /// Sets the chip select pin polarity for a given pin
+ /// When an bcm2835_spi_transfer() occurs, the currently selected chip select pin(s)
+ /// will be asserted to the
+ /// value given by active. When transfers are not happening, the chip select pin(s)
+ /// return to the complement (inactive) value.
+ /// \param[in] cs The chip select pin to affect
+ /// \param[in] active Whether the chip select pin is to be active HIGH
+ extern void bcm2835_spi_setChipSelectPolarity(uint8_t cs, uint8_t active);
+
+ /// Transfers one byte to and from the currently selected SPI slave.
+ /// Asserts the currently selected CS pins (as previously set by bcm2835_spi_chipSelect)
+ /// during the transfer.
+ /// Clocks the 8 bit value out on MOSI, and simultaneously clocks in data from MISO.
+ /// Returns the read data byte from the slave.
+ /// Uses polled transfer as per section 10.6.1 of the BCM 2835 ARM Peripherls manual
+ /// \param[in] value The 8 bit data byte to write to MOSI
+ /// \return The 8 bit byte simultaneously read from MISO
+ /// \sa bcm2835_spi_transfern()
+ extern uint8_t bcm2835_spi_transfer(uint8_t value);
+
+ /// Transfers any number of bytes to and from the currently selected SPI slave.
+ /// Asserts the currently selected CS pins (as previously set by bcm2835_spi_chipSelect)
+ /// during the transfer.
+ /// Clocks the len 8 bit bytes out on MOSI, and simultaneously clocks in data from MISO.
+ /// The data read read from the slave is placed into rbuf. rbuf must be at least len bytes long
+ /// Uses polled transfer as per section 10.6.1 of the BCM 2835 ARM Peripherls manual
+ /// \param[in] tbuf Buffer of bytes to send.
+ /// \param[out] rbuf Received bytes will by put in this buffer
+ /// \param[in] len Number of bytes in the tbuf buffer, and the number of bytes to send/received
+ /// \sa bcm2835_spi_transfer()
+ extern void bcm2835_spi_transfernb(char* tbuf, char* rbuf, uint32_t len);
+
+ /// Transfers any number of bytes to and from the currently selected SPI slave
+ /// using bcm2835_spi_transfernb.
+ /// The returned data from the slave replaces the transmitted data in the buffer.
+ /// \param[in,out] buf Buffer of bytes to send. Received bytes will replace the contents
+ /// \param[in] len Number of bytes int eh buffer, and the number of bytes to send/received
+ /// \sa bcm2835_spi_transfer()
+ extern void bcm2835_spi_transfern(char* buf, uint32_t len);
+
+ /// Transfers any number of bytes to the currently selected SPI slave.
+ /// Asserts the currently selected CS pins (as previously set by bcm2835_spi_chipSelect)
+ /// during the transfer.
+ /// \param[in] buf Buffer of bytes to send.
+ /// \param[in] len Number of bytes in the tbuf buffer, and the number of bytes to send
+ extern void bcm2835_spi_writenb(char* buf, uint32_t len);
+
+ /// @}
+
+ /// \defgroup i2c I2C access
+ /// These functions let you use I2C (The Broadcom Serial Control bus with the Philips
+ /// I2C bus/interface version 2.1 January 2000.) to interface with an external I2C device.
+ /// @{
+
+ /// Start I2C operations.
+ /// Forces RPi I2C pins P1-03 (SDA) and P1-05 (SCL)
+ /// to alternate function ALT0, which enables those pins for I2C interface.
+ /// You should call bcm2835_i2c_end() when all I2C functions are complete to return the pins to
+ /// their default functions
+ /// \sa bcm2835_i2c_end()
+ extern void bcm2835_i2c_begin(void);
+
+ /// End I2C operations.
+ /// I2C pins P1-03 (SDA) and P1-05 (SCL)
+ /// are returned to their default INPUT behaviour.
+ extern void bcm2835_i2c_end(void);
+
+ /// Sets the I2C slave address.
+ /// \param[in] addr The I2C slave address.
+ extern void bcm2835_i2c_setSlaveAddress(uint8_t addr);
+
+ /// Sets the I2C clock divider and therefore the I2C clock speed.
+ /// \param[in] divider The desired I2C clock divider, one of BCM2835_I2C_CLOCK_DIVIDER_*,
+ /// see \ref bcm2835I2CClockDivider
+ extern void bcm2835_i2c_setClockDivider(uint16_t divider);
+
+ /// Sets the I2C clock divider by converting the baudrate parameter to
+ /// the equivalent I2C clock divider. ( see \sa bcm2835_i2c_setClockDivider)
+ /// For the I2C standard 100khz you would set baudrate to 100000
+ /// The use of baudrate corresponds to its use in the I2C kernel device
+ /// driver. (Of course, bcm2835 has nothing to do with the kernel driver)
+ extern void bcm2835_i2c_set_baudrate(uint32_t baudrate);
+
+ /// Transfers any number of bytes to the currently selected I2C slave.
+ /// (as previously set by \sa bcm2835_i2c_setSlaveAddress)
+ /// \param[in] buf Buffer of bytes to send.
+ /// \param[in] len Number of bytes in the buf buffer, and the number of bytes to send.
+ /// \return reason see \ref bcm2835I2CReasonCodes
+ extern uint8_t bcm2835_i2c_write(const char * buf, uint32_t len);
+
+ /// Transfers any number of bytes from the currently selected I2C slave.
+ /// (as previously set by \sa bcm2835_i2c_setSlaveAddress)
+ /// \param[in] buf Buffer of bytes to receive.
+ /// \param[in] len Number of bytes in the buf buffer, and the number of bytes to received.
+ /// \return reason see \ref bcm2835I2CReasonCodes
+ extern uint8_t bcm2835_i2c_read(char* buf, uint32_t len);
+
+ /// Allows reading from I2C slaves that require a repeated start (without any prior stop)
+ /// to read after the required slave register has been set. For example, the popular
+ /// MPL3115A2 pressure and temperature sensor. Note that your device must support or
+ /// require this mode. If your device does not require this mode then the standard
+ /// combined:
+ /// \sa bcm2835_i2c_write
+ /// \sa bcm2835_i2c_read
+ /// are a better choice.
+ /// Will read from the slave previously set by \sa bcm2835_i2c_setSlaveAddress
+ /// \param[in] regaddr Buffer containing the slave register you wish to read from.
+ /// \param[in] buf Buffer of bytes to receive.
+ /// \param[in] len Number of bytes in the buf buffer, and the number of bytes to received.
+ /// \return reason see \ref bcm2835I2CReasonCodes
+ extern uint8_t bcm2835_i2c_read_register_rs(char* regaddr, char* buf, uint32_t len);
+
+ /// @}
+
+ /// \defgroup st System Timer access
+ /// Allows access to and delays using the System Timer Counter.
+ /// @{
+
+ /// Read the System Timer Counter register.
+ /// \return the value read from the System Timer Counter Lower 32 bits register
+ uint64_t bcm2835_st_read(void);
+
+ /// Delays for the specified number of microseconds with offset.
+ /// \param[in] offset_micros Offset in microseconds
+ /// \param[in] micros Delay in microseconds
+ extern void bcm2835_st_delay(uint64_t offset_micros, uint64_t micros);
+
+ /// @}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BCM2835_H
+
+/// @example blink.c
+/// Blinks RPi GPIO pin 11 on and off
+
+/// @example input.c
+/// Reads the state of an RPi input pin
+
+/// @example event.c
+/// Shows how to use event detection on an input pin
+
+/// @example spi.c
+/// Shows how to use SPI interface to transfer a byte to and from an SPI device
+
+/// @example spin.c
+/// Shows how to use SPI interface to transfer a number of bytes to and from an SPI device
diff --git a/samples/C++/cuda.cu b/samples/C++/cuda.cu
deleted file mode 100644
index ddef40cd..00000000
--- a/samples/C++/cuda.cu
+++ /dev/null
@@ -1,39 +0,0 @@
-void foo()
-{
- cudaArray* cu_array;
- texture tex;
-
- // Allocate array
- cudaChannelFormatDesc description = cudaCreateChannelDesc();
- cudaMallocArray(&cu_array, &description, width, height);
-
- // Copy image data to array
- cudaMemcpyToArray(cu_array, image, width*height*sizeof(float), cudaMemcpyHostToDevice);
-
- // Set texture parameters (default)
- tex.addressMode[0] = cudaAddressModeClamp;
- tex.addressMode[1] = cudaAddressModeClamp;
- tex.filterMode = cudaFilterModePoint;
- tex.normalized = false; // do not normalize coordinates
-
- // Bind the array to the texture
- cudaBindTextureToArray(tex, cu_array);
-
- // Run kernel
- dim3 blockDim(16, 16, 1);
- dim3 gridDim((width + blockDim.x - 1)/ blockDim.x, (height + blockDim.y - 1) / blockDim.y, 1);
- kernel<<< gridDim, blockDim, 0 >>>(d_data, height, width);
-
- // Unbind the array from the texture
- cudaUnbindTexture(tex);
-} //end foo()
-
-__global__ void kernel(float* odata, int height, int width)
-{
- unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
- unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
- if (x < width && y < height) {
- float c = tex2D(tex, x, y);
- odata[y*width+x] = c;
- }
-}
diff --git a/samples/C++/epoll_reactor.ipp b/samples/C++/epoll_reactor.ipp
new file mode 100644
index 00000000..5d592aff
--- /dev/null
+++ b/samples/C++/epoll_reactor.ipp
@@ -0,0 +1,664 @@
+//
+// detail/impl/epoll_reactor.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_IMPL_EPOLL_REACTOR_IPP
+#define BOOST_ASIO_DETAIL_IMPL_EPOLL_REACTOR_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include
+
+#if defined(BOOST_ASIO_HAS_EPOLL)
+
+#include
+#include
+#include
+#include
+#include
+
+#if defined(BOOST_ASIO_HAS_TIMERFD)
+# include
+#endif // defined(BOOST_ASIO_HAS_TIMERFD)
+
+#include
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+epoll_reactor::epoll_reactor(boost::asio::io_service& io_service)
+ : boost::asio::detail::service_base(io_service),
+ io_service_(use_service(io_service)),
+ mutex_(),
+ interrupter_(),
+ epoll_fd_(do_epoll_create()),
+ timer_fd_(do_timerfd_create()),
+ shutdown_(false)
+{
+ // Add the interrupter's descriptor to epoll.
+ epoll_event ev = { 0, { 0 } };
+ ev.events = EPOLLIN | EPOLLERR | EPOLLET;
+ ev.data.ptr = &interrupter_;
+ epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, interrupter_.read_descriptor(), &ev);
+ interrupter_.interrupt();
+
+ // Add the timer descriptor to epoll.
+ if (timer_fd_ != -1)
+ {
+ ev.events = EPOLLIN | EPOLLERR;
+ ev.data.ptr = &timer_fd_;
+ epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, timer_fd_, &ev);
+ }
+}
+
+epoll_reactor::~epoll_reactor()
+{
+ if (epoll_fd_ != -1)
+ close(epoll_fd_);
+ if (timer_fd_ != -1)
+ close(timer_fd_);
+}
+
+void epoll_reactor::shutdown_service()
+{
+ mutex::scoped_lock lock(mutex_);
+ shutdown_ = true;
+ lock.unlock();
+
+ op_queue ops;
+
+ while (descriptor_state* state = registered_descriptors_.first())
+ {
+ for (int i = 0; i < max_ops; ++i)
+ ops.push(state->op_queue_[i]);
+ state->shutdown_ = true;
+ registered_descriptors_.free(state);
+ }
+
+ timer_queues_.get_all_timers(ops);
+
+ io_service_.abandon_operations(ops);
+}
+
+void epoll_reactor::fork_service(boost::asio::io_service::fork_event fork_ev)
+{
+ if (fork_ev == boost::asio::io_service::fork_child)
+ {
+ if (epoll_fd_ != -1)
+ ::close(epoll_fd_);
+ epoll_fd_ = -1;
+ epoll_fd_ = do_epoll_create();
+
+ if (timer_fd_ != -1)
+ ::close(timer_fd_);
+ timer_fd_ = -1;
+ timer_fd_ = do_timerfd_create();
+
+ interrupter_.recreate();
+
+ // Add the interrupter's descriptor to epoll.
+ epoll_event ev = { 0, { 0 } };
+ ev.events = EPOLLIN | EPOLLERR | EPOLLET;
+ ev.data.ptr = &interrupter_;
+ epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, interrupter_.read_descriptor(), &ev);
+ interrupter_.interrupt();
+
+ // Add the timer descriptor to epoll.
+ if (timer_fd_ != -1)
+ {
+ ev.events = EPOLLIN | EPOLLERR;
+ ev.data.ptr = &timer_fd_;
+ epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, timer_fd_, &ev);
+ }
+
+ update_timeout();
+
+ // Re-register all descriptors with epoll.
+ mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);
+ for (descriptor_state* state = registered_descriptors_.first();
+ state != 0; state = state->next_)
+ {
+ ev.events = state->registered_events_;
+ ev.data.ptr = state;
+ int result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, state->descriptor_, &ev);
+ if (result != 0)
+ {
+ boost::system::error_code ec(errno,
+ boost::asio::error::get_system_category());
+ boost::asio::detail::throw_error(ec, "epoll re-registration");
+ }
+ }
+ }
+}
+
+void epoll_reactor::init_task()
+{
+ io_service_.init_task();
+}
+
+int epoll_reactor::register_descriptor(socket_type descriptor,
+ epoll_reactor::per_descriptor_data& descriptor_data)
+{
+ descriptor_data = allocate_descriptor_state();
+
+ {
+ mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
+
+ descriptor_data->reactor_ = this;
+ descriptor_data->descriptor_ = descriptor;
+ descriptor_data->shutdown_ = false;
+ }
+
+ epoll_event ev = { 0, { 0 } };
+ ev.events = EPOLLIN | EPOLLERR | EPOLLHUP | EPOLLPRI | EPOLLET;
+ descriptor_data->registered_events_ = ev.events;
+ ev.data.ptr = descriptor_data;
+ int result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev);
+ if (result != 0)
+ return errno;
+
+ return 0;
+}
+
+int epoll_reactor::register_internal_descriptor(
+ int op_type, socket_type descriptor,
+ epoll_reactor::per_descriptor_data& descriptor_data, reactor_op* op)
+{
+ descriptor_data = allocate_descriptor_state();
+
+ {
+ mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
+
+ descriptor_data->reactor_ = this;
+ descriptor_data->descriptor_ = descriptor;
+ descriptor_data->shutdown_ = false;
+ descriptor_data->op_queue_[op_type].push(op);
+ }
+
+ epoll_event ev = { 0, { 0 } };
+ ev.events = EPOLLIN | EPOLLERR | EPOLLHUP | EPOLLPRI | EPOLLET;
+ descriptor_data->registered_events_ = ev.events;
+ ev.data.ptr = descriptor_data;
+ int result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev);
+ if (result != 0)
+ return errno;
+
+ return 0;
+}
+
+void epoll_reactor::move_descriptor(socket_type,
+ epoll_reactor::per_descriptor_data& target_descriptor_data,
+ epoll_reactor::per_descriptor_data& source_descriptor_data)
+{
+ target_descriptor_data = source_descriptor_data;
+ source_descriptor_data = 0;
+}
+
+void epoll_reactor::start_op(int op_type, socket_type descriptor,
+ epoll_reactor::per_descriptor_data& descriptor_data, reactor_op* op,
+ bool is_continuation, bool allow_speculative)
+{
+ if (!descriptor_data)
+ {
+ op->ec_ = boost::asio::error::bad_descriptor;
+ post_immediate_completion(op, is_continuation);
+ return;
+ }
+
+ mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
+
+ if (descriptor_data->shutdown_)
+ {
+ post_immediate_completion(op, is_continuation);
+ return;
+ }
+
+ if (descriptor_data->op_queue_[op_type].empty())
+ {
+ if (allow_speculative
+ && (op_type != read_op
+ || descriptor_data->op_queue_[except_op].empty()))
+ {
+ if (op->perform())
+ {
+ descriptor_lock.unlock();
+ io_service_.post_immediate_completion(op, is_continuation);
+ return;
+ }
+
+ if (op_type == write_op)
+ {
+ if ((descriptor_data->registered_events_ & EPOLLOUT) == 0)
+ {
+ epoll_event ev = { 0, { 0 } };
+ ev.events = descriptor_data->registered_events_ | EPOLLOUT;
+ ev.data.ptr = descriptor_data;
+ if (epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev) == 0)
+ {
+ descriptor_data->registered_events_ |= ev.events;
+ }
+ else
+ {
+ op->ec_ = boost::system::error_code(errno,
+ boost::asio::error::get_system_category());
+ io_service_.post_immediate_completion(op, is_continuation);
+ return;
+ }
+ }
+ }
+ }
+ else
+ {
+ if (op_type == write_op)
+ {
+ descriptor_data->registered_events_ |= EPOLLOUT;
+ }
+
+ epoll_event ev = { 0, { 0 } };
+ ev.events = descriptor_data->registered_events_;
+ ev.data.ptr = descriptor_data;
+ epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
+ }
+ }
+
+ descriptor_data->op_queue_[op_type].push(op);
+ io_service_.work_started();
+}
+
+void epoll_reactor::cancel_ops(socket_type,
+ epoll_reactor::per_descriptor_data& descriptor_data)
+{
+ if (!descriptor_data)
+ return;
+
+ mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
+
+ op_queue ops;
+ for (int i = 0; i < max_ops; ++i)
+ {
+ while (reactor_op* op = descriptor_data->op_queue_[i].front())
+ {
+ op->ec_ = boost::asio::error::operation_aborted;
+ descriptor_data->op_queue_[i].pop();
+ ops.push(op);
+ }
+ }
+
+ descriptor_lock.unlock();
+
+ io_service_.post_deferred_completions(ops);
+}
+
+void epoll_reactor::deregister_descriptor(socket_type descriptor,
+ epoll_reactor::per_descriptor_data& descriptor_data, bool closing)
+{
+ if (!descriptor_data)
+ return;
+
+ mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
+
+ if (!descriptor_data->shutdown_)
+ {
+ if (closing)
+ {
+ // The descriptor will be automatically removed from the epoll set when
+ // it is closed.
+ }
+ else
+ {
+ epoll_event ev = { 0, { 0 } };
+ epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, descriptor, &ev);
+ }
+
+ op_queue ops;
+ for (int i = 0; i < max_ops; ++i)
+ {
+ while (reactor_op* op = descriptor_data->op_queue_[i].front())
+ {
+ op->ec_ = boost::asio::error::operation_aborted;
+ descriptor_data->op_queue_[i].pop();
+ ops.push(op);
+ }
+ }
+
+ descriptor_data->descriptor_ = -1;
+ descriptor_data->shutdown_ = true;
+
+ descriptor_lock.unlock();
+
+ free_descriptor_state(descriptor_data);
+ descriptor_data = 0;
+
+ io_service_.post_deferred_completions(ops);
+ }
+}
+
+void epoll_reactor::deregister_internal_descriptor(socket_type descriptor,
+ epoll_reactor::per_descriptor_data& descriptor_data)
+{
+ if (!descriptor_data)
+ return;
+
+ mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
+
+ if (!descriptor_data->shutdown_)
+ {
+ epoll_event ev = { 0, { 0 } };
+ epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, descriptor, &ev);
+
+ op_queue ops;
+ for (int i = 0; i < max_ops; ++i)
+ ops.push(descriptor_data->op_queue_[i]);
+
+ descriptor_data->descriptor_ = -1;
+ descriptor_data->shutdown_ = true;
+
+ descriptor_lock.unlock();
+
+ free_descriptor_state(descriptor_data);
+ descriptor_data = 0;
+ }
+}
+
+void epoll_reactor::run(bool block, op_queue& ops)
+{
+ // This code relies on the fact that the task_io_service queues the reactor
+ // task behind all descriptor operations generated by this function. This
+ // means, that by the time we reach this point, any previously returned
+ // descriptor operations have already been dequeued. Therefore it is now safe
+ // for us to reuse and return them for the task_io_service to queue again.
+
+ // Calculate a timeout only if timerfd is not used.
+ int timeout;
+ if (timer_fd_ != -1)
+ timeout = block ? -1 : 0;
+ else
+ {
+ mutex::scoped_lock lock(mutex_);
+ timeout = block ? get_timeout() : 0;
+ }
+
+ // Block on the epoll descriptor.
+ epoll_event events[128];
+ int num_events = epoll_wait(epoll_fd_, events, 128, timeout);
+
+#if defined(BOOST_ASIO_HAS_TIMERFD)
+ bool check_timers = (timer_fd_ == -1);
+#else // defined(BOOST_ASIO_HAS_TIMERFD)
+ bool check_timers = true;
+#endif // defined(BOOST_ASIO_HAS_TIMERFD)
+
+ // Dispatch the waiting events.
+ for (int i = 0; i < num_events; ++i)
+ {
+ void* ptr = events[i].data.ptr;
+ if (ptr == &interrupter_)
+ {
+ // No need to reset the interrupter since we're leaving the descriptor
+ // in a ready-to-read state and relying on edge-triggered notifications
+ // to make it so that we only get woken up when the descriptor's epoll
+ // registration is updated.
+
+#if defined(BOOST_ASIO_HAS_TIMERFD)
+ if (timer_fd_ == -1)
+ check_timers = true;
+#else // defined(BOOST_ASIO_HAS_TIMERFD)
+ check_timers = true;
+#endif // defined(BOOST_ASIO_HAS_TIMERFD)
+ }
+#if defined(BOOST_ASIO_HAS_TIMERFD)
+ else if (ptr == &timer_fd_)
+ {
+ check_timers = true;
+ }
+#endif // defined(BOOST_ASIO_HAS_TIMERFD)
+ else
+ {
+ // The descriptor operation doesn't count as work in and of itself, so we
+ // don't call work_started() here. This still allows the io_service to
+ // stop if the only remaining operations are descriptor operations.
+ descriptor_state* descriptor_data = static_cast(ptr);
+ descriptor_data->set_ready_events(events[i].events);
+ ops.push(descriptor_data);
+ }
+ }
+
+ if (check_timers)
+ {
+ mutex::scoped_lock common_lock(mutex_);
+ timer_queues_.get_ready_timers(ops);
+
+#if defined(BOOST_ASIO_HAS_TIMERFD)
+ if (timer_fd_ != -1)
+ {
+ itimerspec new_timeout;
+ itimerspec old_timeout;
+ int flags = get_timeout(new_timeout);
+ timerfd_settime(timer_fd_, flags, &new_timeout, &old_timeout);
+ }
+#endif // defined(BOOST_ASIO_HAS_TIMERFD)
+ }
+}
+
+void epoll_reactor::interrupt()
+{
+ epoll_event ev = { 0, { 0 } };
+ ev.events = EPOLLIN | EPOLLERR | EPOLLET;
+ ev.data.ptr = &interrupter_;
+ epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, interrupter_.read_descriptor(), &ev);
+}
+
+int epoll_reactor::do_epoll_create()
+{
+#if defined(EPOLL_CLOEXEC)
+ int fd = epoll_create1(EPOLL_CLOEXEC);
+#else // defined(EPOLL_CLOEXEC)
+ int fd = -1;
+ errno = EINVAL;
+#endif // defined(EPOLL_CLOEXEC)
+
+ if (fd == -1 && (errno == EINVAL || errno == ENOSYS))
+ {
+ fd = epoll_create(epoll_size);
+ if (fd != -1)
+ ::fcntl(fd, F_SETFD, FD_CLOEXEC);
+ }
+
+ if (fd == -1)
+ {
+ boost::system::error_code ec(errno,
+ boost::asio::error::get_system_category());
+ boost::asio::detail::throw_error(ec, "epoll");
+ }
+
+ return fd;
+}
+
+int epoll_reactor::do_timerfd_create()
+{
+#if defined(BOOST_ASIO_HAS_TIMERFD)
+# if defined(TFD_CLOEXEC)
+ int fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
+# else // defined(TFD_CLOEXEC)
+ int fd = -1;
+ errno = EINVAL;
+# endif // defined(TFD_CLOEXEC)
+
+ if (fd == -1 && errno == EINVAL)
+ {
+ fd = timerfd_create(CLOCK_MONOTONIC, 0);
+ if (fd != -1)
+ ::fcntl(fd, F_SETFD, FD_CLOEXEC);
+ }
+
+ return fd;
+#else // defined(BOOST_ASIO_HAS_TIMERFD)
+ return -1;
+#endif // defined(BOOST_ASIO_HAS_TIMERFD)
+}
+
+epoll_reactor::descriptor_state* epoll_reactor::allocate_descriptor_state()
+{
+ mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);
+ return registered_descriptors_.alloc();
+}
+
+void epoll_reactor::free_descriptor_state(epoll_reactor::descriptor_state* s)
+{
+ mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);
+ registered_descriptors_.free(s);
+}
+
+void epoll_reactor::do_add_timer_queue(timer_queue_base& queue)
+{
+ mutex::scoped_lock lock(mutex_);
+ timer_queues_.insert(&queue);
+}
+
+void epoll_reactor::do_remove_timer_queue(timer_queue_base& queue)
+{
+ mutex::scoped_lock lock(mutex_);
+ timer_queues_.erase(&queue);
+}
+
+void epoll_reactor::update_timeout()
+{
+#if defined(BOOST_ASIO_HAS_TIMERFD)
+ if (timer_fd_ != -1)
+ {
+ itimerspec new_timeout;
+ itimerspec old_timeout;
+ int flags = get_timeout(new_timeout);
+ timerfd_settime(timer_fd_, flags, &new_timeout, &old_timeout);
+ return;
+ }
+#endif // defined(BOOST_ASIO_HAS_TIMERFD)
+ interrupt();
+}
+
+int epoll_reactor::get_timeout()
+{
+ // By default we will wait no longer than 5 minutes. This will ensure that
+ // any changes to the system clock are detected after no longer than this.
+ return timer_queues_.wait_duration_msec(5 * 60 * 1000);
+}
+
+#if defined(BOOST_ASIO_HAS_TIMERFD)
+int epoll_reactor::get_timeout(itimerspec& ts)
+{
+ ts.it_interval.tv_sec = 0;
+ ts.it_interval.tv_nsec = 0;
+
+ long usec = timer_queues_.wait_duration_usec(5 * 60 * 1000 * 1000);
+ ts.it_value.tv_sec = usec / 1000000;
+ ts.it_value.tv_nsec = usec ? (usec % 1000000) * 1000 : 1;
+
+ return usec ? 0 : TFD_TIMER_ABSTIME;
+}
+#endif // defined(BOOST_ASIO_HAS_TIMERFD)
+
+struct epoll_reactor::perform_io_cleanup_on_block_exit
+{
+ explicit perform_io_cleanup_on_block_exit(epoll_reactor* r)
+ : reactor_(r), first_op_(0)
+ {
+ }
+
+ ~perform_io_cleanup_on_block_exit()
+ {
+ if (first_op_)
+ {
+ // Post the remaining completed operations for invocation.
+ if (!ops_.empty())
+ reactor_->io_service_.post_deferred_completions(ops_);
+
+ // A user-initiated operation has completed, but there's no need to
+ // explicitly call work_finished() here. Instead, we'll take advantage of
+ // the fact that the task_io_service will call work_finished() once we
+ // return.
+ }
+ else
+ {
+ // No user-initiated operations have completed, so we need to compensate
+ // for the work_finished() call that the task_io_service will make once
+ // this operation returns.
+ reactor_->io_service_.work_started();
+ }
+ }
+
+ epoll_reactor* reactor_;
+ op_queue ops_;
+ operation* first_op_;
+};
+
+epoll_reactor::descriptor_state::descriptor_state()
+ : operation(&epoll_reactor::descriptor_state::do_complete)
+{
+}
+
+operation* epoll_reactor::descriptor_state::perform_io(uint32_t events)
+{
+ mutex_.lock();
+ perform_io_cleanup_on_block_exit io_cleanup(reactor_);
+ mutex::scoped_lock descriptor_lock(mutex_, mutex::scoped_lock::adopt_lock);
+
+ // Exception operations must be processed first to ensure that any
+ // out-of-band data is read before normal data.
+ static const int flag[max_ops] = { EPOLLIN, EPOLLOUT, EPOLLPRI };
+ for (int j = max_ops - 1; j >= 0; --j)
+ {
+ if (events & (flag[j] | EPOLLERR | EPOLLHUP))
+ {
+ while (reactor_op* op = op_queue_[j].front())
+ {
+ if (op->perform())
+ {
+ op_queue_[j].pop();
+ io_cleanup.ops_.push(op);
+ }
+ else
+ break;
+ }
+ }
+ }
+
+ // The first operation will be returned for completion now. The others will
+ // be posted for later by the io_cleanup object's destructor.
+ io_cleanup.first_op_ = io_cleanup.ops_.front();
+ io_cleanup.ops_.pop();
+ return io_cleanup.first_op_;
+}
+
+void epoll_reactor::descriptor_state::do_complete(
+ io_service_impl* owner, operation* base,
+ const boost::system::error_code& ec, std::size_t bytes_transferred)
+{
+ if (owner)
+ {
+ descriptor_state* descriptor_data = static_cast(base);
+ uint32_t events = static_cast(bytes_transferred);
+ if (operation* op = descriptor_data->perform_io(events))
+ {
+ op->complete(*owner, ec, 0);
+ }
+ }
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include
+
+#endif // defined(BOOST_ASIO_HAS_EPOLL)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_EPOLL_REACTOR_IPP
diff --git a/samples/C++/libcanister.h b/samples/C++/libcanister.h
new file mode 100644
index 00000000..b7d82a52
--- /dev/null
+++ b/samples/C++/libcanister.h
@@ -0,0 +1,138 @@
+#ifndef LIBCANIH
+#define LIBCANIH
+#include
+#include
+#include
+#include
+
+#define int64 unsigned long long
+//#define DEBUG
+
+#ifdef DEBUG
+#define dout cout
+#else
+#define dout if (0) cerr
+#endif
+
+using namespace std;
+
+namespace libcanister
+{
+
+ //the canmem object is a generic memory container used commonly
+ //throughout the canister framework to hold memory of uncertain
+ //length which may or may not contain null bytes.
+ class canmem
+ {
+ public:
+ char* data; //the raw memory block
+ int size; //the absolute length of the block
+ canmem(); //creates an unallocated canmem
+ canmem(int allocsize); //creates an allocated, blank canmem of size
+ canmem(char* strdata); //automates the creation of zero-limited canmems
+ ~canmem(); //cleans up the canmem
+ void zeromem(); //overwrites this canmem
+ void fragmem(); //overwrites this canmem with fragment notation
+ void countlen(); //counts length of zero-limited strings and stores it in size
+ void trim(); //removes any nulls from the end of the string
+ static canmem null(); //returns a singleton null canmem
+
+ };
+
+ //contains information about the canister
+ class caninfo
+ {
+ public:
+ canmem path; //physical path
+ canmem internalname; //a name for the canister
+ int numfiles; //the number of files in the canister
+ };
+
+ //necessary for the use of this class as a type in canfile
+ class canister;
+
+ //this object holds the definition of a 'file' within the
+ //canister 'filesystem.'
+ class canfile
+ {
+ public:
+ libcanister::canister* parent; //the canister that holds this file
+ canmem path; //internal path ('filename')
+ canmem data; //the file's decompressed contents
+ int isfrag; //0 = probably not fragment, 1 = definitely a fragment (ignore)
+ int cfid; //'canfile id' -- a unique ID for this file
+ int64 dsize; //ondisk size (compressed form size)
+ int cachestate; //0 = not in memory, 1 = in memory, 2 = in memory and needs flush
+ //-1 = error, check the data for the message
+ void cache(); //pull the file from disk and cache it in memory
+ void cachedump(); //deletes the contents of this file from the memory cache after assuring the on disk copy is up to date
+ void cachedumpfinal(fstream& infile); //same as cachedump, but more efficient during closing procedures
+ void flush(); //updates the on disk copy, but retains the memory cache
+ };
+
+ //the primary class
+ //this defines and controls a single canister
+ class canister
+ {
+ //table of contents
+ //absolutely worthless to the control code in the canister
+ //but quite useful to programs using the API, as they may
+ //desire to enumerate the files in a canister for a user's
+ //use or for their own.
+ //contains a newline-delimited list of files in the container.
+ canfile TOC;
+ public:
+ caninfo info; //the general info about this canister
+
+ //the raw canfiles -- recommended that programs do not modify
+ //these files directly, but not enforced.
+ canfile* files;
+ bool readonly; //if true then no write routines will do anything
+
+ //maximum number of files to have in memory at any given
+ //time, change this to whatever suits your application.
+ int cachemax;
+ int cachecnt; //number of files in the cache (should not be modified)
+
+ //both initialize the canister from a physical location
+ canister (canmem fspath);
+ canister (char* fspath);
+
+ //destroys the canister (after flushing the modded buffers, of course)
+ ~canister();
+
+ //open the fspath
+ //does it exist?
+ // | --- yes --- opening it (return 1)
+ // | --- yes --- file is corrupted, halting (return -1)
+ // | --- no --- making a new one (return 0)
+ int open();
+
+ //close the canister, flush all buffers, clean up
+ int close();
+
+ //deletes the file at path inside this canister
+ int delFile(canmem path);
+
+ //pulls the contents of the file from disk or memory and returns it as a file
+ canfile getFile(canmem path);
+
+ //creates a file if it does not exist, otherwise overwrites
+ //returns whether operation succeeded
+ bool writeFile(canmem path, canmem data);
+ bool writeFile(canfile file);
+
+ //get the 'table of contents', a file containing a newline delimited
+ //list of the file paths in the container which have contents
+ canfile getTOC();
+
+ //brings the cache back within the cachemax limit
+ //important: sCFID is the safe CFID
+ //(the CFID of the file we want to avoid uncaching)
+ //really just used internally, but it can't do any harm.
+ void cacheclean(int sCFID, bool dFlush = false);
+ };
+
+}
+
+#endif
\ No newline at end of file
diff --git a/samples/C++/metrics.h b/samples/C++/metrics.h
new file mode 100644
index 00000000..b6da859d
--- /dev/null
+++ b/samples/C++/metrics.h
@@ -0,0 +1,92 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef NINJA_METRICS_H_
+#define NINJA_METRICS_H_
+
+#include
+#include
+using namespace std;
+
+#include "util.h" // For int64_t.
+
+/// The Metrics module is used for the debug mode that dumps timing stats of
+/// various actions. To use, see METRIC_RECORD below.
+
+/// A single metrics we're tracking, like "depfile load time".
+struct Metric {
+ string name;
+ /// Number of times we've hit the code path.
+ int count;
+ /// Total time (in micros) we've spent on the code path.
+ int64_t sum;
+};
+
+
+/// A scoped object for recording a metric across the body of a function.
+/// Used by the METRIC_RECORD macro.
+struct ScopedMetric {
+ explicit ScopedMetric(Metric* metric);
+ ~ScopedMetric();
+
+private:
+ Metric* metric_;
+ /// Timestamp when the measurement started.
+ /// Value is platform-dependent.
+ int64_t start_;
+};
+
+/// The singleton that stores metrics and prints the report.
+struct Metrics {
+ Metric* NewMetric(const string& name);
+
+ /// Print a summary report to stdout.
+ void Report();
+
+private:
+ vector metrics_;
+};
+
+/// Get the current time as relative to some epoch.
+/// Epoch varies between platforms; only useful for measuring elapsed time.
+int64_t GetTimeMillis();
+
+/// A simple stopwatch which returns the time
+/// in seconds since Restart() was called.
+struct Stopwatch {
+ public:
+ Stopwatch() : started_(0) {}
+
+ /// Seconds since Restart() call.
+ double Elapsed() const {
+ return 1e-6 * static_cast(Now() - started_);
+ }
+
+ void Restart() { started_ = Now(); }
+
+ private:
+ uint64_t started_;
+ uint64_t Now() const;
+};
+
+/// The primary interface to metrics. Use METRIC_RECORD("foobar") at the top
+/// of a function to get timing stats recorded for each call of the function.
+#define METRIC_RECORD(name) \
+ static Metric* metrics_h_metric = \
+ g_metrics ? g_metrics->NewMetric(name) : NULL; \
+ ScopedMetric metrics_h_scoped(metrics_h_metric);
+
+extern Metrics* g_metrics;
+
+#endif // NINJA_METRICS_H_
diff --git a/samples/C++/render_adapter.cpp b/samples/C++/render_adapter.cpp
new file mode 100644
index 00000000..4a18f6f6
--- /dev/null
+++ b/samples/C++/render_adapter.cpp
@@ -0,0 +1,6 @@
+#include
+
+namespace Gui
+{
+
+}
diff --git a/samples/C++/rpc.h b/samples/C++/rpc.h
new file mode 100644
index 00000000..ce810992
--- /dev/null
+++ b/samples/C++/rpc.h
@@ -0,0 +1,26 @@
+// Copyright (C) 2013 Simon Que
+//
+// This file is part of DuinoCube.
+//
+// DuinoCube is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// DuinoCube is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DuinoCube. If not, see .
+
+// DuinoCube remote procedure call functions.
+
+#include
+
+// Initializes RPC system.
+void rpc_init();
+
+// Runs the RPC server loop forever.
+void rpc_server_loop();
diff --git a/samples/C/bootstrap.h b/samples/C/bootstrap.h
new file mode 100644
index 00000000..8c29de82
--- /dev/null
+++ b/samples/C/bootstrap.h
@@ -0,0 +1,102 @@
+#ifndef BOOTSTRAP_H
+#define BOOTSTRAP_H
+
+#include
+#include "cxrs.h"
+
+/* If we're not using GNU C, elide __attribute__ */
+#ifndef __GNUC__
+# define __attribute__(x) /*NOTHING*/
+#endif
+
+typedef struct object object;
+
+object *true;
+object *false;
+object *eof;
+object *empty_list;
+object *global_enviroment;
+
+enum obj_type {
+ scm_bool,
+ scm_empty_list,
+ scm_eof,
+ scm_char,
+ scm_int,
+ scm_pair,
+ scm_symbol,
+ scm_prim_fun,
+ scm_lambda,
+ scm_str,
+ scm_file
+};
+
+typedef object *(*prim_proc)(object *args);
+
+object *read(FILE *in);
+object *eval(object *code, object *env);
+void print(FILE *out, object *obj, int display);
+
+int check_type(enum obj_type type, object *obj, int err_on_false);
+
+static inline int is_true(object *obj)
+{
+ return obj != false;
+}
+
+object *make_int(int value);
+int obj2int(object *i);
+
+object *make_bool(int value);
+int obj2bool(object *b);
+
+object *make_char(char c);
+char obj2char(object *ch);
+
+object *make_str(char *str);
+char *obj2str(object *str);
+
+object *cons(object *car, object *cdr);
+object *car(object *pair);
+object *cdr(object *pair);
+void set_car(object *pair, object *new);
+void set_cdr(object *pair, object *new);
+
+object *make_symbol(char *name);
+char *sym2str(object *sym);
+object *get_symbol(char *name) __attribute__((pure));
+
+object *make_prim_fun(prim_proc fun);
+prim_proc obj2prim_proc(object *proc);
+
+object *make_lambda(object *args, object *code, object *env);
+object *lambda_code(object *lambda);
+object *lambda_args(object *lambda);
+
+object *make_port(FILE *handle, int direction);
+int port_direction(object *port);
+FILE *port_handle(object *port);
+void set_port_handle_to_null(object *port);
+
+/*both of these should never be called*/
+object *apply_proc(object *);
+object *eval_proc(object *);
+
+
+object *maybe_add_begin(object *code);
+
+void init_enviroment(object *env);
+
+
+void eval_err(char *msg, object *code) __attribute__((noreturn));
+
+void define_var(object *var, object *val, object *env);
+void set_var(object *var, object *val, object *env);
+object *get_var(object *var, object *env);
+
+object *cond2nested_if(object *cond);
+object *let2lambda(object *let);
+object *and2nested_if(object *and);
+object *or2nested_if(object *or);
+
+#endif /*include guard*/
diff --git a/samples/C/dynarray.cats b/samples/C/dynarray.cats
new file mode 100644
index 00000000..95ee54ba
--- /dev/null
+++ b/samples/C/dynarray.cats
@@ -0,0 +1,56 @@
+/* ******************************************************************* */
+/* */
+/* Applied Type System */
+/* */
+/* ******************************************************************* */
+
+/*
+** ATS/Postiats - Unleashing the Potential of Types!
+** Copyright (C) 2011-20?? Hongwei Xi, ATS Trustful Software, Inc.
+** All rights reserved
+**
+** ATS is free software; you can redistribute it and/or modify it under
+** the terms of the GNU GENERAL PUBLIC LICENSE (GPL) as published by the
+** Free Software Foundation; either version 3, or (at your option) any
+** later version.
+**
+** ATS is distributed in the hope that it will be useful, but WITHOUT ANY
+** WARRANTY; without even the implied warranty of MERCHANTABILITY or
+** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+** for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with ATS; see the file COPYING. If not, please write to the
+** Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+** 02110-1301, USA.
+*/
+
+/* ****** ****** */
+
+/*
+(* Author: Hongwei Xi *)
+(* Authoremail: hwxi AT cs DOT bu DOT edu *)
+(* Start time: March, 2013 *)
+*/
+
+/* ****** ****** */
+
+#ifndef ATSHOME_LIBATS_DYNARRAY_CATS
+#define ATSHOME_LIBATS_DYNARRAY_CATS
+
+/* ****** ****** */
+
+#include
+
+/* ****** ****** */
+
+#define atslib_dynarray_memcpy memcpy
+#define atslib_dynarray_memmove memmove
+
+/* ****** ****** */
+
+#endif // ifndef ATSHOME_LIBATS_DYNARRAY_CATS
+
+/* ****** ****** */
+
+/* end of [dynarray.cats] */
diff --git a/samples/C/jni_layer.h b/samples/C/jni_layer.h
new file mode 100644
index 00000000..ededf805
--- /dev/null
+++ b/samples/C/jni_layer.h
@@ -0,0 +1,61 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class jni_JniLayer */
+
+#ifndef _Included_jni_JniLayer
+#define _Included_jni_JniLayer
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: jni_JniLayer
+ * Method: jni_layer_initialize
+ * Signature: ([II)J
+ */
+JNIEXPORT jlong JNICALL Java_jni_JniLayer_jni_1layer_1initialize
+ (JNIEnv *, jobject, jintArray, jint, jint);
+
+/*
+ * Class: jni_JniLayer
+ * Method: jni_layer_mainloop
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jni_JniLayer_jni_1layer_1mainloop
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: jni_JniLayer
+ * Method: jni_layer_set_button
+ * Signature: (JII)V
+ */
+JNIEXPORT void JNICALL Java_jni_JniLayer_jni_1layer_1set_1button
+ (JNIEnv *, jobject, jlong, jint, jint);
+
+/*
+ * Class: jni_JniLayer
+ * Method: jni_layer_set_analog
+ * Signature: (JIIF)V
+ */
+JNIEXPORT void JNICALL Java_jni_JniLayer_jni_1layer_1set_1analog
+ (JNIEnv *, jobject, jlong, jint, jint, jfloat);
+
+/*
+ * Class: jni_JniLayer
+ * Method: jni_layer_report_analog_chg
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_jni_JniLayer_jni_1layer_1report_1analog_1chg
+ (JNIEnv *, jobject, jlong, jint);
+
+/*
+ * Class: jni_JniLayer
+ * Method: jni_layer_kill
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jni_JniLayer_jni_1layer_1kill
+ (JNIEnv *, jobject, jlong);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/samples/C/readline.cats b/samples/C/readline.cats
new file mode 100644
index 00000000..3fad326b
--- /dev/null
+++ b/samples/C/readline.cats
@@ -0,0 +1,47 @@
+/*
+** API in ATS for GNU-readline
+*/
+
+/* ****** ****** */
+
+/*
+** Permission to use, copy, modify, and distribute this software for any
+** purpose with or without fee is hereby granted, provided that the above
+** copyright notice and this permission notice appear in all copies.
+**
+** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+** WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+** MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+** ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+** WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+** ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+** OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+/* ****** ****** */
+
+#ifndef READLINE_READLINE_CATS
+#define READLINE_READLINE_CATS
+
+/* ****** ****** */
+
+#include
+
+/* ****** ****** */
+//
+#define \
+atscntrb_readline_rl_library_version() ((char*)rl_library_version)
+//
+#define atscntrb_readline_rl_readline_version() (rl_readline_version)
+//
+/* ****** ****** */
+
+#define atscntrb_readline_readline readline
+
+/* ****** ****** */
+
+#endif // ifndef READLINE_READLINE_CATS
+
+/* ****** ****** */
+
+/* end of [readline.cats] */
diff --git a/samples/C/syscalldefs.h b/samples/C/syscalldefs.h
new file mode 100644
index 00000000..a29c867e
--- /dev/null
+++ b/samples/C/syscalldefs.h
@@ -0,0 +1,5 @@
+static const syscalldef syscalldefs[] = {
+ [SYSCALL_OR_NUM(0, SYS_restart_syscall)] = MAKE_UINT16(0, 1),
+ [SYSCALL_OR_NUM(1, SYS_exit)] = MAKE_UINT16(1, 17),
+ [SYSCALL_OR_NUM(2, SYS_fork)] = MAKE_UINT16(0, 22),
+};
diff --git a/samples/Cirru/array.cirru b/samples/Cirru/array.cirru
new file mode 100644
index 00000000..9375c650
--- /dev/null
+++ b/samples/Cirru/array.cirru
@@ -0,0 +1,12 @@
+
+print $ array
+ int 1
+ string 2
+
+print $ array
+ int 1
+ array
+ int 2
+ string 3
+ array
+ string 4
\ No newline at end of file
diff --git a/samples/Cirru/block.cirru b/samples/Cirru/block.cirru
new file mode 100644
index 00000000..a9bf0c83
--- /dev/null
+++ b/samples/Cirru/block.cirru
@@ -0,0 +1,7 @@
+
+set f $ block (a b c)
+ print a b c
+
+call f (int 1) (int 2) (int 3)
+
+f (int 1) (int 2) (int 3)
\ No newline at end of file
diff --git a/samples/Cirru/bool.cirru b/samples/Cirru/bool.cirru
new file mode 100644
index 00000000..686d132e
--- /dev/null
+++ b/samples/Cirru/bool.cirru
@@ -0,0 +1,7 @@
+
+print $ bool true
+print $ bool false
+print $ bool yes
+print $ bool no
+print $ bool 1
+print $ bool 0
\ No newline at end of file
diff --git a/samples/Cirru/map.cirru b/samples/Cirru/map.cirru
new file mode 100644
index 00000000..5f445668
--- /dev/null
+++ b/samples/Cirru/map.cirru
@@ -0,0 +1,14 @@
+
+print $ map
+ a $ int 5
+ b $ array (int 1) (int 2)
+ c $ map
+ int 1
+ array (int 4)
+
+set m $ map
+ a $ int 1
+
+set m b $ int 2
+
+print m
\ No newline at end of file
diff --git a/samples/Cirru/number.cirru b/samples/Cirru/number.cirru
new file mode 100644
index 00000000..56e0ac7d
--- /dev/null
+++ b/samples/Cirru/number.cirru
@@ -0,0 +1,3 @@
+
+print $ int 1
+print $ float 1.2
\ No newline at end of file
diff --git a/samples/Cirru/require.cirru b/samples/Cirru/require.cirru
new file mode 100644
index 00000000..53283468
--- /dev/null
+++ b/samples/Cirru/require.cirru
@@ -0,0 +1,2 @@
+
+require ./stdio.cr
diff --git a/samples/Cirru/scope.cirru b/samples/Cirru/scope.cirru
new file mode 100644
index 00000000..9a6512c9
--- /dev/null
+++ b/samples/Cirru/scope.cirru
@@ -0,0 +1,23 @@
+
+set a (int 2)
+
+print (self)
+
+set c (child)
+
+under c
+ under parent
+ print a
+
+print $ get c a
+
+set c x (int 3)
+print $ get c x
+
+set just-print $ code
+ print a
+
+print just-print
+
+eval (self) just-print
+eval just-print
\ No newline at end of file
diff --git a/samples/Cirru/stdio.cirru b/samples/Cirru/stdio.cirru
new file mode 100644
index 00000000..ef5400e6
--- /dev/null
+++ b/samples/Cirru/stdio.cirru
@@ -0,0 +1,55 @@
+
+set a $ string 1
+print a
+
+print (string 1)
+
+print nothing
+
+print
+ map
+ a (int 4)
+ b $ map
+ a $ int 5
+ b $ int 6
+ c $ map
+ int 7
+
+print
+ array
+ int 1
+ int 2
+ array
+ int 3
+ int 4
+
+print
+ array
+ int 1
+ map
+ a $ int 2
+ b $ array
+ int 3
+
+print
+ int 1
+ int 2
+
+print $ code
+ set a 1
+ print (get a)
+ print $ array
+ int a
+ array
+ int a
+
+set container (map)
+set container code $ code
+ set a 1
+ print (get a)
+ print $ array
+ int a
+ array
+ int a
+
+print container
\ No newline at end of file
diff --git a/samples/Cirru/string.cirru b/samples/Cirru/string.cirru
new file mode 100644
index 00000000..d4c4331b
--- /dev/null
+++ b/samples/Cirru/string.cirru
@@ -0,0 +1,3 @@
+
+print $ string a
+print $ string "a b"
\ No newline at end of file
diff --git a/samples/Clojure/for.clj b/samples/Clojure/for.clj
new file mode 100644
index 00000000..725f7b2d
--- /dev/null
+++ b/samples/Clojure/for.clj
@@ -0,0 +1,17 @@
+(defn prime? [n]
+ (not-any? zero? (map #(rem n %) (range 2 n))))
+
+(range 3 33 2)
+'(3 5 7 9 11 13 15 17 19 21 23 25 27 29 31)
+
+;; :when continues through the collection even if some have the
+;; condition evaluate to false, like filter
+(for [x (range 3 33 2) :when (prime? x)]
+ x)
+'(3 5 7 11 13 17 19 23 29 31)
+
+;; :while stops at the first collection element that evaluates to
+;; false, like take-while
+(for [x (range 3 33 2) :while (prime? x)]
+ x)
+'(3 5 7)
diff --git a/samples/Clojure/hiccup.hic b/samples/Clojure/hiccup.hic
new file mode 100644
index 00000000..318f03da
--- /dev/null
+++ b/samples/Clojure/hiccup.hic
@@ -0,0 +1,8 @@
+[:html
+ [:head
+ [:meta {:charset "utf-8"}]
+ [:link {:rel "stylesheet" :href "css/bootstrap.min.css"}]
+ [:script {:src "app.js"}]]
+ [:body
+ [:div.nav
+ [:p "Hello world!"]]]]
diff --git a/samples/Clojure/into-array.cljc b/samples/Clojure/into-array.cljc
new file mode 100644
index 00000000..a1c9fa29
--- /dev/null
+++ b/samples/Clojure/into-array.cljc
@@ -0,0 +1,13 @@
+(defn into-array
+ ([aseq]
+ (into-array nil aseq))
+ ([type aseq]
+ (let [n (count aseq)
+ a (make-array n)]
+ (loop [aseq (seq aseq)
+ i 0]
+ (if (< i n)
+ (do
+ (aset a i (first aseq))
+ (recur (next aseq) (inc i)))
+ a)))))
diff --git a/samples/Clojure/protocol.cljs b/samples/Clojure/protocol.cljs
new file mode 100644
index 00000000..5496ac0c
--- /dev/null
+++ b/samples/Clojure/protocol.cljs
@@ -0,0 +1,15 @@
+(defprotocol ISound (sound []))
+
+(deftype Cat []
+ ISound
+ (sound [_] "Meow!"))
+
+(deftype Dog []
+ ISound
+ (sound [_] "Woof!"))
+
+(extend-type default
+ ISound
+ (sound [_] "... silence ..."))
+
+(sound 1) ;; => "... silence ..."
diff --git a/samples/Clojure/rand.cljscm b/samples/Clojure/rand.cljscm
new file mode 100644
index 00000000..ca07579d
--- /dev/null
+++ b/samples/Clojure/rand.cljscm
@@ -0,0 +1,5 @@
+(defn rand
+ "Returns a random floating point number between 0 (inclusive) and
+ n (default 1) (exclusive)."
+ ([] (scm* [n] (random-real)))
+ ([n] (* (rand) n)))
\ No newline at end of file
diff --git a/samples/Clojure/svg.cljx b/samples/Clojure/svg.cljx
new file mode 100644
index 00000000..dd2206d4
--- /dev/null
+++ b/samples/Clojure/svg.cljx
@@ -0,0 +1,20 @@
+^:clj (ns c2.svg
+ (:use [c2.core :only [unify]]
+ [c2.maths :only [Pi Tau radians-per-degree
+ sin cos mean]]))
+
+^:cljs (ns c2.svg
+ (:use [c2.core :only [unify]]
+ [c2.maths :only [Pi Tau radians-per-degree
+ sin cos mean]])
+ (:require [c2.dom :as dom]))
+
+;;Stub for float fn, which does not exist on cljs runtime
+^:cljs (def float identity)
+
+(defn ->xy
+ "Convert coordinates (potentially map of `{:x :y}`) to 2-vector."
+ [coordinates]
+ (cond
+ (and (vector? coordinates) (= 2 (count coordinates))) coordinates
+ (map? coordinates) [(:x coordinates) (:y coordinates)]))
diff --git a/samples/Clojure/unit-test.cl2 b/samples/Clojure/unit-test.cl2
new file mode 100644
index 00000000..bac21586
--- /dev/null
+++ b/samples/Clojure/unit-test.cl2
@@ -0,0 +1,20 @@
+(deftest function-tests
+ (is (= 3
+ (count [1 2 3])))
+ (is (= false
+ (not true)))
+ (is (= true
+ (contains? {:foo 1 :bar 2} :foo)))
+
+ (is (= {"foo" 1, "baz" 3}
+ (select-keys {:foo 1 :bar 2 :baz 3} [:foo :baz])))
+
+ (is (= [1 2 3]
+ (vals {:foo 1 :bar 2 :baz 3})))
+
+ (is (= ["foo" "bar" "baz"]
+ (keys {:foo 1 :bar 2 :baz 3})))
+
+ (is (= [2 4 6]
+ (filter (fn [x] (=== (rem x 2) 0)) [1 2 3 4 5 6]))))
+
diff --git a/samples/Common Lisp/macros-advanced.cl b/samples/Common Lisp/macros-advanced.cl
new file mode 100644
index 00000000..b746d769
--- /dev/null
+++ b/samples/Common Lisp/macros-advanced.cl
@@ -0,0 +1,82 @@
+;; @file macros-advanced.cl
+;;
+;; @breif Advanced macro practices - defining your own macros
+;;
+;; Macro definition skeleton:
+;; (defmacro name (parameter*)
+;; "Optional documentation string"
+;; body-form*)
+;;
+;; Note that backquote expression is most often used in the `body-form`
+;;
+
+; `primep` test a number for prime
+(defun primep (n)
+ "test a number for prime"
+ (if (< n 2) (return-from primep))
+ (do ((i 2 (1+ i)) (p t (not (zerop (mod n i)))))
+ ((> i (sqrt n)) p)
+ (when (not p) (return))))
+; `next-prime` return the next prime bigger than the specified number
+(defun next-prime (n)
+ "return the next prime bigger than the speicified number"
+ (do ((i (1+ n) (1+ i)))
+ ((primep i) i)))
+;
+; The recommended procedures to writting a new macro are as follows:
+; 1. Write a sample call to the macro and the code it should expand into
+(do-primes (p 0 19)
+ (format t "~d " p))
+; Expected expanded codes
+(do ((p (next-prime (- 0 1)) (next-prime p)))
+ ((> p 19))
+ (format t "~d " p))
+; 2. Write code that generate the hardwritten expansion from the arguments in
+; the sample call
+(defmacro do-primes (var-and-range &rest body)
+ (let ((var (first var-and-range))
+ (start (second var-and-range))
+ (end (third var-and-range)))
+ `(do ((,var (next-prime (- ,start 1)) (next-prime ,var)))
+ ((> ,var ,end))
+ ,@body)))
+; 2-1. More concise implementations with the 'parameter list destructuring' and
+; '&body' synonym, it also emits more friendly messages on incorrent input.
+(defmacro do-primes ((var start end) &body body)
+ `(do ((,var (next-prime (- ,start 1)) (next-prime ,var)))
+ ((> ,var ,end))
+ ,@body))
+; 2-2. Test the result of macro expansion with the `macroexpand-1` function
+(macroexpand-1 '(do-primes (p 0 19) (format t "~d " p)))
+; 3. Make sure the macro abstraction does not "leak"
+(defmacro do-primes ((var start end) &body body)
+ (let ((end-value-name (gensym)))
+ `(do ((,var (next-prime (- ,start 1)) (next-prime ,var))
+ (,end-value-name ,end))
+ ((> ,var ,end-value-name))
+ ,@body)))
+; 3-1. Rules to observe to avoid common and possible leaks
+; a. include any subforms in the expansion in positions that will be evaluated
+; in the same order as the subforms appear in the macro call
+; b. make sure subforms are evaluated only once by creating a variable in the
+; expansion to hold the value of evaluating the argument form, and then
+; using that variable anywhere else the value is needed in the expansion
+; c. use `gensym` at macro expansion time to create variable names used in the
+; expansion
+;
+; Appendix I. Macro-writting macros, 'with-gensyms', to guranttee that rule c
+; gets observed.
+; Example usage of `with-gensyms`
+(defmacro do-primes-a ((var start end) &body body)
+ "do-primes implementation with macro-writting macro 'with-gensyms'"
+ (with-gensyms (end-value-name)
+ `(do ((,var (next-prime (- ,start 1)) (next-prime ,var))
+ (,end-value-name ,end))
+ ((> ,var ,end-value-name))
+ ,@body)))
+; Define the macro, note how comma is used to interpolate the value of the loop
+; expression
+(defmacro with-gensyms ((&rest names) &body body)
+ `(let ,(loop for n in names collect `(,n (gensym)))
+ ,@body)
+)
\ No newline at end of file
diff --git a/samples/Common Lisp/motor-inferencia.cl b/samples/Common Lisp/motor-inferencia.cl
new file mode 100644
index 00000000..6a2a97ea
--- /dev/null
+++ b/samples/Common Lisp/motor-inferencia.cl
@@ -0,0 +1,475 @@
+#|
+ESCUELA POLITECNICA SUPERIOR - UNIVERSIDAD AUTONOMA DE MADRID
+INTELIGENCIA ARTIFICIAL
+
+Motor de inferencia
+Basado en parte en "Paradigms of AI Programming: Case Studies
+in Common Lisp", de Peter Norvig, 1992
+|#
+
+
+;;;;;;;;;;;;;;;;;;;;;
+;;;; Global variables
+;;;;;;;;;;;;;;;;;;;;;
+
+
+(defvar *hypothesis-list*)
+(defvar *rule-list*)
+(defvar *fact-list*)
+
+;;;;;;;;;;;;;;;;;;;;;
+;;;; Constants
+;;;;;;;;;;;;;;;;;;;;;
+
+(defconstant +fail+ nil "Indicates unification failure")
+
+(defconstant +no-bindings+ '((nil))
+ "Indicates unification success, with no variables.")
+
+(defconstant *mundo-abierto* nil)
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;; Functions for the user
+;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
+;; Resets *fact-list* to NIL
+(defun erase-facts () (setq *fact-list* nil))
+
+(defun set-hypothesis-list (h) (setq *hypothesis-list* h))
+
+
+;; Returns a list of solutions, each one satisfying all the hypothesis contained
+;; in *hypothesis-list*
+(defun motor-inferencia ()
+ (consulta *hypothesis-list*))
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;
+;;;; Auxiliary functions
+;;;;;;;;;;;;;;;;;;;;;;;;
+
+#|____________________________________________________________________________
+FUNCTION: CONSULTA
+
+COMMENTS:
+CONSULTA receives a list of hypothesis (variable ), and returns
+a list of binding lists (each binding list being a solution).
+
+EXAMPLES:
+hypotheses is:
+((brothers ?x ?y) (neighbours juan ?x)).
+
+That is, we are searching the brothers of the possible neighbors of Juan.
+
+The function can return in this case:
+
+(((?x . sergio) (?y . javier)) ((?x . julian) (?y . mario)) ((?x . julian) (?y . pedro))).
+That is, the neighbors of Juan (Sergio and Julian) have 3 brothers in total(Javier, Mario, Pedro)
+____________________________________________________________________________|#
+
+(defun consulta (hypotheses)
+ (if (null hypotheses) (list +no-bindings+)
+ (mapcan #'(lambda (b)
+ (mapcar #'(lambda (x) (une-bindings-con-bindings b x))
+ (consulta (subst-bindings b (rest hypotheses)))))
+ (find-hypothesis-value (first hypotheses)))))
+
+
+
+#|____________________________________________________________________________
+FUNCTION: FIND-HYPOTHESIS-VALUE
+
+COMMENTS:
+This function manages the query a single query (only one hypothesis) given a binding list.
+It tries (in the following order) to:
+- Answer the query from *fact-list*
+- Answer the query from the rules in *rule-list*
+- Ask the user
+
+The function returns a list of solutions (list of binding lists).
+
+EXAMPLES:
+If hypothesis is (brothers ?x ?y)
+and the function returns:
+(((?x . sergio) (?y . javier)) ((?x . julian) (?y . maria)) ((?x . alberto) (?y . pedro))).
+
+Means that Sergio and Javier and brothers, Julian and Mario are brothers, and Alberto and Pedro are brothers.
+____________________________________________________________________________|#
+
+(defun find-hypothesis-value (hypothesis)
+ (let (rules)
+ (cond
+ ((equality? hypothesis)
+ (value-from-equality hypothesis))
+ ((value-from-facts hypothesis))
+ ((setq good-rules (find-rules hypothesis))
+ (value-from-rules hypothesis good-rules))
+ (t (ask-user hypothesis)))))
+
+
+
+; une-bindings-con-bindings takes two binding lists and returns a binding list
+; Assumes that b1 and b2 are not +fail+
+(defun une-bindings-con-bindings (b1 b2)
+ (cond
+ ((equal b1 +no-bindings+) b2)
+ ((equal b2 +no-bindings+) b1)
+ (T (append b1 b2))))
+
+
+
+#|____________________________________________________________________________
+FUNCTION: VALUE-FROM-FACTS
+
+COMMENTS:
+Returns all the solutions of obtained directly from *fact-list*
+
+EXAMPLES:
+> (setf *fact-list* '((man luis) (man pedro)(woman mart)(man daniel)(woman laura)))
+
+> (value-from-facts '(man ?x))
+returns:
+
+(((?X . LUIS)) ((?X . PEDRO)) ((?X . DANIEL)))
+____________________________________________________________________________|#
+
+(defun value-from-facts (hypothesis)
+ (mapcan #'(lambda(x) (let ((aux (unify hypothesis x)))
+ (when aux (list aux)))) *fact-list*))
+
+
+
+
+#|____________________________________________________________________________
+FUNCTION: FIND-RULES
+
+COMMENTS:
+Returns the rules in *rule-list* whose THENs unify with the term given in
+The variables in the rules that satisfy this requirement are renamed.
+
+EXAMPLES:
+> (setq *rule-list*
+ '((R1 (pertenece ?E (?E . ?_)))
+ (R2 (pertenece ?E (?_ . ?Xs)) :- ((pertenece ?E ?Xs)))))
+
+Then:
+> (FIND-RULES (PERTENECE 1 (2 5)))
+returns:
+((R2 (PERTENECE ?E.1 (?_ . ?XS.2)) :- ((PERTENECE ?E.1 ?XS.2))))
+That is, only the THEN of rule R2 unify with
+
+However,
+> (FIND-RULES (PERTENECE 1 (1 6 7)))
+
+returns:
+((R1 (PERTENECE ?E.6 (?E.6 . ?_)))
+ (R2 (PERTENECE ?E.7 (?_ . ?XS.8)) :- ((PERTENECE ?E.7 ?XS.8))))
+So the THEN of both rules unify with
+____________________________________________________________________________|#
+
+(defun find-rules (hypothesis)
+ (mapcan #'(lambda(b) (let ((renamed-rule (rename-variables b)))
+ (when (in-then? hypothesis renamed-rule)
+ (list renamed-rule)))) *rule-list*))
+
+(defun in-then? (hypothesis rule)
+ (unless (null (rule-then rule))
+ (not (equal +fail+ (unify hypothesis (rule-then rule))))))
+
+
+
+#|____________________________________________________________________________
+FUNCTION: VALUE-FROM-RULES
+
+COMMENTS:
+Returns all the solutions to found using all the rules given in
+the list . Note that a single rule can have multiple solutions.
+____________________________________________________________________________|#
+(defun value-from-rules (hypothesis rules)
+ (mapcan #'(lambda (r) (eval-rule hypothesis r)) rules))
+
+(defun limpia-vinculos (termino bindings)
+ (unify termino (subst-bindings bindings termino)))
+
+
+#|____________________________________________________________________________
+FUNCTION: EVAL-RULE
+
+COMMENTS:
+Returns all the solutions found using the rule given as input argument.
+
+EXAMPLES:
+> (setq *rule-list*
+ '((R1 (pertenece ?E (?E . ?_)))
+ (R2 (pertenece ?E (?_ . ?Xs)) :- ((pertenece ?E ?Xs)))))
+Then:
+> (EVAL-RULE
+ (PERTENECE 1 (1 6 7))
+ (R1 (PERTENECE ?E.42 (?E.42 . ?_))))
+returns:
+(((NIL)))
+That is, the query (PERTENECE 1 (1 6 7)) can be proven from the given rule, and
+no binding in the variables in the query is necessary (in fact, the query has no variables).
+On the other hand:
+> (EVAL-RULE
+ (PERTENECE 1 (7))
+ (R2 (PERTENECE ?E.49 (?_ . ?XS.50)) :- ((PERTENECE ?E.49 ?XS.50))))
+returns:
+NIL
+That is, the query can not be proven from the rule R2.
+____________________________________________________________________________|#
+
+(defun eval-rule (hypothesis rule)
+ (let ((bindings-then
+ (unify (rule-then rule) hypothesis)))
+ (unless (equal +fail+ bindings-then)
+ (if (rule-ifs rule)
+ (mapcar #'(lambda(b) (limpia-vinculos hypothesis (append bindings-then b)))
+ (consulta (subst-bindings bindings-then (rule-ifs rule))))
+ (list (limpia-vinculos hypothesis bindings-then))))))
+
+
+(defun ask-user (hypothesis)
+ (let ((question hypothesis))
+ (cond
+ ((variables-in question) +fail+)
+ ((not-in-fact-list? question) +fail+)
+ (*mundo-abierto*
+ (format t "~%Es cierto el hecho ~S? (T/nil)" question)
+ (cond
+ ((read) (add-fact question) +no-bindings+)
+ (T (add-fact (list 'NOT question)) +fail+)))
+ (T +fail+))))
+
+
+; value-from-equality:
+(defun value-from-equality (hypothesis)
+ (let ((new-bindings (unify (second hypothesis) (third hypothesis))))
+ (if (not (equal +fail+ new-bindings))
+ (list new-bindings))))
+
+
+
+#|____________________________________________________________________________
+FUNCTION: UNIFY
+
+COMMENTS:
+Finds the most general unifier of two input expressions, taking into account the
+bindings specified in the input
+In case the two expressions can unify, the function returns the total bindings necessary
+for that unification. Otherwise, returns +fail+
+
+EXAMPLES:
+> (unify '1 '1)
+((NIL)) ;; which is the constant +no-bindings+
+> (unify 1 '2)
+nil ;; which is the constant +fail+
+> (unify '?x 1)
+((?x . 1))
+> (unify '(1 1) ?x)
+((? x 1 1))
+> (unify '?_ '?x)
+((NIL))
+> (unify '(p ?x 1 2) '(p ?y ?_ ?_))
+((?x . ?y))
+> (unify '(?a . ?_) '(1 2 3))
+((?a . 1))
+> (unify '(?_ ?_) '(1 2))
+((nil))
+> (unify '(?a . ?b) '(1 2 3))
+((?b 2 3) (?a . 1))
+> (unify '(?a . ?b) '(?v . ?d))
+((?b . ?d) (?a . ?v))
+> (unify '(?eval (+ 1 1)) '1)
+nil
+> (unify '(?eval (+ 1 1)) '2)
+(nil))
+____________________________________________________________________________|#
+
+(defun unify (x y &optional (bindings +no-bindings+))
+ "See if x and y match with given bindings. If they do,
+ return a binding list that would make them equal [p 303]."
+ (cond ((eq bindings +fail+) +fail+)
+ ((eql x y) bindings)
+ ((eval? x) (unify-eval x y bindings))
+ ((eval? y) (unify-eval y x bindings))
+ ((variable? x) (unify-var x y bindings))
+ ((variable? y) (unify-var y x bindings))
+ ((and (consp x) (consp y))
+ (unify (rest x) (rest y)
+ (unify (first x) (first y) bindings)))
+ (t +fail+)))
+
+
+;; rename-variables: renombra ?X por ?X.1, ?Y por ?Y.2 etc. salvo ?_ que no se renombra
+(defun rename-variables (x)
+ "Replace all variables in x with new ones. Excepto ?_"
+ (sublis (mapcar #'(lambda (var)
+ (if (anonymous-var? var)
+ (make-binding var var)
+ (make-binding var (new-variable var))))
+ (variables-in x))
+ x))
+
+
+
+;;;; Auxiliary Functions
+
+(defun unify-var (var x bindings)
+ "Unify var with x, using (and maybe extending) bindings [p 303]."
+ (cond ((or (anonymous-var? var)(anonymous-var? x)) bindings)
+ ((get-binding var bindings)
+ (unify (lookup var bindings) x bindings))
+ ((and (variable? x) (get-binding x bindings))
+ (unify var (lookup x bindings) bindings))
+ ((occurs-in? var x bindings)
+ +fail+)
+ (t (extend-bindings var x bindings))))
+
+(defun variable? (x)
+ "Is x a variable (a symbol starting with ?)?"
+ (and (symbolp x) (eql (char (symbol-name x) 0) #\?)))
+
+(defun get-binding (var bindings)
+ "Find a (variable . value) pair in a binding list."
+ (assoc var bindings))
+
+(defun binding-var (binding)
+ "Get the variable part of a single binding."
+ (car binding))
+
+(defun binding-val (binding)
+ "Get the value part of a single binding."
+ (cdr binding))
+
+(defun make-binding (var val) (cons var val))
+
+(defun lookup (var bindings)
+ "Get the value part (for var) from a binding list."
+ (binding-val (get-binding var bindings)))
+
+(defun extend-bindings (var val bindings)
+ "Add a (var . value) pair to a binding list."
+ (append
+ (unless (eq bindings +no-bindings+) bindings)
+ (list (make-binding var val))))
+
+(defun occurs-in? (var x bindings)
+ "Does var occur anywhere inside x?"
+ (cond ((eq var x) t)
+ ((and (variable? x) (get-binding x bindings))
+ (occurs-in? var (lookup x bindings) bindings))
+ ((consp x) (or (occurs-in? var (first x) bindings)
+ (occurs-in? var (rest x) bindings)))
+ (t nil)))
+
+(defun subst-bindings (bindings x)
+ "Substitute the value of variables in bindings into x,
+ taking recursively bound variables into account."
+ (cond ((eq bindings +fail+) +fail+)
+ ((eq bindings +no-bindings+) x)
+ ((and (listp x) (eq '?eval (car x)))
+ (subst-bindings-quote bindings x))
+ ((and (variable? x) (get-binding x bindings))
+ (subst-bindings bindings (lookup x bindings)))
+ ((atom x) x)
+ (t (cons (subst-bindings bindings (car x)) ;; s/reuse-cons/cons
+ (subst-bindings bindings (cdr x))))))
+
+(defun unifier (x y)
+ "Return something that unifies with both x and y (or fail)."
+ (subst-bindings (unify x y) x))
+
+(defun variables-in (exp)
+ "Return a list of all the variables in EXP."
+ (unique-find-anywhere-if #'variable? exp))
+
+(defun unique-find-anywhere-if (predicate tree &optional found-so-far)
+ "Return a list of leaves of tree satisfying predicate,
+ with duplicates removed."
+ (if (atom tree)
+ (if (funcall predicate tree)
+ (pushnew tree found-so-far)
+ found-so-far)
+ (unique-find-anywhere-if
+ predicate
+ (first tree)
+ (unique-find-anywhere-if predicate (rest tree)
+ found-so-far))))
+
+(defun find-anywhere-if (predicate tree)
+ "Does predicate apply to any atom in the tree?"
+ (if (atom tree)
+ (funcall predicate tree)
+ (or (find-anywhere-if predicate (first tree))
+ (find-anywhere-if predicate (rest tree)))))
+
+(defun new-variable (var)
+ "Create a new variable. Assumes user never types variables of form ?X.9"
+ (gentemp (format nil "~S." var)))
+; (gentemp "?") )
+;;;
+
+(defun anonymous-var? (x)
+ (eq x '?_))
+
+(defun subst-bindings-quote (bindings x)
+ "Substitute the value of variables in bindings into x,
+ taking recursively bound variables into account."
+ (cond ((eq bindings +fail+) +fail+)
+ ((eq bindings +no-bindings+) x)
+ ((and (variable? x) (get-binding x bindings))
+ (if (variable? (lookup x bindings))
+ (subst-bindings-quote bindings (lookup x bindings))
+ (subst-bindings-quote bindings (list 'quote (lookup x bindings)))
+ )
+ )
+ ((atom x) x)
+ (t (cons (subst-bindings-quote bindings (car x)) ;; s/reuse-cons/cons
+ (subst-bindings-quote bindings (cdr x))))))
+
+(defun eval? (x)
+ (and (consp x) (eq (first x) '?eval)))
+
+(defun unify-eval (x y bindings)
+ (let ((exp (subst-bindings-quote bindings (second x))))
+ (if (variables-in exp)
+ +fail+
+ (unify (eval exp) y bindings))))
+
+
+
+(defun rule-ifs (rule) (fourth rule))
+(defun rule-then (rule) (second rule))
+
+
+(defun equality? (term)
+ (and (consp term) (eql (first term) '?=)))
+
+
+(defun in-fact-list? (expresion)
+ (some #'(lambda(x) (equal x expresion)) *fact-list*))
+
+(defun not-in-fact-list? (expresion)
+ (if (eq (car expresion) 'NOT)
+ (in-fact-list? (second expresion))
+ (in-fact-list? (list 'NOT expresion))))
+
+
+;; add-fact:
+
+(defun add-fact (fact)
+ (setq *fact-list* (cons fact *fact-list*)))
+
+
+(defun variable? (x)
+ "Is x a variable (a symbol starting with ?) except ?eval and ?="
+ (and (not (equal x '?eval)) (not (equal x '?=))
+ (symbolp x) (eql (char (symbol-name x) 0) #\?)))
+
+
+;; EOF
\ No newline at end of file
diff --git a/samples/Common Lisp/sample.lisp b/samples/Common Lisp/sample.lisp
new file mode 100644
index 00000000..9bef6781
--- /dev/null
+++ b/samples/Common Lisp/sample.lisp
@@ -0,0 +1,21 @@
+;;;; -*- lisp -*-
+
+(in-package :foo)
+
+;;; Header comment.
+(defvar *foo*)
+
+(eval-when (:execute :compile-toplevel :load-toplevel)
+ (defun add (x &optional y &key z)
+ (declare (ignore z))
+ ;; Inline comment.
+ (+ x (or y 1))))
+
+#|
+Multi-line comment.
+|#
+
+(defmacro foo (x &body b)
+ (if x
+ `(1+ ,x) ;After-line comment.
+ 42))
diff --git a/samples/Component Pascal/Example.cp b/samples/Component Pascal/Example.cp
new file mode 100644
index 00000000..5bace2c4
--- /dev/null
+++ b/samples/Component Pascal/Example.cp
@@ -0,0 +1,130 @@
+MODULE ObxControls;
+(**
+ project = "BlackBox"
+ organization = "www.oberon.ch"
+ contributors = "Oberon microsystems"
+ version = "System/Rsrc/About"
+ copyright = "System/Rsrc/About"
+ license = "Docu/BB-License"
+ changes = ""
+ issues = ""
+
+**)
+
+IMPORT Dialog, Ports, Properties, Views;
+
+CONST beginner = 0; advanced = 1; expert = 2; guru = 3; (* user classes *)
+
+TYPE
+ View = POINTER TO RECORD (Views.View)
+ size: INTEGER (* border size in mm *)
+ END;
+
+VAR
+ data*: RECORD
+ class*: INTEGER; (* current user class *)
+ list*: Dialog.List; (* list of currently available sizes, derived from class *)
+ width*: INTEGER (* width of next view to be opened. Derived from
+ class, or entered through a text entry field *)
+ END;
+
+ predef: ARRAY 6 OF INTEGER; (* table of predefined sizes *)
+
+
+PROCEDURE SetList;
+BEGIN
+ IF data.class = beginner THEN
+ data.list.SetLen(1);
+ data.list.SetItem(0, "default")
+ ELSIF data.class = advanced THEN
+ data.list.SetLen(4);
+ data.list.SetItem(0, "default");
+ data.list.SetItem(1, "small");
+ data.list.SetItem(2, "medium");
+ data.list.SetItem(3, "large");
+ ELSE
+ data.list.SetLen(6);
+ data.list.SetItem(0, "default");
+ data.list.SetItem(1, "small");
+ data.list.SetItem(2, "medium");
+ data.list.SetItem(3, "large");
+ data.list.SetItem(4, "tiny");
+ data.list.SetItem(5, "huge");
+ END
+END SetList;
+
+(* View *)
+
+PROCEDURE (v: View) CopyFromSimpleView (source: Views.View);
+BEGIN
+ v.size := source(View).size
+END CopyFromSimpleView;
+
+PROCEDURE (v: View) Restore (f: Views.Frame; l, t, r, b: INTEGER);
+BEGIN (* fill view with a red square of size v.size *)
+ IF v.size = 0 THEN v.size := predef[0] END; (* lazy initialization of size *)
+ f.DrawRect(0, 0, v.size, v.size, Ports.fill, Ports.red)
+END Restore;
+
+PROCEDURE (v: View) HandlePropMsg (VAR msg: Views.PropMessage);
+BEGIN
+ WITH msg: Properties.SizePref DO
+ IF v.size = 0 THEN v.size := predef[0] END; (* lazy initialization of size *)
+ msg.w := v.size; msg.h := v.size (* tell environment about desired width and height *)
+ ELSE (* ignore other messages *)
+ END
+END HandlePropMsg;
+
+(* notifiers *)
+
+PROCEDURE ClassNotify* (op, from, to: INTEGER);
+BEGIN (* react to change in data.class *)
+ IF op = Dialog.changed THEN
+ IF (to = beginner) OR (to = advanced) & (data.list.index > 3) THEN
+ (* if class is reduced, make sure that selection contains legal elements *)
+ data.list.index := 0; data.width := predef[0]; (* modify interactor *)
+ Dialog.Update(data) (* redraw controls where necessary *)
+ END;
+ SetList;
+ Dialog.UpdateList(data.list) (* reconstruct list box contents *)
+ END
+END ClassNotify;
+
+PROCEDURE ListNotify* (op, from, to: INTEGER);
+BEGIN (* reacto to change in data.list (index to was selected) *)
+ IF op = Dialog.changed THEN
+ data.width := predef[to]; (* modify interactor *)
+ Dialog.Update(data) (* redraw controls where necessary *)
+ END
+END ListNotify;
+
+(* guards *)
+
+PROCEDURE ListGuard* (VAR par: Dialog.Par);
+BEGIN (* disable list box for a beginner *)
+ par.disabled := data.class = beginner
+END ListGuard;
+
+PROCEDURE WidthGuard* (VAR par: Dialog.Par);
+BEGIN (* make text entry field read-only if user is not guru *)
+ par.readOnly := data.class # guru
+END WidthGuard;
+
+(* commands *)
+
+PROCEDURE Open*;
+ VAR v: View;
+BEGIN
+ NEW(v); (* create and initialize a new view *)
+ v.size := data.width * Ports.mm; (* define view's size in function of class *)
+ Views.OpenAux(v, "Example") (* open the view in a window *)
+END Open;
+
+BEGIN (* initialization of global variables *)
+ predef[0] := 40; predef[1] := 30; predef[2] := 50; (* predefined sizes *)
+ predef[3] := 70; predef[4] := 20; predef[5] := 100;
+ data.class := beginner; (* default values *)
+ data.list.index := 0;
+ data.width := predef[0];
+ SetList
+END ObxControls.
diff --git a/samples/Component Pascal/Example2.cps b/samples/Component Pascal/Example2.cps
new file mode 100644
index 00000000..4c4b3930
--- /dev/null
+++ b/samples/Component Pascal/Example2.cps
@@ -0,0 +1,71 @@
+MODULE ObxFact;
+(**
+ project = "BlackBox"
+ organization = "www.oberon.ch"
+ contributors = "Oberon microsystems"
+ version = "System/Rsrc/About"
+ copyright = "System/Rsrc/About"
+ license = "Docu/BB-License"
+ changes = ""
+ issues = ""
+
+**)
+
+IMPORT
+ Stores, Models, TextModels, TextControllers, Integers;
+
+PROCEDURE Read(r: TextModels.Reader; VAR x: Integers.Integer);
+ VAR i, len, beg: INTEGER; ch: CHAR; buf: POINTER TO ARRAY OF CHAR;
+BEGIN
+ r.ReadChar(ch);
+ WHILE ~r.eot & (ch <= " ") DO r.ReadChar(ch) END;
+ ASSERT(~r.eot & (((ch >= "0") & (ch <= "9")) OR (ch = "-")));
+ beg := r.Pos() - 1; len := 0;
+ REPEAT INC(len); r.ReadChar(ch) UNTIL r.eot OR (ch < "0") OR (ch > "9");
+ NEW(buf, len + 1);
+ i := 0; r.SetPos(beg);
+ REPEAT r.ReadChar(buf[i]); INC(i) UNTIL i = len;
+ buf[i] := 0X;
+ Integers.ConvertFromString(buf^, x)
+END Read;
+
+PROCEDURE Write(w: TextModels.Writer; x: Integers.Integer);
+ VAR i: INTEGER;
+BEGIN
+ IF Integers.Sign(x) < 0 THEN w.WriteChar("-") END;
+ i := Integers.Digits10Of(x);
+ IF i # 0 THEN
+ REPEAT DEC(i); w.WriteChar(Integers.ThisDigit10(x, i)) UNTIL i = 0
+ ELSE w.WriteChar("0")
+ END
+END Write;
+
+PROCEDURE Compute*;
+ VAR beg, end, i, n: INTEGER; ch: CHAR;
+ s: Stores.Operation;
+ r: TextModels.Reader; w: TextModels.Writer; attr: TextModels.Attributes;
+ c: TextControllers.Controller;
+ x: Integers.Integer;
+BEGIN
+ c := TextControllers.Focus();
+ IF (c # NIL) & c.HasSelection() THEN
+ c.GetSelection(beg, end);
+ r := c.text.NewReader(NIL); r.SetPos(beg); r.ReadChar(ch);
+ WHILE ~r.eot & (beg < end) & (ch <= " ") DO r.ReadChar(ch); INC(beg) END;
+ IF ~r.eot & (beg < end) THEN
+ r.ReadPrev; Read(r, x);
+ end := r.Pos(); r.ReadPrev; attr :=r.attr;
+ IF (Integers.Sign(x) > 0) & (Integers.Compare(x, Integers.Long(MAX(LONGINT))) <= 0) THEN
+ n := SHORT(Integers.Short(x)); i := 2; x := Integers.Long(1);
+ WHILE i <= n DO x := Integers.Product(x, Integers.Long(i)); INC(i) END;
+ Models.BeginScript(c.text, "computation", s);
+ c.text.Delete(beg, end);
+ w := c.text.NewWriter(NIL); w.SetPos(beg); w.SetAttr(attr);
+ Write(w, x);
+ Models.EndScript(c.text, s)
+ END
+ END
+ END
+END Compute;
+
+END ObxFact.
\ No newline at end of file
diff --git a/samples/Creole/creole.creole b/samples/Creole/creole.creole
new file mode 100644
index 00000000..7e3b8bef
--- /dev/null
+++ b/samples/Creole/creole.creole
@@ -0,0 +1,47 @@
+= Creole
+
+Creole is a Creole-to-HTML converter for Creole, the lightweight markup
+language (http://wikicreole.org/). Github uses this converter to render *.creole files.
+
+Project page on github:
+
+* http://github.com/minad/creole
+
+Travis-CI:
+
+* https://travis-ci.org/minad/creole
+
+RDOC:
+
+* http://rdoc.info/projects/minad/creole
+
+== INSTALLATION
+
+{{{
+gem install creole
+}}}
+
+== SYNOPSIS
+
+{{{
+require 'creole'
+html = Creole.creolize('== Creole text')
+}}}
+
+== BUGS
+
+If you found a bug, please report it at the Creole project's tracker
+on GitHub:
+
+http://github.com/minad/creole/issues
+
+== AUTHORS
+
+* Lars Christensen (larsch)
+* Daniel Mendler (minad)
+
+== LICENSE
+
+Creole is Copyright (c) 2008 - 2013 Lars Christensen, Daniel Mendler. It is free software, and
+may be redistributed under the terms specified in the README file of
+the Ruby distribution.
diff --git a/samples/Crystal/const_spec.cr b/samples/Crystal/const_spec.cr
new file mode 100644
index 00000000..3ab20f14
--- /dev/null
+++ b/samples/Crystal/const_spec.cr
@@ -0,0 +1,169 @@
+#!/usr/bin/env bin/crystal --run
+require "../../spec_helper"
+
+describe "Codegen: const" do
+ it "define a constant" do
+ run("A = 1; A").to_i.should eq(1)
+ end
+
+ it "support nested constant" do
+ run("class B; A = 1; end; B::A").to_i.should eq(1)
+ end
+
+ it "support constant inside a def" do
+ run("
+ class Foo
+ A = 1
+
+ def foo
+ A
+ end
+ end
+
+ Foo.new.foo
+ ").to_i.should eq(1)
+ end
+
+ it "finds nearest constant first" do
+ run("
+ A = 1
+
+ class Foo
+ A = 2.5_f32
+
+ def foo
+ A
+ end
+ end
+
+ Foo.new.foo
+ ").to_f32.should eq(2.5)
+ end
+
+ it "allows constants with same name" do
+ run("
+ A = 1
+
+ class Foo
+ A = 2.5_f32
+
+ def foo
+ A
+ end
+ end
+
+ A
+ Foo.new.foo
+ ").to_f32.should eq(2.5)
+ end
+
+ it "constants with expression" do
+ run("
+ A = 1 + 1
+ A
+ ").to_i.should eq(2)
+ end
+
+ it "finds global constant" do
+ run("
+ A = 1
+
+ class Foo
+ def foo
+ A
+ end
+ end
+
+ Foo.new.foo
+ ").to_i.should eq(1)
+ end
+
+ it "define a constant in lib" do
+ run("lib Foo; A = 1; end; Foo::A").to_i.should eq(1)
+ end
+
+ it "invokes block in const" do
+ run("require \"prelude\"; A = [\"1\"].map { |x| x.to_i }; A[0]").to_i.should eq(1)
+ end
+
+ it "declare constants in right order" do
+ run("A = 1 + 1; B = true ? A : 0; B").to_i.should eq(2)
+ end
+
+ it "uses correct types lookup" do
+ run("
+ module A
+ class B
+ def foo
+ 1
+ end
+ end
+
+ C = B.new;
+ end
+
+ def foo
+ A::C.foo
+ end
+
+ foo
+ ").to_i.should eq(1)
+ end
+
+ it "codegens variable assignment in const" do
+ run("
+ class Foo
+ def initialize(@x)
+ end
+
+ def x
+ @x
+ end
+ end
+
+ A = begin
+ f = Foo.new(1)
+ f
+ end
+
+ def foo
+ A.x
+ end
+
+ foo
+ ").to_i.should eq(1)
+ end
+
+ it "declaring var" do
+ run("
+ BAR = begin
+ a = 1
+ while 1 == 2
+ b = 2
+ end
+ a
+ end
+ class Foo
+ def compile
+ BAR
+ end
+ end
+
+ Foo.new.compile
+ ").to_i.should eq(1)
+ end
+
+ it "initialize const that might raise an exception" do
+ run("
+ require \"prelude\"
+ CONST = (raise \"OH NO\" if 1 == 2)
+
+ def doit
+ CONST
+ rescue
+ end
+
+ doit.nil?
+ ").to_b.should be_true
+ end
+end
diff --git a/samples/Crystal/declare_var_spec.cr b/samples/Crystal/declare_var_spec.cr
new file mode 100644
index 00000000..c6a44127
--- /dev/null
+++ b/samples/Crystal/declare_var_spec.cr
@@ -0,0 +1,79 @@
+#!/usr/bin/env bin/crystal --run
+require "../../spec_helper"
+
+describe "Type inference: declare var" do
+ it "types declare var" do
+ assert_type("a :: Int32") { int32 }
+ end
+
+ it "types declare var and reads it" do
+ assert_type("a :: Int32; a") { int32 }
+ end
+
+ it "types declare var and changes its type" do
+ assert_type("a :: Int32; while 1 == 2; a = 'a'; end; a") { union_of(int32, char) }
+ end
+
+ it "declares instance var which appears in initialize" do
+ result = assert_type("
+ class Foo
+ @x :: Int32
+ end
+
+ Foo.new") { types["Foo"] }
+
+ mod = result.program
+
+ foo = mod.types["Foo"] as NonGenericClassType
+ foo.instance_vars["@x"].type.should eq(mod.int32)
+ end
+
+ it "declares instance var of generic class" do
+ result = assert_type("
+ class Foo(T)
+ @x :: T
+ end
+
+ Foo(Int32).new") do
+ foo = types["Foo"] as GenericClassType
+ foo_i32 = foo.instantiate([int32] of Type | ASTNode)
+ foo_i32.lookup_instance_var("@x").type.should eq(int32)
+ foo_i32
+ end
+ end
+
+ it "declares instance var of generic class after reopen" do
+ result = assert_type("
+ class Foo(T)
+ end
+
+ f = Foo(Int32).new
+
+ class Foo(T)
+ @x :: T
+ end
+
+ f") do
+ foo = types["Foo"] as GenericClassType
+ foo_i32 = foo.instantiate([int32] of Type | ASTNode)
+ foo_i32.lookup_instance_var("@x").type.should eq(int32)
+ foo_i32
+ end
+ end
+
+ it "declares an instance variable in initialize" do
+ assert_type("
+ class Foo
+ def initialize
+ @x :: Int32
+ end
+
+ def x
+ @x
+ end
+ end
+
+ Foo.new.x
+ ") { int32 }
+ end
+end
diff --git a/samples/Crystal/transformer.cr b/samples/Crystal/transformer.cr
new file mode 100644
index 00000000..8bb78fbe
--- /dev/null
+++ b/samples/Crystal/transformer.cr
@@ -0,0 +1,515 @@
+module Crystal
+ class ASTNode
+ def transform(transformer)
+ transformer.before_transform self
+ node = transformer.transform self
+ transformer.after_transform self
+ node
+ end
+ end
+
+ class Transformer
+ def before_transform(node)
+ end
+
+ def after_transform(node)
+ end
+
+ def transform(node : Expressions)
+ exps = [] of ASTNode
+ node.expressions.each do |exp|
+ new_exp = exp.transform(self)
+ if new_exp
+ if new_exp.is_a?(Expressions)
+ exps.concat new_exp.expressions
+ else
+ exps << new_exp
+ end
+ end
+ end
+
+ if exps.length == 1
+ exps[0]
+ else
+ node.expressions = exps
+ node
+ end
+ end
+
+ def transform(node : Call)
+ if node_obj = node.obj
+ node.obj = node_obj.transform(self)
+ end
+ transform_many node.args
+
+ if node_block = node.block
+ node.block = node_block.transform(self)
+ end
+
+ if node_block_arg = node.block_arg
+ node.block_arg = node_block_arg.transform(self)
+ end
+
+ node
+ end
+
+ def transform(node : And)
+ node.left = node.left.transform(self)
+ node.right = node.right.transform(self)
+ node
+ end
+
+ def transform(node : Or)
+ node.left = node.left.transform(self)
+ node.right = node.right.transform(self)
+ node
+ end
+
+ def transform(node : StringInterpolation)
+ transform_many node.expressions
+ node
+ end
+
+ def transform(node : ArrayLiteral)
+ transform_many node.elements
+
+ if node_of = node.of
+ node.of = node_of.transform(self)
+ end
+
+ node
+ end
+
+ def transform(node : HashLiteral)
+ transform_many node.keys
+ transform_many node.values
+
+ if of_key = node.of_key
+ node.of_key = of_key.transform(self)
+ end
+
+ if of_value = node.of_value
+ node.of_value = of_value.transform(self)
+ end
+
+ node
+ end
+
+ def transform(node : If)
+ node.cond = node.cond.transform(self)
+ node.then = node.then.transform(self)
+ node.else = node.else.transform(self)
+ node
+ end
+
+ def transform(node : Unless)
+ node.cond = node.cond.transform(self)
+ node.then = node.then.transform(self)
+ node.else = node.else.transform(self)
+ node
+ end
+
+ def transform(node : IfDef)
+ node.cond = node.cond.transform(self)
+ node.then = node.then.transform(self)
+ node.else = node.else.transform(self)
+ node
+ end
+
+ def transform(node : MultiAssign)
+ transform_many node.targets
+ transform_many node.values
+ node
+ end
+
+ def transform(node : SimpleOr)
+ node.left = node.left.transform(self)
+ node.right = node.right.transform(self)
+ node
+ end
+
+ def transform(node : Def)
+ transform_many node.args
+ node.body = node.body.transform(self)
+
+ if receiver = node.receiver
+ node.receiver = receiver.transform(self)
+ end
+
+ if block_arg = node.block_arg
+ node.block_arg = block_arg.transform(self)
+ end
+
+ node
+ end
+
+ def transform(node : Macro)
+ transform_many node.args
+ node.body = node.body.transform(self)
+
+ if receiver = node.receiver
+ node.receiver = receiver.transform(self)
+ end
+
+ if block_arg = node.block_arg
+ node.block_arg = block_arg.transform(self)
+ end
+
+ node
+ end
+
+ def transform(node : PointerOf)
+ node.exp = node.exp.transform(self)
+ node
+ end
+
+ def transform(node : SizeOf)
+ node.exp = node.exp.transform(self)
+ node
+ end
+
+ def transform(node : InstanceSizeOf)
+ node.exp = node.exp.transform(self)
+ node
+ end
+
+ def transform(node : IsA)
+ node.obj = node.obj.transform(self)
+ node.const = node.const.transform(self)
+ node
+ end
+
+ def transform(node : RespondsTo)
+ node.obj = node.obj.transform(self)
+ node
+ end
+
+ def transform(node : Case)
+ node.cond = node.cond.transform(self)
+ transform_many node.whens
+
+ if node_else = node.else
+ node.else = node_else.transform(self)
+ end
+
+ node
+ end
+
+ def transform(node : When)
+ transform_many node.conds
+ node.body = node.body.transform(self)
+ node
+ end
+
+ def transform(node : ImplicitObj)
+ node
+ end
+
+ def transform(node : ClassDef)
+ node.body = node.body.transform(self)
+
+ if superclass = node.superclass
+ node.superclass = superclass.transform(self)
+ end
+
+ node
+ end
+
+ def transform(node : ModuleDef)
+ node.body = node.body.transform(self)
+ node
+ end
+
+ def transform(node : While)
+ node.cond = node.cond.transform(self)
+ node.body = node.body.transform(self)
+ node
+ end
+
+ def transform(node : Generic)
+ node.name = node.name.transform(self)
+ transform_many node.type_vars
+ node
+ end
+
+ def transform(node : ExceptionHandler)
+ node.body = node.body.transform(self)
+ transform_many node.rescues
+
+ if node_ensure = node.ensure
+ node.ensure = node_ensure.transform(self)
+ end
+
+ node
+ end
+
+ def transform(node : Rescue)
+ node.body = node.body.transform(self)
+ transform_many node.types
+ node
+ end
+
+ def transform(node : Union)
+ transform_many node.types
+ node
+ end
+
+ def transform(node : Hierarchy)
+ node.name = node.name.transform(self)
+ node
+ end
+
+ def transform(node : Metaclass)
+ node.name = node.name.transform(self)
+ node
+ end
+
+ def transform(node : Arg)
+ if default_value = node.default_value
+ node.default_value = default_value.transform(self)
+ end
+
+ if restriction = node.restriction
+ node.restriction = restriction.transform(self)
+ end
+
+ node
+ end
+
+ def transform(node : BlockArg)
+ node.fun = node.fun.transform(self)
+ node
+ end
+
+ def transform(node : Fun)
+ transform_many node.inputs
+
+ if output = node.output
+ node.output = output.transform(self)
+ end
+
+ node
+ end
+
+ def transform(node : Block)
+ node.args.map! { |exp| exp.transform(self) as Var }
+ node.body = node.body.transform(self)
+ node
+ end
+
+ def transform(node : FunLiteral)
+ node.def.body = node.def.body.transform(self)
+ node
+ end
+
+ def transform(node : FunPointer)
+ if obj = node.obj
+ node.obj = obj.transform(self)
+ end
+ node
+ end
+
+ def transform(node : Return)
+ transform_many node.exps
+ node
+ end
+
+ def transform(node : Break)
+ transform_many node.exps
+ node
+ end
+
+ def transform(node : Next)
+ transform_many node.exps
+ node
+ end
+
+ def transform(node : Yield)
+ if scope = node.scope
+ node.scope = scope.transform(self)
+ end
+ transform_many node.exps
+ node
+ end
+
+ def transform(node : Include)
+ node.name = node.name.transform(self)
+ node
+ end
+
+ def transform(node : Extend)
+ node.name = node.name.transform(self)
+ node
+ end
+
+ def transform(node : RangeLiteral)
+ node.from = node.from.transform(self)
+ node.to = node.to.transform(self)
+ node
+ end
+
+ def transform(node : Assign)
+ node.target = node.target.transform(self)
+ node.value = node.value.transform(self)
+ node
+ end
+
+ def transform(node : Nop)
+ node
+ end
+
+ def transform(node : NilLiteral)
+ node
+ end
+
+ def transform(node : BoolLiteral)
+ node
+ end
+
+ def transform(node : NumberLiteral)
+ node
+ end
+
+ def transform(node : CharLiteral)
+ node
+ end
+
+ def transform(node : StringLiteral)
+ node
+ end
+
+ def transform(node : SymbolLiteral)
+ node
+ end
+
+ def transform(node : RegexLiteral)
+ node
+ end
+
+ def transform(node : Var)
+ node
+ end
+
+ def transform(node : MetaVar)
+ node
+ end
+
+ def transform(node : InstanceVar)
+ node
+ end
+
+ def transform(node : ClassVar)
+ node
+ end
+
+ def transform(node : Global)
+ node
+ end
+
+ def transform(node : Require)
+ node
+ end
+
+ def transform(node : Path)
+ node
+ end
+
+ def transform(node : Self)
+ node
+ end
+
+ def transform(node : LibDef)
+ node.body = node.body.transform(self)
+ node
+ end
+
+ def transform(node : FunDef)
+ if body = node.body
+ node.body = body.transform(self)
+ end
+ node
+ end
+
+ def transform(node : TypeDef)
+ node
+ end
+
+ def transform(node : StructDef)
+ node
+ end
+
+ def transform(node : UnionDef)
+ node
+ end
+
+ def transform(node : EnumDef)
+ node
+ end
+
+ def transform(node : ExternalVar)
+ node
+ end
+
+ def transform(node : IndirectRead)
+ node.obj = node.obj.transform(self)
+ node
+ end
+
+ def transform(node : IndirectWrite)
+ node.obj = node.obj.transform(self)
+ node.value = node.value.transform(self)
+ node
+ end
+
+ def transform(node : TypeOf)
+ transform_many node.expressions
+ node
+ end
+
+ def transform(node : Primitive)
+ node
+ end
+
+ def transform(node : Not)
+ node
+ end
+
+ def transform(node : TypeFilteredNode)
+ node
+ end
+
+ def transform(node : TupleLiteral)
+ transform_many node.exps
+ node
+ end
+
+ def transform(node : Cast)
+ node.obj = node.obj.transform(self)
+ node.to = node.to.transform(self)
+ node
+ end
+
+ def transform(node : DeclareVar)
+ node.var = node.var.transform(self)
+ node.declared_type = node.declared_type.transform(self)
+ node
+ end
+
+ def transform(node : Alias)
+ node.value = node.value.transform(self)
+ node
+ end
+
+ def transform(node : TupleIndexer)
+ node
+ end
+
+ def transform(node : Attribute)
+ node
+ end
+
+ def transform_many(exps)
+ exps.map! { |exp| exp.transform(self) } if exps
+ end
+ end
+end
diff --git a/samples/Cuda/scalarProd_kernel.cuh b/samples/Cuda/scalarProd_kernel.cuh
new file mode 100644
index 00000000..7622c597
--- /dev/null
+++ b/samples/Cuda/scalarProd_kernel.cuh
@@ -0,0 +1,52 @@
+__global__ void scalarProdGPU(
+ float *d_C,
+ float *d_A,
+ float *d_B,
+ int vectorN,
+ int elementN
+)
+{
+ //Accumulators cache
+ __shared__ float accumResult[ACCUM_N];
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Cycle through every pair of vectors,
+ // taking into account that vector counts can be different
+ // from total number of thread blocks
+ ////////////////////////////////////////////////////////////////////////////
+ for (int vec = blockIdx.x; vec < vectorN; vec += gridDim.x)
+ {
+ int vectorBase = IMUL(elementN, vec);
+ int vectorEnd = vectorBase + elementN;
+
+ ////////////////////////////////////////////////////////////////////////
+ // Each accumulator cycles through vectors with
+ // stride equal to number of total number of accumulators ACCUM_N
+ // At this stage ACCUM_N is only preferred be a multiple of warp size
+ // to meet memory coalescing alignment constraints.
+ ////////////////////////////////////////////////////////////////////////
+ for (int iAccum = threadIdx.x; iAccum < ACCUM_N; iAccum += blockDim.x)
+ {
+ float sum = 0;
+
+ for (int pos = vectorBase + iAccum; pos < vectorEnd; pos += ACCUM_N)
+ sum += d_A[pos] * d_B[pos];
+
+ accumResult[iAccum] = sum;
+ }
+
+ ////////////////////////////////////////////////////////////////////////
+ // Perform tree-like reduction of accumulators' results.
+ // ACCUM_N has to be power of two at this stage
+ ////////////////////////////////////////////////////////////////////////
+ for (int stride = ACCUM_N / 2; stride > 0; stride >>= 1)
+ {
+ __syncthreads();
+
+ for (int iAccum = threadIdx.x; iAccum < stride; iAccum += blockDim.x)
+ accumResult[iAccum] += accumResult[stride + iAccum];
+ }
+
+ if (threadIdx.x == 0) d_C[vec] = accumResult[0];
+ }
+}
\ No newline at end of file
diff --git a/samples/Cuda/vectorAdd.cu b/samples/Cuda/vectorAdd.cu
new file mode 100644
index 00000000..cdc21dff
--- /dev/null
+++ b/samples/Cuda/vectorAdd.cu
@@ -0,0 +1,46 @@
+#include
+#include
+
+/**
+ * CUDA Kernel Device code
+ *
+ * Computes the vector addition of A and B into C. The 3 vectors have the same
+ * number of elements numElements.
+ */
+__global__ void
+vectorAdd(const float *A, const float *B, float *C, int numElements)
+{
+ int i = blockDim.x * blockIdx.x + threadIdx.x;
+
+ if (i < numElements)
+ {
+ C[i] = A[i] + B[i];
+ }
+}
+
+/**
+ * Host main routine
+ */
+int
+main(void)
+{
+ // Error code to check return values for CUDA calls
+ cudaError_t err = cudaSuccess;
+
+ // Launch the Vector Add CUDA Kernel
+ int threadsPerBlock = 256;
+ int blocksPerGrid =(numElements + threadsPerBlock - 1) / threadsPerBlock;
+ vectorAdd<<>>(d_A, d_B, d_C, numElements);
+ err = cudaGetLastError();
+
+ if (err != cudaSuccess)
+ {
+ fprintf(stderr, "Failed to launch vectorAdd kernel (error code %s)!\n", cudaGetErrorString(err));
+ exit(EXIT_FAILURE);
+ }
+
+ // Reset the device and exit
+ err = cudaDeviceReset();
+
+ return 0;
+}
\ No newline at end of file
diff --git a/samples/DM/example.dm b/samples/DM/example.dm
new file mode 100644
index 00000000..b8f1fad4
--- /dev/null
+++ b/samples/DM/example.dm
@@ -0,0 +1,87 @@
+// This is a single line comment.
+/*
+ This is a multi-line comment
+*/
+
+// Pre-processor keywords
+
+#define PI 3.1415
+
+#if PI == 4
+
+#define G 5
+
+#elif PI == 3
+
+#define I 6
+
+#else
+
+#define K 7
+
+#endif
+
+
+var/GlobalCounter = 0
+var/const/CONST_VARIABLE = 2
+var/list/MyList = list("anything", 1, new /datum/entity)
+var/list/EmptyList[99] // creates a list of 99 null entries
+var/list/NullList = null
+
+/*
+ Entity Class
+*/
+
+/datum/entity
+ var/name = "Entity"
+ var/number = 0
+
+/datum/entity/proc/myFunction()
+ world.log << "Entity has called myFunction"
+
+/datum/entity/New()
+ number = GlobalCounter++
+
+/*
+ Unit Class, Extends from Entity
+*/
+
+/datum/entity/unit
+ name = "Unit"
+
+/datum/entity/unit/New()
+ ..() // calls the parent's proc; equal to super() and base() in other languages
+ number = rand(1, 99)
+
+/datum/entity/unit/myFunction()
+ world.log << "Unit has overriden and called myFunction"
+
+// Global Function
+/proc/ReverseList(var/list/input)
+ var/list/output = list()
+ for(var/i = input.len; i >= 1; i--) // IMPORTANT: List Arrays count from 1.
+ output += input[i] // "+= x" is ".Add(x)"
+ return output
+
+// Bitflags
+/proc/DoStuff()
+ var/bitflag = 0
+ bitflag |= 8
+ return bitflag
+
+/proc/DoOtherStuff()
+ var/bitflag = 65535 // 16 bits is the maximum amount
+ bitflag &= ~8
+ return bitflag
+
+// Logic
+/proc/DoNothing()
+ var/pi = PI
+ if(pi == 4)
+ world.log << "PI is 4"
+ else if(pi == CONST_VARIABLE)
+ world.log << "PI is [CONST_VARIABLE]!"
+ else
+ world.log << "PI is approximety [pi]"
+
+#undef PI // Undefine PI
\ No newline at end of file
diff --git a/samples/Dart/point.dart b/samples/Dart/point.dart
index 5bb74b29..ee91239b 100644
--- a/samples/Dart/point.dart
+++ b/samples/Dart/point.dart
@@ -1,15 +1,19 @@
+import 'dart:math' as math;
+
class Point {
+ num x, y;
+
Point(this.x, this.y);
- distanceTo(Point other) {
+
+ num distanceTo(Point other) {
var dx = x - other.x;
var dy = y - other.y;
- return Math.sqrt(dx * dx + dy * dy);
+ return math.sqrt(dx * dx + dy * dy);
}
- var x, y;
}
-main() {
- Point p = new Point(2, 3);
- Point q = new Point(3, 4);
+void main() {
+ var p = new Point(2, 3);
+ var q = new Point(3, 4);
print('distance from p to q = ${p.distanceTo(q)}');
}
diff --git a/samples/Dogescript/example.djs b/samples/Dogescript/example.djs
new file mode 100644
index 00000000..6903cc5a
--- /dev/null
+++ b/samples/Dogescript/example.djs
@@ -0,0 +1,16 @@
+quiet
+ wow
+ such language
+ very syntax
+ github recognized wow
+loud
+
+such language much friendly
+ rly friendly is true
+ plz console.loge with 'such friend, very inclusive'
+ but
+ plz console.loge with 'no love for doge'
+ wow
+wow
+
+module.exports is language
\ No newline at end of file
diff --git a/samples/E/Extends.E b/samples/E/Extends.E
new file mode 100644
index 00000000..002a9105
--- /dev/null
+++ b/samples/E/Extends.E
@@ -0,0 +1,31 @@
+# from
+# http://wiki.erights.org/wiki/Walnut/Ordinary_Programming/Objects_and_Functions
+def makeVehicle(self) {
+ def vehicle {
+ to milesTillEmpty() {
+ return self.milesPerGallon() * self.getFuelRemaining()
+ }
+ }
+ return vehicle
+}
+
+def makeCar() {
+ var fuelRemaining := 20
+ def car extends makeVehicle(car) {
+ to milesPerGallon() {return 19}
+ to getFuelRemaining() {return fuelRemaining}
+ }
+ return car
+}
+
+def makeJet() {
+ var fuelRemaining := 2000
+ def jet extends makeVehicle(jet) {
+ to milesPerGallon() {return 2}
+ to getFuelRemaining() {return fuelRemaining}
+ }
+ return jet
+}
+
+def car := makeCar()
+println(`The car can go ${car.milesTillEmpty()} miles.`)
diff --git a/samples/E/Functions.E b/samples/E/Functions.E
new file mode 100644
index 00000000..086e4f7a
--- /dev/null
+++ b/samples/E/Functions.E
@@ -0,0 +1,21 @@
+# from
+# http://wiki.erights.org/wiki/Walnut/Ordinary_Programming/Objects_and_Functions
+def makeCar(var name) {
+ var x := 0
+ var y := 0
+ def car {
+ to moveTo(newX,newY) {
+ x := newX
+ y := newY
+ }
+ to getX() {return x}
+ to getY() {return y}
+ to setName(newName) {name := newName}
+ to getName() {return name}
+ }
+ return car
+}
+# Now use the makeCar function to make a car, which we will move and print
+def sportsCar := makeCar("Ferrari")
+sportsCar.moveTo(10,20)
+println(`The car ${sportsCar.getName()} is at X location ${sportsCar.getX()}`)
diff --git a/samples/E/Guards.E b/samples/E/Guards.E
new file mode 100644
index 00000000..e3e841ae
--- /dev/null
+++ b/samples/E/Guards.E
@@ -0,0 +1,69 @@
+# from
+# http://wiki.erights.org/wiki/Walnut/Advanced_Topics/Build_your_Own_Guards
+def makeVOCPair(brandName :String) :near {
+
+ var myTempContents := def none {}
+
+ def brand {
+ to __printOn(out :TextWriter) :void {
+ out.print(brandName)
+ }
+ }
+
+ def ProveAuth {
+ to __printOn(out :TextWriter) :void {
+ out.print(`<$brandName prover>`)
+ }
+ to getBrand() :near { return brand }
+ to coerce(specimen, optEjector) :near {
+ def sealedBox {
+ to getBrand() :near { return brand }
+ to offerContent() :void {
+ myTempContents := specimen
+ }
+ }
+ return sealedBox
+ }
+ }
+ def CheckAuth {
+ to __printOn(out :TextWriter) :void {
+ out.print(`<$brandName checker template>`)
+ }
+ to getBrand() :near { return brand }
+ match [`get`, authList :any[]] {
+ def checker {
+ to __printOn(out :TextWriter) :void {
+ out.print(`<$brandName checker>`)
+ }
+ to getBrand() :near { return brand }
+ to coerce(specimenBox, optEjector) :any {
+ myTempContents := null
+ if (specimenBox.__respondsTo("offerContent", 0)) {
+ # XXX Using __respondsTo/2 here is a kludge
+ specimenBox.offerContent()
+ } else {
+ myTempContents := specimenBox
+ }
+ for auth in authList {
+ if (auth == myTempContents) {
+ return auth
+ }
+ }
+ myTempContents := none
+ throw.eject(optEjector,
+ `Unmatched $brandName authorization`)
+ }
+ }
+ }
+ match [`__respondsTo`, [`get`, _]] {
+ true
+ }
+ match [`__respondsTo`, [_, _]] {
+ false
+ }
+ match [`__getAllegedType`, []] {
+ null.__getAllegedType()
+ }
+ }
+ return [ProveAuth, CheckAuth]
+}
diff --git a/samples/E/IO.E b/samples/E/IO.E
new file mode 100644
index 00000000..e96e41ad
--- /dev/null
+++ b/samples/E/IO.E
@@ -0,0 +1,14 @@
+# E sample from
+# http://wiki.erights.org/wiki/Walnut/Ordinary_Programming/InputOutput
+#File objects for hardwired files:
+def file1 :=
+def file2 :=
+
+#Using a variable for a file name:
+def filePath := "c:\\docs\\myFile.txt"
+def file3 := [filePath]
+
+#Using a single character to specify a Windows drive
+def file4 :=
+def file5 :=
+def file6 :=
diff --git a/samples/E/Promises.E b/samples/E/Promises.E
new file mode 100644
index 00000000..ae03c6ec
--- /dev/null
+++ b/samples/E/Promises.E
@@ -0,0 +1,9 @@
+# E snippet from
+# http://wiki.erights.org/wiki/Walnut/Distributed_Computing/Promises
+when (tempVow) -> {
+ #...use tempVow
+} catch prob {
+ #.... report problem
+} finally {
+ #....log event
+}
diff --git a/samples/E/minChat.E b/samples/E/minChat.E
new file mode 100644
index 00000000..b422a71e
--- /dev/null
+++ b/samples/E/minChat.E
@@ -0,0 +1,18 @@
+# from
+# http://wiki.erights.org/wiki/Walnut/Secure_Distributed_Computing/Auditing_minChat
+pragma.syntax("0.9")
+to send(message) {
+ when (friend<-receive(message)) -> {
+ chatUI.showMessage("self", message)
+ } catch prob {chatUI.showMessage("system", "connection lost")}
+}
+to receive(message) {chatUI.showMessage("friend", message)}
+to receiveFriend(friendRcvr) {
+ bind friend := friendRcvr
+ chatUI.showMessage("system", "friend has arrived")
+}
+to save(file) {file.setText(makeURIFromObject(chatController))}
+to load(file) {
+ bind friend := getObjectFromURI(file.getText())
+ friend <- receiveFriend(chatController)
+}
diff --git a/samples/Ecl/sample.ecl b/samples/ECL/sample.ecl
similarity index 100%
rename from samples/Ecl/sample.ecl
rename to samples/ECL/sample.ecl
diff --git a/samples/Eagle/Eagle.brd b/samples/Eagle/Eagle.brd
new file mode 100644
index 00000000..27f3cbdd
--- /dev/null
+++ b/samples/Eagle/Eagle.brd
@@ -0,0 +1,1396 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>Resistors, Capacitors, Inductors</b><p>
+Based on the previous libraries:
+<ul>
+<li>r.lbr
+<li>cap.lbr
+<li>cap-fe.lbr
+<li>captant.lbr
+<li>polcap.lbr
+<li>ipc-smd.lbr
+</ul>
+All SMD packages are defined according to the IPC specifications and CECC<p>
+<author>Created by librarian@cadsoft.de</author><p>
+<p>
+for Electrolyt Capacitors see also :<p>
+www.bccomponents.com <p>
+www.panasonic.com<p>
+www.kemet.com<p>
+http://www.secc.co.jp/pdf/os_e/2004/e_os_all.pdf <b>(SANYO)</b>
+<p>
+for trimmer refence see : <u>www.electrospec-inc.com/cross_references/trimpotcrossref.asp</u><p>
+
+<table border=0 cellspacing=0 cellpadding=0 width="100%" cellpaddding=0>
+<tr valign="top">
+
+<! <td width="10"> </td>
+<td width="90%">
+
+<b><font color="#0000FF" size="4">TRIM-POT CROSS REFERENCE</font></b>
+<P>
+<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2>
+ <TR>
+ <TD COLSPAN=8>
+ <FONT SIZE=3 FACE=ARIAL><B>RECTANGULAR MULTI-TURN</B></FONT>
+ </TD>
+ </TR>
+ <TR>
+ <TD ALIGN=CENTER>
+ <B>
+ <FONT SIZE=3 FACE=ARIAL color="#FF0000">BOURNS</FONT>
+ </B>
+ </TD>
+ <TD ALIGN=CENTER>
+ <B>
+ <FONT SIZE=3 FACE=ARIAL color="#FF0000">BI TECH</FONT>
+ </B>
+ </TD>
+ <TD ALIGN=CENTER>
+ <B>
+ <FONT SIZE=3 FACE=ARIAL color="#FF0000">DALE-VISHAY</FONT>
+ </B>
+ </TD>
+ <TD ALIGN=CENTER>
+ <B>
+ <FONT SIZE=3 FACE=ARIAL color="#FF0000">PHILIPS/MEPCO</FONT>
+ </B>
+ </TD>
+ <TD ALIGN=CENTER>
+ <B>
+ <FONT SIZE=3 FACE=ARIAL color="#FF0000">MURATA</FONT>
+ </B>
+ </TD>
+ <TD ALIGN=CENTER>
+ <B>
+ <FONT SIZE=3 FACE=ARIAL color="#FF0000">PANASONIC</FONT>
+ </B>
+ </TD>
+ <TD ALIGN=CENTER>
+ <B>
+ <FONT SIZE=3 FACE=ARIAL color="#FF0000">SPECTROL</FONT>
+ </B>
+ </TD>
+ <TD ALIGN=CENTER>
+ <B>
+ <FONT SIZE=3 FACE=ARIAL color="#FF0000">MILSPEC</FONT>
+ </B>
+ </TD><TD> </TD>
+ </TR>
+ <TR>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3 >
+ 3005P<BR>
+ 3006P<BR>
+ 3006W<BR>
+ 3006Y<BR>
+ 3009P<BR>
+ 3009W<BR>
+ 3009Y<BR>
+ 3057J<BR>
+ 3057L<BR>
+ 3057P<BR>
+ 3057Y<BR>
+ 3059J<BR>
+ 3059L<BR>
+ 3059P<BR>
+ 3059Y<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ 89P<BR>
+ 89W<BR>
+ 89X<BR>
+ 89PH<BR>
+ 76P<BR>
+ 89XH<BR>
+ 78SLT<BR>
+ 78L ALT<BR>
+ 56P ALT<BR>
+ 78P ALT<BR>
+ T8S<BR>
+ 78L<BR>
+ 56P<BR>
+ 78P<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ T18/784<BR>
+ 783<BR>
+ 781<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ 2199<BR>
+ 1697/1897<BR>
+ 1680/1880<BR>
+ 2187<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ 8035EKP/CT20/RJ-20P<BR>
+ -<BR>
+ RJ-20X<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ 1211L<BR>
+ 8012EKQ ALT<BR>
+ 8012EKR ALT<BR>
+ 1211P<BR>
+ 8012EKJ<BR>
+ 8012EKL<BR>
+ 8012EKQ<BR>
+ 8012EKR<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ 2101P<BR>
+ 2101W<BR>
+ 2101Y<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ 2102L<BR>
+ 2102S<BR>
+ 2102Y<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ EVMCOG<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ 43P<BR>
+ 43W<BR>
+ 43Y<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ 40L<BR>
+ 40P<BR>
+ 40Y<BR>
+ 70Y-T602<BR>
+ 70L<BR>
+ 70P<BR>
+ 70Y<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ RT/RTR12<BR>
+ RT/RTR12<BR>
+ RT/RTR12<BR>
+ -<BR>
+ RJ/RJR12<BR>
+ RJ/RJR12<BR>
+ RJ/RJR12<BR></FONT>
+ </TD>
+ </TR>
+ <TR>
+ <TD COLSPAN=8> 
+ </TD>
+ </TR>
+ <TR>
+ <TD COLSPAN=8>
+ <FONT SIZE=4 FACE=ARIAL><B>SQUARE MULTI-TURN</B></FONT>
+ </TD>
+ </TR>
+ <TR>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>BOURN</B></FONT>
+ </TD>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>BI TECH</B></FONT>
+ </TD>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>DALE-VISHAY</B></FONT>
+ </TD>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>PHILIPS/MEPCO</B></FONT>
+ </TD>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>MURATA</B></FONT>
+ </TD>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>PANASONIC</B></FONT>
+ </TD>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>SPECTROL</B></FONT>
+ </TD>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>MILSPEC</B></FONT>
+ </TD>
+ </TR>
+ <TR>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ 3250L<BR>
+ 3250P<BR>
+ 3250W<BR>
+ 3250X<BR>
+ 3252P<BR>
+ 3252W<BR>
+ 3252X<BR>
+ 3260P<BR>
+ 3260W<BR>
+ 3260X<BR>
+ 3262P<BR>
+ 3262W<BR>
+ 3262X<BR>
+ 3266P<BR>
+ 3266W<BR>
+ 3266X<BR>
+ 3290H<BR>
+ 3290P<BR>
+ 3290W<BR>
+ 3292P<BR>
+ 3292W<BR>
+ 3292X<BR>
+ 3296P<BR>
+ 3296W<BR>
+ 3296X<BR>
+ 3296Y<BR>
+ 3296Z<BR>
+ 3299P<BR>
+ 3299W<BR>
+ 3299X<BR>
+ 3299Y<BR>
+ 3299Z<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ 66P ALT<BR>
+ 66W ALT<BR>
+ 66X ALT<BR>
+ 66P ALT<BR>
+ 66W ALT<BR>
+ 66X ALT<BR>
+ -<BR>
+ 64W ALT<BR>
+ -<BR>
+ 64P ALT<BR>
+ 64W ALT<BR>
+ 64X ALT<BR>
+ 64P<BR>
+ 64W<BR>
+ 64X<BR>
+ 66X ALT<BR>
+ 66P ALT<BR>
+ 66W ALT<BR>
+ 66P<BR>
+ 66W<BR>
+ 66X<BR>
+ 67P<BR>
+ 67W<BR>
+ 67X<BR>
+ 67Y<BR>
+ 67Z<BR>
+ 68P<BR>
+ 68W<BR>
+ 68X<BR>
+ 67Y ALT<BR>
+ 67Z ALT<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ 5050<BR>
+ 5091<BR>
+ 5080<BR>
+ 5087<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ T63YB<BR>
+ T63XB<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ 5887<BR>
+ 5891<BR>
+ 5880<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ T93Z<BR>
+ T93YA<BR>
+ T93XA<BR>
+ T93YB<BR>
+ T93XB<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ 8026EKP<BR>
+ 8026EKW<BR>
+ 8026EKM<BR>
+ 8026EKP<BR>
+ 8026EKB<BR>
+ 8026EKM<BR>
+ 1309X<BR>
+ 1309P<BR>
+ 1309W<BR>
+ 8024EKP<BR>
+ 8024EKW<BR>
+ 8024EKN<BR>
+ RJ-9P/CT9P<BR>
+ RJ-9W<BR>
+ RJ-9X<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ 3103P<BR>
+ 3103Y<BR>
+ 3103Z<BR>
+ 3103P<BR>
+ 3103Y<BR>
+ 3103Z<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ 3105P/3106P<BR>
+ 3105W/3106W<BR>
+ 3105X/3106X<BR>
+ 3105Y/3106Y<BR>
+ 3105Z/3105Z<BR>
+ 3102P<BR>
+ 3102W<BR>
+ 3102X<BR>
+ 3102Y<BR>
+ 3102Z<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ EVMCBG<BR>
+ EVMCCG<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ 55-1-X<BR>
+ 55-4-X<BR>
+ 55-3-X<BR>
+ 55-2-X<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ 50-2-X<BR>
+ 50-4-X<BR>
+ 50-3-X<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ 64P<BR>
+ 64W<BR>
+ 64X<BR>
+ 64Y<BR>
+ 64Z<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ RT/RTR22<BR>
+ RT/RTR22<BR>
+ RT/RTR22<BR>
+ RT/RTR22<BR>
+ RJ/RJR22<BR>
+ RJ/RJR22<BR>
+ RJ/RJR22<BR>
+ RT/RTR26<BR>
+ RT/RTR26<BR>
+ RT/RTR26<BR>
+ RJ/RJR26<BR>
+ RJ/RJR26<BR>
+ RJ/RJR26<BR>
+ RJ/RJR26<BR>
+ RJ/RJR26<BR>
+ RJ/RJR26<BR>
+ RT/RTR24<BR>
+ RT/RTR24<BR>
+ RT/RTR24<BR>
+ RJ/RJR24<BR>
+ RJ/RJR24<BR>
+ RJ/RJR24<BR>
+ RJ/RJR24<BR>
+ RJ/RJR24<BR>
+ RJ/RJR24<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ </TR>
+ <TR>
+ <TD COLSPAN=8> 
+ </TD>
+ </TR>
+ <TR>
+ <TD COLSPAN=8>
+ <FONT SIZE=4 FACE=ARIAL><B>SINGLE TURN</B></FONT>
+ </TD>
+ </TR>
+ <TR>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>BOURN</B></FONT>
+ </TD>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>BI TECH</B></FONT>
+ </TD>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>DALE-VISHAY</B></FONT>
+ </TD>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>PHILIPS/MEPCO</B></FONT>
+ </TD>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>MURATA</B></FONT>
+ </TD>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>PANASONIC</B></FONT>
+ </TD>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>SPECTROL</B></FONT>
+ </TD>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>MILSPEC</B></FONT>
+ </TD>
+ </TR>
+ <TR>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ 3323P<BR>
+ 3323S<BR>
+ 3323W<BR>
+ 3329H<BR>
+ 3329P<BR>
+ 3329W<BR>
+ 3339H<BR>
+ 3339P<BR>
+ 3339W<BR>
+ 3352E<BR>
+ 3352H<BR>
+ 3352K<BR>
+ 3352P<BR>
+ 3352T<BR>
+ 3352V<BR>
+ 3352W<BR>
+ 3362H<BR>
+ 3362M<BR>
+ 3362P<BR>
+ 3362R<BR>
+ 3362S<BR>
+ 3362U<BR>
+ 3362W<BR>
+ 3362X<BR>
+ 3386B<BR>
+ 3386C<BR>
+ 3386F<BR>
+ 3386H<BR>
+ 3386K<BR>
+ 3386M<BR>
+ 3386P<BR>
+ 3386S<BR>
+ 3386W<BR>
+ 3386X<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ 25P<BR>
+ 25S<BR>
+ 25RX<BR>
+ 82P<BR>
+ 82M<BR>
+ 82PA<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ 91E<BR>
+ 91X<BR>
+ 91T<BR>
+ 91B<BR>
+ 91A<BR>
+ 91V<BR>
+ 91W<BR>
+ 25W<BR>
+ 25V<BR>
+ 25P<BR>
+ -<BR>
+ 25S<BR>
+ 25U<BR>
+ 25RX<BR>
+ 25X<BR>
+ 72XW<BR>
+ 72XL<BR>
+ 72PM<BR>
+ 72RX<BR>
+ -<BR>
+ 72PX<BR>
+ 72P<BR>
+ 72RXW<BR>
+ 72RXL<BR>
+ 72X<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ -<BR>
+ -<BR>
+ T7YB<BR>
+ T7YA<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ TXD<BR>
+ TYA<BR>
+ TYP<BR>
+ -<BR>
+ TYD<BR>
+ TX<BR>
+ -<BR>
+ 150SX<BR>
+ 100SX<BR>
+ 102T<BR>
+ 101S<BR>
+ 190T<BR>
+ 150TX<BR>
+ 101<BR>
+ -<BR>
+ -<BR>
+ 101SX<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ ET6P<BR>
+ ET6S<BR>
+ ET6X<BR>
+ RJ-6W/8014EMW<BR>
+ RJ-6P/8014EMP<BR>
+ RJ-6X/8014EMX<BR>
+ TM7W<BR>
+ TM7P<BR>
+ TM7X<BR>
+ -<BR>
+ 8017SMS<BR>
+ -<BR>
+ 8017SMB<BR>
+ 8017SMA<BR>
+ -<BR>
+ -<BR>
+ CT-6W<BR>
+ CT-6H<BR>
+ CT-6P<BR>
+ CT-6R<BR>
+ -<BR>
+ CT-6V<BR>
+ CT-6X<BR>
+ -<BR>
+ -<BR>
+ 8038EKV<BR>
+ -<BR>
+ 8038EKX<BR>
+ -<BR>
+ -<BR>
+ 8038EKP<BR>
+ 8038EKZ<BR>
+ 8038EKW<BR>
+ -<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ -<BR>
+ -<BR>
+ 3321H<BR>
+ 3321P<BR>
+ 3321N<BR>
+ 1102H<BR>
+ 1102P<BR>
+ 1102T<BR>
+ RVA0911V304A<BR>
+ -<BR>
+ RVA0911H413A<BR>
+ RVG0707V100A<BR>
+ RVA0607V(H)306A<BR>
+ RVA1214H213A<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ 3104B<BR>
+ 3104C<BR>
+ 3104F<BR>
+ 3104H<BR>
+ -<BR>
+ 3104M<BR>
+ 3104P<BR>
+ 3104S<BR>
+ 3104W<BR>
+ 3104X<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ EVMQ0G<BR>
+ EVMQIG<BR>
+ EVMQ3G<BR>
+ EVMS0G<BR>
+ EVMQ0G<BR>
+ EVMG0G<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ EVMK4GA00B<BR>
+ EVM30GA00B<BR>
+ EVMK0GA00B<BR>
+ EVM38GA00B<BR>
+ EVMB6<BR>
+ EVLQ0<BR>
+ -<BR>
+ EVMMSG<BR>
+ EVMMBG<BR>
+ EVMMAG<BR>
+ -<BR>
+ -<BR>
+ EVMMCS<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ EVMM1<BR>
+ -<BR>
+ -<BR>
+ EVMM0<BR>
+ -<BR>
+ -<BR>
+ EVMM3<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ -<BR>
+ -<BR>
+ 62-3-1<BR>
+ 62-1-2<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ 67R<BR>
+ -<BR>
+ 67P<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ 67X<BR>
+ 63V<BR>
+ 63S<BR>
+ 63M<BR>
+ -<BR>
+ -<BR>
+ 63H<BR>
+ 63P<BR>
+ -<BR>
+ -<BR>
+ 63X<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ -<BR>
+ -<BR>
+ RJ/RJR50<BR>
+ RJ/RJR50<BR>
+ RJ/RJR50<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ </TR>
+</TABLE>
+<P> <P>
+<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=3>
+ <TR>
+ <TD COLSPAN=7>
+ <FONT color="#0000FF" SIZE=4 FACE=ARIAL><B>SMD TRIM-POT CROSS REFERENCE</B></FONT>
+ <P>
+ <FONT SIZE=4 FACE=ARIAL><B>MULTI-TURN</B></FONT>
+ </TD>
+ </TR>
+ <TR>
+ <TD>
+ <FONT SIZE=3 FACE=ARIAL><B>BOURNS</B></FONT>
+ </TD>
+ <TD>
+ <FONT SIZE=3 FACE=ARIAL><B>BI TECH</B></FONT>
+ </TD>
+ <TD>
+ <FONT SIZE=3 FACE=ARIAL><B>DALE-VISHAY</B></FONT>
+ </TD>
+ <TD>
+ <FONT SIZE=3 FACE=ARIAL><B>PHILIPS/MEPCO</B></FONT>
+ </TD>
+ <TD>
+ <FONT SIZE=3 FACE=ARIAL><B>PANASONIC</B></FONT>
+ </TD>
+ <TD>
+ <FONT SIZE=3 FACE=ARIAL><B>TOCOS</B></FONT>
+ </TD>
+ <TD>
+ <FONT SIZE=3 FACE=ARIAL><B>AUX/KYOCERA</B></FONT>
+ </TD>
+ </TR>
+ <TR>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ 3224G<BR>
+ 3224J<BR>
+ 3224W<BR>
+ 3269P<BR>
+ 3269W<BR>
+ 3269X<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ 44G<BR>
+ 44J<BR>
+ 44W<BR>
+ 84P<BR>
+ 84W<BR>
+ 84X<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ -<BR>
+ -<BR>
+ ST63Z<BR>
+ ST63Y<BR>
+ -<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ -<BR>
+ -<BR>
+ ST5P<BR>
+ ST5W<BR>
+ ST5X<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ </TR>
+ <TR>
+ <TD COLSPAN=7> 
+ </TD>
+ </TR>
+ <TR>
+ <TD COLSPAN=7>
+ <FONT SIZE=4 FACE=ARIAL><B>SINGLE TURN</B></FONT>
+ </TD>
+ </TR>
+ <TR>
+ <TD>
+ <FONT SIZE=3 FACE=ARIAL><B>BOURNS</B></FONT>
+ </TD>
+ <TD>
+ <FONT SIZE=3 FACE=ARIAL><B>BI TECH</B></FONT>
+ </TD>
+ <TD>
+ <FONT SIZE=3 FACE=ARIAL><B>DALE-VISHAY</B></FONT>
+ </TD>
+ <TD>
+ <FONT SIZE=3 FACE=ARIAL><B>PHILIPS/MEPCO</B></FONT>
+ </TD>
+ <TD>
+ <FONT SIZE=3 FACE=ARIAL><B>PANASONIC</B></FONT>
+ </TD>
+ <TD>
+ <FONT SIZE=3 FACE=ARIAL><B>TOCOS</B></FONT>
+ </TD>
+ <TD>
+ <FONT SIZE=3 FACE=ARIAL><B>AUX/KYOCERA</B></FONT>
+ </TD>
+ </TR>
+ <TR>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ 3314G<BR>
+ 3314J<BR>
+ 3364A/B<BR>
+ 3364C/D<BR>
+ 3364W/X<BR>
+ 3313G<BR>
+ 3313J<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ 23B<BR>
+ 23A<BR>
+ 21X<BR>
+ 21W<BR>
+ -<BR>
+ 22B<BR>
+ 22A<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ ST5YL/ST53YL<BR>
+ ST5YJ/5T53YJ<BR>
+ ST-23A<BR>
+ ST-22B<BR>
+ ST-22<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ ST-4B<BR>
+ ST-4A<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ ST-3B<BR>
+ ST-3A<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ EVM-6YS<BR>
+ EVM-1E<BR>
+ EVM-1G<BR>
+ EVM-1D<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ G4B<BR>
+ G4A<BR>
+ TR04-3S1<BR>
+ TRG04-2S1<BR>
+ -<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ -<BR>
+ DVR-43A<BR>
+ CVR-42C<BR>
+ CVR-42A/C<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ </TR>
+</TABLE>
+<P>
+<FONT SIZE=4 FACE=ARIAL><B>ALT = ALTERNATE</B></FONT>
+<P>
+
+ 
+<P>
+</td>
+</tr>
+</table>
+
+
+<b>RESISTOR</b><p>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+<b>Pin Header Connectors</b><p>
+<author>Created by librarian@cadsoft.de</author>
+
+
+<b>PIN HEADER</b>
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>EAGLE Design Rules</b>
+<p>
+Die Standard-Design-Rules sind so gewählt, dass sie für
+die meisten Anwendungen passen. Sollte ihre Platine
+besondere Anforderungen haben, treffen Sie die erforderlichen
+Einstellungen hier und speichern die Design Rules unter
+einem neuen Namen ab.
+<b>EAGLE Design Rules</b>
+<p>
+The default Design Rules have been set to cover
+a wide range of applications. Your particular design
+may have different requirements, so please make the
+necessary adjustments and save your customized
+design rules under a new name.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/Eagle/Eagle.sch b/samples/Eagle/Eagle.sch
new file mode 100644
index 00000000..5a72a868
--- /dev/null
+++ b/samples/Eagle/Eagle.sch
@@ -0,0 +1,3612 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>Frames for Sheet and Layout</b>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>DRAWING_NAME
+>LAST_DATE_TIME
+>SHEET
+Sheet:
+
+
+
+
+
+<b>FRAME</b><p>
+DIN A4, landscape with location and doc. field
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>Resistors, Capacitors, Inductors</b><p>
+Based on the previous libraries:
+<ul>
+<li>r.lbr
+<li>cap.lbr
+<li>cap-fe.lbr
+<li>captant.lbr
+<li>polcap.lbr
+<li>ipc-smd.lbr
+</ul>
+All SMD packages are defined according to the IPC specifications and CECC<p>
+<author>Created by librarian@cadsoft.de</author><p>
+<p>
+for Electrolyt Capacitors see also :<p>
+www.bccomponents.com <p>
+www.panasonic.com<p>
+www.kemet.com<p>
+http://www.secc.co.jp/pdf/os_e/2004/e_os_all.pdf <b>(SANYO)</b>
+<p>
+for trimmer refence see : <u>www.electrospec-inc.com/cross_references/trimpotcrossref.asp</u><p>
+
+<table border=0 cellspacing=0 cellpadding=0 width="100%" cellpaddding=0>
+<tr valign="top">
+
+<! <td width="10"> </td>
+<td width="90%">
+
+<b><font color="#0000FF" size="4">TRIM-POT CROSS REFERENCE</font></b>
+<P>
+<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2>
+ <TR>
+ <TD COLSPAN=8>
+ <FONT SIZE=3 FACE=ARIAL><B>RECTANGULAR MULTI-TURN</B></FONT>
+ </TD>
+ </TR>
+ <TR>
+ <TD ALIGN=CENTER>
+ <B>
+ <FONT SIZE=3 FACE=ARIAL color="#FF0000">BOURNS</FONT>
+ </B>
+ </TD>
+ <TD ALIGN=CENTER>
+ <B>
+ <FONT SIZE=3 FACE=ARIAL color="#FF0000">BI TECH</FONT>
+ </B>
+ </TD>
+ <TD ALIGN=CENTER>
+ <B>
+ <FONT SIZE=3 FACE=ARIAL color="#FF0000">DALE-VISHAY</FONT>
+ </B>
+ </TD>
+ <TD ALIGN=CENTER>
+ <B>
+ <FONT SIZE=3 FACE=ARIAL color="#FF0000">PHILIPS/MEPCO</FONT>
+ </B>
+ </TD>
+ <TD ALIGN=CENTER>
+ <B>
+ <FONT SIZE=3 FACE=ARIAL color="#FF0000">MURATA</FONT>
+ </B>
+ </TD>
+ <TD ALIGN=CENTER>
+ <B>
+ <FONT SIZE=3 FACE=ARIAL color="#FF0000">PANASONIC</FONT>
+ </B>
+ </TD>
+ <TD ALIGN=CENTER>
+ <B>
+ <FONT SIZE=3 FACE=ARIAL color="#FF0000">SPECTROL</FONT>
+ </B>
+ </TD>
+ <TD ALIGN=CENTER>
+ <B>
+ <FONT SIZE=3 FACE=ARIAL color="#FF0000">MILSPEC</FONT>
+ </B>
+ </TD><TD> </TD>
+ </TR>
+ <TR>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3 >
+ 3005P<BR>
+ 3006P<BR>
+ 3006W<BR>
+ 3006Y<BR>
+ 3009P<BR>
+ 3009W<BR>
+ 3009Y<BR>
+ 3057J<BR>
+ 3057L<BR>
+ 3057P<BR>
+ 3057Y<BR>
+ 3059J<BR>
+ 3059L<BR>
+ 3059P<BR>
+ 3059Y<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ 89P<BR>
+ 89W<BR>
+ 89X<BR>
+ 89PH<BR>
+ 76P<BR>
+ 89XH<BR>
+ 78SLT<BR>
+ 78L ALT<BR>
+ 56P ALT<BR>
+ 78P ALT<BR>
+ T8S<BR>
+ 78L<BR>
+ 56P<BR>
+ 78P<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ T18/784<BR>
+ 783<BR>
+ 781<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ 2199<BR>
+ 1697/1897<BR>
+ 1680/1880<BR>
+ 2187<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ 8035EKP/CT20/RJ-20P<BR>
+ -<BR>
+ RJ-20X<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ 1211L<BR>
+ 8012EKQ ALT<BR>
+ 8012EKR ALT<BR>
+ 1211P<BR>
+ 8012EKJ<BR>
+ 8012EKL<BR>
+ 8012EKQ<BR>
+ 8012EKR<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ 2101P<BR>
+ 2101W<BR>
+ 2101Y<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ 2102L<BR>
+ 2102S<BR>
+ 2102Y<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ EVMCOG<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ 43P<BR>
+ 43W<BR>
+ 43Y<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ 40L<BR>
+ 40P<BR>
+ 40Y<BR>
+ 70Y-T602<BR>
+ 70L<BR>
+ 70P<BR>
+ 70Y<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ RT/RTR12<BR>
+ RT/RTR12<BR>
+ RT/RTR12<BR>
+ -<BR>
+ RJ/RJR12<BR>
+ RJ/RJR12<BR>
+ RJ/RJR12<BR></FONT>
+ </TD>
+ </TR>
+ <TR>
+ <TD COLSPAN=8> 
+ </TD>
+ </TR>
+ <TR>
+ <TD COLSPAN=8>
+ <FONT SIZE=4 FACE=ARIAL><B>SQUARE MULTI-TURN</B></FONT>
+ </TD>
+ </TR>
+ <TR>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>BOURN</B></FONT>
+ </TD>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>BI TECH</B></FONT>
+ </TD>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>DALE-VISHAY</B></FONT>
+ </TD>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>PHILIPS/MEPCO</B></FONT>
+ </TD>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>MURATA</B></FONT>
+ </TD>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>PANASONIC</B></FONT>
+ </TD>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>SPECTROL</B></FONT>
+ </TD>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>MILSPEC</B></FONT>
+ </TD>
+ </TR>
+ <TR>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ 3250L<BR>
+ 3250P<BR>
+ 3250W<BR>
+ 3250X<BR>
+ 3252P<BR>
+ 3252W<BR>
+ 3252X<BR>
+ 3260P<BR>
+ 3260W<BR>
+ 3260X<BR>
+ 3262P<BR>
+ 3262W<BR>
+ 3262X<BR>
+ 3266P<BR>
+ 3266W<BR>
+ 3266X<BR>
+ 3290H<BR>
+ 3290P<BR>
+ 3290W<BR>
+ 3292P<BR>
+ 3292W<BR>
+ 3292X<BR>
+ 3296P<BR>
+ 3296W<BR>
+ 3296X<BR>
+ 3296Y<BR>
+ 3296Z<BR>
+ 3299P<BR>
+ 3299W<BR>
+ 3299X<BR>
+ 3299Y<BR>
+ 3299Z<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ 66P ALT<BR>
+ 66W ALT<BR>
+ 66X ALT<BR>
+ 66P ALT<BR>
+ 66W ALT<BR>
+ 66X ALT<BR>
+ -<BR>
+ 64W ALT<BR>
+ -<BR>
+ 64P ALT<BR>
+ 64W ALT<BR>
+ 64X ALT<BR>
+ 64P<BR>
+ 64W<BR>
+ 64X<BR>
+ 66X ALT<BR>
+ 66P ALT<BR>
+ 66W ALT<BR>
+ 66P<BR>
+ 66W<BR>
+ 66X<BR>
+ 67P<BR>
+ 67W<BR>
+ 67X<BR>
+ 67Y<BR>
+ 67Z<BR>
+ 68P<BR>
+ 68W<BR>
+ 68X<BR>
+ 67Y ALT<BR>
+ 67Z ALT<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ 5050<BR>
+ 5091<BR>
+ 5080<BR>
+ 5087<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ T63YB<BR>
+ T63XB<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ 5887<BR>
+ 5891<BR>
+ 5880<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ T93Z<BR>
+ T93YA<BR>
+ T93XA<BR>
+ T93YB<BR>
+ T93XB<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ 8026EKP<BR>
+ 8026EKW<BR>
+ 8026EKM<BR>
+ 8026EKP<BR>
+ 8026EKB<BR>
+ 8026EKM<BR>
+ 1309X<BR>
+ 1309P<BR>
+ 1309W<BR>
+ 8024EKP<BR>
+ 8024EKW<BR>
+ 8024EKN<BR>
+ RJ-9P/CT9P<BR>
+ RJ-9W<BR>
+ RJ-9X<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ 3103P<BR>
+ 3103Y<BR>
+ 3103Z<BR>
+ 3103P<BR>
+ 3103Y<BR>
+ 3103Z<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ 3105P/3106P<BR>
+ 3105W/3106W<BR>
+ 3105X/3106X<BR>
+ 3105Y/3106Y<BR>
+ 3105Z/3105Z<BR>
+ 3102P<BR>
+ 3102W<BR>
+ 3102X<BR>
+ 3102Y<BR>
+ 3102Z<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ EVMCBG<BR>
+ EVMCCG<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ 55-1-X<BR>
+ 55-4-X<BR>
+ 55-3-X<BR>
+ 55-2-X<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ 50-2-X<BR>
+ 50-4-X<BR>
+ 50-3-X<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ 64P<BR>
+ 64W<BR>
+ 64X<BR>
+ 64Y<BR>
+ 64Z<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ RT/RTR22<BR>
+ RT/RTR22<BR>
+ RT/RTR22<BR>
+ RT/RTR22<BR>
+ RJ/RJR22<BR>
+ RJ/RJR22<BR>
+ RJ/RJR22<BR>
+ RT/RTR26<BR>
+ RT/RTR26<BR>
+ RT/RTR26<BR>
+ RJ/RJR26<BR>
+ RJ/RJR26<BR>
+ RJ/RJR26<BR>
+ RJ/RJR26<BR>
+ RJ/RJR26<BR>
+ RJ/RJR26<BR>
+ RT/RTR24<BR>
+ RT/RTR24<BR>
+ RT/RTR24<BR>
+ RJ/RJR24<BR>
+ RJ/RJR24<BR>
+ RJ/RJR24<BR>
+ RJ/RJR24<BR>
+ RJ/RJR24<BR>
+ RJ/RJR24<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ </TR>
+ <TR>
+ <TD COLSPAN=8> 
+ </TD>
+ </TR>
+ <TR>
+ <TD COLSPAN=8>
+ <FONT SIZE=4 FACE=ARIAL><B>SINGLE TURN</B></FONT>
+ </TD>
+ </TR>
+ <TR>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>BOURN</B></FONT>
+ </TD>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>BI TECH</B></FONT>
+ </TD>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>DALE-VISHAY</B></FONT>
+ </TD>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>PHILIPS/MEPCO</B></FONT>
+ </TD>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>MURATA</B></FONT>
+ </TD>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>PANASONIC</B></FONT>
+ </TD>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>SPECTROL</B></FONT>
+ </TD>
+ <TD ALIGN=CENTER>
+ <FONT SIZE=3 FACE=ARIAL><B>MILSPEC</B></FONT>
+ </TD>
+ </TR>
+ <TR>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ 3323P<BR>
+ 3323S<BR>
+ 3323W<BR>
+ 3329H<BR>
+ 3329P<BR>
+ 3329W<BR>
+ 3339H<BR>
+ 3339P<BR>
+ 3339W<BR>
+ 3352E<BR>
+ 3352H<BR>
+ 3352K<BR>
+ 3352P<BR>
+ 3352T<BR>
+ 3352V<BR>
+ 3352W<BR>
+ 3362H<BR>
+ 3362M<BR>
+ 3362P<BR>
+ 3362R<BR>
+ 3362S<BR>
+ 3362U<BR>
+ 3362W<BR>
+ 3362X<BR>
+ 3386B<BR>
+ 3386C<BR>
+ 3386F<BR>
+ 3386H<BR>
+ 3386K<BR>
+ 3386M<BR>
+ 3386P<BR>
+ 3386S<BR>
+ 3386W<BR>
+ 3386X<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ 25P<BR>
+ 25S<BR>
+ 25RX<BR>
+ 82P<BR>
+ 82M<BR>
+ 82PA<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ 91E<BR>
+ 91X<BR>
+ 91T<BR>
+ 91B<BR>
+ 91A<BR>
+ 91V<BR>
+ 91W<BR>
+ 25W<BR>
+ 25V<BR>
+ 25P<BR>
+ -<BR>
+ 25S<BR>
+ 25U<BR>
+ 25RX<BR>
+ 25X<BR>
+ 72XW<BR>
+ 72XL<BR>
+ 72PM<BR>
+ 72RX<BR>
+ -<BR>
+ 72PX<BR>
+ 72P<BR>
+ 72RXW<BR>
+ 72RXL<BR>
+ 72X<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ -<BR>
+ -<BR>
+ T7YB<BR>
+ T7YA<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ TXD<BR>
+ TYA<BR>
+ TYP<BR>
+ -<BR>
+ TYD<BR>
+ TX<BR>
+ -<BR>
+ 150SX<BR>
+ 100SX<BR>
+ 102T<BR>
+ 101S<BR>
+ 190T<BR>
+ 150TX<BR>
+ 101<BR>
+ -<BR>
+ -<BR>
+ 101SX<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ ET6P<BR>
+ ET6S<BR>
+ ET6X<BR>
+ RJ-6W/8014EMW<BR>
+ RJ-6P/8014EMP<BR>
+ RJ-6X/8014EMX<BR>
+ TM7W<BR>
+ TM7P<BR>
+ TM7X<BR>
+ -<BR>
+ 8017SMS<BR>
+ -<BR>
+ 8017SMB<BR>
+ 8017SMA<BR>
+ -<BR>
+ -<BR>
+ CT-6W<BR>
+ CT-6H<BR>
+ CT-6P<BR>
+ CT-6R<BR>
+ -<BR>
+ CT-6V<BR>
+ CT-6X<BR>
+ -<BR>
+ -<BR>
+ 8038EKV<BR>
+ -<BR>
+ 8038EKX<BR>
+ -<BR>
+ -<BR>
+ 8038EKP<BR>
+ 8038EKZ<BR>
+ 8038EKW<BR>
+ -<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ -<BR>
+ -<BR>
+ 3321H<BR>
+ 3321P<BR>
+ 3321N<BR>
+ 1102H<BR>
+ 1102P<BR>
+ 1102T<BR>
+ RVA0911V304A<BR>
+ -<BR>
+ RVA0911H413A<BR>
+ RVG0707V100A<BR>
+ RVA0607V(H)306A<BR>
+ RVA1214H213A<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ 3104B<BR>
+ 3104C<BR>
+ 3104F<BR>
+ 3104H<BR>
+ -<BR>
+ 3104M<BR>
+ 3104P<BR>
+ 3104S<BR>
+ 3104W<BR>
+ 3104X<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ EVMQ0G<BR>
+ EVMQIG<BR>
+ EVMQ3G<BR>
+ EVMS0G<BR>
+ EVMQ0G<BR>
+ EVMG0G<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ EVMK4GA00B<BR>
+ EVM30GA00B<BR>
+ EVMK0GA00B<BR>
+ EVM38GA00B<BR>
+ EVMB6<BR>
+ EVLQ0<BR>
+ -<BR>
+ EVMMSG<BR>
+ EVMMBG<BR>
+ EVMMAG<BR>
+ -<BR>
+ -<BR>
+ EVMMCS<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ EVMM1<BR>
+ -<BR>
+ -<BR>
+ EVMM0<BR>
+ -<BR>
+ -<BR>
+ EVMM3<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ -<BR>
+ -<BR>
+ 62-3-1<BR>
+ 62-1-2<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ 67R<BR>
+ -<BR>
+ 67P<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ 67X<BR>
+ 63V<BR>
+ 63S<BR>
+ 63M<BR>
+ -<BR>
+ -<BR>
+ 63H<BR>
+ 63P<BR>
+ -<BR>
+ -<BR>
+ 63X<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ -<BR>
+ -<BR>
+ RJ/RJR50<BR>
+ RJ/RJR50<BR>
+ RJ/RJR50<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ </TR>
+</TABLE>
+<P> <P>
+<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=3>
+ <TR>
+ <TD COLSPAN=7>
+ <FONT color="#0000FF" SIZE=4 FACE=ARIAL><B>SMD TRIM-POT CROSS REFERENCE</B></FONT>
+ <P>
+ <FONT SIZE=4 FACE=ARIAL><B>MULTI-TURN</B></FONT>
+ </TD>
+ </TR>
+ <TR>
+ <TD>
+ <FONT SIZE=3 FACE=ARIAL><B>BOURNS</B></FONT>
+ </TD>
+ <TD>
+ <FONT SIZE=3 FACE=ARIAL><B>BI TECH</B></FONT>
+ </TD>
+ <TD>
+ <FONT SIZE=3 FACE=ARIAL><B>DALE-VISHAY</B></FONT>
+ </TD>
+ <TD>
+ <FONT SIZE=3 FACE=ARIAL><B>PHILIPS/MEPCO</B></FONT>
+ </TD>
+ <TD>
+ <FONT SIZE=3 FACE=ARIAL><B>PANASONIC</B></FONT>
+ </TD>
+ <TD>
+ <FONT SIZE=3 FACE=ARIAL><B>TOCOS</B></FONT>
+ </TD>
+ <TD>
+ <FONT SIZE=3 FACE=ARIAL><B>AUX/KYOCERA</B></FONT>
+ </TD>
+ </TR>
+ <TR>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ 3224G<BR>
+ 3224J<BR>
+ 3224W<BR>
+ 3269P<BR>
+ 3269W<BR>
+ 3269X<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ 44G<BR>
+ 44J<BR>
+ 44W<BR>
+ 84P<BR>
+ 84W<BR>
+ 84X<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ -<BR>
+ -<BR>
+ ST63Z<BR>
+ ST63Y<BR>
+ -<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ -<BR>
+ -<BR>
+ ST5P<BR>
+ ST5W<BR>
+ ST5X<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ </TR>
+ <TR>
+ <TD COLSPAN=7> 
+ </TD>
+ </TR>
+ <TR>
+ <TD COLSPAN=7>
+ <FONT SIZE=4 FACE=ARIAL><B>SINGLE TURN</B></FONT>
+ </TD>
+ </TR>
+ <TR>
+ <TD>
+ <FONT SIZE=3 FACE=ARIAL><B>BOURNS</B></FONT>
+ </TD>
+ <TD>
+ <FONT SIZE=3 FACE=ARIAL><B>BI TECH</B></FONT>
+ </TD>
+ <TD>
+ <FONT SIZE=3 FACE=ARIAL><B>DALE-VISHAY</B></FONT>
+ </TD>
+ <TD>
+ <FONT SIZE=3 FACE=ARIAL><B>PHILIPS/MEPCO</B></FONT>
+ </TD>
+ <TD>
+ <FONT SIZE=3 FACE=ARIAL><B>PANASONIC</B></FONT>
+ </TD>
+ <TD>
+ <FONT SIZE=3 FACE=ARIAL><B>TOCOS</B></FONT>
+ </TD>
+ <TD>
+ <FONT SIZE=3 FACE=ARIAL><B>AUX/KYOCERA</B></FONT>
+ </TD>
+ </TR>
+ <TR>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ 3314G<BR>
+ 3314J<BR>
+ 3364A/B<BR>
+ 3364C/D<BR>
+ 3364W/X<BR>
+ 3313G<BR>
+ 3313J<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ 23B<BR>
+ 23A<BR>
+ 21X<BR>
+ 21W<BR>
+ -<BR>
+ 22B<BR>
+ 22A<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ ST5YL/ST53YL<BR>
+ ST5YJ/5T53YJ<BR>
+ ST-23A<BR>
+ ST-22B<BR>
+ ST-22<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ ST-4B<BR>
+ ST-4A<BR>
+ -<BR>
+ -<BR>
+ -<BR>
+ ST-3B<BR>
+ ST-3A<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ EVM-6YS<BR>
+ EVM-1E<BR>
+ EVM-1G<BR>
+ EVM-1D<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ G4B<BR>
+ G4A<BR>
+ TR04-3S1<BR>
+ TRG04-2S1<BR>
+ -<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ <TD BGCOLOR="#cccccc" ALIGN=CENTER><FONT FACE=ARIAL SIZE=3>
+ -<BR>
+ -<BR>
+ DVR-43A<BR>
+ CVR-42C<BR>
+ CVR-42A/C<BR>
+ -<BR>
+ -<BR></FONT>
+ </TD>
+ </TR>
+</TABLE>
+<P>
+<FONT SIZE=4 FACE=ARIAL><B>ALT = ALTERNATE</B></FONT>
+<P>
+
+ 
+<P>
+</td>
+</tr>
+</table>
+
+
+<b>RESISTOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b> wave soldering<p>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+wave soldering
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+wave soldering
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+wave soldering
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+wave soldering
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+wave soldering
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+wave soldering
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+wave soldering
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+wave soldering
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+Source: http://download.siliconexpert.com/pdfs/2005/02/24/Semi_Ap/2/VSH/Resistor/dcrcwfre.pdf
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b> wave soldering<p>
+Source: http://download.siliconexpert.com/pdfs/2005/02/24/Semi_Ap/2/VSH/Resistor/dcrcwfre.pdf
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+MELF 0.10 W
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+MELF 0.25 W
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+MELF 0.12 W
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+MELF 0.10 W
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+MELF 0.25 W
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+MELF 0.25 W
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+MELF 0.12 W
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+MELF 0.25 W
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+type 0204, grid 5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+type 0204, grid 7.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+type 0207, grid 10 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+type 0207, grid 12 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+<b>RESISTOR</b><p>
+type 0207, grid 15mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+<b>RESISTOR</b><p>
+type 0207, grid 2.5 mm
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>RESISTOR</b><p>
+type 0207, grid 5 mm
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>RESISTOR</b><p>
+type 0207, grid 7.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+type 0309, grid 10mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+type 0309, grid 12.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+type 0411, grid 12.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+type 0411, grid 15 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+type 0411, grid 3.81 mm
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+<b>RESISTOR</b><p>
+type 0414, grid 15 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+type 0414, grid 5 mm
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+<b>RESISTOR</b><p>
+type 0617, grid 17.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+type 0617, grid 22.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+type 0617, grid 5 mm
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+<b>RESISTOR</b><p>
+type 0922, grid 22.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+<b>RESISTOR</b><p>
+type 0613, grid 5 mm
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+<b>RESISTOR</b><p>
+type 0613, grid 15 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+type 0817, grid 22.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+0817
+
+
+
+
+<b>RESISTOR</b><p>
+type 0817, grid 6.35 mm
+
+
+
+
+
+
+>NAME
+>VALUE
+0817
+
+
+
+<b>RESISTOR</b><p>
+type V234, grid 12.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+type V235, grid 17.78 mm
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+type V526-0, grid 2.5 mm
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>Mini MELF 0102 Axial</b>
+
+
+
+
+>NAME
+>VALUE
+
+
+
+<b>RESISTOR</b><p>
+type 0922, grid 7.5 mm
+
+
+
+
+
+
+>NAME
+>VALUE
+0922
+
+
+
+<b>CECC Size RC2211</b> Reflow Soldering<p>
+source Beyschlag
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CECC Size RC2211</b> Wave Soldering<p>
+source Beyschlag
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CECC Size RC3715</b> Reflow Soldering<p>
+source Beyschlag
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CECC Size RC3715</b> Wave Soldering<p>
+source Beyschlag
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CECC Size RC6123</b> Reflow Soldering<p>
+source Beyschlag
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CECC Size RC6123</b> Wave Soldering<p>
+source Beyschlag
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>RESISTOR</b><p>
+type RDH, grid 15 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+RDH
+
+
+
+
+<b>RESISTOR</b><p>
+type 0204, grid 2.5 mm
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>RESISTOR</b><p>
+type 0309, grid 2.5 mm
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b> chip<p>
+Source: http://www.vishay.com/docs/20008/dcrcw.pdf
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>Bulk Metal® Foil Technology</b>, Tubular Axial Lead Resistors, Meets or Exceeds MIL-R-39005 Requirements<p>
+MIL SIZE RNC55<br>
+Source: VISHAY .. vta56.pdf
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Bulk Metal® Foil Technology</b>, Tubular Axial Lead Resistors, Meets or Exceeds MIL-R-39005 Requirements<p>
+MIL SIZE RNC60<br>
+Source: VISHAY .. vta56.pdf
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Bulk Metal® Foil Technology</b>, Tubular Axial Lead Resistors, Meets or Exceeds MIL-R-39005 Requirements<p>
+MIL SIZE RBR52<br>
+Source: VISHAY .. vta56.pdf
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Bulk Metal® Foil Technology</b>, Tubular Axial Lead Resistors, Meets or Exceeds MIL-R-39005 Requirements<p>
+MIL SIZE RBR53<br>
+Source: VISHAY .. vta56.pdf
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Bulk Metal® Foil Technology</b>, Tubular Axial Lead Resistors, Meets or Exceeds MIL-R-39005 Requirements<p>
+MIL SIZE RBR54<br>
+Source: VISHAY .. vta56.pdf
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Bulk Metal® Foil Technology</b>, Tubular Axial Lead Resistors, Meets or Exceeds MIL-R-39005 Requirements<p>
+MIL SIZE RBR55<br>
+Source: VISHAY .. vta56.pdf
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Bulk Metal® Foil Technology</b>, Tubular Axial Lead Resistors, Meets or Exceeds MIL-R-39005 Requirements<p>
+MIL SIZE RBR56<br>
+Source: VISHAY .. vta56.pdf
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Package 4527</b><p>
+Source: http://www.vishay.com/docs/31059/wsrhigh.pdf
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>Wirewound Resistors, Precision Power</b><p>
+Source: VISHAY wscwsn.pdf
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>Wirewound Resistors, Precision Power</b><p>
+Source: VISHAY wscwsn.pdf
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>Wirewound Resistors, Precision Power</b><p>
+Source: VISHAY wscwsn.pdf
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>Wirewound Resistors, Precision Power</b><p>
+Source: VISHAY wscwsn.pdf
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>Wirewound Resistors, Precision Power</b><p>
+Source: VISHAY wscwsn.pdf
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>Wirewound Resistors, Precision Power</b><p>
+Source: VISHAY wscwsn.pdf
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CRCW1218 Thick Film, Rectangular Chip Resistors</b><p>
+Source: http://www.vishay.com .. dcrcw.pdf
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Chip Monolithic Ceramic Capacitors</b> Medium Voltage High Capacitance for General Use<p>
+Source: http://www.murata.com .. GRM43DR72E224KW01.pdf
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+<B>RESISTOR</B>, American symbol
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>Pin Header Connectors</b><p>
+<author>Created by librarian@cadsoft.de</author>
+
+
+<b>PIN HEADER</b>
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>PIN HEADER</b>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/Frege/CommandLineClock.fr b/samples/Frege/CommandLineClock.fr
new file mode 100644
index 00000000..5bdde621
--- /dev/null
+++ b/samples/Frege/CommandLineClock.fr
@@ -0,0 +1,44 @@
+{--
+ This program displays the
+ current time on stdandard output
+ every other second.
+ -}
+
+module examples.CommandLineClock where
+
+data Date = native java.util.Date where
+ native new :: () -> IO (MutableIO Date) -- new Date()
+ native toString :: Mutable s Date -> ST s String -- d.toString()
+
+--- 'IO' action to give us the current time as 'String'
+current :: IO String
+current = do
+ d <- Date.new ()
+ d.toString
+
+{-
+ "java.lang.Thread.sleep" takes a "long" and
+ returns nothing, but may throw an InterruptedException.
+ This is without doubt an IO action.
+
+ public static void sleep(long millis)
+ throws InterruptedException
+
+ Encoded in Frege:
+ - argument type long Long
+ - result void ()
+ - does IO IO ()
+ - throws ... throws ....
+
+-}
+-- .... defined in frege.java.Lang
+-- native sleep java.lang.Thread.sleep :: Long -> IO () throws InterruptedException
+
+
+main args =
+ forever do
+ current >>= print
+ print "\r"
+ stdout.flush
+ Thread.sleep 999
+
\ No newline at end of file
diff --git a/samples/Frege/Concurrent.fr b/samples/Frege/Concurrent.fr
new file mode 100644
index 00000000..5f9df994
--- /dev/null
+++ b/samples/Frege/Concurrent.fr
@@ -0,0 +1,147 @@
+module examples.Concurrent where
+
+import System.Random
+import Java.Net (URL)
+import Control.Concurrent as C
+
+main2 args = do
+ m <- newEmptyMVar
+ forkIO do
+ m.put 'x'
+ m.put 'y'
+ m.put 'z'
+ replicateM_ 3 do
+ c <- m.take
+ print "got: "
+ println c
+
+
+example1 = do
+ forkIO (replicateM_ 100000 (putChar 'a'))
+ replicateM_ 100000 (putChar 'b')
+
+example2 = do
+ s <- getLine
+ case s.long of
+ Right n -> forkIO (setReminder n) >> example2
+ Left _ -> println ("exiting ...")
+
+setReminder :: Long -> IO ()
+setReminder n = do
+ println ("Ok, I remind you in " ++ show n ++ " seconds")
+ Thread.sleep (1000L*n)
+ println (show n ++ " seconds is up!")
+
+table = "table"
+
+mainPhil _ = do
+ [fork1,fork2,fork3,fork4,fork5] <- mapM MVar.new [1..5]
+ forkIO (philosopher "Kant" fork5 fork1)
+ forkIO (philosopher "Locke" fork1 fork2)
+ forkIO (philosopher "Wittgenstein" fork2 fork3)
+ forkIO (philosopher "Nozick" fork3 fork4)
+ forkIO (philosopher "Mises" fork4 fork5)
+ return ()
+
+philosopher :: String -> MVar Int -> MVar Int -> IO ()
+philosopher me left right = do
+ g <- Random.newStdGen
+ let phil g = do
+ let (tT,g1) = Random.randomR (60L, 120L) g
+ (eT, g2) = Random.randomR (80L, 160L) g1
+ thinkTime = 300L * tT
+ eatTime = 300L * eT
+
+ println(me ++ " is going to the dining room and takes his seat.")
+ fl <- left.take
+ println (me ++ " takes up left fork (" ++ show fl ++ ")")
+ rFork <- right.poll
+ case rFork of
+ Just fr -> do
+ println (me ++ " takes up right fork. (" ++ show fr ++ ")")
+ println (me ++ " is going to eat for " ++ show eatTime ++ "ms")
+ Thread.sleep eatTime
+ println (me ++ " finished eating.")
+ right.put fr
+ println (me ++ " took down right fork.")
+ left.put fl
+ println (me ++ " took down left fork.")
+ table.notifyAll
+ println(me ++ " is going to think for " ++ show thinkTime ++ "ms.")
+ Thread.sleep thinkTime
+ phil g2
+ Nothing -> do
+ println (me ++ " finds right fork is already in use.")
+ left.put fl
+ println (me ++ " took down left fork.")
+ table.notifyAll
+ println (me ++ " is going to the bar to await notifications from table.")
+ table.wait
+ println (me ++ " got notice that something changed at the table.")
+ phil g2
+
+ inter :: InterruptedException -> IO ()
+ inter _ = return ()
+
+ phil g `catch` inter
+
+
+getURL xx = do
+ url <- URL.new xx
+ con <- url.openConnection
+ con.connect
+ is <- con.getInputStream
+ typ <- con.getContentType
+ -- stderr.println ("content-type is " ++ show typ)
+ ir <- InputStreamReader.new is (fromMaybe "UTF-8" (charset typ))
+ `catch` unsupportedEncoding is
+ br <- BufferedReader.new ir
+ br.getLines
+ where
+ unsupportedEncoding :: InputStream -> UnsupportedEncodingException -> IO InputStreamReader
+ unsupportedEncoding is x = do
+ stderr.println x.catched
+ InputStreamReader.new is "UTF-8"
+
+ charset ctyp = do
+ typ <- ctyp
+ case typ of
+ m~´charset=(\S+)´ -> m.group 1
+ _ -> Nothing
+
+
+type SomeException = Throwable
+
+main ["dining"] = mainPhil []
+
+main _ = do
+ m1 <- MVar.newEmpty
+ m2 <- MVar.newEmpty
+ m3 <- MVar.newEmpty
+
+ forkIO do
+ r <- (catchAll . getURL) "http://www.wikipedia.org/wiki/Haskell"
+ m1.put r
+
+ forkIO do
+ r <- (catchAll . getURL) "htto://www.wikipedia.org/wiki/Java"
+ m2.put r
+
+ forkIO do
+ r <- (catchAll . getURL) "http://www.wikipedia.org/wiki/Frege"
+ m3.put r
+
+ r1 <- m1.take
+ r2 <- m2.take
+ r3 <- m3.take
+ println (result r1, result r2, result r3)
+ -- case r3 of
+ -- Right ss -> mapM_ putStrLn ss
+ -- Left _ -> return ()
+ where
+ result :: (SomeException|[String]) -> (String|Int)
+ result (Left x) = Left x.getClass.getName
+ result (Right y) = (Right . sum . map length) y
+ -- mapM_ putStrLn r2
+
+
\ No newline at end of file
diff --git a/samples/Frege/Sudoku.fr b/samples/Frege/Sudoku.fr
new file mode 100644
index 00000000..88bfd966
--- /dev/null
+++ b/samples/Frege/Sudoku.fr
@@ -0,0 +1,561 @@
+package examples.Sudoku where
+
+import Data.TreeMap (Tree, keys)
+import Data.List as DL hiding (find, union)
+
+
+type Element = Int -- 1,2,3,4,5,6,7,8,9
+type Zelle = [Element] -- set of candidates
+type Position = Int -- 0..80
+type Feld = (Position, Zelle)
+type Brett = [Feld]
+
+--- data type for assumptions and conclusions
+data Assumption =
+ !ISNOT Position Element
+ | !IS Position Element
+
+
+derive Eq Assumption
+derive Ord Assumption
+instance Show Assumption where
+ show (IS p e) = pname p ++ "=" ++ e.show
+ show (ISNOT p e) = pname p ++ "/" ++ e.show
+
+showcs cs = joined " " (map Assumption.show cs)
+
+elements :: [Element] -- all possible elements
+elements = [1 .. 9]
+
+{-
+ a b c d e f g h i
+ 0 1 2 | 3 4 5 | 6 7 8 1
+ 9 10 11 |12 13 14 |15 16 17 2
+ 18 19 20 |21 22 23 |24 25 26 3
+ ---------|---------|--------
+ 27 28 29 |30 31 32 |33 34 35 4
+ 36 37 38 |39 40 41 |42 43 44 5
+ 45 46 47 |48 49 50 |51 52 53 6
+ ---------|---------|--------
+ 54 55 56 |57 58 59 |60 61 62 7
+ 63 64 65 |66 67 68 |69 70 71 8
+ 72 73 74 |75 76 77 |78 79 80 9
+-}
+
+positions :: [Position] -- all possible positions
+positions = [0..80]
+rowstarts :: [Position] -- all positions where a row is starting
+rowstarts = [0,9,18,27,36,45,54,63,72]
+colstarts :: [Position] -- all positions where a column is starting
+colstarts = [0,1,2,3,4,5,6,7,8]
+boxstarts :: [Position] -- all positions where a box is starting
+boxstarts = [0,3,6,27,30,33,54,57,60]
+boxmuster :: [Position] -- pattern for a box, by adding upper left position results in real box
+boxmuster = [0,1,2,9,10,11,18,19,20]
+
+
+--- extract field for position
+getf :: Brett -> Position -> Feld
+getf (f:fs) p
+ | fst f == p = f
+ | otherwise = getf fs p
+getf [] p = (p,[])
+
+
+--- extract cell for position
+getc :: Brett -> Position -> Zelle
+getc b p = snd (getf b p)
+
+--- compute the list of all positions that belong to the same row as a given position
+row :: Position -> [Position]
+row p = [z..(z+8)] where z = (p `quot` 9) * 9
+
+--- compute the list of all positions that belong to the same col as a given position
+col :: Position -> [Position]
+col p = map (c+) rowstarts where c = p `mod` 9
+
+--- compute the list of all positions that belong to the same box as a given position
+box :: Position -> [Position]
+box p = map (z+) boxmuster where
+ ri = p `div` 27 * 27 -- 0, 27 or 54, depending on row
+ ci = p `mod` 9 -- column index 0..8, 0,1,2 is left, 3,4,5 is middle, 6,7,8 is right
+ cs = ci `div` 3 * 3 -- 0, 3 or 6
+ z = ri + cs
+
+--- check if candidate set has exactly one member, i.e. field has been solved
+single :: Zelle -> Bool
+single [_] = true
+single _ = false
+
+unsolved :: Zelle -> Bool
+unsolved [_] = false
+unsolved _ = true
+
+-- list of rows, cols, boxes
+allrows = map row rowstarts
+allcols = map col colstarts
+allboxs = map box boxstarts
+allrcb = zip (repeat "row") allrows
+ ++ zip (repeat "col") allcols
+ ++ zip (repeat "box") allboxs
+
+
+containers :: [(Position -> [Position], String)]
+containers = [(row, "row"), (col, "col"), (box, "box")]
+
+-- ----------------- PRINTING ------------------------------------
+-- printable coordinate of field, upper left is a1, lower right is i9
+pname p = packed [chr (ord 'a' + p `mod` 9), chr (ord '1' + p `div` 9)]
+
+-- print board
+printb b = mapM_ p1line allrows >> println ""
+ where
+ p1line row = do
+ print (joined "" (map pfld line))
+ where line = map (getc b) row
+
+-- print field (brief)
+-- ? = no candidate
+-- 5 = field is 5
+-- . = some candidates
+pfld [] = "?"
+pfld [x] = show x
+pfld zs = "0"
+
+-- print initial/final board
+result msg b = do
+ println ("Result: " ++ msg)
+ print ("Board: ")
+ printb b
+ return b
+
+res012 b = case concatMap (getc b) [0,1,2] of
+ [a,b,c] -> a*100+b*10+c
+ _ -> 9999999
+
+-- -------------------------- BOARD ALTERATION ACTIONS ---------------------------------
+-- print a message about what is done to the board and return the new board
+turnoff1 :: Position -> Zelle -> Brett -> IO Brett
+turnoff1 i off b
+ | single nc = do
+ -- print (pname i)
+ -- print ": set to "
+ -- print (head nc)
+ -- println " (naked single)"
+ return newb
+ | otherwise = return newb
+ where
+ cell = getc b i
+ nc = filter (`notElem` off) cell
+ newb = (i, nc) : [ f | f <- b, fst f != i ]
+
+turnoff :: Int -> Zelle -> String -> Brett -> IO Brett
+turnoff i off msg b = do
+ -- print (pname i)
+ -- print ": set to "
+ -- print nc
+ -- print " by clearing "
+ -- print off
+ -- print " "
+ -- println msg
+ return newb
+ where
+ cell = getc b i
+ nc = filter (`notElem` off) cell
+ newb = (i, nc) : [ f | f <- b, fst f != i ]
+
+turnoffh ps off msg b = foldM toh b ps
+ where
+ toh b p = turnoff p off msg b
+
+setto :: Position -> Element -> String -> Brett -> IO Brett
+setto i n cname b = do
+ -- print (pname i)
+ -- print ": set to "
+ -- print n
+ -- print " (hidden single in "
+ -- print cname
+ -- println ")"
+ return newb
+ where
+ nf = [n]
+ newb = (i, nf) : [ f | f <- b, fst f != i ]
+
+
+-- ----------------------------- SOLVING STRATEGIES ---------------------------------------------
+-- reduce candidate sets that contains numbers already in same row, col or box
+-- This finds (and logs) NAKED SINGLEs in passing.
+reduce b = [ turnoff1 p sss | (p,cell) <- b, -- for each field
+ unsolved cell, -- with more than 1 candidate
+ -- single fields in containers that are candidates of that field
+ sss = [ s | (rcb, _) <- containers, [s] <- map (getc b) (rcb p), s `elem` cell],
+ sss != [] ] -- collect field index, elements to remove from candidate set
+
+-- look for a number that appears in exactly 1 candidate set of a container
+-- this number can go in no other place (HIDDEN SINGLE)
+hiddenSingle b = [ setto i n cname | -- select index, number, containername
+ (cname, rcb) <- allrcb, -- FOR rcb IN allrcb
+ n <- elements, -- FOR n IN elements
+ fs = filter (unsolved • snd) (map (getf b) rcb),
+ occurs = filter ((n `elem`) • snd) fs,
+ length occurs == 1,
+ (i, _) <- occurs ]
+
+-- look for NAKED PAIRS, TRIPLES, QUADS
+nakedPair n b = [ turnoff p t ("(naked tuple in " ++ nm ++ ")") | -- SELECT pos, tuple, name
+ -- n <- [2,3,4], // FOR n IN [2,3,4]
+ (nm, rcb) <- allrcb, -- FOR rcb IN containers
+ fs = map (getf b) rcb, -- let fs = fields for rcb positions
+ u = (fold union [] . filter unsolved . map snd) fs, -- let u = union of non single candidates
+ t <- n `outof` u, -- FOR t IN n-tuples
+ hit = (filter ((`subset` t) . snd) . filter (unsolved . snd)) fs,
+ length hit == n,
+ (p, cell) <- fs,
+ p `notElem` map fst hit,
+ any (`elem` cell) t
+ ]
+
+-- look for HIDDEN PAIRS, TRIPLES or QUADS
+hiddenPair n b = [ turnoff p off ("(hidden " ++ show t ++ " in " ++ nm ++ ")") | -- SELECT pos, tuple, name
+ -- n <- [2,3,4], // FOR n IN [2,3,4]
+ (nm, rcb) <- allrcb, -- FOR rcb IN containers
+ fs = map (getf b) rcb, -- let fs = fields for rcb positions
+ u = (fold union [] . filter ((>1) . length) . map snd) fs, -- let u = union of non single candidates
+ t <- n `outof` u, -- FOR t IN n-tuples
+ hit = (filter (any ( `elem` t) . snd) . filter (unsolved . snd)) fs,
+ length hit == n,
+ off = (fold union [] . map snd) hit `minus` t,
+ off != [],
+ (p, cell) <- hit,
+ ! (cell `subset` t)
+ ]
+
+a `subset` b = all (`elem` b) a
+a `union` b = uniq (sort (a ++ b))
+a `minus` b = filter (`notElem` b) a
+a `common` b = filter (`elem` b) a
+n `outof` as
+ | length as < n = []
+ | [] <- as = []
+ | 1 >= n = map (:[]) as
+ | (a:bs) <- as = map (a:) ((n-1) `outof` bs) ++ (n `outof` bs)
+ | otherwise = undefined -- cannot happen because either as is empty or not
+
+same f a b = b `elem` f a
+
+intersectionlist = [(allboxs, row, "box/row intersection"), (allboxs, col, "box/col intersection"),
+ (allrows ++ allcols, box, "line/box intersection")]
+intersections b = [
+ turnoff pos [c] reason | -- SELECT position, candidate, reson
+ (from, container, reason) <- intersectionlist,
+ rcb <- from,
+ fs = (filter (unsolved . snd) . map (getf b)) rcb, -- fs = fields in from with more than 1 candidate
+ c <- (fold union [] • map snd) fs, -- FOR c IN union of candidates
+ cpos = (map fst • filter ((c `elem`) • snd)) fs, -- cpos = positions where c occurs
+ cpos != [], -- WHERE cpos is not empty
+ all (same container (head cpos)) (tail cpos), -- WHERE all positions are in the intersection
+ -- we can remove all occurences of c that are in container, but not in from
+ (pos, cell) <- map (getf b) (container (head cpos)),
+ c `elem` cell,
+ pos `notElem` rcb ]
+
+
+-- look for an XY Wing
+-- - there exists a cell A with candidates X and Y
+-- - there exists a cell B with candidates X and Z that shares a container with A
+-- - there exists a cell C with candidates Y and Z that shares a container with A
+-- reasoning
+-- - if A is X, B will be Z
+-- - if A is Y, C will be Z
+-- - since A will indeed be X or Y -> B or C will be Z
+-- - thus, no cell that can see B and C can be Z
+xyWing board = [ turnoff p [z] ("xy wing " ++ pname b ++ " " ++ pname c ++ " because of " ++ pname a) |
+ (a, [x,y]) <- board, -- there exists a cell a with candidates x and y
+ rcba = map (getf board) (row a ++ col a ++ box a), -- rcba = all fields that share a container with a
+ (b, [b1, b2]) <- rcba,
+ b != a,
+ b1 == x && b2 != y || b2 == x && b1 != y, -- there exists a cell B with candidates x and z
+ z = if b1 == x then b2 else b1,
+ (c, [c1, c2]) <- rcba,
+ c != a, c!= b,
+ c1 == y && c2 == z || c1 == z && c2 == y, -- there exists a cell C with candidates y and z
+ ps = (uniq . sort) ((row b ++ col b ++ box b) `common` (row c ++ col c ++ box c)),
+ -- remove z in ps
+ (p, cs) <- map (getf board) ps,
+ p != b, p != c,
+ z `elem` cs ]
+
+-- look for a N-Fish (2: X-Wing, 3: Swordfish, 4: Jellyfish)
+-- When all candidates for a particular digit in N rows are located
+-- in only N columns, we can eliminate all candidates from those N columns
+-- which are not located on those N rows
+fish n board = fish "row" allrows row col ++ fish "col" allcols col row where
+ fishname 2 = "X-Wing"
+ fishname 3 = "Swordfish"
+ fishname 4 = "Jellyfish"
+ fishname _ = "unknown fish"
+ fish nm allrows row col = [ turnoff p [x] (fishname n ++ " in " ++ nm ++ " " ++ show (map (pname . head) rset)) |
+ rset <- n `outof` allrows, -- take n rows (or cols)
+ x <- elements, -- look for certain number
+ rflds = map (filter ((>1) . length . snd) . map (getf board)) rset, -- unsolved fields in the rowset
+ colss = (map (map (head . col . fst) . filter ((x `elem`) . snd)) rflds), -- where x occurs in candidates
+ all ((>1) . length) colss, -- x must appear in at least 2 cols
+ cols = fold union [] colss,
+ length cols == n,
+ cstart <- cols,
+ (p, cell) <- map (getf board) (col cstart),
+ x `elem` cell,
+ all (p `notElem`) rset]
+
+
+-- compute immediate consequences of an assumption of the form (p `IS` e) or (p `ISNOT` e)
+conseq board (IS p e) = uniq (sort ([ p `ISNOT` x | x <- getc board p, x != e ] ++
+ [ a `ISNOT` e |
+ (a,cs) <- map (getf board) (row p ++ col p ++ box p),
+ a != p,
+ e `elem` cs
+ ]))
+conseq board (ISNOT p e) = uniq (sort ([ p `IS` x | cs = getc board p, length cs == 2, x <- cs, x != e ] ++
+ [ a `IS` e |
+ cp <- [row p, box p, col p],
+ as = (filter ((e `elem`) . getc board) . filter (p!=)) cp,
+ length as == 1,
+ a = head as
+ ]))
+
+-- check if two assumptions contradict each other
+contradicts (IS a x) (IS b y) = a==b && x!=y
+contradicts (IS a x) (ISNOT b y) = a==b && x==y
+contradicts (ISNOT a x) (IS b y) = a==b && x==y
+contradicts (ISNOT _ _) (ISNOT _ _) = false
+
+-- get the Position of an Assumption
+aPos (IS p _) = p
+aPos (ISNOT p _) = p
+
+-- get List of elements that must be turned off when assumption is true/false
+toClear board true (IS p x) = filter (x!=) (getc board p)
+toClear board false (IS p x) = [x]
+toClear board true (ISNOT p x) = [x]
+toClear board false (ISNOT p x) = filter (x!=) (getc board p)
+
+
+-- look for assumptions whose implications contradict themself
+chain board paths = [ solution a (head cs) (reverse cs) |
+ (a, css) <- paths,
+ cs <- take 1 [ cs | cs <- css, contradicts a (head cs) ]
+ ]
+ where
+ solution a c cs = turnoff (aPos a) (toClear board false a) reason where
+ reason = "Assumption " ++ show a ++ " implies " ++ show c ++ "\n\t"
+ ++ showcs cs ++ "\n\t"
+ ++ "Therefore, " ++ show a ++ " must be false."
+
+-- look for an assumption that yields to contradictory implications
+-- this assumption must be false
+chainContra board paths = [ solution a (reverse pro) (reverse contra) |
+ (a, css) <- paths, -- FOR ALL assumptions "a" with list of conlusions "css"
+ (pro, contra) <- take 1 [ (pro, contra) |
+ pro <- (uniqBy (using head) . sortBy (comparing head)) css, -- FOR ALL conslusion chains "pro"
+ c = head pro, -- LET "c" BE the final conclusion
+ contra <- take 1 (filter ((contradicts c) . head) css) -- THE FIRST conclusion that contradicts c
+ ]
+ ]
+ where
+ solution a pro con = turnoff (aPos a) (toClear board false a) reason where
+ reason = ("assumption " ++ show a ++ " leads to contradictory conclusions\n\t"
+ ++ showcs pro ++ "\n\t" ++ showcs con)
+
+
+
+-- look for a common implication c of some assumptions ai, where at least 1 ai is true
+-- so that (a0 OR a1 OR a2 OR ...) IMPLIES c
+-- For all cells pi in same container that have x as candidate, we can construct (p0==x OR p1==x OR ... OR pi==x)
+-- For a cell p with candidates ci, we can construct (p==c0 OR p==c1)
+cellRegionChain board paths = [ solution b as (map head os) |
+ as <- cellas ++ regionas, -- one of as must be true
+ iss = filter ((`elem` as) . fst) paths, -- the implications for as
+ (a, ass) <- take 1 iss, -- implications for first assumption
+ fs <- (uniqBy (using head) . sortBy (comparing head)) ass,
+ b = head fs, -- final conclusions of first assumption
+ os = [fs] : map (take 1 . filter ((b==) . head) . snd) (tail iss), -- look for implications with same conclusion
+ all ([]!=) os]
+ where
+ cellas = [ map (p `IS`) candidates | (p, candidates@(_:_:_)) <- board ]
+ regionas = [ map (`IS` e) ps |
+ region <- map (map (getf board)) (allrows ++ allcols ++ allboxs),
+ e <- elements,
+ ps = map fst (filter ((e `elem`) . snd) region),
+ length ps > 1 ]
+ solution b as oss = turnoff (aPos b) (toClear board true b) reason where
+ reason = "all of the assumptions " ++ joined ", " (map show as) ++ " imply " ++ show b ++ "\n\t"
+ ++ joined "\n\t" (map (showcs . reverse) oss) ++ "\n\t"
+ ++ "One of them must be true, so " ++ show b ++ " must be true."
+
+
+{-
+ Wir brauchen für einige Funktionen eine Datenstruktur wie
+ [ (Assumption, [[Assumption]]) ]
+ d.i. eine Liste von möglichen Annahmen samt aller Schlußketten.
+ Idealerweise sollte die Schlußkette in umgekehrter Reihenfolge vorliegen,
+ dann kann man einfach finden:
+ - Annahmen, die zum Selbstwiderspruch führen.
+ - alles, was aus einer bestimmten Annahme folgt (map (map head) [[a]])
+ -...
+-}
+--- Liste aller Annahmen für ein bestimmtes Brett
+assumptions :: Brett -> [Assumption]
+assumptions board = [ a |
+ (p, cs) <- board,
+ !(single cs),
+ a <- map (ISNOT p) cs ++ map (IS p) cs ]
+
+consequences :: Brett -> [Assumption] -> [[Assumption]]
+consequences board as = map (conseq board) as
+
+acstree :: Brett -> Tree Assumption [Assumption]
+acstree board = Tree.fromList (zip as cs)
+ where
+ as = assumptions board
+ cs = consequences board as
+
+-- bypass maybe on tree lookup
+find :: Tree Assumption [Assumption] -> Assumption -> [Assumption]
+find t a
+ | Just cs <- t.lookup a = cs
+ | otherwise = error ("no consequences for " ++ show a)
+
+-- for performance resons, we confine ourselves to implication chains of length 20 per assumption
+mkPaths :: Tree Assumption [Assumption] -> [ (Assumption, [[Assumption]]) ]
+mkPaths acst = map impl (keys acst) -- {[a1], [a2], [a3] ]
+ where
+ -- [Assumption] -> [(a, [chains, ordered by length]
+ impl a = (a, impls [[a]])
+ impls ns = (take 1000 • concat • takeUntil null • iterate expandchain) ns
+ -- expandchain :: [[Assumption]] -> [[Assumption]]
+ expandchain css = [ (n:a:as) |
+ (a : as) <- css, -- list of assumptions
+ n <- find acst a, -- consequences of a
+ n `notElem` as -- avoid loops
+ ]
+ -- uni (a:as) = a : uni (filter ((head a !=) • head) as)
+ -- uni [] = empty
+ -- empty = []
+
+
+-- ------------------ SOLVE A SUDOKU --------------------------
+-- Apply all available strategies until nothing changes anymore
+-- Strategy functions are supposed to return a list of
+-- functions, which, when applied to a board, give a changed board.
+-- When a strategy does not find anything to alter,
+-- it returns [], and the next strategy can be tried.
+solve b
+ | all (single . snd) b = result "Solved" b
+ | any (([]==) . snd) b = result "not solvable" b
+ | res@(_:_) <- reduce b = apply b res >>=solve -- compute smallest candidate sets
+ -- comment "candidate sets are up to date" = ()
+ | res@(_:_) <- hiddenSingle b = apply b res >>= solve -- find HIDDEN SINGLES
+ -- comment "no more hidden singles" = ()
+ | res@(_:_) <- intersections b = apply b res >>= solve -- find locked candidates
+ -- comment "no more intersections" = ()
+ | res@(_:_) <- nakedPair 2 b = apply b res >>= solve -- find NAKED PAIRS, TRIPLES or QUADRUPELS
+ -- comment "no more naked pairs" = ()
+ | res@(_:_) <- hiddenPair 2 b = apply b res >>= solve -- find HIDDEN PAIRS, TRIPLES or QUADRUPELS
+ -- comment "no more hidden pairs" = ()
+ -- res@(_:_) <- nakedPair 3 b = apply b res >>= solve // find NAKED PAIRS, TRIPLES or QUADRUPELS
+ -- | comment "no more naked triples" = ()
+ -- res@(_:_) <- hiddenPair 3 b = apply b res >>= solve // find HIDDEN PAIRS, TRIPLES or QUADRUPELS
+ -- | comment "no more hidden triples" = ()
+ -- res@(_:_) <- nakedPair 4 b = apply b res >>=solve // find NAKED PAIRS, TRIPLES or QUADRUPELS
+ -- | comment "no more naked quadruples" = ()
+ -- res@(_:_) <- hiddenPair 4 b = apply b res >>=solve // find HIDDEN PAIRS, TRIPLES or QUADRUPELS
+ -- | comment "no more hidden quadruples" = ()
+ | res@(_:_) <- xyWing b = apply b res >>=solve -- find XY WINGS
+ -- comment "no more xy wings" = ()
+ | res@(_:_) <- fish 2 b = apply b res >>=solve -- find 2-FISH
+ -- comment "no more x-wings" = ()
+ -- res@(_:_) <- fish 3 b = apply b res >>=solve // find 3-FISH
+ -- | comment "no more swordfish" = ()
+ -- res@(_:_) <- fish 4 b = apply b res >>=solve // find 4-FISH
+ -- | comment "no more jellyfish" = ()
+ -- | comment pcomment = ()
+ | res@(_:_) <- chain b paths = apply b (take 9 res) >>= solve -- find forcing chains
+ | res@(_:_) <- cellRegionChain b paths = apply b (take 9 res) >>= solve -- find common conclusion for true assumption
+ | res@(_:_) <- chainContra b paths = apply b (take 9 res) >>= solve -- find assumptions that allow to infer both a and !a
+ -- comment "consistent conclusions only" = ()
+
+ | otherwise = result "ambiguous" b
+ where
+ apply brd fs = foldM (\b\f -> f b) brd fs
+ paths = mkPaths (acstree b)
+ -- pcomment = show (length paths) ++ " assumptions with " ++ show (fold (+) 0 (map (length <~ snd) paths))
+ -- ++ " implication chains"
+
+-- comment com = do stderr << com << "\n" for false
+-- log com = do stderr << com << "\n" for true
+
+--- turn a string into a row
+mkrow :: String -> [Zelle]
+mkrow s = mkrow1 xs
+ where
+ xs = s ++ "---------" -- make sure at least 9 elements
+ mkrow1 xs = (take 9 • filter ([]!=) • map f • unpacked) xs
+ f x | x >= '1' && x <= '9' = [ord x - ord '0']
+ | x == ' ' = [] -- ignored
+ | otherwise = elements
+
+main ["-h"] = main []
+main ["-help"] = main []
+main [] = do
+ mapM_ stderr.println [
+ "usage: java Sudoku file ...",
+ " java Sudoku position",
+ "where position is a 81 char string consisting of digits",
+ "One can get such a string by going to",
+ "http://www.sudokuoftheday.com/pages/s-o-t-d.php",
+ "Right click on the puzzle and open it in new tab",
+ "Copy the 81 digits from the URL in the address field of your browser.",
+ "",
+ "There is also a file with hard sudokus in examples/top95.txt\n"]
+ return ()
+
+
+main [s@#^[0-9\W]{81}$#] = solve board >> return ()
+ where
+ board = zip positions felder
+ felder = decode s
+
+main files = forM_ files sudoku
+ where
+ sudoku file = do
+ br <- openReader file
+ lines <- BufferedReader.getLines br
+ bs <- process lines
+ ss <- mapM (\b -> print "Puzzle: " >> printb b >> solve b) bs
+ println ("Euler: " ++ show (sum (map res012 ss)))
+ return ()
+
+-- "--3-" => [1..9, 1..9, [3], 1..9]
+decode s = map candi (unpacked s) where
+ candi c | c >= '1' && c <= '9' = [(ord c - ord '0')]
+ | otherwise = elements
+process [] = return []
+process (s:ss)
+ | length s == 81 = consider b1
+ | length s == 9,
+ length acht == 8,
+ all ((9==) • length) acht = consider b2
+ | otherwise = do
+ stderr.println ("skipped line: " ++ s)
+ process ss
+ where
+ acht = take 8 ss
+ neun = fold (++) "" (s:acht)
+ b1 = zip positions (decode s)
+ b2 = zip positions (decode neun)
+ consider b = do
+ -- print "Puzzle: "
+ -- printb b
+ bs <- process ss
+ return (b:bs)
+
diff --git a/samples/Frege/SwingExamples.fr b/samples/Frege/SwingExamples.fr
new file mode 100644
index 00000000..73569546
--- /dev/null
+++ b/samples/Frege/SwingExamples.fr
@@ -0,0 +1,79 @@
+package examples.SwingExamples where
+
+import Java.Awt (ActionListener)
+import Java.Swing
+
+
+main _ = do
+ rs <- mapM Runnable.new [helloWorldGUI, buttonDemoGUI, celsiusConverterGUI]
+ mapM_ invokeLater rs
+ println "Hit enter to end ...."
+ s <- getLine
+ return ()
+
+celsiusConverterGUI = do
+ tempTextField <- JTextField.new()
+ celsiusLabel <- JLabel.new ()
+ convertButton <- JButton.new ()
+ fahrenheitLabel <- JLabel.new ()
+ frame <- JFrame.new ()
+ frame.setDefaultCloseOperation JFrame.dispose_on_close
+ frame.setTitle "Celsius Converter"
+ celsiusLabel.setText "Celsius"
+ convertButton.setText "Convert"
+ let convertButtonActionPerformed _ = do
+ celsius <- tempTextField.getText
+ case celsius.double of
+ Left _ -> fahrenheitLabel.setText ("not a valid number: " ++ celsius)
+ Right c -> fahrenheitLabel.setText (show (c*1.8 + 32.0).long ++ " Fahrenheit")
+ return ()
+ ActionListener.new convertButtonActionPerformed >>= convertButton.addActionListener
+ fahrenheitLabel.setText "Fahrenheit"
+ contentPane <- frame.getContentPane
+ layout <- GroupLayout.new contentPane
+ contentPane.setLayout layout
+ -- TODO continue
+ -- http://docs.oracle.com/javase/tutorial/displayCode.html?code=http://docs.oracle.com/javase/tutorial/uiswing/examples/learn/CelsiusConverterProject/src/learn/CelsiusConverterGUI.java
+ frame.pack
+ frame.setVisible true
+
+helloWorldGUI = do
+ frame <- JFrame.new "Hello World Frege"
+ frame.setDefaultCloseOperation(JFrame.dispose_on_close)
+ label <- JLabel.new "Hello World!"
+ cp <- frame.getContentPane
+ cp.add label
+ frame.pack
+ frame.setVisible true
+
+buttonDemoGUI = do
+ frame <- JFrame.new "Button Demo"
+ frame.setDefaultCloseOperation(JFrame.dispose_on_close)
+ newContentPane <- JPanel.new ()
+ b1::JButton <- JButton.new "Disable middle button"
+ b1.setVerticalTextPosition SwingConstants.center
+ b1.setHorizontalTextPosition SwingConstants.leading
+ b2::JButton <- JButton.new "Middle button"
+ b2.setVerticalTextPosition SwingConstants.center
+ b2.setHorizontalTextPosition SwingConstants.leading
+ b3::JButton <- JButton.new "Enable middle button"
+ b3.setVerticalTextPosition SwingConstants.center
+ b3.setHorizontalTextPosition SwingConstants.leading
+ b3.setEnabled false
+ let action1 _ = do
+ b2.setEnabled false
+ b1.setEnabled false
+ b3.setEnabled true
+ action3 _ = do
+ b2.setEnabled true
+ b1.setEnabled true
+ b3.setEnabled false
+ ActionListener.new action1 >>= b1.addActionListener
+ ActionListener.new action3 >>= b3.addActionListener
+ newContentPane.add b1
+ newContentPane.add b2
+ newContentPane.add b3
+ newContentPane.setOpaque true
+ frame.setContentPane newContentPane
+ frame.pack
+ frame.setVisible true
diff --git a/samples/GAMS/transport.gms b/samples/GAMS/transport.gms
new file mode 100644
index 00000000..fb6ccbc9
--- /dev/null
+++ b/samples/GAMS/transport.gms
@@ -0,0 +1,76 @@
+*Basic example of transport model from GAMS model library
+
+$Title A Transportation Problem (TRNSPORT,SEQ=1)
+$Ontext
+
+This problem finds a least cost shipping schedule that meets
+requirements at markets and supplies at factories.
+
+
+Dantzig, G B, Chapter 3.3. In Linear Programming and Extensions.
+Princeton University Press, Princeton, New Jersey, 1963.
+
+This formulation is described in detail in:
+Rosenthal, R E, Chapter 2: A GAMS Tutorial. In GAMS: A User's Guide.
+The Scientific Press, Redwood City, California, 1988.
+
+The line numbers will not match those in the book because of these
+comments.
+
+$Offtext
+
+
+ Sets
+ i canning plants / seattle, san-diego /
+ j markets / new-york, chicago, topeka / ;
+ Parameters
+ a(i) capacity of plant i in cases
+ / seattle 350
+ san-diego 600 /
+ b(j) demand at market j in cases
+ / new-york 325
+ chicago 300
+ topeka 275 / ;
+ Table d(i,j) distance in thousands of miles
+ new-york chicago topeka
+ seattle 2.5 1.7 1.8
+ san-diego 2.5 1.8 1.4 ;
+ Scalar f freight in dollars per case per thousand miles /90/ ;
+ Parameter c(i,j) transport cost in thousands of dollars per case ;
+ c(i,j) = f * d(i,j) / 1000 ;
+ Variables
+ x(i,j) shipment quantities in cases
+ z total transportation costs in thousands of dollars ;
+
+ Positive Variable x ;
+
+ Equations
+ cost define objective function
+ supply(i) observe supply limit at plant i
+ demand(j) satisfy demand at market j ;
+
+ cost .. z =e= sum((i,j), c(i,j)*x(i,j)) ;
+
+ supply(i) .. sum(j, x(i,j)) =l= a(i) ;
+
+ demand(j) .. sum(i, x(i,j)) =g= b(j) ;
+
+ Model transport /all/ ;
+
+ Solve transport using lp minimizing z ;
+
+ Display x.l, x.m ;
+
+$ontext
+#user model library stuff
+Main topic Basic GAMS
+Featured item 1 Trnsport model
+Featured item 2
+Featured item 3
+Featured item 4
+Description
+Basic example of transport model from GAMS model library
+
+
+
+$offtext
\ No newline at end of file
diff --git a/samples/GAP/Magic.gd b/samples/GAP/Magic.gd
new file mode 100644
index 00000000..cdd8baec
--- /dev/null
+++ b/samples/GAP/Magic.gd
@@ -0,0 +1,307 @@
+#############################################################################
+##
+## Magic.gd AutoDoc package
+##
+## Copyright 2013, Max Horn, JLU Giessen
+## Sebastian Gutsche, University of Kaiserslautern
+##
+#############################################################################
+
+
+#! @Description
+#! This is the main function of the &AutoDoc; package. It can perform
+#! any combination of the following three tasks:
+#!
+#!
+#! It can (re)generate a scaffold for your package manual.
+#! That is, it can produce two XML files in &GAPDoc; format to be used as part
+#! of your manual: First, a file named doc/PACKAGENAME.xml
+#! (with your package's name substituted) which is used as
+#! main file for the package manual, i.e. this file sets the
+#! XML DOCTYPE and defines various XML entities, includes
+#! other XML files (both those generated by &AutoDoc; as well
+#! as additional files created by other means), tells &GAPDoc;
+#! to generate a table of content and an index, and more.
+#! Secondly, it creates a file doc/title.xml containing a title
+#! page for your documentation, with information about your package
+#! (name, description, version), its authors and more, based
+#! on the data in your PackageInfo.g.
+#!
+#!
+#! It can scan your package for &AutoDoc; based documentation (by using &AutoDoc;
+#! tags and the Autodoc command.
+#! This will
+#! produce further XML files to be used as part of the package manual.
+#!
+#!
+#! It can use &GAPDoc; to generate PDF, text and HTML (with
+#! MathJaX enabled) documentation from the &GAPDoc; XML files it
+#! generated as well as additional such files provided by you. For
+#! this, it invokes
+#! to convert the XML sources, and it also instructs &GAPDoc; to copy
+#! supplementary files (such as CSS style files) into your doc directory
+#! (see ).
+#!
+#!
+#! For more information and some examples, please refer to Chapter .
+#!
+#! The parameters have the following meanings:
+#!
+#!
+#! package_name
+#!
+#! The name of the package whose documentation should be(re)generated.
+#!
+#!
+#!
+#! option_record
+#!
+#! option_record can be a record with some additional options.
+#! The following are currently supported:
+#!
+#! dir
+#!
+#! This should be a string containing a (relative) path or a
+#! Directory() object specifying where the package documentation
+#! (i.e. the &GAPDoc; XML files) are stored.
+#!
+#! Default value: "doc/".
+#!
+#! scaffold
+#!
+#! This controls whether and how to generate scaffold XML files
+#! for the main and title page of the package's documentation.
+#!
+#! The value should be either true, false or a
+#! record. If it is a record or true (the latter is
+#! equivalent to specifying an empty record), then this feature is
+#! enabled. It is also enabled if opt.scaffold is missing but the
+#! package's info record in PackageInfo.g has an AutoDoc entry.
+#! In all other cases (in particular if opt.scaffold is
+#! false), scaffolding is disabled.
+#!
+#!
+#! If opt.scaffold is a record, it may contain the following entries.
+#!
+#### TODO: mention merging with PackageInfo.AutoDoc!
+#!
+#!
+#! includes
+#!
+#! A list of XML files to be included in the body of the main XML file.
+#! If you specify this list and also are using &AutoDoc; to document
+#! your operations with &AutoDoc; comments,
+#! you can add AutoDocMainFile.xml to this list
+#! to control at which point the documentation produced by &AutoDoc;
+#! is inserted. If you do not do this, it will be added after the last
+#! of your own XML files.
+#!
+#!
+#! appendix
+#!
+#! This entry is similar to opt.scaffold.includes but is used
+#! to specify files to include after the main body of the manual,
+#! i.e. typically appendices.
+#!
+#!
+#! bib
+#!
+#! The name of a bibliography file, in Bibtex or XML format.
+#! If this key is not set, but there is a file doc/PACKAGENAME.bib
+#! then it is assumed that you want to use this as your bibliography.
+#!
+#!
+#### TODO: The 'entities' param is a bit strange. We should probably change it to be a bit more
+#### general, as one might want to define other entities... For now, we do not document it
+#### to leave us the choice of revising how it works.
+####
+#### entities
+####
+#### A list of package names or other entities which are used to define corresponding XML entities.
+#### For example, if set to a list containing the string SomePackage,
+#### then the following is added to the XML preamble:
+#### SomePackage'>]]>
+#### This allows you to write &SomePackage; in your documentation
+#### to reference that package. If another type of entity is desired, one can simply add,
+#### instead of a string, add a two entry list a to the list. It will be handled as
+#### a[ 2 ]'>]]>,
+#### so please be careful.
+####
+#!
+#! TitlePage
+#!
+#! A record whose entries are used to embellish the generated titlepage
+#! for the package manual with extra information, such as a copyright
+#! statement or acknowledgments. To this end, the names of the record
+#! components are used as XML element names, and the values of the
+#! components are outputted as content of these XML elements. For
+#! example, you could pass the following record to set a custom
+#! acknowledgements text:
+#!
+#! For a list of valid entries in the titlepage, please refer to the
+#! &GAPDoc; manual, specifically section
+#! and following.
+#!
+#! document_class
+#!
+#! Sets the document class of the resulting pdf. The value can either be a string
+#! which has to be the name of the new document class, a list containing this string, or
+#! a list of two strings. Then the first one has to be the document class name, the second one
+#! the option string ( contained in [ ] ) in LaTeX.
+#!
+#! latex_header_file
+#!
+#! Replaces the standard header from &GAPDoc; completely with the header in this LaTeX file.
+#! Please be careful here, and look at GAPDoc's latexheader.tex file for an example.
+#!
+#! gapdoc_latex_options
+#!
+#! Must be a record with entries which can be understood by SetGapDocLaTeXOptions. Each entry can be a string, which
+#! will be given to &GAPDoc; directly, or a list containing of two entries: The first one must be the string "file",
+#! the second one a filename. This file will be read and then its content is passed to &GAPDoc; as option with the name
+#! of the entry.
+#!
+#!
+#!
+#!
+#!
+#!
+#! autodoc
+#!
+#! This controls whether and how to generate addition XML documentation files
+#! by scanning for &AutoDoc; documentation comments.
+#!
+#! The value should be either true, false or a
+#! record. If it is a record or true (the latter is
+#! equivalent to specifying an empty record), then this feature is
+#! enabled. It is also enabled if opt.autodoc is missing but the
+#! package depends (directly) on the &AutoDoc; package.
+#! In all other cases (in particular if opt.autodoc is
+#! false), this feature is disabled.
+#!
+#!
+#! If opt.autodoc is a record, it may contain the following entries.
+#!
+#!
+#!
+#! files
+#!
+#! A list of files (given by paths relative to the package directory)
+#! to be scanned for &AutoDoc; documentation comments.
+#! Usually it is more convenient to use autodoc.scan_dirs, see below.
+#!
+#!
+#! scan_dirs
+#!
+#! A list of subdirectories of the package directory (given as relative paths)
+#! which &AutoDoc; then scans for .gi, .gd and .g files; all of these files
+#! are then scanned for &AutoDoc; documentation comments.
+#!
+#! Default value: [ "gap", "lib", "examples", "examples/doc" ].
+#!
+#!
+#! level
+#!
+#! This defines the level of the created documentation. The default value is 0.
+#! When parts of the manual are declared with a higher value
+#! they will not be printed into the manual.
+#!
+#!
+#### TODO: Document section_intros later on.
+#### However, note that thanks to the new AutoDoc comment syntax, the only remaining
+#### use for this seems to be the ability to specify the order of chapters and
+#### sections.
+#### section_intros
+####
+#### TODO.
+####
+#!
+#!
+#!
+#!
+#!
+#! gapdoc
+#!
+#! This controls whether and how to invoke &GAPDoc; to create HTML, PDF and text
+#! files from your various XML files.
+#!
+#! The value should be either true, false or a
+#! record. If it is a record or true (the latter is
+#! equivalent to specifying an empty record), then this feature is
+#! enabled. It is also enabled if opt.gapdoc is missing.
+#! In all other cases (in particular if opt.gapdoc is
+#! false), this feature is disabled.
+#!
+#!
+#! If opt.gapdoc is a record, it may contain the following entries.
+#!
+#!
+#!
+#!
+#### Note: 'main' is strictly speaking also used for the scaffold.
+#### However, if one uses the scaffolding mechanism, then it is not
+#### really necessary to specify a custom name for the main XML file.
+#### Thus, the purpose of this parameter is to cater for packages
+#### that have existing documentation using a different XML name,
+#### and which do not wish to use scaffolding.
+####
+#### This explain why we only allow specifying gapdoc.main.
+#### The scaffolding code will still honor it, though, just in case.
+#! main
+#!
+#! The name of the main XML file of the package manual.
+#! This exists primarily to support packages with existing manual
+#! which use a filename here which differs from the default.
+#! In particular, specifying this is unnecessary when using scaffolding.
+#!
+#! Default value: PACKAGENAME.xml.
+#!
+#!
+#! files
+#!
+#! A list of files (given by paths relative to the package directory)
+#! to be scanned for &GAPDoc; documentation comments.
+#! Usually it is more convenient to use gapdoc.scan_dirs, see below.
+#!
+#!
+#! scan_dirs
+#!
+#! A list of subdirectories of the package directory (given as relative paths)
+#! which &AutoDoc; then scans for .gi, .gd and .g files; all of these files
+#! are then scanned for &GAPDoc; documentation comments.
+#!
+#! Default value: [ "gap", "lib", "examples", "examples/doc" ].
+#!
+#!
+#!
+#!
+## This is the maketest part. Still under construction.
+#! maketest
+#!
+#! The maketest item can be true or a record. When it is true,
+#! a simple maketest.g is created in the main package directory,
+#! which can be used to test the examples from the manual. As a record,
+#! the entry can have the following entries itself, to specify some options.
+#!
+#! filename
+#!
+#! Sets the name of the test file.
+#!
+#! commands
+#!
+#! A list of strings, each one a command, which
+#! will be executed at the beginning of the test file.
+#!
+#!
+#!
+#!
+#!
+#!
+#!
+#!
+#! @Returns nothing
+#! @Arguments package_name[, option_record ]
+#! @ChapterInfo AutoDoc, The AutoDoc() function
+DeclareGlobalFunction( "AutoDoc" );
+
diff --git a/samples/GAP/Magic.gi b/samples/GAP/Magic.gi
new file mode 100644
index 00000000..5202a1de
--- /dev/null
+++ b/samples/GAP/Magic.gi
@@ -0,0 +1,534 @@
+#############################################################################
+##
+## Magic.gi AutoDoc package
+##
+## Copyright 2013, Max Horn, JLU Giessen
+## Sebastian Gutsche, University of Kaiserslautern
+##
+#############################################################################
+
+# Check if a string has the given suffix or not. Another
+# name for this would "StringEndsWithOtherString".
+# For example, AUTODOC_HasSuffix("file.gi", ".gi") returns
+# true while AUTODOC_HasSuffix("file.txt", ".gi") returns false.
+BindGlobal( "AUTODOC_HasSuffix",
+function(str, suffix)
+ local n, m;
+ n := Length(str);
+ m := Length(suffix);
+ return n >= m and str{[n-m+1..n]} = suffix;
+end );
+
+# Given a string containing a ".", , return its suffix,
+# i.e. the bit after the last ".". For example, given "test.txt",
+# it returns "txt".
+BindGlobal( "AUTODOC_GetSuffix",
+function(str)
+ local i;
+ i := Length(str);
+ while i > 0 and str[i] <> '.' do i := i - 1; od;
+ if i < 0 then return ""; fi;
+ return str{[i+1..Length(str)]};
+end );
+
+# Check whether the given directory exists, and if not, attempt
+# to create it.
+BindGlobal( "AUTODOC_CreateDirIfMissing",
+function(d)
+ local tmp;
+ if not IsDirectoryPath(d) then
+ tmp := CreateDir(d); # Note: CreateDir is currently undocumented
+ if tmp = fail then
+ Error("Cannot create directory ", d, "\n",
+ "Error message: ", LastSystemError().message, "\n");
+ return false;
+ fi;
+ fi;
+ return true;
+end );
+
+
+# Scan the given (by name) subdirs of a package dir for
+# files with one of the given extensions, and return the corresponding
+# filenames, as relative paths (relative to the package dir).
+#
+# For example, the invocation
+# AUTODOC_FindMatchingFiles("AutoDoc", [ "gap/" ], [ "gi", "gd" ]);
+# might return a list looking like
+# [ "gap/AutoDocMainFunction.gd", "gap/AutoDocMainFunction.gi", ... ]
+BindGlobal( "AUTODOC_FindMatchingFiles",
+function (pkg, subdirs, extensions)
+ local d_rel, d, tmp, files, result;
+
+ result := [];
+
+ for d_rel in subdirs do
+ # Get the absolute path to the directory in side the package...
+ d := DirectoriesPackageLibrary( pkg, d_rel );
+ if IsEmpty( d ) then
+ continue;
+ fi;
+ d := d[1];
+ # ... but also keep the relative path (such as "gap")
+ d_rel := Directory( d_rel );
+
+ files := DirectoryContents( d );
+ Sort( files );
+ for tmp in files do
+ if not AUTODOC_GetSuffix( tmp ) in [ "g", "gi", "gd", "autodoc" ] then
+ continue;
+ fi;
+ if not IsReadableFile( Filename( d, tmp ) ) then
+ continue;
+ fi;
+ Add( result, Filename( d_rel, tmp ) );
+ od;
+ od;
+ return result;
+end );
+
+
+# AutoDoc(pkg[, opt])
+#
+## Make this function callable with the package_name AutoDocWorksheet.
+## Which will then create a worksheet!
+InstallGlobalFunction( AutoDoc,
+function( arg )
+ local pkg, package_info, opt, scaffold, gapdoc, maketest,
+ autodoc, pkg_dir, doc_dir, doc_dir_rel, d, tmp,
+ title_page, tree, is_worksheet, position_document_class, i, gapdoc_latex_option_record;
+
+ pkg := arg[1];
+
+ if LowercaseString( pkg ) = "autodocworksheet" then
+ is_worksheet := true;
+ package_info := rec( );
+ pkg_dir := DirectoryCurrent( );
+ else
+ is_worksheet := false;
+ package_info := PackageInfo( pkg )[ 1 ];
+ pkg_dir := DirectoriesPackageLibrary( pkg, "" )[1];
+ fi;
+
+ if Length(arg) >= 2 then
+ opt := arg[2];
+ else
+ opt := rec();
+ fi;
+
+ # Check for certain user supplied options, and if present, add them
+ # to the opt record.
+ tmp := function( key )
+ local val;
+ val := ValueOption( key );
+ if val <> fail then
+ opt.(key) := val;
+ fi;
+ end;
+
+ tmp( "dir" );
+ tmp( "scaffold" );
+ tmp( "autodoc" );
+ tmp( "gapdoc" );
+ tmp( "maketest" );
+
+ #
+ # Setup the output directory
+ #
+ if not IsBound( opt.dir ) then
+ doc_dir := "doc";
+ elif IsString( opt.dir ) or IsDirectory( opt.dir ) then
+ doc_dir := opt.dir;
+ else
+ Error( "opt.dir must be a string containing a path, or a directory object" );
+ fi;
+
+ if IsString( doc_dir ) then
+ # Record the relative version of the path
+ doc_dir_rel := Directory( doc_dir );
+
+ # We intentionally do not use
+ # DirectoriesPackageLibrary( pkg, "doc" )
+ # because it returns an empty list if the subdirectory is missing.
+ # But we want to handle that case by creating the directory.
+ doc_dir := Filename(pkg_dir, doc_dir);
+ doc_dir := Directory(doc_dir);
+
+ else
+ # TODO: doc_dir_rel = ... ?
+ fi;
+
+ # Ensure the output directory exists, create it if necessary
+ AUTODOC_CreateDirIfMissing(Filename(doc_dir, ""));
+
+ # Let the developer know where we are generating the documentation.
+ # This helps diagnose problems where multiple instances of a package
+ # are visible to GAP and the wrong one is used for generating the
+ # documentation.
+ # TODO: Using Info() instead of Print?
+ Print( "Generating documentation in ", doc_dir, "\n" );
+
+ #
+ # Extract scaffolding settings, which can be controlled via
+ # opt.scaffold or package_info.AutoDoc. The former has precedence.
+ #
+ if not IsBound(opt.scaffold) then
+ # Default: enable scaffolding if and only if package_info.AutoDoc is present
+ if IsBound( package_info.AutoDoc ) then
+ scaffold := rec( );
+ fi;
+ elif IsRecord(opt.scaffold) then
+ scaffold := opt.scaffold;
+ elif IsBool(opt.scaffold) then
+ if opt.scaffold = true then
+ scaffold := rec();
+ fi;
+ else
+ Error("opt.scaffold must be a bool or a record");
+ fi;
+
+ # Merge package_info.AutoDoc into scaffold
+ if IsBound(scaffold) and IsBound( package_info.AutoDoc ) then
+ AUTODOC_APPEND_RECORD_WRITEONCE( scaffold, package_info.AutoDoc );
+ fi;
+
+ if IsBound( scaffold ) then
+ AUTODOC_WriteOnce( scaffold, "TitlePage", true );
+ AUTODOC_WriteOnce( scaffold, "MainPage", true );
+ fi;
+
+
+ #
+ # Extract AutoDoc settings
+ #
+ if not IsBound(opt.autodoc) and not is_worksheet then
+ # Enable AutoDoc support if the package depends on AutoDoc.
+ tmp := Concatenation( package_info.Dependencies.NeededOtherPackages,
+ package_info.Dependencies.SuggestedOtherPackages );
+ if ForAny( tmp, x -> LowercaseString(x[1]) = "autodoc" ) then
+ autodoc := rec();
+ fi;
+ elif IsRecord(opt.autodoc) then
+ autodoc := opt.autodoc;
+ elif IsBool(opt.autodoc) and opt.autodoc = true then
+ autodoc := rec();
+ fi;
+
+ if IsBound(autodoc) then
+ if not IsBound( autodoc.files ) then
+ autodoc.files := [ ];
+ fi;
+
+ if not IsBound( autodoc.scan_dirs ) and not is_worksheet then
+ autodoc.scan_dirs := [ "gap", "lib", "examples", "examples/doc" ];
+ elif not IsBound( autodoc.scan_dirs ) and is_worksheet then
+ autodoc.scan_dirs := [ ];
+ fi;
+
+ if not IsBound( autodoc.level ) then
+ autodoc.level := 0;
+ fi;
+
+ PushOptions( rec( level_value := autodoc.level ) );
+
+ if not is_worksheet then
+ Append( autodoc.files, AUTODOC_FindMatchingFiles(pkg, autodoc.scan_dirs, [ "g", "gi", "gd" ]) );
+ fi;
+ fi;
+
+ #
+ # Extract GAPDoc settings
+ #
+ if not IsBound( opt.gapdoc ) then
+ # Enable GAPDoc support by default
+ gapdoc := rec();
+ elif IsRecord( opt.gapdoc ) then
+ gapdoc := opt.gapdoc;
+ elif IsBool( opt.gapdoc ) and opt.gapdoc = true then
+ gapdoc := rec();
+ fi;
+
+ #
+ # Extract test settings
+ #
+
+ if IsBound( opt.maketest ) then
+ if IsRecord( opt.maketest ) then
+ maketest := opt.maketest;
+ elif opt.maketest = true then
+ maketest := rec( );
+ fi;
+ fi;
+
+ if IsBound( gapdoc ) then
+
+ if not IsBound( gapdoc.main ) then
+ gapdoc.main := pkg;
+ fi;
+
+ # FIXME: the following may break if a package uses more than one book
+ if IsBound( package_info.PackageDoc ) and IsBound( package_info.PackageDoc[1].BookName ) then
+ gapdoc.bookname := package_info.PackageDoc[1].BookName;
+ elif not is_worksheet then
+ # Default: book name = package name
+ gapdoc.bookname := pkg;
+
+ Print("\n");
+ Print("WARNING: PackageInfo.g is missing a PackageDoc entry!\n");
+ Print("Without this, your package manual will not be recognized by the GAP help system.\n");
+ Print("You can correct this by adding the following to your PackageInfo.g:\n");
+ Print("PackageDoc := rec(\n");
+ Print(" BookName := ~.PackageName,\n");
+ #Print(" BookName := \"", pkg, "\",\n");
+ Print(" ArchiveURLSubset := [\"doc\"],\n");
+ Print(" HTMLStart := \"doc/chap0.html\",\n");
+ Print(" PDFFile := \"doc/manual.pdf\",\n");
+ Print(" SixFile := \"doc/manual.six\",\n");
+ Print(" LongTitle := ~.Subtitle,\n");
+ Print("),\n");
+ Print("\n");
+ fi;
+
+ if not IsBound( gapdoc.files ) then
+ gapdoc.files := [];
+ fi;
+
+ if not IsBound( gapdoc.scan_dirs ) and not is_worksheet then
+ gapdoc.scan_dirs := [ "gap", "lib", "examples", "examples/doc" ];
+ fi;
+
+ if not is_worksheet then
+ Append( gapdoc.files, AUTODOC_FindMatchingFiles(pkg, gapdoc.scan_dirs, [ "g", "gi", "gd" ]) );
+ fi;
+
+ # Attempt to weed out duplicates as they may confuse GAPDoc (this
+ # won't work if there are any non-normalized paths in the list).
+ gapdoc.files := Set( gapdoc.files );
+
+ # Convert the file paths in gapdoc.files, which are relative to
+ # the package directory, to paths which are relative to the doc directory.
+ # For this, we assume that doc_dir_rel is normalized (e.g.
+ # it does not contains '//') and relative.
+ d := Number( Filename( doc_dir_rel, "" ), x -> x = '/' );
+ d := Concatenation( ListWithIdenticalEntries(d, "../") );
+ gapdoc.files := List( gapdoc.files, f -> Concatenation( d, f ) );
+ fi;
+
+
+ # read tree
+ # FIXME: shouldn't tree be declared inside of an 'if IsBound(autodoc)' section?
+ tree := DocumentationTree( );
+
+ if IsBound( autodoc ) then
+ if IsBound( autodoc.section_intros ) then
+ AUTODOC_PROCESS_INTRO_STRINGS( autodoc.section_intros : Tree := tree );
+ fi;
+
+ AutoDocScanFiles( autodoc.files : PackageName := pkg, Tree := tree );
+ fi;
+
+ if is_worksheet then
+ # FIXME: We use scaffold and autodoc here without checking whether
+ # they are bound. Does that mean worksheets always use them?
+ if IsRecord( scaffold.TitlePage ) and IsBound( scaffold.TitlePage.Title ) then
+ pkg := scaffold.TitlePage.Title;
+
+ elif IsBound( tree!.TitlePage.Title ) then
+ pkg := tree!.TitlePage.Title;
+
+ elif IsBound( autodoc.files ) and Length( autodoc.files ) > 0 then
+ pkg := autodoc.files[ 1 ];
+
+ while Position( pkg, '/' ) <> fail do
+ Remove( pkg, 1 );
+ od;
+
+ while Position( pkg, '.' ) <> fail do
+ Remove( pkg, Length( pkg ) );
+ od;
+
+ else
+ Error( "could not figure out a title." );
+ fi;
+
+ if not IsString( pkg ) then
+ pkg := JoinStringsWithSeparator( pkg, " " );
+ fi;
+
+ gapdoc.main := ReplacedString( pkg, " ", "_" );
+ gapdoc.bookname := ReplacedString( pkg, " ", "_" );
+ fi;
+
+ #
+ # Generate scaffold
+ #
+ gapdoc_latex_option_record := rec( );
+
+ if IsBound( scaffold ) then
+ ## Syntax is [ "class", [ "options" ] ]
+ if IsBound( scaffold.document_class ) then
+ position_document_class := PositionSublist( GAPDoc2LaTeXProcs.Head, "documentclass" );
+
+ if IsString( scaffold.document_class ) then
+ scaffold.document_class := [ scaffold.document_class ];
+ fi;
+
+ if position_document_class = fail then
+ Error( "something is wrong with the LaTeX header" );
+ fi;
+
+ GAPDoc2LaTeXProcs.Head := Concatenation(
+ GAPDoc2LaTeXProcs.Head{[ 1 .. PositionSublist( GAPDoc2LaTeXProcs.Head, "{", position_document_class ) ]},
+ scaffold.document_class[ 1 ],
+ GAPDoc2LaTeXProcs.Head{[ PositionSublist( GAPDoc2LaTeXProcs.Head, "}", position_document_class ) .. Length( GAPDoc2LaTeXProcs.Head ) ]} );
+
+ if Length( scaffold.document_class ) = 2 then
+
+ GAPDoc2LaTeXProcs.Head := Concatenation(
+ GAPDoc2LaTeXProcs.Head{[ 1 .. PositionSublist( GAPDoc2LaTeXProcs.Head, "[", position_document_class ) ]},
+ scaffold.document_class[ 2 ],
+ GAPDoc2LaTeXProcs.Head{[ PositionSublist( GAPDoc2LaTeXProcs.Head, "]", position_document_class ) .. Length( GAPDoc2LaTeXProcs.Head ) ]} );
+ fi;
+ fi;
+
+ if IsBound( scaffold.latex_header_file ) then
+ GAPDoc2LaTeXProcs.Head := StringFile( scaffold.latex_header_file );
+ fi;
+
+ if IsBound( scaffold.gapdoc_latex_options ) then
+ if IsRecord( scaffold.gapdoc_latex_options ) then
+ for i in RecNames( scaffold.gapdoc_latex_options ) do
+ if not IsString( scaffold.gapdoc_latex_options.( i ) )
+ and IsList( scaffold.gapdoc_latex_options.( i ) )
+ and LowercaseString( scaffold.gapdoc_latex_options.( i )[ 1 ] ) = "file" then
+ scaffold.gapdoc_latex_options.( i ) := StringFile( scaffold.gapdoc_latex_options.( i )[ 2 ] );
+ fi;
+ od;
+
+ gapdoc_latex_option_record := scaffold.gapdoc_latex_options;
+ fi;
+ fi;
+
+ if not IsBound( scaffold.includes ) then
+ scaffold.includes := [ ];
+ fi;
+
+ if IsBound( autodoc ) then
+ # If scaffold.includes is already set, then we add
+ # AutoDocMainFile.xml to it, but *only* if it not already
+ # there. This way, package authors can control where
+ # it is put in their includes list.
+ if not "AutoDocMainFile.xml" in scaffold.includes then
+ Add( scaffold.includes, "AutoDocMainFile.xml" );
+ fi;
+ fi;
+
+ if IsBound( scaffold.bib ) and IsBool( scaffold.bib ) then
+ if scaffold.bib = true then
+ scaffold.bib := Concatenation( pkg, ".bib" );
+ else
+ Unbind( scaffold.bib );
+ fi;
+ elif not IsBound( scaffold.bib ) then
+ # If there is a doc/PKG.bib file, assume that we want to reference it in the scaffold.
+ if IsReadableFile( Filename( doc_dir, Concatenation( pkg, ".bib" ) ) ) then
+ scaffold.bib := Concatenation( pkg, ".bib" );
+ fi;
+ fi;
+
+ AUTODOC_WriteOnce( scaffold, "index", true );
+
+ if IsBound( gapdoc ) then
+ if AUTODOC_GetSuffix( gapdoc.main ) = "xml" then
+ scaffold.main_xml_file := gapdoc.main;
+ else
+ scaffold.main_xml_file := Concatenation( gapdoc.main, ".xml" );
+ fi;
+ fi;
+
+ # TODO: It should be possible to only rebuild the title page. (Perhaps also only the main page? but this is less important)
+ if IsBound( scaffold.TitlePage ) then
+ if IsRecord( scaffold.TitlePage ) then
+ title_page := scaffold.TitlePage;
+ else
+ title_page := rec( );
+ fi;
+
+ AUTODOC_WriteOnce( title_page, "dir", doc_dir );
+ AUTODOC_APPEND_RECORD_WRITEONCE( title_page, tree!.TitlePage );
+
+ if not is_worksheet then
+ AUTODOC_APPEND_RECORD_WRITEONCE( title_page, ExtractTitleInfoFromPackageInfo( pkg ) );
+ fi;
+
+ CreateTitlePage( title_page );
+ fi;
+
+ if IsBound( scaffold.MainPage ) and scaffold.MainPage <> false then
+ scaffold.dir := doc_dir;
+ scaffold.book_name := pkg;
+ CreateMainPage( scaffold );
+ fi;
+ fi;
+
+ #
+ # Run AutoDoc
+ #
+ if IsBound( autodoc ) then
+ WriteDocumentation( tree, doc_dir );
+ fi;
+
+
+ #
+ # Run GAPDoc
+ #
+ if IsBound( gapdoc ) then
+
+ # Ask GAPDoc to use UTF-8 as input encoding for LaTeX, as the XML files
+ # of the documentation are also in UTF-8 encoding, and may contain characters
+ # not contained in the default Latin 1 encoding.
+ SetGapDocLaTeXOptions( "utf8", gapdoc_latex_option_record );
+
+ MakeGAPDocDoc( doc_dir, gapdoc.main, gapdoc.files, gapdoc.bookname, "MathJax" );
+
+ CopyHTMLStyleFiles( Filename( doc_dir, "" ) );
+
+ # The following (undocumented) API is there for compatibility
+ # with old-style gapmacro.tex based package manuals. It
+ # produces a manual.lab file which those packages can use if
+ # they wish to link to things in the manual we are currently
+ # generating. This can probably be removed eventually, but for
+ # now, doing it does not hurt.
+
+ # FIXME: It seems that this command does not work if pdflatex
+ # is not present. Maybe we should remove it.
+
+ if not is_worksheet then
+ GAPDocManualLab( pkg );
+ fi;
+
+ fi;
+
+ if IsBound( maketest ) then
+
+ AUTODOC_WriteOnce( maketest, "filename", "maketest.g" );
+ AUTODOC_WriteOnce( maketest, "folder", pkg_dir );
+ AUTODOC_WriteOnce( maketest, "scan_dir", doc_dir );
+ AUTODOC_WriteOnce( maketest, "files_to_scan", gapdoc.files );
+
+ if IsString( maketest.folder ) then
+ maketest.folder := Directory( maketest.folder );
+ fi;
+
+ if IsString( maketest.scan_dir ) then
+ maketest.scan_dir := Directory( maketest.scan_dir );
+ fi;
+
+ AUTODOC_WriteOnce( maketest, "commands", [ ] );
+ AUTODOC_WriteOnce( maketest, "book_name", gapdoc.main );
+
+ CreateMakeTest( maketest );
+ fi;
+
+ return true;
+end );
diff --git a/samples/GAP/PackageInfo.g b/samples/GAP/PackageInfo.g
new file mode 100644
index 00000000..68e5ecdb
--- /dev/null
+++ b/samples/GAP/PackageInfo.g
@@ -0,0 +1,115 @@
+#############################################################################
+##
+## PackageInfo.g for the package `cvec' Max Neunhoeffer
+##
+## (created from Frank Lübeck's PackageInfo.g template file)
+##
+
+SetPackageInfo( rec(
+
+PackageName := "cvec",
+Subtitle := "Compact vectors over finite fields",
+Version := "2.5.1",
+Date := "04/04/2014", # dd/mm/yyyy format
+
+## Information about authors and maintainers.
+Persons := [
+ rec(
+ LastName := "Neunhoeffer",
+ FirstNames := "Max",
+ IsAuthor := true,
+ IsMaintainer := false,
+ Email := "neunhoef@mcs.st-and.ac.uk",
+ WWWHome := "http://www-groups.mcs.st-and.ac.uk/~neunhoef/",
+ PostalAddress := Concatenation( [
+ "School of Mathematics and Statistics\n",
+ "University of St Andrews\n",
+ "Mathematical Institute\n",
+ "North Haugh\n",
+ "St Andrews, Fife KY16 9SS\n",
+ "Scotland, UK" ] ),
+ Place := "St Andrews",
+ Institution := "University of St Andrews"
+ ),
+],
+
+## Status information. Currently the following cases are recognized:
+## "accepted" for successfully refereed packages
+## "deposited" for packages for which the GAP developers agreed
+## to distribute them with the core GAP system
+## "dev" for development versions of packages
+## "other" for all other packages
+##
+# Status := "accepted",
+Status := "deposited",
+
+## You must provide the next two entries if and only if the status is
+## "accepted" because is was successfully refereed:
+# format: 'name (place)'
+# CommunicatedBy := "Mike Atkinson (St. Andrews)",
+#CommunicatedBy := "",
+# format: mm/yyyy
+# AcceptDate := "08/1999",
+#AcceptDate := "",
+
+PackageWWWHome := "http://neunhoef.github.io/cvec/",
+README_URL := Concatenation(~.PackageWWWHome, "README"),
+PackageInfoURL := Concatenation(~.PackageWWWHome, "PackageInfo.g"),
+ArchiveURL := Concatenation("https://github.com/neunhoef/cvec/",
+ "releases/download/v", ~.Version,
+ "/cvec-", ~.Version),
+ArchiveFormats := ".tar.gz .tar.bz2",
+
+## Here you must provide a short abstract explaining the package content
+## in HTML format (used on the package overview Web page) and an URL
+## for a Webpage with more detailed information about the package
+## (not more than a few lines, less is ok):
+## Please, use 'GAP' and
+## 'MyPKG' for specifing package names.
+##
+AbstractHTML :=
+ "This package provides an implementation of compact vectors over finite\
+ fields. Contrary to earlier implementations no table lookups are used\
+ but only word-based processor arithmetic. This allows for bigger finite\
+ fields and higher speed.",
+
+PackageDoc := rec(
+ BookName := "cvec",
+ ArchiveURLSubset := ["doc"],
+ HTMLStart := "doc/chap0.html",
+ PDFFile := "doc/manual.pdf",
+ SixFile := "doc/manual.six",
+ LongTitle := "Compact vectors over finite fields",
+),
+
+Dependencies := rec(
+ GAP := ">=4.5.5",
+ NeededOtherPackages := [
+ ["GAPDoc", ">= 1.2"],
+ ["IO", ">= 4.1"],
+ ["orb", ">= 4.2"],
+ ],
+ SuggestedOtherPackages := [],
+ ExternalConditions := []
+),
+
+AvailabilityTest := function()
+ if not "cvec" in SHOW_STAT() and
+ Filename(DirectoriesPackagePrograms("cvec"), "cvec.so") = fail then
+ #Info(InfoWarning, 1, "cvec: kernel cvec functions not available.");
+ return fail;
+ fi;
+ return true;
+end,
+
+## *Optional*, but recommended: path relative to package root to a file which
+## contains as many tests of the package functionality as sensible.
+#TestFile := "tst/testall.g",
+
+## *Optional*: Here you can list some keyword related to the topic
+## of the package.
+Keywords := []
+
+));
+
+
diff --git a/samples/GAP/example.gd b/samples/GAP/example.gd
new file mode 100644
index 00000000..c285ea32
--- /dev/null
+++ b/samples/GAP/example.gd
@@ -0,0 +1,23 @@
+#############################################################################
+##
+#W example.gd
+##
+## This file contains a sample of a GAP declaration file.
+##
+DeclareProperty( "SomeProperty", IsLeftModule );
+DeclareGlobalFunction( "SomeGlobalFunction" );
+
+
+#############################################################################
+##
+#C IsQuuxFrobnicator()
+##
+##
+##
+##
+##
+## Tests whether R is a quux frobnicator.
+##
+##
+##
+DeclareSynonym( "IsQuuxFrobnicator", IsField and IsGroup );
diff --git a/samples/GAP/example.gi b/samples/GAP/example.gi
new file mode 100644
index 00000000..c9c5e55d
--- /dev/null
+++ b/samples/GAP/example.gi
@@ -0,0 +1,64 @@
+#############################################################################
+##
+#W example.gd
+##
+## This file contains a sample of a GAP implementation file.
+##
+
+
+#############################################################################
+##
+#M SomeOperation( )
+##
+## performs some operation on
+##
+InstallMethod( SomeProperty,
+ "for left modules",
+ [ IsLeftModule ], 0,
+ function( M )
+ if IsFreeLeftModule( M ) and not IsTrivial( M ) then
+ return true;
+ fi;
+ TryNextMethod();
+ end );
+
+
+
+#############################################################################
+##
+#F SomeGlobalFunction( )
+##
+## A global variadic funfion.
+##
+InstallGlobalFunction( SomeGlobalFunction, function( arg )
+ if Length( arg ) = 3 then
+ return arg[1] + arg[2] * arg[3];
+ elif Length( arg ) = 2 then
+ return arg[1] - arg[2]
+ else
+ Error( "usage: SomeGlobalFunction( , [, ] )" );
+ fi;
+ end );
+
+
+#
+# A plain function.
+#
+SomeFunc := function(x, y)
+ local z, func, tmp, j;
+ z := x * 1.0;
+ y := 17^17 - y;
+ func := a -> a mod 5;
+ tmp := List( [1..50], func );
+ while y > 0 do
+ for j in tmp do
+ Print(j, "\n");
+ od;
+ repeat
+ y := y - 1;
+ until 0 < 1;
+ y := y -1;
+ od;
+ return z;
+end;
+
\ No newline at end of file
diff --git a/samples/GAP/vspc.gd b/samples/GAP/vspc.gd
new file mode 100644
index 00000000..d381e6f1
--- /dev/null
+++ b/samples/GAP/vspc.gd
@@ -0,0 +1,822 @@
+#############################################################################
+##
+#W vspc.gd GAP library Thomas Breuer
+##
+##
+#Y Copyright (C) 1997, Lehrstuhl D für Mathematik, RWTH Aachen, Germany
+#Y (C) 1998 School Math and Comp. Sci., University of St Andrews, Scotland
+#Y Copyright (C) 2002 The GAP Group
+##
+## This file declares the operations for vector spaces.
+##
+## The operations for bases of free left modules can be found in the file
+## lib/basis.gd.
+##
+
+
+#############################################################################
+##
+#C IsLeftOperatorRing()
+##
+##
+##
+##
+##
+##
+##
+##
+DeclareSynonym( "IsLeftOperatorRing",
+ IsLeftOperatorAdditiveGroup and IsRing and IsAssociativeLOpDProd );
+#T really?
+
+
+#############################################################################
+##
+#C IsLeftOperatorRingWithOne()
+##
+##
+##
+##
+##
+##
+##
+##
+DeclareSynonym( "IsLeftOperatorRingWithOne",
+ IsLeftOperatorAdditiveGroup and IsRingWithOne
+ and IsAssociativeLOpDProd );
+#T really?
+
+
+#############################################################################
+##
+#C IsLeftVectorSpace( )
+#C IsVectorSpace( )
+##
+## <#GAPDoc Label="IsLeftVectorSpace">
+##
+##
+##
+##
+##
+## A vector space in &GAP; is a free left module
+## (see ) over a division ring
+## (see Chapter ).
+##
+## Whenever we talk about an F-vector space V then V is
+## an additive group (see ) on which the
+## division ring F acts via multiplication from the left such that
+## this action and the addition in V are left and right distributive.
+## The division ring F can be accessed as value of the attribute
+## .
+##
+## Vector spaces in &GAP; are always left vector spaces,
+## and are
+## synonyms.
+##
+##
+## <#/GAPDoc>
+##
+DeclareSynonym( "IsLeftVectorSpace",
+ IsLeftModule and IsLeftActedOnByDivisionRing );
+
+DeclareSynonym( "IsVectorSpace", IsLeftVectorSpace );
+
+InstallTrueMethod( IsFreeLeftModule,
+ IsLeftModule and IsLeftActedOnByDivisionRing );
+
+
+#############################################################################
+##
+#F IsGaussianSpace( )
+##
+## <#GAPDoc Label="IsGaussianSpace">
+##
+##
+##
+##
+## The filter (see )
+## for the row space (see )
+## or matrix space (see ) V
+## over the field F, say,
+## indicates that the entries of all row vectors or matrices in V,
+## respectively, are all contained in F.
+## In this case, V is called a Gaussian vector space.
+## Bases for Gaussian spaces can be computed using Gaussian elimination for
+## a given list of vector space generators.
+## mats:= [ [[1,1],[2,2]], [[3,4],[0,1]] ];;
+## gap> V:= VectorSpace( Rationals, mats );;
+## gap> IsGaussianSpace( V );
+## true
+## gap> mats[1][1][1]:= E(4);; # an element in an extension field
+## gap> V:= VectorSpace( Rationals, mats );;
+## gap> IsGaussianSpace( V );
+## false
+## gap> V:= VectorSpace( Field( Rationals, [ E(4) ] ), mats );;
+## gap> IsGaussianSpace( V );
+## true
+## ]]>
+##
+##
+## <#/GAPDoc>
+##
+DeclareFilter( "IsGaussianSpace", IsVectorSpace );
+
+InstallTrueMethod( IsGaussianSpace,
+ IsVectorSpace and IsFullMatrixModule );
+
+InstallTrueMethod( IsGaussianSpace,
+ IsVectorSpace and IsFullRowModule );
+
+
+#############################################################################
+##
+#C IsDivisionRing( )
+##
+## <#GAPDoc Label="IsDivisionRing">
+##
+##
+##
+##
+## A division ring in &GAP; is a nontrivial associative algebra
+## D with a multiplicative inverse for each nonzero element.
+## In &GAP; every division ring is a vector space over a division ring
+## (possibly over itself).
+## Note that being a division ring is thus not a property that a ring can
+## get, because a ring is usually not represented as a vector space.
+##
+## The field of coefficients is stored as the value of the attribute
+## of D.
+##
+##
+## <#/GAPDoc>
+##
+DeclareSynonymAttr( "IsDivisionRing",
+ IsMagmaWithInversesIfNonzero
+ and IsLeftOperatorRingWithOne
+ and IsLeftVectorSpace
+ and IsNonTrivial
+ and IsAssociative
+ and IsEuclideanRing );
+
+
+#############################################################################
+##
+#A GeneratorsOfLeftVectorSpace( )
+#A GeneratorsOfVectorSpace( )
+##
+## <#GAPDoc Label="GeneratorsOfLeftVectorSpace">
+##
+##
+##
+##
+##
+## For an F-vector space V,
+## returns a list of vectors in
+## V that generate V as an F-vector space.
+## GeneratorsOfVectorSpace( FullRowSpace( Rationals, 3 ) );
+## [ [ 1, 0, 0 ], [ 0, 1, 0 ], [ 0, 0, 1 ] ]
+## ]]>
+##
+##
+## <#/GAPDoc>
+##
+DeclareSynonymAttr( "GeneratorsOfLeftVectorSpace",
+ GeneratorsOfLeftOperatorAdditiveGroup );
+
+DeclareSynonymAttr( "GeneratorsOfVectorSpace",
+ GeneratorsOfLeftOperatorAdditiveGroup );
+
+
+#############################################################################
+##
+#A CanonicalBasis( )
+##
+## <#GAPDoc Label="CanonicalBasis">
+##
+##
+##
+##
+## If the vector space V supports a canonical basis then
+## returns this basis,
+## otherwise fail is returned.
+##
+## The defining property of a canonical basis is that its vectors are
+## uniquely determined by the vector space.
+## If canonical bases exist for two vector spaces over the same left acting
+## domain (see ) then the equality of
+## these vector spaces can be decided by comparing the canonical bases.
+##
+## The exact meaning of a canonical basis depends on the type of V.
+## Canonical bases are defined for example for Gaussian row and matrix
+## spaces (see ).
+##
+## If one designs a new kind of vector spaces
+## (see ) and
+## defines a canonical basis for these spaces then the
+## method one installs
+## (see )
+## must not call .
+## On the other hand, one probably should install a
+## method that simply calls ,
+## the value of the method
+## (see and
+## )
+## being CANONICAL_BASIS_FLAGS.
+## vecs:= [ [ 1, 2, 3 ], [ 1, 1, 1 ], [ 1, 1, 1 ] ];;
+## gap> V:= VectorSpace( Rationals, vecs );;
+## gap> B:= CanonicalBasis( V );
+## CanonicalBasis( )
+## gap> BasisVectors( B );
+## [ [ 1, 0, -1 ], [ 0, 1, 2 ] ]
+## ]]>
+##
+##
+## <#/GAPDoc>
+##
+DeclareAttribute( "CanonicalBasis", IsFreeLeftModule );
+
+
+#############################################################################
+##
+#F IsRowSpace( )
+##
+## <#GAPDoc Label="IsRowSpace">
+##
+##
+##
+##
+## A row space in &GAP; is a vector space that consists of
+## row vectors (see Chapter ).
+##
+##
+## <#/GAPDoc>
+##
+DeclareSynonym( "IsRowSpace", IsRowModule and IsVectorSpace );
+
+
+#############################################################################
+##
+#F IsGaussianRowSpace( )
+##
+##
+##
+##
+##
+## A row space is Gaussian if the left acting domain contains all
+## scalars that occur in the vectors.
+## Thus one can use Gaussian elimination in the calculations.
+##
+## (Otherwise the space is non-Gaussian.
+## We will need a flag for this to write down methods that delegate from
+## non-Gaussian spaces to Gaussian ones.)
+##
+##
+##
+##
+DeclareSynonym( "IsGaussianRowSpace", IsGaussianSpace and IsRowSpace );
+
+
+#############################################################################
+##
+#F IsNonGaussianRowSpace( )
+##
+##
+##
+##
+##
+## If an F-vector space V is in the filter
+## then this expresses that V
+## consists of row vectors (see ) such
+## that not all entries in these row vectors are contained in F
+## (so Gaussian elimination cannot be used to compute an F-basis
+## from a list of vector space generators),
+## and that V is handled via the mechanism of nice bases
+## (see ) in the following way.
+## Let K be the field spanned by the entries of all vectors in
+## V.
+## Then the value of V is
+## a basis B of the field extension K / ( K \cap F ),
+## and the value of v \in V
+## is defined by replacing each entry of v by the list of its
+## B-coefficients, and then forming the concatenation.
+##
+## So the associated nice vector space is a Gaussian row space
+## (see ).
+##
+##
+##
+DeclareHandlingByNiceBasis( "IsNonGaussianRowSpace",
+ "for non-Gaussian row spaces" );
+
+
+#############################################################################
+##
+#F IsMatrixSpace( )
+##
+## <#GAPDoc Label="IsMatrixSpace">
+##
+##
+##
+##
+## A matrix space in &GAP; is a vector space that consists of matrices
+## (see Chapter ).
+##
+##
+## <#/GAPDoc>
+##
+DeclareSynonym( "IsMatrixSpace", IsMatrixModule and IsVectorSpace );
+
+
+#############################################################################
+##
+#F IsGaussianMatrixSpace( )
+##
+##
+##
+##
+##
+## A matrix space is Gaussian if the left acting domain contains all
+## scalars that occur in the vectors.
+## Thus one can use Gaussian elimination in the calculations.
+##
+## (Otherwise the space is non-Gaussian.
+## We will need a flag for this to write down methods that delegate from
+## non-Gaussian spaces to Gaussian ones.)
+##
+##
+##
+DeclareSynonym( "IsGaussianMatrixSpace", IsGaussianSpace and IsMatrixSpace );
+
+
+#############################################################################
+##
+#F IsNonGaussianMatrixSpace( )
+##
+##
+##
+##
+##
+## If an F-vector space V is in the filter
+##
+## then this expresses that V consists of matrices
+## (see )
+## such that not all entries in these matrices are contained in F
+## (so Gaussian elimination cannot be used to compute an F-basis
+## from a list of vector space generators),
+## and that V is handled via the mechanism of nice bases
+## (see ) in the following way.
+## Let K be the field spanned by the entries of all vectors in V.
+## The value of V is irrelevant,
+## and the value of v \in V
+## is defined as the concatenation of the rows of v.
+##
+## So the associated nice vector space is a (not necessarily Gaussian)
+## row space (see ).
+##
+##
+##
+DeclareHandlingByNiceBasis( "IsNonGaussianMatrixSpace",
+ "for non-Gaussian matrix spaces" );
+
+
+#############################################################################
+##
+#A NormedRowVectors( ) . . . normed vectors in a Gaussian row space
+##
+## <#GAPDoc Label="NormedRowVectors">
+##
+##
+##
+##
+## For a finite Gaussian row space V
+## (see , ),
+## returns a list of those nonzero
+## vectors in V that have a one in the first nonzero component.
+##
+## The result list can be used as action domain for the action of a matrix
+## group via , which yields the natural action on
+## one-dimensional subspaces of V
+## (see also ).
+## vecs:= NormedRowVectors( GF(3)^2 );
+## [ [ 0*Z(3), Z(3)^0 ], [ Z(3)^0, 0*Z(3) ], [ Z(3)^0, Z(3)^0 ],
+## [ Z(3)^0, Z(3) ] ]
+## gap> Action( GL(2,3), vecs, OnLines );
+## Group([ (3,4), (1,2,4) ])
+## ]]>
+##
+##
+## <#/GAPDoc>
+##
+DeclareAttribute( "NormedRowVectors", IsGaussianSpace );
+
+
+#############################################################################
+##
+#A TrivialSubspace( )
+##
+## <#GAPDoc Label="TrivialSubspace">
+##
+##
+##
+##
+## For a vector space V, returns the
+## subspace of V that consists of the zero vector in V.
+## V:= GF(3)^3;;
+## gap> triv:= TrivialSubspace( V );
+##
+## gap> AsSet( triv );
+## [ [ 0*Z(3), 0*Z(3), 0*Z(3) ] ]
+## ]]>
+##
+##
+## <#/GAPDoc>
+##
+DeclareSynonymAttr( "TrivialSubspace", TrivialSubmodule );
+
+
+#############################################################################
+##
+#F VectorSpace( , [, ][, "basis"] )
+##
+## <#GAPDoc Label="VectorSpace">
+##
+##
+##
+##
+## For a field F and a collection gens of vectors,
+## returns the F-vector space spanned by
+## the elements in gens.
+##
+## The optional argument zero can be used to specify the zero element
+## of the space; zeromust be given if gens is empty.
+## The optional string "basis" indicates that gens is known to
+## be linearly independent over F, in particular the dimension of the
+## vector space is immediately set;
+## note that need not return the basis formed by
+## gens if the string "basis" is given as an argument.
+##
+## V:= VectorSpace( Rationals, [ [ 1, 2, 3 ], [ 1, 1, 1 ] ] );
+##
+## ]]>
+##
+##
+## <#/GAPDoc>
+##
+DeclareGlobalFunction( "VectorSpace" );
+
+
+#############################################################################
+##
+#F Subspace( , [, "basis"] ) . subspace of generated by
+#F SubspaceNC( , [, "basis"] )
+##
+## <#GAPDoc Label="Subspace">
+##
+##
+##
+##
+##
+## For an F-vector space V and a list or collection
+## gens that is a subset of V,
+## returns the F-vector space spanned by
+## gens; if gens is empty then the trivial subspace
+## (see ) of V is returned.
+## The parent (see ) of the returned vector space
+## is set to V.
+##
+## does the same as ,
+## except that it omits the check whether gens is a subset of
+## V.
+##
+## The optional string "basis" indicates that gens is known to
+## be linearly independent over F.
+## In this case the dimension of the subspace is immediately set,
+## and both and do
+## not check whether gens really is linearly independent and
+## whether gens is a subset of V.
+##
+## V:= VectorSpace( Rationals, [ [ 1, 2, 3 ], [ 1, 1, 1 ] ] );;
+## gap> W:= Subspace( V, [ [ 0, 1, 2 ] ] );
+##
+## ]]>
+##
+##
+## <#/GAPDoc>
+##
+DeclareSynonym( "Subspace", Submodule );
+
+DeclareSynonym( "SubspaceNC", SubmoduleNC );
+
+
+#############################################################################
+##
+#O AsVectorSpace( , ) . . . . . . . . . view as -vector space
+##
+## <#GAPDoc Label="AsVectorSpace">
+##
+##
+##
+##
+## Let F be a division ring and D a domain.
+## If the elements in D form an F-vector space then
+## returns this F-vector space,
+## otherwise fail is returned.
+##
+## can be used for example to view a given
+## vector space as a vector space over a smaller or larger division ring.
+## V:= FullRowSpace( GF( 27 ), 3 );
+## ( GF(3^3)^3 )
+## gap> Dimension( V ); LeftActingDomain( V );
+## 3
+## GF(3^3)
+## gap> W:= AsVectorSpace( GF( 3 ), V );
+##
+## gap> Dimension( W ); LeftActingDomain( W );
+## 9
+## GF(3)
+## gap> AsVectorSpace( GF( 9 ), V );
+## fail
+## ]]>
+##
+##
+## <#/GAPDoc>
+##
+DeclareSynonym( "AsVectorSpace", AsLeftModule );
+
+
+#############################################################################
+##
+#O AsSubspace( , ) . . . . . . . . . . . view as subspace of
+##
+## <#GAPDoc Label="AsSubspace">
+##
+##
+##
+##
+## Let V be an F-vector space, and U a collection.
+## If U is a subset of V such that the elements of U
+## form an F-vector space then returns this
+## vector space, with parent set to V
+## (see ).
+## Otherwise fail is returned.
+## V:= VectorSpace( Rationals, [ [ 1, 2, 3 ], [ 1, 1, 1 ] ] );;
+## gap> W:= VectorSpace( Rationals, [ [ 1/2, 1/2, 1/2 ] ] );;
+## gap> U:= AsSubspace( V, W );
+##
+## gap> Parent( U ) = V;
+## true
+## gap> AsSubspace( V, [ [ 1, 1, 1 ] ] );
+## fail
+## ]]>
+##
+##
+## <#/GAPDoc>
+##
+DeclareOperation( "AsSubspace", [ IsVectorSpace, IsCollection ] );
+
+
+#############################################################################
+##
+#F Intersection2Spaces( , , )
+##
+##
+##
+##
+##
+## is a function that takes two arguments V and W which must
+## be finite dimensional vector spaces,
+## and returns the intersection of V and W.
+##
+## If the left acting domains are different then let F be their
+## intersection.
+## The intersection of V and W is computed as intersection of
+## AsStruct( F, V ) and
+## AsStruct( F, V ).
+##
+## If the left acting domains are equal to F then the intersection of
+## V and W is returned either as F-Substruct
+## with the common parent of V and W or as
+## F-Struct, in both cases with known basis.
+##
+## This function is used to handle the intersections of two vector spaces,
+## two algebras, two algebras-with-one, two left ideals, two right ideals,
+## two two-sided ideals.
+##
+##
+##
+DeclareGlobalFunction( "Intersection2Spaces" );
+
+
+#############################################################################
+##
+#F FullRowSpace( , )
+##
+## <#GAPDoc Label="FullRowSpace">
+##
+##
+##
+##
+##
+## For a field F and a nonnegative integer n,
+## returns the F-vector space that
+## consists of all row vectors (see ) of
+## length n with entries in F.
+##
+## An alternative to construct this vector space is via
+## F^n.
+## FullRowSpace( GF( 9 ), 3 );
+## ( GF(3^2)^3 )
+## gap> GF(9)^3; # the same as above
+## ( GF(3^2)^3 )
+## ]]>
+##
+##
+## <#/GAPDoc>
+##
+DeclareSynonym( "FullRowSpace", FullRowModule );
+DeclareSynonym( "RowSpace", FullRowModule );
+
+
+#############################################################################
+##
+#F FullMatrixSpace( , , )
+##
+## <#GAPDoc Label="FullMatrixSpace">
+##
+##
+##
+##
+##
+## For a field F and two positive integers m and n,
+## returns the F-vector space that
+## consists of all m by n matrices
+## (see ) with entries in F.
+##
+## If m = n then the result is in fact an algebra
+## (see ).
+##
+## An alternative to construct this vector space is via
+## F^[m,n].
+## FullMatrixSpace( GF(2), 4, 5 );
+## ( GF(2)^[ 4, 5 ] )
+## gap> GF(2)^[ 4, 5 ]; # the same as above
+## ( GF(2)^[ 4, 5 ] )
+## ]]>
+##
+##
+## <#/GAPDoc>
+##
+DeclareSynonym( "FullMatrixSpace", FullMatrixModule );
+DeclareSynonym( "MatrixSpace", FullMatrixModule );
+DeclareSynonym( "MatSpace", FullMatrixModule );
+
+
+#############################################################################
+##
+#C IsSubspacesVectorSpace( )
+##
+## <#GAPDoc Label="IsSubspacesVectorSpace">
+##
+##
+##
+##
+## The domain of all subspaces of a (finite) vector space or of all
+## subspaces of fixed dimension, as returned by
+## (see ) lies in the category
+## .
+## D:= Subspaces( GF(3)^3 );
+## Subspaces( ( GF(3)^3 ) )
+## gap> Size( D );
+## 28
+## gap> iter:= Iterator( D );;
+## gap> NextIterator( iter );
+##
+## gap> NextIterator( iter );
+##
+## gap> IsSubspacesVectorSpace( D );
+## true
+## ]]>
+##
+##
+## <#/GAPDoc>
+##
+DeclareCategory( "IsSubspacesVectorSpace", IsDomain );
+
+
+#############################################################################
+##
+#M IsFinite( ) . . . . . . . . . . . . . . . . . for a subspaces domain
+##
+## Returns `true' if is finite.
+## We allow subspaces domains in `IsSubspacesVectorSpace' only for finite
+## vector spaces.
+##
+InstallTrueMethod( IsFinite, IsSubspacesVectorSpace );
+
+
+#############################################################################
+##
+#A Subspaces( [, ] )
+##
+## <#GAPDoc Label="Subspaces">
+##
+##
+##
+##
+## Called with a finite vector space v,
+## returns the domain of all subspaces of V.
+##
+## Called with V and a nonnegative integer k,
+## returns the domain of all k-dimensional
+## subspaces of V.
+##
+## Special and methods are
+## provided for these domains.
+##
+##
+##
+## <#/GAPDoc>
+##
+DeclareAttribute( "Subspaces", IsLeftModule );
+DeclareOperation( "Subspaces", [ IsLeftModule, IsInt ] );
+
+
+#############################################################################
+##
+#F IsSubspace( , )
+##
+##
+##
+##
+##
+## check that U is a vector space that is contained in V
+##
+##
+##
+##
+DeclareGlobalFunction( "IsSubspace" );
+
+
+#############################################################################
+##
+#A OrthogonalSpaceInFullRowSpace( )
+##
+##
+##
+##
+##
+## For a Gaussian row space U over F,
+##
+## returns a complement of U in the full row space of same vector
+## dimension as U over F.
+##
+##
+##
+DeclareAttribute( "OrthogonalSpaceInFullRowSpace", IsGaussianSpace );
+
+
+#############################################################################
+##
+#P IsVectorSpaceHomomorphism( )
+##
+##
+##
+##
+##
+## A mapping f is a vector space homomorphism (or linear mapping)
+## if the source and range are vector spaces
+## (see )
+## over the same division ring D
+## (see ),
+## and if f( a + b ) = f(a) + f(b) and f( s * a ) = s * f(a)
+## hold for all elements a, b in the source of f and
+## s \in D.
+##
+##
+##
+DeclareProperty( "IsVectorSpaceHomomorphism", IsGeneralMapping );
+
+
+#############################################################################
+##
+#E
+
diff --git a/samples/GAP/vspc.gi b/samples/GAP/vspc.gi
new file mode 100644
index 00000000..b7a88871
--- /dev/null
+++ b/samples/GAP/vspc.gi
@@ -0,0 +1,651 @@
+#############################################################################
+##
+#W vspc.gi GAP library Thomas Breuer
+##
+##
+#Y Copyright (C) 1997, Lehrstuhl D für Mathematik, RWTH Aachen, Germany
+#Y (C) 1998 School Math and Comp. Sci., University of St Andrews, Scotland
+#Y Copyright (C) 2002 The GAP Group
+##
+## This file contains generic methods for vector spaces.
+##
+
+
+#############################################################################
+##
+#M SetLeftActingDomain( , )
+##
+## check whether the left acting domain of the external left set
+## knows that it is a division ring.
+## This is used, e.g., to tell a free module over a division ring
+## that it is a vector space.
+##
+InstallOtherMethod( SetLeftActingDomain,
+ "method to set also 'IsLeftActedOnByDivisionRing'",
+ [ IsAttributeStoringRep and IsLeftActedOnByRing, IsObject ],0,
+ function( extL, D )
+ if HasIsDivisionRing( D ) and IsDivisionRing( D ) then
+ SetIsLeftActedOnByDivisionRing( extL, true );
+ fi;
+ TryNextMethod();
+ end );
+
+
+#############################################################################
+##
+#M IsLeftActedOnByDivisionRing( )
+##
+InstallMethod( IsLeftActedOnByDivisionRing,
+ "method for external left set that is left acted on by a ring",
+ [ IsExtLSet and IsLeftActedOnByRing ],
+ function( M )
+ if IsIdenticalObj( M, LeftActingDomain( M ) ) then
+ TryNextMethod();
+ else
+ return IsDivisionRing( LeftActingDomain( M ) );
+ fi;
+ end );
+
+
+#############################################################################
+##
+#F VectorSpace( , [, ][, "basis"] )
+##
+## The only difference between `VectorSpace' and `FreeLeftModule' shall be
+## that the left acting domain of a vector space must be a division ring.
+##
+InstallGlobalFunction( VectorSpace, function( arg )
+ if Length( arg ) = 0 or not IsDivisionRing( arg[1] ) then
+ Error( "usage: VectorSpace( , [, ][, \"basis\"] )" );
+ fi;
+ return CallFuncList( FreeLeftModule, arg );
+ end );
+
+
+#############################################################################
+##
+#M AsSubspace( , ) . . . . . . . for a vector space and a collection
+##
+InstallMethod( AsSubspace,
+ "for a vector space and a collection",
+ [ IsVectorSpace, IsCollection ],
+ function( V, C )
+ local newC;
+
+ if not IsSubset( V, C ) then
+ return fail;
+ fi;
+ newC:= AsVectorSpace( LeftActingDomain( V ), C );
+ if newC = fail then
+ return fail;
+ fi;
+ SetParent( newC, V );
+ UseIsomorphismRelation( C, newC );
+ UseSubsetRelation( C, newC );
+
+ return newC;
+ end );
+
+
+#############################################################################
+##
+#M AsLeftModule( , ) . . . . . . for division ring and vector space
+##
+## View the vector space as a vector space over the division ring .
+##
+InstallMethod( AsLeftModule,
+ "method for a division ring and a vector space",
+ [ IsDivisionRing, IsVectorSpace ],
+ function( F, V )
+
+ local W, # the space, result
+ base, # basis vectors of field extension
+ gen, # loop over generators of 'V'
+ b, # loop over 'base'
+ gens, # generators of 'V'
+ newgens; # extended list of generators
+
+ if Characteristic( F ) <> Characteristic( LeftActingDomain( V ) ) then
+
+ # This is impossible.
+ return fail;
+
+ elif F = LeftActingDomain( V ) then
+
+ # No change of the left acting domain is necessary.
+ return V;
+
+ elif IsSubset( F, LeftActingDomain( V ) ) then
+
+ # Check whether 'V' is really a space over the bigger field,
+ # that is, whether the set of elements does not change.
+ base:= BasisVectors( Basis( AsField( LeftActingDomain( V ), F ) ) );
+ for gen in GeneratorsOfLeftModule( V ) do
+ for b in base do
+ if not b * gen in V then
+
+ # The field extension would change the set of elements.
+ return fail;
+
+ fi;
+ od;
+ od;
+
+ # Construct the space.
+ W:= LeftModuleByGenerators( F, GeneratorsOfLeftModule(V), Zero(V) );
+
+ elif IsSubset( LeftActingDomain( V ), F ) then
+
+ # View 'V' as a space over a smaller field.
+ # For that, the list of generators must be extended.
+ gens:= GeneratorsOfLeftModule( V );
+ if IsEmpty( gens ) then
+ W:= LeftModuleByGenerators( F, [], Zero( V ) );
+ else
+
+ base:= BasisVectors( Basis( AsField( F, LeftActingDomain( V ) ) ) );
+ newgens:= [];
+ for b in base do
+ for gen in gens do
+ Add( newgens, b * gen );
+ od;
+ od;
+ W:= LeftModuleByGenerators( F, newgens );
+
+ fi;
+
+ else
+
+ # View 'V' first as space over the intersection of fields,
+ # and then over the desired field.
+ return AsLeftModule( F,
+ AsLeftModule( Intersection( F,
+ LeftActingDomain( V ) ), V ) );
+
+ fi;
+
+ UseIsomorphismRelation( V, W );
+ UseSubsetRelation( V, W );
+ return W;
+ end );
+
+
+#############################################################################
+##
+#M ViewObj( ) . . . . . . . . . . . . . . . . . . . view a vector space
+##
+## print left acting domain, if known also dimension or no. of generators
+##
+InstallMethod( ViewObj,
+ "for vector space with known generators",
+ [ IsVectorSpace and HasGeneratorsOfLeftModule ],
+ function( V )
+ Print( "" );
+ end );
+
+InstallMethod( ViewObj,
+ "for vector space with known dimension",
+ [ IsVectorSpace and HasDimension ],
+ 1, # override method for known generators
+ function( V )
+ Print( "" );
+ end );
+
+InstallMethod( ViewObj,
+ "for vector space",
+ [ IsVectorSpace ],
+ function( V )
+ Print( "" );
+ end );
+
+
+#############################################################################
+##
+#M PrintObj( ) . . . . . . . . . . . . . . . . . . . for a vector space
+##
+InstallMethod( PrintObj,
+ "method for vector space with left module generators",
+ [ IsVectorSpace and HasGeneratorsOfLeftModule ],
+ function( V )
+ Print( "VectorSpace( ", LeftActingDomain( V ), ", ",
+ GeneratorsOfLeftModule( V ) );
+ if IsEmpty( GeneratorsOfLeftModule( V ) ) and HasZero( V ) then
+ Print( ", ", Zero( V ), " )" );
+ else
+ Print( " )" );
+ fi;
+ end );
+
+InstallMethod( PrintObj,
+ "method for vector space",
+ [ IsVectorSpace ],
+ function( V )
+ Print( "VectorSpace( ", LeftActingDomain( V ), ", ... )" );
+ end );
+
+
+#############################################################################
+##
+#M \/( , ) . . . . . . . . . factor of a vector space by a subspace
+#M \/( , ) . . . . . . factor of a vector space by a subspace
+##
+InstallOtherMethod( \/,
+ "method for vector space and collection",
+ IsIdenticalObj,
+ [ IsVectorSpace, IsCollection ],
+ function( V, vectors )
+ if IsVectorSpace( vectors ) then
+ TryNextMethod();
+ else
+ return V / Subspace( V, vectors );
+ fi;
+ end );
+
+InstallOtherMethod( \/,
+ "generic method for two vector spaces",
+ IsIdenticalObj,
+ [ IsVectorSpace, IsVectorSpace ],
+ function( V, W )
+ return ImagesSource( NaturalHomomorphismBySubspace( V, W ) );
+ end );
+
+
+#############################################################################
+##
+#M Intersection2Spaces( , , )
+##
+InstallGlobalFunction( Intersection2Spaces,
+ function( AsStructure, Substructure, Structure )
+ return function( V, W )
+ local inters, # intersection, result
+ F, # coefficients field
+ gensV, # list of generators of 'V'
+ gensW, # list of generators of 'W'
+ VW, # sum of 'V' and 'W'
+ B; # basis of 'VW'
+
+ if LeftActingDomain( V ) <> LeftActingDomain( W ) then
+
+ # Compute the intersection as vector space over the intersection
+ # of the coefficients fields.
+ # (Note that the characteristic is the same.)
+ F:= Intersection2( LeftActingDomain( V ), LeftActingDomain( W ) );
+ return Intersection2( AsStructure( F, V ), AsStructure( F, W ) );
+
+ elif IsFiniteDimensional( V ) and IsFiniteDimensional( W ) then
+
+ # Compute the intersection of two spaces over the same field.
+ gensV:= GeneratorsOfLeftModule( V );
+ gensW:= GeneratorsOfLeftModule( W );
+ if IsEmpty( gensV ) then
+ if Zero( V ) in W then
+ inters:= V;
+ else
+ inters:= [];
+ fi;
+ elif IsEmpty( gensW ) then
+ if Zero( V ) in W then
+ inters:= W;
+ else
+ inters:= [];
+ fi;
+ else
+ # Compute a common coefficient space.
+ VW:= LeftModuleByGenerators( LeftActingDomain( V ),
+ Concatenation( gensV, gensW ) );
+ B:= Basis( VW );
+
+ # Construct the coefficient subspaces corresponding to 'V' and 'W'.
+ gensV:= List( gensV, x -> Coefficients( B, x ) );
+ gensW:= List( gensW, x -> Coefficients( B, x ) );
+
+ # Construct the intersection of row spaces, and carry back to VW.
+ inters:= List( SumIntersectionMat( gensV, gensW )[2],
+ x -> LinearCombination( B, x ) );
+
+ # Construct the intersection space, if possible with a parent.
+ if HasParent( V ) and HasParent( W )
+ and IsIdenticalObj( Parent( V ), Parent( W ) ) then
+ inters:= Substructure( Parent( V ), inters, "basis" );
+ elif IsEmpty( inters ) then
+ inters:= Substructure( V, inters, "basis" );
+ SetIsTrivial( inters, true );
+ else
+ inters:= Structure( LeftActingDomain( V ), inters, "basis" );
+ fi;
+
+ # Run implications by the subset relation.
+ UseSubsetRelation( V, inters );
+ UseSubsetRelation( W, inters );
+ fi;
+
+ # Return the result.
+ return inters;
+
+ else
+ TryNextMethod();
+ fi;
+ end;
+end );
+
+
+#############################################################################
+##
+#M Intersection2( , ) . . . . . . . . . . . . . for two vector spaces
+##
+InstallMethod( Intersection2,
+ "method for two vector spaces",
+ IsIdenticalObj,
+ [ IsVectorSpace, IsVectorSpace ],
+ Intersection2Spaces( AsLeftModule, SubspaceNC, VectorSpace ) );
+
+
+#############################################################################
+##
+#M ClosureLeftModule( , ) . . . . . . . . . closure of a vector space
+##
+InstallMethod( ClosureLeftModule,
+ "method for a vector space with basis, and a vector",
+ IsCollsElms,
+ [ IsVectorSpace and HasBasis, IsVector ],
+ function( V, w )
+ local B; # basis of 'V'
+
+ # We can test membership easily.
+ B:= Basis( V );
+#T why easily?
+ if Coefficients( B, w ) = fail then
+
+ # In the case of a vector space, we know a basis of the closure.
+ B:= Concatenation( BasisVectors( B ), [ w ] );
+ V:= LeftModuleByGenerators( LeftActingDomain( V ), B );
+ UseBasis( V, B );
+
+ fi;
+ return V;
+ end );
+
+
+#############################################################################
+##
+## Methods for collections of subspaces of a vector space
+##
+
+
+#############################################################################
+##
+#R IsSubspacesVectorSpaceDefaultRep( )
+##
+## is the representation of domains of subspaces of a vector space ,
+## with the components 'structure' (with value ) and 'dimension'
+## (with value either the dimension of the subspaces in the domain
+## or the string '\"all\"', which means that the domain contains all
+## subspaces of ).
+##
+DeclareRepresentation(
+ "IsSubspacesVectorSpaceDefaultRep",
+ IsComponentObjectRep,
+ [ "dimension", "structure" ] );
+#T not IsAttributeStoringRep?
+
+
+#############################################################################
+##
+#M PrintObj( ) . . . . . . . . . . . . . . . . . for a subspaces domain
+##
+InstallMethod( PrintObj,
+ "method for a subspaces domain",
+ [ IsSubspacesVectorSpace and IsSubspacesVectorSpaceDefaultRep ],
+ function( D )
+ if IsInt( D!.dimension ) then
+ Print( "Subspaces( ", D!.structure, ", ", D!.dimension, " )" );
+ else
+ Print( "Subspaces( ", D!.structure, " )" );
+ fi;
+ end );
+
+
+#############################################################################
+##
+#M Size( ) . . . . . . . . . . . . . . . . . . . for a subspaces domain
+##
+## The number of $k$-dimensional subspaces in a $n$-dimensional space over
+## the field with $q$ elements is
+## $$
+## a(n,k) = \prod_{i=0}^{k-1} \frac{q^n-q^i}{q^k-q^i} =
+## \prod_{i=0}^{k-1} \frac{q^{n-i}-1}{q^{k-i}-1}.
+## $$
+## We have the recursion
+## $$
+## a(n,k+1) = a(n,k) \frac{q^{n-i}-1}{q^{i+1}-1}.
+## $$
+##
+## (The number of all subspaces is $\sum_{k=0}^n a(n,k)$.)
+##
+InstallMethod( Size,
+ "method for a subspaces domain",
+ [ IsSubspacesVectorSpace and IsSubspacesVectorSpaceDefaultRep ],
+ function( D )
+
+ local k,
+ n,
+ q,
+ size,
+ qn,
+ qd,
+ ank,
+ i;
+
+ if D!.dimension = "all" then
+
+ # all subspaces of the space
+ n:= Dimension( D!.structure );
+
+ q:= Size( LeftActingDomain( D!.structure ) );
+ size:= 1;
+ qn:= q^n;
+ qd:= q;
+
+ # $a(n,0)$
+ ank:= 1;
+
+ for k in [ 1 .. Int( (n-1)/2 ) ] do
+
+ # Compute $a(n,k)$.
+ ank:= ank * ( qn - 1 ) / ( qd - 1 );
+ qn:= qn / q;
+ qd:= qd * q;
+
+ size:= size + ank;
+
+ od;
+
+ size:= 2 * size;
+
+ if n mod 2 = 0 then
+
+ # Add the number of spaces of dimension $n/2$.
+ size:= size + ank * ( qn - 1 ) / ( qd - 1 );
+ fi;
+
+ else
+
+ # number of spaces of dimension 'k' only
+ n:= Dimension( D!.structure );
+ if D!.dimension < 0 or
+ n < D!.dimension then
+ return 0;
+ elif n / 2 < D!.dimension then
+ k:= n - D!.dimension;
+ else
+ k:= D!.dimension;
+ fi;
+
+ q:= Size( LeftActingDomain( D!.structure ) );
+ size:= 1;
+
+ qn:= q^n;
+ qd:= q;
+ for i in [ 1 .. k ] do
+ size:= size * ( qn - 1 ) / ( qd - 1 );
+ qn:= qn / q;
+ qd:= qd * q;
+ od;
+
+ fi;
+
+ # Return the result.
+ return size;
+ end );
+
+
+#############################################################################
+##
+#M Enumerator( ) . . . . . . . . . . . . . . . . for a subspaces domain
+##
+## Use the iterator to compute the elements list.
+#T This is not allowed!
+##
+InstallMethod( Enumerator,
+ "method for a subspaces domain",
+ [ IsSubspacesVectorSpace and IsSubspacesVectorSpaceDefaultRep ],
+ function( D )
+ local iter, # iterator for 'D'
+ elms; # elements list, result
+
+ iter:= Iterator( D );
+ elms:= [];
+ while not IsDoneIterator( iter ) do
+ Add( elms, NextIterator( iter ) );
+ od;
+ return elms;
+ end );
+#T necessary?
+
+
+#############################################################################
+##
+#M Iterator( ) . . . . . . . . . . . . . . . . . for a subspaces domain
+##
+## uses the subspaces iterator for full row spaces and the mechanism of
+## associated row spaces.
+##
+BindGlobal( "IsDoneIterator_Subspaces",
+ iter -> IsDoneIterator( iter!.associatedIterator ) );
+
+BindGlobal( "NextIterator_Subspaces", function( iter )
+ local next;
+ next:= NextIterator( iter!.associatedIterator );
+ next:= List( GeneratorsOfLeftModule( next ),
+ x -> LinearCombination( iter!.basis, x ) );
+ return Subspace( iter!.structure, next, "basis" );
+ end );
+
+BindGlobal( "ShallowCopy_Subspaces",
+ iter -> rec( structure := iter!.structure,
+ basis := iter!.basis,
+ associatedIterator := ShallowCopy(
+ iter!.associatedIterator ) ) );
+
+InstallMethod( Iterator,
+ "for a subspaces domain",
+ [ IsSubspacesVectorSpace and IsSubspacesVectorSpaceDefaultRep ],
+ function( D )
+ local V; # the vector space
+
+ V:= D!.structure;
+ return IteratorByFunctions( rec(
+ IsDoneIterator := IsDoneIterator_Subspaces,
+ NextIterator := NextIterator_Subspaces,
+ ShallowCopy := ShallowCopy_Subspaces,
+ structure := V,
+ basis := Basis( V ),
+ associatedIterator := Iterator(
+ Subspaces( FullRowSpace( LeftActingDomain( V ),
+ Dimension( V ) ),
+ D!.dimension ) ) ) );
+ end );
+
+
+#############################################################################
+##
+#M Subspaces( , )
+##
+InstallMethod( Subspaces,
+ "for a vector space, and an integer",
+ [ IsVectorSpace, IsInt ],
+ function( V, dim )
+ if IsFinite( V ) then
+ return Objectify( NewType( CollectionsFamily( FamilyObj( V ) ),
+ IsSubspacesVectorSpace
+ and IsSubspacesVectorSpaceDefaultRep ),
+ rec(
+ structure := V,
+ dimension := dim
+ )
+ );
+ else
+ TryNextMethod();
+ fi;
+ end );
+
+
+#############################################################################
+##
+#M Subspaces( )
+##
+InstallMethod( Subspaces,
+ "for a vector space",
+ [ IsVectorSpace ],
+ function( V )
+ if IsFinite( V ) then
+ return Objectify( NewType( CollectionsFamily( FamilyObj( V ) ),
+ IsSubspacesVectorSpace
+ and IsSubspacesVectorSpaceDefaultRep ),
+ rec(
+ structure := V,
+ dimension := "all"
+ )
+ );
+ else
+ TryNextMethod();
+ fi;
+ end );
+
+
+#############################################################################
+##
+#F IsSubspace( , ) . . . . . . . . . . . . . . . . . check <=
+##
+InstallGlobalFunction( IsSubspace, function( V, U )
+ return IsVectorSpace( U ) and IsSubset( V, U );
+end );
+
+
+#############################################################################
+##
+#M IsVectorSpaceHomomorphism( )
+##
+InstallMethod( IsVectorSpaceHomomorphism,
+ [ IsGeneralMapping ],
+ function( map )
+ local S, R, F;
+ S:= Source( map );
+ if not IsVectorSpace( S ) then
+ return false;
+ fi;
+ R:= Range( map );
+ if not IsVectorSpace( R ) then
+ return false;
+ fi;
+ F:= LeftActingDomain( S );
+ return ( F = LeftActingDomain( R ) ) and IsLinearMapping( F, map );
+ end );
+
+
+#############################################################################
+##
+#E
+
diff --git a/samples/GLSL/SimpleLighting.gl2.frag b/samples/GLSL/SimpleLighting.gl2.frag
new file mode 100644
index 00000000..bb851f86
--- /dev/null
+++ b/samples/GLSL/SimpleLighting.gl2.frag
@@ -0,0 +1,9 @@
+static const char* SimpleFragmentShader = STRINGIFY(
+
+varying vec4 FrontColor;
+
+void main(void)
+{
+ gl_FragColor = FrontColor;
+}
+);
diff --git a/samples/GLSL/recurse1.frag b/samples/GLSL/recurse1.frag
new file mode 100644
index 00000000..66b4c3fe
--- /dev/null
+++ b/samples/GLSL/recurse1.frag
@@ -0,0 +1,48 @@
+#version 330 core
+
+// cross-unit recursion
+
+void main() {}
+
+// two-level recursion
+
+float cbar(int);
+
+void cfoo(float)
+{
+ cbar(2);
+}
+
+// four-level, out of order
+
+void CB();
+void CD();
+void CA() { CB(); }
+void CC() { CD(); }
+
+// high degree
+
+void CBT();
+void CDT();
+void CAT() { CBT(); CBT(); CBT(); }
+void CCT() { CDT(); CDT(); CBT(); }
+
+// not recursive
+
+void norA() {}
+void norB() { norA(); }
+void norC() { norA(); }
+void norD() { norA(); }
+void norE() { norB(); }
+void norF() { norB(); }
+void norG() { norE(); }
+void norH() { norE(); }
+void norI() { norE(); }
+
+// not recursive, but with a call leading into a cycle if ignoring direction
+
+void norcA() { }
+void norcB() { norcA(); }
+void norcC() { norcB(); }
+void norcD() { norcC(); norcB(); } // head of cycle
+void norcE() { norcD(); } // lead into cycle
diff --git a/samples/Game Maker Language/ClientBeginStep.gml b/samples/Game Maker Language/ClientBeginStep.gml
new file mode 100644
index 00000000..64d14110
--- /dev/null
+++ b/samples/Game Maker Language/ClientBeginStep.gml
@@ -0,0 +1,642 @@
+/*
+ Originally from /Source/gg2/Scripts/Client/ClientBeginStep.gml in Gang Garrison 2
+
+ Copyright (C) 2008-2013 Faucet Software
+ http://www.ganggarrison.com
+
+ This program is free software;
+ you can redistribute it and/or modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 3 of the License, or (at your option)
+ any later version.
+ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU General Public License for more details.
+ You should have received a copy of the GNU General Public License along with this program; if not,
+ see .
+
+ Additional permission under GNU GPL version 3 section 7
+ If you modify this Program, or any covered work, by linking or combining it with the Game Maker runtime library,
+ the 39dll library/extension, Hobbel's Download Manager DLL, or modified versions of these libraries,
+ the licensors of this Program grant you additional permission to convey the resulting work.
+*/
+
+// receive and interpret the server's message(s)
+var i, playerObject, playerID, player, otherPlayerID, otherPlayer, sameVersion, buffer, plugins, pluginsRequired, usePlugins;
+
+if(tcp_eof(global.serverSocket)) {
+ if(gotServerHello)
+ show_message("You have been disconnected from the server.");
+ else
+ show_message("Unable to connect to the server.");
+ instance_destroy();
+ exit;
+}
+
+if(room == DownloadRoom and keyboard_check(vk_escape))
+{
+ instance_destroy();
+ exit;
+}
+
+if(downloadingMap)
+{
+ while(tcp_receive(global.serverSocket, min(1024, downloadMapBytes-buffer_size(downloadMapBuffer))))
+ {
+ write_buffer(downloadMapBuffer, global.serverSocket);
+ if(buffer_size(downloadMapBuffer) == downloadMapBytes)
+ {
+ write_buffer_to_file(downloadMapBuffer, "Maps/" + downloadMapName + ".png");
+ downloadingMap = false;
+ buffer_destroy(downloadMapBuffer);
+ downloadMapBuffer = -1;
+ exit;
+ }
+ }
+ exit;
+}
+
+roomchange = false;
+do {
+ if(tcp_receive(global.serverSocket,1)) {
+ switch(read_ubyte(global.serverSocket)) {
+ case HELLO:
+ gotServerHello = true;
+ global.joinedServerName = receivestring(global.serverSocket, 1);
+ downloadMapName = receivestring(global.serverSocket, 1);
+ advertisedMapMd5 = receivestring(global.serverSocket, 1);
+ receiveCompleteMessage(global.serverSocket, 1, global.tempBuffer);
+ pluginsRequired = read_ubyte(global.tempBuffer);
+ plugins = receivestring(global.serverSocket, 1);
+ if(string_pos("/", downloadMapName) != 0 or string_pos("\", downloadMapName) != 0)
+ {
+ show_message("Server sent illegal map name: "+downloadMapName);
+ instance_destroy();
+ exit;
+ }
+
+ if (!noReloadPlugins && string_length(plugins))
+ {
+ usePlugins = pluginsRequired || !global.serverPluginsPrompt;
+ if (global.serverPluginsPrompt)
+ {
+ var prompt;
+ if (pluginsRequired)
+ {
+ prompt = show_question(
+ "This server requires the following plugins to play on it: "
+ + string_replace_all(plugins, ",", "#")
+ + '#They are downloaded from the source: "'
+ + PLUGIN_SOURCE
+ + '"#The source states: "'
+ + PLUGIN_SOURCE_NOTICE
+ + '"#Do you wish to download them and continue connecting?'
+ );
+ if (!prompt)
+ {
+ instance_destroy();
+ exit;
+ }
+ }
+ else
+ {
+ prompt = show_question(
+ "This server suggests the following optional plugins to play on it: "
+ + string_replace_all(plugins, ",", "#")
+ + '#They are downloaded from the source: "'
+ + PLUGIN_SOURCE
+ + '"#The source states: "'
+ + PLUGIN_SOURCE_NOTICE
+ + '"#Do you wish to download them and use them?'
+ );
+ if (prompt)
+ {
+ usePlugins = true;
+ }
+ }
+ }
+ if (usePlugins)
+ {
+ if (!loadserverplugins(plugins))
+ {
+ show_message("Error ocurred loading server-sent plugins.");
+ instance_destroy();
+ exit;
+ }
+ global.serverPluginsInUse = true;
+ }
+ }
+ noReloadPlugins = false;
+
+ if(advertisedMapMd5 != "")
+ {
+ var download;
+ download = not file_exists("Maps/" + downloadMapName + ".png");
+ if(!download and CustomMapGetMapMD5(downloadMapName) != advertisedMapMd5)
+ {
+ if(show_question("The server's copy of the map (" + downloadMapName + ") differs from ours.#Would you like to download this server's version of the map?"))
+ download = true;
+ else
+ {
+ instance_destroy();
+ exit;
+ }
+ }
+
+ if(download)
+ {
+ write_ubyte(global.serverSocket, DOWNLOAD_MAP);
+ socket_send(global.serverSocket);
+ receiveCompleteMessage(global.serverSocket,4,global.tempBuffer);
+ downloadMapBytes = read_uint(global.tempBuffer);
+ downloadMapBuffer = buffer_create();
+ downloadingMap = true;
+ roomchange=true;
+ }
+ }
+ ClientPlayerJoin(global.serverSocket);
+ if(global.rewardKey != "" and global.rewardId != "")
+ {
+ var rewardId;
+ rewardId = string_copy(global.rewardId, 0, 255);
+ write_ubyte(global.serverSocket, REWARD_REQUEST);
+ write_ubyte(global.serverSocket, string_length(rewardId));
+ write_string(global.serverSocket, rewardId);
+ }
+ if(global.queueJumping == true)
+ {
+ write_ubyte(global.serverSocket, CLIENT_SETTINGS);
+ write_ubyte(global.serverSocket, global.queueJumping);
+ }
+ socket_send(global.serverSocket);
+ break;
+
+ case JOIN_UPDATE:
+ receiveCompleteMessage(global.serverSocket,2,global.tempBuffer);
+ global.playerID = read_ubyte(global.tempBuffer);
+ global.currentMapArea = read_ubyte(global.tempBuffer);
+ break;
+
+ case FULL_UPDATE:
+ deserializeState(FULL_UPDATE);
+ break;
+
+ case QUICK_UPDATE:
+ deserializeState(QUICK_UPDATE);
+ break;
+
+ case CAPS_UPDATE:
+ deserializeState(CAPS_UPDATE);
+ break;
+
+ case INPUTSTATE:
+ deserializeState(INPUTSTATE);
+ break;
+
+ case PLAYER_JOIN:
+ player = instance_create(0,0,Player);
+ player.name = receivestring(global.serverSocket, 1);
+
+ ds_list_add(global.players, player);
+ if(ds_list_size(global.players)-1 == global.playerID) {
+ global.myself = player;
+ instance_create(0,0,PlayerControl);
+ }
+ break;
+
+ case PLAYER_LEAVE:
+ // Delete player from the game, adjust own ID accordingly
+ receiveCompleteMessage(global.serverSocket,1,global.tempBuffer);
+ playerID = read_ubyte(global.tempBuffer);
+ player = ds_list_find_value(global.players, playerID);
+ removePlayer(player);
+ if(playerID < global.playerID) {
+ global.playerID -= 1;
+ }
+ break;
+
+ case PLAYER_DEATH:
+ var causeOfDeath, assistantPlayerID, assistantPlayer;
+ receiveCompleteMessage(global.serverSocket,4,global.tempBuffer);
+ playerID = read_ubyte(global.tempBuffer);
+ otherPlayerID = read_ubyte(global.tempBuffer);
+ assistantPlayerID = read_ubyte(global.tempBuffer);
+ causeOfDeath = read_ubyte(global.tempBuffer);
+
+ player = ds_list_find_value(global.players, playerID);
+
+ otherPlayer = noone;
+ if(otherPlayerID != 255)
+ otherPlayer = ds_list_find_value(global.players, otherPlayerID);
+
+ assistantPlayer = noone;
+ if(assistantPlayerID != 255)
+ assistantPlayer = ds_list_find_value(global.players, assistantPlayerID);
+
+ doEventPlayerDeath(player, otherPlayer, assistantPlayer, causeOfDeath);
+ break;
+
+ case BALANCE:
+ receiveCompleteMessage(global.serverSocket,1,global.tempBuffer);
+ balanceplayer=read_ubyte(global.tempBuffer);
+ if balanceplayer == 255 {
+ if !instance_exists(Balancer) instance_create(x,y,Balancer);
+ with(Balancer) notice=0;
+ } else {
+ player = ds_list_find_value(global.players, balanceplayer);
+ if(player.object != -1) {
+ with(player.object) {
+ instance_destroy();
+ }
+ player.object = -1;
+ }
+ if(player.team==TEAM_RED) {
+ player.team = TEAM_BLUE;
+ } else {
+ player.team = TEAM_RED;
+ }
+ if !instance_exists(Balancer) instance_create(x,y,Balancer);
+ Balancer.name=player.name;
+ with (Balancer) notice=1;
+ }
+ break;
+
+ case PLAYER_CHANGETEAM:
+ receiveCompleteMessage(global.serverSocket,2,global.tempBuffer);
+ player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
+ if(player.object != -1) {
+ with(player.object) {
+ instance_destroy();
+ }
+ player.object = -1;
+ }
+ player.team = read_ubyte(global.tempBuffer);
+ break;
+
+ case PLAYER_CHANGECLASS:
+ receiveCompleteMessage(global.serverSocket,2,global.tempBuffer);
+ player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
+ if(player.object != -1) {
+ with(player.object) {
+ instance_destroy();
+ }
+ player.object = -1;
+ }
+ player.class = read_ubyte(global.tempBuffer);
+ break;
+
+ case PLAYER_CHANGENAME:
+ receiveCompleteMessage(global.serverSocket,1,global.tempBuffer);
+ player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
+ player.name = receivestring(global.serverSocket, 1);
+ if player=global.myself {
+ global.playerName=player.name
+ }
+ break;
+
+ case PLAYER_SPAWN:
+ receiveCompleteMessage(global.serverSocket,3,global.tempBuffer);
+ player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
+ doEventSpawn(player, read_ubyte(global.tempBuffer), read_ubyte(global.tempBuffer));
+ break;
+
+ case CHAT_BUBBLE:
+ var bubbleImage;
+ receiveCompleteMessage(global.serverSocket,2,global.tempBuffer);
+ player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
+ setChatBubble(player, read_ubyte(global.tempBuffer));
+ break;
+
+ case BUILD_SENTRY:
+ receiveCompleteMessage(global.serverSocket,6,global.tempBuffer);
+ player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
+ buildSentry(player, read_ushort(global.tempBuffer)/5, read_ushort(global.tempBuffer)/5, read_byte(global.tempBuffer));
+ break;
+
+ case DESTROY_SENTRY:
+ receiveCompleteMessage(global.serverSocket,4,global.tempBuffer);
+ playerID = read_ubyte(global.tempBuffer);
+ otherPlayerID = read_ubyte(global.tempBuffer);
+ assistantPlayerID = read_ubyte(global.tempBuffer);
+ causeOfDeath = read_ubyte(global.tempBuffer);
+
+ player = ds_list_find_value(global.players, playerID);
+ if(otherPlayerID == 255) {
+ doEventDestruction(player, noone, noone, causeOfDeath);
+ } else {
+ otherPlayer = ds_list_find_value(global.players, otherPlayerID);
+ if (assistantPlayerID == 255) {
+ doEventDestruction(player, otherPlayer, noone, causeOfDeath);
+ } else {
+ assistantPlayer = ds_list_find_value(global.players, assistantPlayerID);
+ doEventDestruction(player, otherPlayer, assistantPlayer, causeOfDeath);
+ }
+ }
+ break;
+
+ case GRAB_INTEL:
+ receiveCompleteMessage(global.serverSocket,1,global.tempBuffer);
+ player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
+ doEventGrabIntel(player);
+ break;
+
+ case SCORE_INTEL:
+ receiveCompleteMessage(global.serverSocket,1,global.tempBuffer);
+ player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
+ doEventScoreIntel(player);
+ break;
+
+ case DROP_INTEL:
+ receiveCompleteMessage(global.serverSocket,1,global.tempBuffer);
+ player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
+ doEventDropIntel(player);
+ break;
+
+ case RETURN_INTEL:
+ receiveCompleteMessage(global.serverSocket,1,global.tempBuffer);
+ doEventReturnIntel(read_ubyte(global.tempBuffer));
+ break;
+
+ case GENERATOR_DESTROY:
+ receiveCompleteMessage(global.serverSocket,1,global.tempBuffer);
+ team = read_ubyte(global.tempBuffer);
+ doEventGeneratorDestroy(team);
+ break;
+
+ case UBER_CHARGED:
+ receiveCompleteMessage(global.serverSocket,1,global.tempBuffer);
+ player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
+ doEventUberReady(player);
+ break;
+
+ case UBER:
+ receiveCompleteMessage(global.serverSocket,1,global.tempBuffer);
+ player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
+ doEventUber(player);
+ break;
+
+ case OMNOMNOMNOM:
+ receiveCompleteMessage(global.serverSocket,1,global.tempBuffer);
+ player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
+ if(player.object != -1) {
+ with(player.object) {
+ omnomnomnom=true;
+ if(hp < 200)
+ {
+ canEat = false;
+ alarm[6] = eatCooldown; //10 second cooldown
+ }
+ if(player.team == TEAM_RED) {
+ omnomnomnomindex=0;
+ omnomnomnomend=31;
+ } else if(player.team==TEAM_BLUE) {
+ omnomnomnomindex=32;
+ omnomnomnomend=63;
+ }
+ xscale=image_xscale;
+ }
+ }
+ break;
+
+ case TOGGLE_ZOOM:
+ receiveCompleteMessage(global.serverSocket,1,global.tempBuffer);
+ player = ds_list_find_value(global.players, read_ubyte(global.tempBuffer));
+ if player.object != -1 {
+ toggleZoom(player.object);
+ }
+ break;
+
+ case PASSWORD_REQUEST:
+ if(!usePreviousPwd)
+ global.clientPassword = get_string("Enter Password:", "");
+ write_ubyte(global.serverSocket, string_length(global.clientPassword));
+ write_string(global.serverSocket, global.clientPassword);
+ socket_send(global.serverSocket);
+ break;
+
+ case PASSWORD_WRONG:
+ show_message("Incorrect Password.");
+ instance_destroy();
+ exit;
+
+ case INCOMPATIBLE_PROTOCOL:
+ show_message("Incompatible server protocol version.");
+ instance_destroy();
+ exit;
+
+ case KICK:
+ receiveCompleteMessage(global.serverSocket,1,global.tempBuffer);
+ reason = read_ubyte(global.tempBuffer);
+ if reason == KICK_NAME kickReason = "Name Exploit";
+ else if reason == KICK_BAD_PLUGIN_PACKET kickReason = "Invalid plugin packet ID";
+ else if reason == KICK_MULTI_CLIENT kickReason = "There are too many connections from your IP";
+ else kickReason = "";
+ show_message("You have been kicked from the server. "+kickReason+".");
+ instance_destroy();
+ exit;
+
+ case ARENA_STARTROUND:
+ doEventArenaStartRound();
+ break;
+
+ case ARENA_ENDROUND:
+ with ArenaHUD clientArenaEndRound();
+ break;
+
+ case ARENA_RESTART:
+ doEventArenaRestart();
+ break;
+
+ case UNLOCKCP:
+ doEventUnlockCP();
+ break;
+
+ case MAP_END:
+ global.nextMap=receivestring(global.serverSocket, 1);
+ receiveCompleteMessage(global.serverSocket,2,global.tempBuffer);
+ global.winners=read_ubyte(global.tempBuffer);
+ global.currentMapArea=read_ubyte(global.tempBuffer);
+ global.mapchanging = true;
+ if !instance_exists(ScoreTableController) instance_create(0,0,ScoreTableController);
+ instance_create(0,0,WinBanner);
+ break;
+
+ case CHANGE_MAP:
+ roomchange=true;
+ global.mapchanging = false;
+ global.currentMap = receivestring(global.serverSocket, 1);
+ global.currentMapMD5 = receivestring(global.serverSocket, 1);
+ if(global.currentMapMD5 == "") { // if this is an internal map (signified by the lack of an md5)
+ if(findInternalMapRoom(global.currentMap))
+ room_goto_fix(findInternalMapRoom(global.currentMap));
+ else
+ {
+ show_message("Error:#Server went to invalid internal map: " + global.currentMap + "#Exiting.");
+ instance_destroy();
+ exit;
+ }
+ } else { // it's an external map
+ if(string_pos("/", global.currentMap) != 0 or string_pos("\", global.currentMap) != 0)
+ {
+ show_message("Server sent illegal map name: "+global.currentMap);
+ instance_destroy();
+ exit;
+ }
+ if(!file_exists("Maps/" + global.currentMap + ".png") or CustomMapGetMapMD5(global.currentMap) != global.currentMapMD5)
+ { // Reconnect to the server to download the map
+ var oldReturnRoom;
+ oldReturnRoom = returnRoom;
+ returnRoom = DownloadRoom;
+ if (global.serverPluginsInUse)
+ noUnloadPlugins = true;
+ event_perform(ev_destroy,0);
+ ClientCreate();
+ if (global.serverPluginsInUse)
+ noReloadPlugins = true;
+ returnRoom = oldReturnRoom;
+ usePreviousPwd = true;
+ exit;
+ }
+ room_goto_fix(CustomMapRoom);
+ }
+
+ for(i=0; i.
+
+ Additional permission under GNU GPL version 3 section 7
+ If you modify this Program, or any covered work, by linking or combining it with the Game Maker runtime library,
+ the 39dll library/extension, Hobbel's Download Manager DLL, or modified versions of these libraries,
+ the licensors of this Program grant you additional permission to convey the resulting work.
+*/
+// Downloading code.
+
+var downloadHandle, url, tmpfile, window_oldshowborder, window_oldfullscreen;
+timeLeft = 0;
+counter = 0;
+AudioControlPlaySong(-1, false);
+window_oldshowborder = window_get_showborder();
+window_oldfullscreen = window_get_fullscreen();
+window_set_fullscreen(false);
+window_set_showborder(false);
+
+if(global.updaterBetaChannel)
+ url = UPDATE_SOURCE_BETA;
+else
+ url = UPDATE_SOURCE;
+
+tmpfile = temp_directory + "\gg2update.zip";
+
+downloadHandle = httpGet(url, -1);
+
+while(!httpRequestStatus(downloadHandle))
+{ // while download isn't finished
+ sleep(floor(1000/30)); // sleep for the equivalent of one frame
+ io_handle(); // this prevents GameMaker from appearing locked-up
+ httpRequestStep(downloadHandle);
+
+ // check if the user cancelled the download with the esc key
+ if(keyboard_check(vk_escape))
+ {
+ httpRequestDestroy(downloadHandle);
+ window_set_showborder(window_oldshowborder);
+ window_set_fullscreen(window_oldfullscreen);
+ room_goto_fix(Menu);
+ exit;
+ }
+
+ if(counter == 0 || counter mod 60 == 0)
+ timer = random(359)+1;
+ draw_sprite(UpdaterBackgroundS,0,0,0);
+ draw_set_color(c_white);
+ draw_set_halign(fa_left);
+ draw_set_valign(fa_center);
+ minutes=floor(timer/60);
+ seconds=floor(timer-minutes*60);
+ draw_text(x,y-20,string(minutes) + " minutes " + string(seconds) + " seconds Remaining...");
+ counter+=1;
+ var progress, size;
+ progress = httpRequestResponseBodyProgress(downloadHandle);
+ size = httpRequestResponseBodySize(downloadHandle);
+ if (size != -1)
+ {
+ progressBar = floor((progress/size) * 20);
+ offset = 3;
+ for(i=0;i.
+
+ Additional permission under GNU GPL version 3 section 7
+ If you modify this Program, or any covered work, by linking or combining it with the Game Maker runtime library,
+ the 39dll library/extension, Hobbel's Download Manager DLL, or modified versions of these libraries,
+ the licensors of this Program grant you additional permission to convey the resulting work.
+*/
+
+xoffset = view_xview[0];
+yoffset = view_yview[0];
+xsize = view_wview[0];
+ysize = view_hview[0];
+
+if (distance_to_point(xoffset+xsize/2,yoffset+ysize/2) > 800)
+ exit;
+
+var xr, yr;
+xr = round(x);
+yr = round(y);
+
+image_alpha = cloakAlpha;
+
+if (global.myself.team == team and canCloak)
+ image_alpha = cloakAlpha/2 + 0.5;
+
+if (invisible)
+ exit;
+
+if(stabbing)
+ image_alpha -= power(currentWeapon.stab.alpha, 2);
+
+if team == global.myself.team && (player != global.myself || global.showHealthBar == 1){
+ draw_set_alpha(1);
+ draw_healthbar(xr-10, yr-30, xr+10, yr-25,hp*100/maxHp,c_black,c_red,c_green,0,true,true);
+}
+if(distance_to_point(mouse_x, mouse_y)<25) {
+ if cloak && team!=global.myself.team exit;
+ draw_set_alpha(1);
+ draw_set_halign(fa_center);
+ draw_set_valign(fa_bottom);
+ if(team==TEAM_RED) {
+ draw_set_color(c_red);
+ } else {
+ draw_set_color(c_blue);
+ }
+ draw_text(xr, yr-35, player.name);
+
+ if(team == global.myself.team && global.showTeammateStats)
+ {
+ if(weapons[0] == Medigun)
+ draw_text(xr,yr+50, "Superburst: " + string(currentWeapon.uberCharge/20) + "%");
+ else if(weapons[0] == Shotgun)
+ draw_text(xr,yr+50, "Nuts 'N' Bolts: " + string(nutsNBolts));
+ else if(weapons[0] == Minegun)
+ draw_text(xr,yr+50, "Lobbed Mines: " + string(currentWeapon.lobbed));
+ }
+}
+
+draw_set_alpha(1);
+if team == TEAM_RED ubercolour = c_red;
+if team == TEAM_BLUE ubercolour = c_blue;
+
+var sprite, overlaySprite;
+if zoomed
+{
+ if (team == TEAM_RED)
+ sprite = SniperCrouchRedS;
+ else
+ sprite = SniperCrouchBlueS;
+ overlaySprite = sniperCrouchOverlay;
+}
+else
+{
+ sprite = sprite_index;
+ overlaySprite = overlay;
+}
+
+if (omnomnomnom)
+{
+ draw_sprite_ext_overlay(omnomnomnomSprite,omnomnomnomOverlay,omnomnomnomindex,xr,yr,image_xscale,image_yscale,image_angle,c_white,1);
+ if (ubered)
+ draw_sprite_ext_overlay(omnomnomnomSprite,omnomnomnomOverlay,omnomnomnomindex,xr,yr,image_xscale,image_yscale,image_angle,ubercolour,0.7);
+}
+else if (taunting)
+{
+ draw_sprite_ext_overlay(tauntsprite,tauntOverlay,tauntindex,xr,yr,image_xscale,image_yscale,image_angle,c_white,1);
+ if (ubered)
+ draw_sprite_ext_overlay(tauntsprite,tauntOverlay,tauntindex,xr,yr,image_xscale,image_yscale,image_angle,ubercolour,0.7);
+}
+else if (player.humiliated)
+ draw_sprite_ext(humiliationPoses,floor(animationImage)+humiliationOffset,xr,yr,image_xscale,image_yscale,image_angle,c_white,image_alpha);
+else if (!taunting)
+{
+ if (cloak)
+ {
+ if (!ubered)
+ draw_sprite_ext(sprite,floor(animationImage+animationOffset),xr,yr,image_xscale,image_yscale,image_angle,c_white,image_alpha);
+ else if (ubered)
+ {
+ draw_sprite_ext(sprite,floor(animationImage+animationOffset),xr,yr,image_xscale,image_yscale,image_angle,c_white,1);
+ draw_sprite_ext(sprite,floor(animationImage+animationOffset),xr,yr,image_xscale,image_yscale,image_angle,ubercolour,0.7);
+ }
+ }
+ else
+ {
+ if (!ubered)
+ draw_sprite_ext_overlay(sprite,overlaySprite,floor(animationImage+animationOffset),xr,yr,image_xscale,image_yscale,image_angle,c_white,image_alpha);
+ else if (ubered)
+ {
+ draw_sprite_ext_overlay(sprite,overlaySprite,floor(animationImage+animationOffset),xr,yr,image_xscale,image_yscale,image_angle,c_white,1);
+ draw_sprite_ext_overlay(sprite,overlaySprite,floor(animationImage+animationOffset),xr,yr,image_xscale,image_yscale,image_angle,ubercolour,0.7);
+ }
+ }
+}
+if (burnDuration > 0 or burnIntensity > 0) {
+ for(i = 0; i < numFlames * burnIntensity / maxIntensity; i += 1)
+ {
+ draw_sprite_ext(FlameS, alarm[5] + i + random(2), x + flameArray_x[i], y + flameArray_y[i], 1, 1, 0, c_white, burnDuration / maxDuration * 0.71 + 0.35);
+ }
+}
+
+// Copied from Lorgan's itemserver "angels" with slight modifications
+// All credit be upon him
+if (demon != -1)
+{
+ demonX = median(x-40,demonX,x+40);
+ demonY = median(y-40,demonY,y);
+ demonOffset += demonDir;
+ if (abs(demonOffset) > 15)
+ demonDir *= -1;
+
+ var dir;
+ if (demonX > x)
+ dir = -1;
+ else
+ dir = 1;
+
+ if (demonFrame > sprite_get_number(demon))
+ demonFrame = 0;
+
+ if (stabbing || ubered)
+ draw_sprite_ext(demon,demonFrame+floor(animationImage)+7*player.team,demonX,demonY+demonOffset,dir*1,1,0,c_white,1);
+ else
+ draw_sprite_ext(demon,demonFrame+floor(animationImage)+7*player.team,demonX,demonY+demonOffset,dir*1,1,0,c_white,image_alpha);
+
+ demonFrame += 1;
+}
diff --git a/samples/Game Maker Language/characterDrawEvent.gml b/samples/Game Maker Language/characterDrawEvent.gml
new file mode 100644
index 00000000..6dcd8fcc
--- /dev/null
+++ b/samples/Game Maker Language/characterDrawEvent.gml
@@ -0,0 +1,80 @@
+// Originally from /spelunky/Scripts/Platform Engine/characterDrawEvent.gml in the Spelunky Community Update Project
+
+/**********************************************************************************
+ Copyright (c) 2008, 2009 Derek Yu and Mossmouth, LLC
+
+ This file is part of Spelunky.
+
+ You can redistribute and/or modify Spelunky, including its source code, under
+ the terms of the Spelunky User License.
+
+ Spelunky is distributed in the hope that it will be entertaining and useful,
+ but WITHOUT WARRANTY. Please see the Spelunky User License for more details.
+
+ The Spelunky User License should be available in "Game Information", which
+ can be found in the Resource Explorer, or as an external file called COPYING.
+ If not, please obtain a new copy of Spelunky from
+
+***********************************************************************************/
+
+/*
+This event should be placed in the draw event of the platform character.
+*/
+//draws the sprite
+draw = true;
+if (facing == RIGHT) image_xscale = -1;
+else image_xscale = 1;
+
+if (blinkToggle != 1)
+{
+ if ((state == CLIMBING or (sprite_index == sPExit or sprite_index == sDamselExit or sprite_index == sTunnelExit)) and global.hasJetpack and not whipping)
+ {
+ draw_sprite_ext(sprite_index, -1, x, y, image_xscale, image_yscale, image_angle, image_blend, image_alpha);
+ //draw_sprite(sprite_index,-1,x,y);
+ draw_sprite(sJetpackBack,-1,x,y);
+ draw = false;
+ }
+ else if (global.hasJetpack and facing == RIGHT) draw_sprite(sJetpackRight,-1,x-4,y-1);
+ else if (global.hasJetpack) draw_sprite(sJetpackLeft,-1,x+4,y-1);
+ if (draw)
+ {
+ if (redColor > 0) draw_sprite_ext(sprite_index, -1, x, y, image_xscale, image_yscale, image_angle, make_color_rgb(200 + redColor,0,0), image_alpha);
+ else draw_sprite_ext(sprite_index, -1, x, y, image_xscale, image_yscale, image_angle, image_blend, image_alpha);
+ }
+ if (facing == RIGHT)
+ {
+ if (holdArrow == ARROW_NORM)
+ {
+ draw_sprite(sArrowRight, -1, x+4, y+1);
+ }
+ else if (holdArrow == ARROW_BOMB)
+ {
+ if (holdArrowToggle) draw_sprite(sBombArrowRight, 0, x+4, y+2);
+ else draw_sprite(sBombArrowRight, 1, x+4, y+2);
+ }
+ }
+ else if (facing == LEFT)
+ {
+ if (holdArrow == ARROW_NORM)
+ {
+ draw_sprite(sArrowLeft, -1, x-4, y+1);
+ }
+ else if (holdArrow == ARROW_BOMB)
+ {
+ if (holdArrowToggle) draw_sprite(sBombArrowLeft, 0, x-4, y+2);
+ else draw_sprite(sBombArrowLeft, 1, x-4, y+2);
+ }
+ }
+}
+/*
+if canRun
+{
+ xOffset=80
+ if player=1
+ yOffset=120
+ else
+ yOffset=143
+ //draw the "flySpeed" bar, which shows how much speed the character has acquired while holding the "run" button
+ //draw_healthbar(view_xview[0]+224+xOffset,view_yview[0]+432+yOffset,view_xview[0]+400+xOffset,view_yview[0]+450+yOffset,flySpeed,make_color_rgb(0,64,128),c_blue,c_aqua,0,1,1)
+}
+*/
diff --git a/samples/Game Maker Language/characterStepEvent.gml b/samples/Game Maker Language/characterStepEvent.gml
new file mode 100644
index 00000000..7416df80
--- /dev/null
+++ b/samples/Game Maker Language/characterStepEvent.gml
@@ -0,0 +1,1050 @@
+// Originally from /spelunky/Scripts/Platform Engine/characterStepEvent.gml in the Spelunky Community Update Project
+
+/**********************************************************************************
+ Copyright (c) 2008, 2009 Derek Yu and Mossmouth, LLC
+
+ This file is part of Spelunky.
+
+ You can redistribute and/or modify Spelunky, including its source code, under
+ the terms of the Spelunky User License.
+
+ Spelunky is distributed in the hope that it will be entertaining and useful,
+ but WITHOUT WARRANTY. Please see the Spelunky User License for more details.
+
+ The Spelunky User License should be available in "Game Information", which
+ can be found in the Resource Explorer, or as an external file called COPYING.
+ If not, please obtain a new copy of Spelunky from
+
+***********************************************************************************/
+
+/*
+This script should be placed in the step event for the platform character.
+It updates the keys used by the character, moves all of the solids, moves the
+character, sets the sprite index, and sets the animation speed for the sprite.
+*/
+hangCountMax = 3;
+
+//////////////////////////////////////
+// KEYS
+//////////////////////////////////////
+
+kLeft = checkLeft();
+
+if (kLeft) kLeftPushedSteps += 1;
+else kLeftPushedSteps = 0;
+
+kLeftPressed = checkLeftPressed();
+kLeftReleased = checkLeftReleased();
+
+kRight = checkRight();
+
+if (kRight) kRightPushedSteps += 1;
+else kRightPushedSteps = 0;
+
+kRightPressed = checkRightPressed();
+kRightReleased = checkRightReleased();
+
+kUp = checkUp();
+kDown = checkDown();
+
+//key "run"
+if canRun
+ kRun = 0;
+// kRun=runKey
+else
+ kRun=0
+
+kJump = checkJump();
+kJumpPressed = checkJumpPressed();
+kJumpReleased = checkJumpReleased();
+
+if (cantJump > 0)
+{
+ kJump = 0;
+ kJumpPressed = 0;
+ kJumpReleased = 0;
+ cantJump -= 1;
+}
+else
+{
+ if (global.isTunnelMan and
+ sprite_index == sTunnelAttackL and
+ !holdItem)
+ {
+ kJump = 0;
+ kJumpPressed = 0;
+ kJumpReleased = 0;
+ cantJump -= 1;
+ }
+}
+
+kAttack = checkAttack();
+kAttackPressed = checkAttackPressed();
+kAttackReleased = checkAttackReleased();
+
+kItemPressed = checkItemPressed();
+
+xPrev = x;
+yPrev = y;
+
+if (stunned or dead)
+{
+ kLeft = false;
+ kLeftPressed = false;
+ kLeftReleased = false;
+ kRight = false;
+ kRightPressed = false;
+ kRightReleased = false;
+ kUp = false;
+ kDown = false;
+ kJump = false;
+ kJumpPressed = false;
+ kJumpReleased = false;
+ kAttack = false;
+ kAttackPressed = false;
+ kAttackReleased = false;
+ kItemPressed = false;
+}
+
+//////////////////////////////////////////
+// Collisions
+//////////////////////////////////////////
+
+colSolidLeft = false;
+colSolidRight = false;
+colLeft = false;
+colRight = false;
+colTop = false;
+colBot = false;
+colLadder = false;
+colPlatBot = false;
+colPlat = false;
+colWaterTop = false;
+colIceBot = false;
+runKey = false;
+if (isCollisionMoveableSolidLeft(1)) colSolidLeft = true;
+if (isCollisionMoveableSolidRight(1)) colSolidRight = true;
+if (isCollisionLeft(1)) colLeft = true;
+if (isCollisionRight(1)) colRight = true;
+if (isCollisionTop(1)) colTop = true;
+if (isCollisionBottom(1)) colBot = true;
+if (isCollisionLadder()) colLadder = true;
+if (isCollisionPlatformBottom(1)) colPlatBot = true;
+if (isCollisionPlatform()) colPlat = true;
+if (isCollisionWaterTop(1)) colWaterTop = true;
+if (collision_point(x, y+8, oIce, 0, 0)) colIceBot = true;
+if (checkRun())
+{
+ runHeld = 100;
+ runKey = true;
+}
+
+if (checkAttack() and not whipping)
+{
+ runHeld += 1;
+ runKey = true;
+}
+
+if (not runKey or (not kLeft and not kRight)) runHeld = 0;
+
+// allows the character to run left and right
+// if state!=DUCKING and state!=LOOKING_UP and state!=CLIMBING
+if (state != CLIMBING and state != HANGING)
+{
+ if (kLeftReleased and approximatelyZero(xVel)) xAcc -= 0.5
+ if (kRightReleased and approximatelyZero(xVel)) xAcc += 0.5
+
+ if (kLeft and not kRight)
+ {
+ if (colSolidLeft)
+ {
+ // xVel = 3;
+ if (platformCharacterIs(ON_GROUND) and state != DUCKING)
+ {
+ xAcc -= 1;
+ pushTimer += 10;
+ //if (not SS_IsSoundPlaying(global.sndPush)) playSound(global.sndPush);
+ }
+ }
+ else if (kLeftPushedSteps > 2) and (facing=LEFT or approximatelyZero(xVel))
+ {
+ xAcc -= runAcc;
+ }
+ facing = LEFT;
+ //if (platformCharacterIs(ON_GROUND) and abs(xVel) > 0 and alarm[3] < 1) alarm[3] = floor(16/-xVel);
+ }
+
+ if (kRight and not kLeft)
+ {
+ if (colSolidRight)
+ {
+ // xVel = 3;
+ if (platformCharacterIs(ON_GROUND) and state != DUCKING)
+ {
+ xAcc += 1;
+ pushTimer += 10;
+ //if (not SS_IsSoundPlaying(global.sndPush)) playSound(global.sndPush);
+ }
+ }
+ else if (kRightPushedSteps > 2 or colSolidLeft) and (facing=RIGHT or approximatelyZero(xVel))
+ {
+ xAcc += runAcc;
+ }
+ facing = RIGHT;
+ //if (platformCharacterIs(ON_GROUND) and abs(xVel) > 0 and alarm[3] < 1) alarm[3] = floor(16/xVel);
+ }
+}
+
+/******************************************
+
+ LADDERS
+
+*******************************************/
+
+if (state == CLIMBING)
+{
+ if (instance_exists(oCape))
+ {
+ oCape.open = false;
+ }
+ kJumped = false;
+ ladderTimer = 10;
+ ladder = collision_point(x, y, oLadder, 0, 0);
+ if (ladder) x = ladder.x + 8;
+
+ if (kLeft) facing = LEFT;
+ else if (kRight) facing = RIGHT;
+ if (kUp)
+ {
+ if (collision_point(x, y-8, oLadder, 0, 0) or collision_point(x, y-8, oLadderTop, 0, 0))
+ {
+ yAcc -= climbAcc;
+ if (alarm[2] < 1) alarm[2] = 8;
+ }
+ }
+ else if (kDown)
+ {
+ if (collision_point(x, y+8, oLadder, 0, 0) or collision_point(x, y+8, oLadderTop, 0, 0))
+ {
+ yAcc += climbAcc;
+ if (alarm[2] < 1) alarm[2] = 8;
+ }
+ else
+ state = FALLING;
+ if (colBot) state = STANDING;
+ }
+
+ if (kJumpPressed and not whipping)
+ {
+ if (kLeft)
+ xVel = -departLadderXVel;
+ else if (kRight)
+ xVel = departLadderXVel;
+ else
+ xVel = 0;
+ yAcc += departLadderYVel;
+ state = JUMPING;
+ jumpButtonReleased = 0;
+ jumpTime = 0;
+ ladderTimer = 5;
+ }
+}
+else
+{
+ if (ladderTimer > 0) ladderTimer -= 1;
+}
+
+if (platformCharacterIs(IN_AIR) and state != HANGING)
+{
+ yAcc += gravityIntensity;
+}
+
+// Player has landed
+if ((colBot or colPlatBot) and platformCharacterIs(IN_AIR) and yVel >= 0)
+{
+ if (not colPlat or colBot)
+ {
+ yVel = 0;
+ yAcc = 0;
+ state = RUNNING;
+ jumps = 0;
+ }
+ //playSound(global.sndLand);
+}
+if ((colBot or colPlatBot) and not colPlat) yVel = 0;
+
+// Player has just walked off of the edge of a solid
+if (colBot == 0 and (not colPlatBot or colPlat) and platformCharacterIs(ON_GROUND))
+{
+ state = FALLING;
+ yAcc += grav;
+ kJumped = true;
+ if (global.hasGloves) hangCount = 5;
+}
+
+if (colTop)
+{
+ if (dead or stunned) yVel = -yVel * 0.8;
+ else if (state == JUMPING) yVel = abs(yVel*0.3)
+}
+
+if (colLeft and facing == LEFT) or (colRight and facing == RIGHT)
+{
+ if (dead or stunned) xVel = -xVel * 0.5;
+ else xVel = 0;
+}
+
+/******************************************
+
+ JUMPING
+
+*******************************************/
+
+if (kJumpReleased and platformCharacterIs(IN_AIR))
+{
+ kJumped = true;
+}
+else if (platformCharacterIs(ON_GROUND))
+{
+ oCape.open = false;
+ kJumped = false;
+}
+
+if (kJumpPressed and collision_point(x, y, oWeb, 0, 0))
+{
+ obj = instance_place(x, y, oWeb);
+ obj.life -= 1;
+ yAcc += initialJumpAcc * 2;
+ yVel -= 3;
+ xAcc += xVel/2;
+
+ state = JUMPING;
+ jumpButtonReleased = 0;
+ jumpTime = 0;
+
+ grav = gravNorm;
+}
+else if (kJumpPressed and colWaterTop)
+{
+ yAcc += initialJumpAcc * 2;
+ yVel -= 3;
+ xAcc += xVel/2;
+
+ state = JUMPING;
+ jumpButtonReleased = 0;
+ jumpTime = 0;
+
+ grav = gravNorm;
+}
+else if (global.hasCape and kJumpPressed and kJumped and platformCharacterIs(IN_AIR))
+{
+ if (not oCape.open) oCape.open = true;
+ else oCape.open = false;
+}
+else if (global.hasJetpack and kJump and kJumped and platformCharacterIs(IN_AIR) and jetpackFuel > 0)
+{
+ yAcc += initialJumpAcc;
+ yVel = -1;
+ jetpackFuel -= 1;
+ if (alarm[10] < 1) alarm[10] = 3;
+
+ state = JUMPING;
+ jumpButtonReleased = 0;
+ jumpTime = 0;
+
+ grav = 0;
+}
+else if (platformCharacterIs(ON_GROUND) and kJumpPressed and fallTimer == 0)
+{
+ if (xVel > 3 or xVel < -3)
+ {
+ yAcc += initialJumpAcc * 2;
+ xAcc += xVel * 2;
+ }
+ else
+ {
+ yAcc += initialJumpAcc * 2;
+ xAcc += xVel/2;
+ }
+
+ if (global.hasJordans)
+ {
+ yAcc *= 3;
+ yAccLimit = 12;
+ grav = 0.5;
+ }
+ else if (global.hasSpringShoes) yAcc *= 1.5;
+ else
+ {
+ yAccLimit = 6;
+ grav = gravNorm;
+ }
+
+ playSound(global.sndJump);
+
+ pushTimer = 0;
+
+ // the "state" gets changed to JUMPING later on in the code
+ state = FALLING;
+ // "variable jumping" states
+ jumpButtonReleased = 0;
+ jumpTime = 0;
+}
+
+if (jumpTime < jumpTimeTotal) jumpTime += 1;
+//let the character continue to jump
+if (kJump == 0) jumpButtonReleased = 1;
+if (jumpButtonReleased) jumpTime = jumpTimeTotal;
+
+gravityIntensity = (jumpTime/jumpTimeTotal) * grav;
+
+if (kUp and platformCharacterIs(ON_GROUND) and not colLadder)
+{
+ looking = UP;
+ if (xVel == 0 and xAcc == 0) state = LOOKING_UP;
+}
+else looking = 0;
+
+if (not kUp and state == LOOKING_UP)
+{
+ state=STANDING
+}
+
+/******************************************
+
+ HANGING
+
+*******************************************/
+
+if (not colTop)
+{
+if (global.hasGloves and yVel > 0)
+{
+ if (hangCount == 0 and y > 16 and !platformCharacterIs(ON_GROUND) and kRight and colRight and
+ (collision_point(x+9, y-5, oSolid, 0, 0) or collision_point(x+9, y-6, oSolid, 0, 0)))
+ {
+ state = HANGING;
+ move_snap(1, 8);
+ yVel = 0;
+ yAcc = 0;
+ grav = 0;
+ }
+ else if (hangCount == 0 and y > 16 and !platformCharacterIs(ON_GROUND) and kLeft and colLeft and
+ (collision_point(x-9, y-5, oSolid, 0, 0) or collision_point(x-9, y-6, oSolid, 0, 0)))
+ {
+ state = HANGING;
+ move_snap(1, 8);
+ yVel = 0;
+ yAcc = 0;
+ grav = 0;
+ }
+}
+else if (hangCount == 0 and y > 16 and !platformCharacterIs(ON_GROUND) and kRight and colRight and
+ (collision_point(x+9, y-5, oTree, 0, 0) or collision_point(x+9, y-6, oTree, 0, 0)))
+{
+ state = HANGING;
+ move_snap(1, 8);
+ yVel = 0;
+ yAcc = 0;
+ grav = 0;
+}
+else if (hangCount == 0 and y > 16 and !platformCharacterIs(ON_GROUND) and kLeft and colLeft and
+ (collision_point(x-9, y-5, oTree, 0, 0) or collision_point(x-9, y-6, oTree, 0, 0)))
+{
+ state = HANGING;
+ move_snap(1, 8);
+ yVel = 0;
+ yAcc = 0;
+ grav = 0;
+}
+else if (hangCount == 0 and y > 16 and !platformCharacterIs(ON_GROUND) and kRight and colRight and
+ (collision_point(x+9, y-5, oSolid, 0, 0) or collision_point(x+9, y-6, oSolid, 0, 0)) and
+ not collision_point(x+9, y-9, oSolid, 0, 0) and not collision_point(x, y+9, oSolid, 0, 0))
+{
+ state = HANGING;
+ move_snap(1, 8);
+ yVel = 0;
+ yAcc = 0;
+ grav = 0;
+}
+else if (hangCount == 0 and y > 16 and !platformCharacterIs(ON_GROUND) and kLeft and colLeft and
+ (collision_point(x-9, y-5, oSolid, 0, 0) or collision_point(x-9, y-6, oSolid, 0, 0)) and
+ not collision_point(x-9, y-9, oSolid, 0, 0) and not collision_point(x, y+9, oSolid, 0, 0))
+{
+ state = HANGING;
+ move_snap(1, 8);
+ yVel = 0;
+ yAcc = 0;
+ grav = 0;
+}
+
+if (hangCount == 0 and y > 16 and !platformCharacterIs(ON_GROUND) and state == FALLING and
+ (collision_point(x, y-5, oArrow, 0, 0) or collision_point(x, y-6, oArrow, 0, 0)) and
+ not collision_point(x, y-9, oArrow, 0, 0) and not collision_point(x, y+9, oArrow, 0, 0))
+{
+ obj = instance_nearest(x, y-5, oArrow);
+ if (obj.stuck)
+ {
+ state = HANGING;
+ // move_snap(1, 8);
+ yVel = 0;
+ yAcc = 0;
+ grav = 0;
+ }
+}
+
+/*
+if (hangCount == 0 and y > 16 and !platformCharacterIs(ON_GROUND) and state == FALLING and
+ (collision_point(x, y-5, oTreeBranch, 0, 0) or collision_point(x, y-6, oTreeBranch, 0, 0)) and
+ not collision_point(x, y-9, oTreeBranch, 0, 0) and not collision_point(x, y+9, oTreeBranch, 0, 0))
+{
+ state = HANGING;
+ // move_snap(1, 8);
+ yVel = 0;
+ yAcc = 0;
+ grav = 0;
+}
+*/
+
+}
+
+if (hangCount > 0) hangCount -= 1;
+
+if (state == HANGING)
+{
+ if (instance_exists(oCape)) oCape.open = false;
+ kJumped = false;
+
+ if (kDown and kJumpPressed)
+ {
+ grav = gravNorm;
+ state = FALLING;
+ yAcc -= grav;
+ hangCount = 5;
+ if (global.hasGloves) hangCount = 10;
+ }
+ else if (kJumpPressed)
+ {
+ grav = gravNorm;
+ if ((facing == RIGHT and kLeft) or (facing == LEFT and kRight))
+ {
+ state = FALLING;
+ yAcc -= grav;
+ }
+ else
+ {
+ state = JUMPING;
+ yAcc += initialJumpAcc * 2;
+ if (facing == RIGHT) x -= 2;
+ else x += 2;
+ }
+ hangCount = hangCountMax;
+ }
+
+ if ((facing == LEFT and not isCollisionLeft(2)) or
+ (facing == RIGHT and not isCollisionRight(2)))
+ {
+ grav = gravNorm;
+ state = FALLING;
+ yAcc -= grav;
+ hangCount = 4;
+ }
+}
+else
+{
+ grav = gravNorm;
+}
+
+// pressing down while standing
+if (kDown and platformCharacterIs(ON_GROUND) and not whipping)
+{
+ if (colBot)
+ {
+ state = DUCKING;
+ }
+ else if colPlatBot
+ {
+ // climb down ladder if possible, else jump down
+ fallTimer = 0;
+ if (not colBot)
+ {
+ ladder = 0;
+ ladder = instance_place(x, y+16, oLadder);
+ if (instance_exists(ladder))
+ {
+ if (abs(x-(ladder.x+8)) < 4)
+ {
+ x = ladder.x + 8;
+
+ xVel = 0;
+ yVel = 0;
+ xAcc = 0;
+ yAcc = 0;
+ state = CLIMBING;
+ }
+ }
+ else
+ {
+ y += 1;
+ state = FALLING;
+ yAcc += grav;
+ }
+ }
+ else
+ {
+ //the character can't move down because there is a solid in the way
+ state = RUNNING;
+ }
+ }
+}
+if (not kDown and state == DUCKING)
+{
+ state = STANDING;
+ xVel = 0;
+ xAcc = 0;
+}
+if (xVel == 0 and xAcc == 0 and state == RUNNING)
+{
+ state = STANDING;
+}
+if (xAcc != 0 and state == STANDING)
+{
+ state = RUNNING;
+}
+if (yVel < 0 and platformCharacterIs(IN_AIR) and state != HANGING)
+{
+ state = JUMPING;
+}
+if (yVel > 0 and platformCharacterIs(IN_AIR) and state != HANGING)
+{
+ state = FALLING;
+ setCollisionBounds(-5, -6, 5, 8);
+}
+else setCollisionBounds(-5, -8, 5, 8);
+
+// CLIMB LADDER
+colPointLadder = collision_point(x, y, oLadder, 0, 0) or collision_point(x, y, oLadderTop, 0, 0);
+
+if ((kUp and platformCharacterIs(IN_AIR) and collision_point(x, y-8, oLadder, 0, 0) and ladderTimer == 0) or
+ (kUp and colPointLadder and ladderTimer == 0) or
+ (kDown and colPointLadder and ladderTimer == 0 and platformCharacterIs(ON_GROUND) and collision_point(x, y+9, oLadderTop, 0, 0) and xVel == 0))
+{
+ ladder = 0;
+ ladder = instance_place(x, y-8, oLadder);
+ if (instance_exists(ladder))
+ {
+ if (abs(x-(ladder.x+8)) < 4)
+ {
+ x = ladder.x + 8;
+ if (not collision_point(x, y, oLadder, 0, 0) and
+ not collision_point(x, y, oLadderTop, 0, 0))
+ {
+ y = ladder.y + 14;
+ }
+
+ xVel = 0;
+ yVel = 0;
+ xAcc = 0;
+ yAcc = 0;
+ state = CLIMBING;
+ }
+ }
+}
+
+/*
+if (sprite_index == sDuckToHangL or sprite_index == sDamselDtHL)
+{
+ ladder = 0;
+ if (facing == LEFT and collision_rectangle(x-8, y, x, y+16, oLadder, 0, 0) and not collision_point(x-4, y+16, oSolid, 0, 0))
+ {
+ ladder = instance_nearest(x-4, y+16, oLadder);
+ }
+ else if (facing == RIGHT and collision_rectangle(x, y, x+8, y+16, oLadder, 0, 0) and not collision_point(x+4, y+16, oSolid, 0, 0))
+ {
+ ladder = instance_nearest(x+4, y+16, oLadder);
+ }
+
+ if (ladder)
+ {
+ x = ladder.x + 8;
+
+ xVel = 0;
+ yVel = 0;
+ xAcc = 0;
+ yAcc = 0;
+ state = CLIMBING;
+ }
+}
+*/
+/*
+if (colLadder and state == CLIMBING and kJumpPressed and not whipping)
+{
+ if (kLeft)
+ xVel = -departLadderXVel;
+ else if (kRight)
+ xVel = departLadderXVel;
+ else
+ xVel = 0;
+ yAcc += departLadderYVel;
+ state = JUMPING;
+ jumpButtonReleased = 0;
+ jumpTime = 0;
+ ladderTimer = 5;
+}
+*/
+
+// Calculate horizontal/vertical friction
+if (state == CLIMBING)
+{
+ xFric = frictionClimbingX;
+ yFric = frictionClimbingY;
+}
+else
+{
+ if (runKey and platformCharacterIs(ON_GROUND) and runHeld >= 10)
+ {
+ if (kLeft) // run
+ {
+ xVel -= 0.1;
+ xVelLimit = 6;
+ xFric = frictionRunningFastX;
+ }
+ else if (kRight)
+ {
+ xVel += 0.1;
+ xVelLimit = 6;
+ xFric = frictionRunningFastX;
+ }
+ }
+ else if (state == DUCKING)
+ {
+ if (xVel<2 and xVel>-2)
+ {
+ xFric = 0.2
+ xVelLimit = 3;
+ image_speed = 0.8;
+ }
+ else if (kLeft and global.downToRun) // run
+ {
+ xVel -= 0.1;
+ xVelLimit = 6;
+ xFric = frictionRunningFastX;
+ }
+ else if (kRight and global.downToRun)
+ {
+ xVel += 0.1;
+ xVelLimit = 6;
+ xFric = frictionRunningFastX;
+ }
+ else
+ {
+ xVel *= 0.8;
+ if (xVel < 0.5) xVel = 0;
+ xFric = 0.2
+ xVelLimit = 3;
+ image_speed = 0.8;
+ }
+ }
+ else
+ {
+ //decrease the friction when the character is "flying"
+ if (platformCharacterIs(IN_AIR))
+ {
+ if (dead or stunned) xFric = 1.0;
+ else xFric = 0.8;
+ }
+ else
+ {
+ xFric = frictionRunningX;
+ }
+ }
+
+ // Stuck on web or underwater
+ if (collision_point(x, y, oWeb, 0, 0))
+ {
+ xFric = 0.2;
+ yFric = 0.2;
+ fallTimer = 0;
+ }
+ else if (collision_point(x, y, oWater, -1, -1))
+ {
+ if (instance_exists(oCape)) oCape.open = false;
+
+ if (state == FALLING and yVel > 0)
+ {
+ yFric = 0.5;
+ }
+ else if (not collision_point(x, y-9, oWater, -1, -1))
+ {
+ yFric = 1;
+ }
+ else
+ {
+ yFric = 0.9;
+ }
+ }
+ else
+ {
+ swimming = false;
+ yFric = 1;
+ }
+}
+
+if (colIceBot and state != DUCKING and not global.hasSpikeShoes)
+{
+ xFric = 0.98;
+ yFric = 1;
+}
+
+// RUNNING
+
+if (platformCharacterIs(ON_GROUND))
+{
+ if (state == RUNNING and kLeft and colLeft)
+ {
+ pushTimer += 1;
+ }
+ else if (state == RUNNING and kRight and colRight)
+ {
+ pushTimer += 1;
+ }
+ else
+ {
+ pushTimer = 0;
+ }
+
+ if (platformCharacterIs(ON_GROUND) and not kJump and not kDown and not runKey)
+ {
+ xVelLimit = 3;
+ }
+
+
+ // ledge flip
+ if (state == DUCKING and abs(xVel) < 3 and facing == LEFT and
+ collision_point(x, y+9, oSolid, 0, 0) and not collision_line(x-1, y+9, x-10, y+9, oSolid, 0, 0) and kLeft)
+ {
+ state = DUCKTOHANG;
+
+ if (holdItem)
+ {
+ holdItem.held = false;
+ if (holdItem.type == "Gold Idol") holdItem.y -= 8;
+ scrDropItem(-1, -4);
+ }
+
+ with oMonkey
+ {
+ // knock off monkeys that grabbed you
+ if (status == 7)
+ {
+ xVel = -1;
+ yVel = -4;
+ status = 1;
+ vineCounter = 20;
+ grabCounter = 60;
+ }
+ }
+ }
+ else if (state == DUCKING and abs(xVel) < 3 and facing == RIGHT and
+ collision_point(x, y+9, oSolid, 0, 0) and not collision_line(x+1, y+9, x+10, y+9, oSolid, 0, 0) and kRight)
+ {
+ state = DUCKTOHANG;
+
+ if (holdItem)
+ {
+ // holdItem.held = false;
+ if (holdItem.type == "Gold Idol") holdItem.y -= 8;
+ scrDropItem(1, -4);
+ }
+
+ with oMonkey
+ {
+ // knock off monkeys that grabbed you
+ if (status == 7)
+ {
+ xVel = 1;
+ yVel = -4;
+ status = 1;
+ vineCounter = 20;
+ grabCounter = 60;
+ }
+ }
+ }
+}
+
+if (state == DUCKTOHANG)
+{
+ x = xPrev;
+ y = yPrev;
+ xVel = 0;
+ yVel = 0;
+ xAcc = 0;
+ yAcc = 0;
+ grav = 0;
+}
+
+// PARACHUTE AND CAPE
+if (instance_exists(oParachute))
+{
+ yFric = 0.5;
+}
+if (instance_exists(oCape))
+{
+ if (oCape.open) yFric = 0.5;
+}
+
+if (pushTimer > 100) pushTimer = 100;
+
+// limits the acceleration if it is too extreme
+if (xAcc > xAccLimit) xAcc = xAccLimit;
+else if (xAcc < -xAccLimit) xAcc = -xAccLimit;
+if (yAcc > yAccLimit) yAcc = yAccLimit;
+else if (yAcc < -yAccLimit) yAcc = -yAccLimit;
+
+// applies the acceleration
+xVel += xAcc;
+if (dead or stunned) yVel += 0.6;
+else yVel += yAcc;
+
+// nullifies the acceleration
+xAcc = 0;
+yAcc = 0;
+
+// applies the friction to the velocity, now that the velocity has been calculated
+xVel *= xFric;
+yVel *= yFric;
+
+// apply ball and chain
+if (instance_exists(oBall))
+{
+ if (distance_to_object(oBall) >= 24)
+ {
+ if (xVel > 0 and oBall.x < x and abs(oBall.x-x) > 24) xVel = 0;
+ if (xVel < 0 and oBall.x > x and abs(oBall.x-x) > 24) xVel = 0;
+ if (yVel > 0 and oBall.y < y and abs(oBall.y-y) > 24)
+ {
+ if (abs(oBall.x-x) < 1)
+ {
+ x = oBall.x;
+ }
+ else if (oBall.x < x and not kRight)
+ {
+ if (xVel > 0) xVel *= -0.25;
+ else if (xVel == 0) xVel -= 1;
+ }
+ else if (oBall.x > x and not kLeft)
+ {
+ if (xVel < 0) xVel *= -0.25;
+ else if (xVel == 0) xVel += 1;
+ }
+ yVel = 0;
+ fallTimer = 0;
+ }
+ if (yVel < 0 and oBall.y > y and abs(oBall.y-y) > 24) yVel = 0;
+ }
+}
+
+// apply the limits since the velocity may be too extreme
+if (not dead and not stunned)
+{
+ if (xVel > xVelLimit) xVel = xVelLimit;
+ else if (xVel < -xVelLimit) xVel = -xVelLimit;
+}
+if (yVel > yVelLimit) yVel = yVelLimit;
+else if (yVel < -yVelLimit) yVel = -yVelLimit;
+
+// approximates the "active" variables
+if approximatelyZero(xVel) xVel=0
+if approximatelyZero(yVel) yVel=0
+if approximatelyZero(xAcc) xAcc=0
+if approximatelyZero(yAcc) yAcc=0
+
+// prepares the character to move up a hill
+// we need to use the "slopeYPrev" variable later to know the "true" y previous value
+// keep this condition the same
+if maxSlope>0 and platformCharacterIs(ON_GROUND) and xVel!=0
+{
+ slopeYPrev=y
+ for(y=y;y>=slopeYPrev-maxSlope;y-=1)
+ if colTop
+ break
+ slopeChangeInY=slopeYPrev-y
+}
+else
+ slopeChangeInY=0
+
+// moves the character, and balances out the effects caused by other processes
+// keep this condition the same
+if maxSlope*abs(xVel)>0 and platformCharacterIs(ON_GROUND)
+{
+ // we need to check if we should dampen out the speed as the character runs on upward slopes
+ xPrev=x
+ yPrev=slopeYPrev // we don't want to use y, because y is too high
+ yPrevHigh=y // we'll use the higher previous variable later
+ moveTo(xVel,yVel+slopeChangeInY)
+ dist=point_distance(xPrev,yPrev,x,y)// overall distance that has been traveled
+ // we should have only ran at xVel
+ if dist>abs(xVelInteger)
+ {
+ // show_message(string(dist)+ " "+string(abs(xVelInteger)))
+ excess=dist-abs(xVelInteger)
+ if(xVelInteger<0)
+ excess*=-1
+ // move back since the character moved too far
+ x=xPrev
+ y=yPrevHigh // we need the character to be high so the character can move down
+ // this time we'll move the correct distance, but we need to shorten out the xVel a little
+ // these lines can be changed for different types of slowing down when running up hills
+ ratio=abs(xVelInteger)/dist*0.9 //can be changed
+ moveTo( round(xVelInteger*ratio),round(yVelInteger*ratio+slopeChangeInY) )
+ }
+}
+else
+{
+ // we simply move xVel and yVel while in the air or on a ladder
+ moveTo(xVel,yVel)
+}
+// move the character downhill if possible
+// we need to multiply maxDownSlope by the absolute value of xVel since the character normally runs at an xVel larger than 1
+if not colBot and maxDownSlope>0 and xVelInteger!=0 and platformCharacterIs(ON_GROUND)
+{
+ //the character is floating just above the slope, so move the character down
+ upYPrev=y
+ for(y=y;y<=upYPrev+maxDownSlope;y+=1)
+ if colBot // we hit a solid below
+ {
+ upYPrev=y // I know that this doesn't seem to make sense, because of the name of the variable, but it all works out correctly after we break out of this loop
+ break
+ }
+ y=upYPrev
+}
+
+//figures out what the sprite index of the character should be
+characterSprite();
+
+//sets the previous state and the previously previous state
+statePrevPrev = statePrev;
+statePrev = state;
+
+//calculates the image_speed based on the character's velocity
+if (state == RUNNING or state == DUCKING or state == LOOKING_UP)
+{
+ if (state == RUNNING or state == LOOKING_UP) image_speed = abs(xVel) * runAnimSpeed + 0.1;
+}
+
+if (state == CLIMBING) image_speed = sqrt(sqr(abs(xVel))+sqr(abs(yVel))) * climbAnimSpeed
+if (xVel >= 4 or xVel <= -4)
+{
+ image_speed = 1;
+ if (platformCharacterIs(ON_GROUND)) setCollisionBounds(-8, -8, 8, 8);
+ else setCollisionBounds(-5, -8, 5, 8);
+}
+else setCollisionBounds(-5, -8, 5, 8);
+if (whipping) image_speed = 1;
+if (state == DUCKTOHANG)
+{
+ image_index = 0;
+ image_speed = 0.8;
+}
+//limit the image_speed at 1 so the animation always looks good
+if (image_speed > 1) image_speed = 1;
diff --git a/samples/Game Maker Language/doEventPlayerDeath.gml b/samples/Game Maker Language/doEventPlayerDeath.gml
new file mode 100644
index 00000000..47ee7780
--- /dev/null
+++ b/samples/Game Maker Language/doEventPlayerDeath.gml
@@ -0,0 +1,251 @@
+/*
+ Originally from /Source/gg2/Scripts/Events/doEventPlayerDeath.gml in Gang Garrison 2
+
+ Copyright (C) 2008-2013 Faucet Software
+ http://www.ganggarrison.com
+
+ This program is free software;
+ you can redistribute it and/or modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 3 of the License, or (at your option)
+ any later version.
+ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU General Public License for more details.
+ You should have received a copy of the GNU General Public License along with this program; if not,
+ see .
+
+ Additional permission under GNU GPL version 3 section 7
+ If you modify this Program, or any covered work, by linking or combining it with the Game Maker runtime library,
+ the 39dll library/extension, Hobbel's Download Manager DLL, or modified versions of these libraries,
+ the licensors of this Program grant you additional permission to convey the resulting work.
+*/
+
+/**
+ * Perform the "player death" event, i.e. change the appropriate scores,
+ * destroy the character object to much splattering and so on.
+ *
+ * argument0: The player whose character died
+ * argument1: The player who inflicted the fatal damage (or noone for unknown)
+ * argument2: The player who assisted the kill (or noone for no assist)
+ * argument3: The source of the fatal damage
+ */
+var victim, killer, assistant, damageSource;
+victim = argument0;
+killer = argument1;
+assistant = argument2;
+damageSource = argument3;
+
+if(!instance_exists(killer))
+ killer = noone;
+
+if(!instance_exists(assistant))
+ assistant = noone;
+
+//*************************************
+//* Scoring and Kill log
+//*************************************
+
+
+recordKillInLog(victim, killer, assistant, damageSource);
+
+victim.stats[DEATHS] += 1;
+if(killer)
+{
+ if(damageSource == WEAPON_KNIFE || damageSource == WEAPON_BACKSTAB)
+ {
+ killer.stats[STABS] += 1;
+ killer.roundStats[STABS] += 1;
+ killer.stats[POINTS] += 1;
+ killer.roundStats[POINTS] +=1;
+ }
+
+ if (victim.object.currentWeapon.object_index == Medigun)
+ {
+ if (victim.object.currentWeapon.uberReady)
+ {
+ killer.stats[BONUS] += 1;
+ killer.roundStats[BONUS] += 1;
+ killer.stats[POINTS] += 1;
+ killer.roundStats[POINTS] += 1;
+ }
+ }
+
+ if (killer != victim)
+ {
+ killer.stats[KILLS] += 1;
+ killer.roundStats[KILLS] += 1;
+ killer.stats[POINTS] += 1;
+ killer.roundStats[POINTS] += 1;
+ if(victim.object.intel)
+ {
+ killer.stats[DEFENSES] += 1;
+ killer.roundStats[DEFENSES] += 1;
+ killer.stats[POINTS] += 1;
+ killer.roundStats[POINTS] += 1;
+ recordEventInLog(4, killer.team, killer.name, global.myself == killer);
+ }
+ }
+}
+
+if (assistant)
+{
+ assistant.stats[ASSISTS] += 1;
+ assistant.roundStats[ASSISTS] += 1;
+ assistant.stats[POINTS] += .5;
+ assistant.roundStats[POINTS] += .5;
+}
+
+//SPEC
+if (victim == global.myself)
+ instance_create(victim.object.x, victim.object.y, Spectator);
+
+//*************************************
+//* Gibbing
+//*************************************
+var xoffset, yoffset, xsize, ysize;
+
+xoffset = view_xview[0];
+yoffset = view_yview[0];
+xsize = view_wview[0];
+ysize = view_hview[0];
+
+randomize();
+with(victim.object) {
+ if((damageSource == WEAPON_ROCKETLAUNCHER
+ or damageSource == WEAPON_MINEGUN or damageSource == FRAG_BOX
+ or damageSource == WEAPON_REFLECTED_STICKY or damageSource == WEAPON_REFLECTED_ROCKET
+ or damageSource == FINISHED_OFF_GIB or damageSource == GENERATOR_EXPLOSION)
+ and (player.class != CLASS_QUOTE) and (global.gibLevel>1)
+ and distance_to_point(xoffset+xsize/2,yoffset+ysize/2) < 900) {
+ if (hasReward(victim, 'PumpkinGibs'))
+ {
+ repeat(global.gibLevel * 2) {
+ createGib(x,y,PumpkinGib,hspeed,vspeed,random(145)-72, choose(0,1,1,2,2,3), false, true)
+ }
+ }
+ else
+ {
+ repeat(global.gibLevel) {
+ createGib(x,y,Gib,hspeed,vspeed,random(145)-72, 0, false)
+ }
+ switch(player.team)
+ {
+ case TEAM_BLUE :
+ repeat(global.gibLevel - 1) {
+ createGib(x,y,BlueClump,hspeed,vspeed,random(145)-72, 0, false)
+ }
+ break;
+ case TEAM_RED :
+ repeat(global.gibLevel - 1) {
+ createGib(x,y,RedClump,hspeed,vspeed,random(145)-72, 0, false)
+ }
+ break;
+ }
+ }
+
+ repeat(global.gibLevel * 14) {
+ var blood;
+ blood = instance_create(x+random(23)-11,y+random(23)-11,BloodDrop);
+ blood.hspeed=(random(21)-10);
+ blood.vspeed=(random(21)-13);
+ if (hasReward(victim, 'PumpkinGibs'))
+ {
+ blood.sprite_index = PumpkinJuiceS;
+ }
+ }
+ if (!hasReward(victim, 'PumpkinGibs'))
+ {
+ //All Classes gib head, hands, and feet
+ if(global.gibLevel > 2 || choose(0,1) == 1)
+ createGib(x,y,Headgib,0,0,random(105)-52, player.class, false);
+ repeat(global.gibLevel -1){
+ //Medic has specially colored hands
+ if (player.class == CLASS_MEDIC){
+ if (player.team == TEAM_RED)
+ createGib(x,y,Hand, hspeed, vspeed, random(105)-52 , 9, false);
+ else
+ createGib(x,y,Hand, hspeed, vspeed, random(105)-52 , 10, false);
+ }else{
+ createGib(x,y,Hand, hspeed, vspeed, random(105)-52 , player.class, false);
+ }
+ createGib(x,y,Feet,random(5)-2,random(3),random(13)-6 , player.class, true);
+ }
+ }
+
+ //Class specific gibs
+ switch(player.class) {
+ case CLASS_PYRO :
+ if(global.gibLevel > 2 || choose(0,1) == 1)
+ createGib(x,y,Accesory,hspeed,vspeed,random(105)-52, 4, false)
+ break;
+ case CLASS_SOLDIER :
+ if(global.gibLevel > 2 || choose(0,1) == 1){
+ switch(player.team) {
+ case TEAM_BLUE :
+ createGib(x,y,Accesory,hspeed,vspeed,random(105)-52, 2, false);
+ break;
+ case TEAM_RED :
+ createGib(x,y,Accesory,hspeed,vspeed,random(105)-52, 1, false);
+ break;
+ }
+ }
+ break;
+ case CLASS_ENGINEER :
+ if(global.gibLevel > 2 || choose(0,1) == 1)
+ createGib(x,y,Accesory,hspeed,vspeed,random(105)-52, 3, false)
+ break;
+ case CLASS_SNIPER :
+ if(global.gibLevel > 2 || choose(0,1) == 1)
+ createGib(x,y,Accesory,hspeed,vspeed,random(105)-52, 0, false)
+ break;
+ }
+ playsound(x,y,Gibbing);
+ } else {
+ var deadbody;
+ if player.class != CLASS_QUOTE playsound(x,y,choose(DeathSnd1, DeathSnd2));
+ deadbody = instance_create(x,y-30,DeadGuy);
+ // 'GS' reward - *G*olden *S*tatue
+ if(hasReward(player, 'GS'))
+ {
+ deadbody.sprite_index = haxxyStatue;
+ deadbody.image_index = 0;
+ }
+ else
+ {
+ deadbody.sprite_index = sprite_index;
+ deadbody.image_index = CHARACTER_ANIMATION_DEAD;
+ }
+ deadbody.hspeed=hspeed;
+ deadbody.vspeed=vspeed;
+ if(hspeed>0) {
+ deadbody.image_xscale = -1;
+ }
+ }
+}
+
+if (global.gg_birthday){
+ myHat = instance_create(victim.object.x,victim.object.y,PartyHat);
+ myHat.image_index = victim.team;
+}
+if (global.xmas){
+ myHat = instance_create(victim.object.x,victim.object.y,XmasHat);
+ myHat.image_index = victim.team;
+}
+
+
+with(victim.object) {
+ instance_destroy();
+}
+
+//*************************************
+//* Deathcam
+//*************************************
+if( global.killCam and victim == global.myself and killer and killer != victim and !(damageSource == KILL_BOX || damageSource == FRAG_BOX || damageSource == FINISHED_OFF || damageSource == FINISHED_OFF_GIB || damageSource == GENERATOR_EXPLOSION)) {
+ instance_create(0,0,DeathCam);
+ DeathCam.killedby=killer;
+ DeathCam.name=killer.name;
+ DeathCam.oldxview=view_xview[0];
+ DeathCam.oldyview=view_yview[0];
+ DeathCam.lastDamageSource=damageSource;
+ DeathCam.team = global.myself.team;
+}
diff --git a/samples/Game Maker Language/faucet-http.gml b/samples/Game Maker Language/faucet-http.gml
new file mode 100644
index 00000000..c9b4d0f5
--- /dev/null
+++ b/samples/Game Maker Language/faucet-http.gml
@@ -0,0 +1,1469 @@
+#define __http_init
+// ***
+// This function forms part of Faucet HTTP v1.0
+// https://github.com/TazeTSchnitzel/Faucet-HTTP-Extension
+//
+// Copyright (c) 2013-2014, Andrea Faulds
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+// ***
+
+// Creates global.__HttpClient
+// real __http_init()
+
+global.__HttpClient = object_add();
+object_set_persistent(global.__HttpClient, true);
+
+#define __http_split
+// ***
+// This function forms part of Faucet HTTP v1.0
+// https://github.com/TazeTSchnitzel/Faucet-HTTP-Extension
+//
+// Copyright (c) 2013-2014, Andrea Faulds
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+// ***
+
+// real __http_split(string text, delimeter delimeter, real limit)
+// Splits string into items
+
+// text - string comma-separated values
+// delimeter - delimeter to split by
+// limit if non-zero, maximum times to split text
+// When limited, the remaining text will be left as the last item.
+// E.g. splitting "1,2,3,4,5" with delimeter "," and limit 2 yields this list:
+// "1", "2", "3,4,5"
+
+// return value - ds_list containing strings of values
+
+var text, delimeter, limit;
+text = argument0;
+delimeter = argument1;
+limit = argument2;
+
+var list, count;
+list = ds_list_create();
+count = 0;
+
+while (string_pos(delimeter, text) != 0)
+{
+ ds_list_add(list, string_copy(text, 1, string_pos(delimeter,text) - 1));
+ text = string_copy(text, string_pos(delimeter, text) + string_length(delimeter), string_length(text) - string_pos(delimeter, text));
+
+ count += 1;
+ if (limit and count == limit)
+ break;
+}
+ds_list_add(list, text);
+
+return list;
+
+#define __http_parse_url
+// ***
+// This function forms part of Faucet HTTP v1.0
+// https://github.com/TazeTSchnitzel/Faucet-HTTP-Extension
+//
+// Copyright (c) 2013-2014, Andrea Faulds
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+// ***
+
+// Parses a URL into its components
+// real __http_parse_url(string url)
+
+// Return value is a ds_map containing keys for the different URL parts: (or -1 on failure)
+// "url" - the URL which was passed in
+// "scheme" - the URL scheme (e.g. "http")
+// "host" - the hostname (e.g. "example.com" or "127.0.0.1")
+// "port" - the port (e.g. 8000) - this is a real, unlike the others
+// "abs_path" - the absolute path (e.g. "/" or "/index.html")
+// "query" - the query string (e.g. "a=b&c=3")
+// Parts which are not included will not be in the map
+// e.g. http://example.com will not have the "port", "path" or "query" keys
+
+// This will *only* work properly for URLs of format:
+// scheme ":" "//" host [ ":" port ] [ abs_path [ "?" query ]]"
+// where [] denotes an optional component
+// file: URLs will *not* work as they lack the authority (host:port) component
+// It will not work correctly for IPv6 host values
+
+var url;
+url = argument0;
+
+var map;
+map = ds_map_create();
+ds_map_add(map, 'url', url);
+
+// before scheme
+var colonPos;
+// Find colon for end of scheme
+colonPos = string_pos(':', url);
+// No colon - bad URL
+if (colonPos == 0)
+ return -1;
+ds_map_add(map, 'scheme', string_copy(url, 1, colonPos - 1));
+url = string_copy(url, colonPos + 1, string_length(url) - colonPos);
+
+// before double slash
+// remove slashes (yes this will screw up file:// but who cares)
+while (string_char_at(url, 1) == '/')
+ url = string_copy(url, 2, string_length(url) - 1);
+
+// before hostname
+var slashPos, colonPos;
+// Find slash for beginning of path
+slashPos = string_pos('/', url);
+// No slash ahead - http://host format with no ending slash
+if (slashPos == 0)
+{
+ // Find : for beginning of port
+ colonPos = string_pos(':', url);
+}
+else
+{
+ // Find : for beginning of port prior to /
+ colonPos = string_pos(':', string_copy(url, 1, slashPos - 1));
+}
+// No colon - no port
+if (colonPos == 0)
+{
+ // There was no slash
+ if (slashPos == 0)
+ {
+ ds_map_add(map, 'host', url);
+ return map;
+ }
+ // There was a slash
+ else
+ {
+ ds_map_add(map, 'host', string_copy(url, 1, slashPos - 1));
+ url = string_copy(url, slashPos, string_length(url) - slashPos + 1);
+ }
+}
+// There's a colon - port specified
+else
+{
+ // There was no slash
+ if (slashPos == 0)
+ {
+ ds_map_add(map, 'host', string_copy(url, 1, colonPos - 1));
+ ds_map_add(map, 'port', real(string_copy(url, colonPos + 1, string_length(url) - colonPos)));
+ return map;
+ }
+ // There was a slash
+ else
+ {
+ ds_map_add(map, 'host', string_copy(url, 1, colonPos - 1));
+ url = string_copy(url, colonPos + 1, string_length(url) - colonPos);
+ slashPos = string_pos('/', url);
+ ds_map_add(map, 'port', real(string_copy(url, 1, slashPos - 1)));
+ url = string_copy(url, slashPos, string_length(url) - slashPos + 1);
+ }
+}
+
+// before path
+var queryPos;
+queryPos = string_pos('?', url);
+// There's no ? - no query
+if (queryPos == 0)
+{
+ ds_map_add(map, 'abs_path', url);
+ return map;
+}
+else
+{
+ ds_map_add(map, 'abs_path', string_copy(url, 1, queryPos - 1));
+ ds_map_add(map, 'query', string_copy(url, queryPos + 1, string_length(url) - queryPos));
+ return map;
+}
+
+// Return -1 upon unlikely error
+ds_map_destroy(map);
+return -1;
+
+#define __http_resolve_url
+// ***
+// This function forms part of Faucet HTTP v1.0
+// https://github.com/TazeTSchnitzel/Faucet-HTTP-Extension
+//
+// Copyright (c) 2013-2014, Andrea Faulds
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+// ***
+
+// Takes a base URL and a URL reference and applies it to the base URL
+// Returns resulting absolute URL
+// string __http_resolve_url(string baseUrl, string refUrl)
+
+// Return value is a string containing the new absolute URL, or "" on failure
+
+// Works only for restricted URL syntax as understood by by http_resolve_url
+// The sole restriction of which is that only scheme://authority/path URLs work
+// This notably excludes file: URLs which lack the authority component
+
+// As described by RFC3986:
+// URI-reference = URI / relative-ref
+// relative-ref = relative-part [ "?" query ] [ "#" fragment ]
+// relative-part = "//" authority path-abempty
+// / path-absolute
+// / path-noscheme
+// / path-empty
+// However http_resolve_url does *not* deal with fragments
+
+// Algorithm based on that of section 5.2.2 of RFC 3986
+
+var baseUrl, refUrl;
+baseUrl = argument0;
+refUrl = argument1;
+
+// Parse base URL
+var urlParts;
+urlParts = __http_parse_url(baseUrl);
+if (urlParts == -1)
+ return '';
+
+// Try to parse reference URL
+var refUrlParts, canParseRefUrl;
+refUrlParts = __http_parse_url(refUrl);
+canParseRefUrl = (refUrlParts != -1);
+if (refUrlParts != -1)
+ ds_map_destroy(refUrlParts);
+
+var result;
+result = '';
+
+// Parsing of reference URL succeeded - it's absolute and we're done
+if (canParseRefUrl)
+{
+ result = refUrl;
+}
+// Begins with '//' - scheme-relative URL
+else if (string_copy(refUrl, 1, 2) == '//' and string_length(refUrl) > 2)
+{
+ result = ds_map_find_value(urlParts, 'scheme') + ':' + refUrl;
+}
+// Is or begins with '/' - absolute path relative URL
+else if (((string_char_at(refUrl, 1) == '/' and string_length(refUrl) > 1) or refUrl == '/')
+// Doesn't begin with ':' and is not blank - relative path relative URL
+ or (string_char_at(refUrl, 1) != ':' and string_length(refUrl) > 0))
+{
+ // Find '?' for query
+ var queryPos;
+ queryPos = string_pos('?', refUrl);
+ // No query
+ if (queryPos == 0)
+ {
+ refUrl = __http_resolve_path(ds_map_find_value(urlParts, 'abs_path'), refUrl);
+ ds_map_replace(urlParts, 'abs_path', refUrl);
+ if (ds_map_exists(urlParts, 'query'))
+ ds_map_delete(urlParts, 'query');
+ }
+ // Query exists, split
+ else
+ {
+ var path, query;
+ path = string_copy(refUrl, 1, queryPos - 1);
+ query = string_copy(refUrl, queryPos + 1, string_length(relUrl) - queryPos);
+ path = __http_resolve_path(ds_map_find_value(urlParts, 'abs_path'), path);
+ ds_map_replace(urlParts, 'abs_path', path);
+ if (ds_map_exists(urlParts, 'query'))
+ ds_map_replace(urlParts, 'query', query);
+ else
+ ds_map_add(urlParts, 'query', query);
+ }
+ result = __http_construct_url(urlParts);
+}
+
+ds_map_destroy(urlParts);
+return result;
+
+#define __http_resolve_path
+// ***
+// This function forms part of Faucet HTTP v1.0
+// https://github.com/TazeTSchnitzel/Faucet-HTTP-Extension
+//
+// Copyright (c) 2013-2014, Andrea Faulds
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+// ***
+
+// Takes a base path and a path reference and applies it to the base path
+// Returns resulting absolute path
+// string __http_resolve_path(string basePath, string refPath)
+
+// Return value is a string containing the new absolute path
+
+// Deals with UNIX-style / paths, not Windows-style \ paths
+// Can be used to clean up .. and . in non-absolute paths too ('' as basePath)
+
+var basePath, refPath;
+basePath = argument0;
+refPath = argument1;
+
+// refPath begins with '/' (is absolute), we can ignore all of basePath
+if (string_char_at(refPath, 1) == '/')
+{
+ basePath = refPath;
+ refPath = '';
+}
+
+var parts, refParts;
+parts = __http_split(basePath, '/', 0);
+refParts = __http_split(refPath, '/', 0);
+
+if (refPath != '')
+{
+ // Find last part of base path
+ var lastPart;
+ lastPart = ds_list_find_value(parts, ds_list_size(parts) - 1);
+
+ // If it's not blank (points to a file), remove it
+ if (lastPart != '')
+ {
+ ds_list_delete(parts, ds_list_size(parts) - 1);
+ }
+
+ // Concatenate refParts to end of parts
+ var i;
+ for (i = 0; i < ds_list_size(refParts); i += 1)
+ ds_list_add(parts, ds_list_find_value(refParts, i));
+}
+
+// We now don't need refParts any more
+ds_list_destroy(refParts);
+
+// Deal with '..' and '.'
+for (i = 0; i < ds_list_size(parts); i += 1)
+{
+ var part;
+ part = ds_list_find_value(parts, i);
+
+ if (part == '.')
+ {
+ if (i == 1 or i == ds_list_size(parts) - 1)
+ ds_list_replace(parts, i, '');
+ else
+ ds_list_delete(parts, i);
+ i -= 1;
+ continue;
+ }
+ else if (part == '..')
+ {
+ if (i > 1)
+ {
+ ds_list_delete(parts, i - 1);
+ ds_list_delete(part, i);
+ i -= 2;
+ }
+ else
+ {
+ ds_list_replace(parts, i, '');
+ i -= 1;
+ }
+ continue;
+ }
+ else if (part == '' and i != 0 and i != ds_list_size(parts) - 1)
+ {
+ ds_list_delete(parts, i);
+ i -= 1;
+ continue;
+ }
+}
+
+// Reconstruct path from parts
+var path;
+path = '';
+for (i = 0; i < ds_list_size(parts); i += 1)
+{
+ if (i != 0)
+ path += '/';
+ path += ds_list_find_value(parts, i);
+}
+
+ds_map_destroy(parts);
+return path;
+
+#define __http_parse_hex
+// ***
+// This function forms part of Faucet HTTP v1.0
+// https://github.com/TazeTSchnitzel/Faucet-HTTP-Extension
+//
+// Copyright (c) 2013-2014, Andrea Faulds
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+// ***
+
+// Takes a lowercase hexadecimal string and returns its integer value
+// real __http_parse_hex(string hexString)
+
+// Return value is the whole number value (or -1 if invalid)
+// Only works for whole numbers (non-fractional numbers >= 0) and lowercase hex
+
+var hexString;
+hexString = argument0;
+
+var result, hexValues;
+result = 0;
+hexValues = "0123456789abcdef";
+
+var i;
+for (i = 1; i <= string_length(hexString); i += 1) {
+ result *= 16;
+ var digit;
+ digit = string_pos(string_char_at(hexString, i), hexValues) - 1;
+ if (digit == -1)
+ return -1;
+ result += digit;
+}
+
+return result;
+
+#define __http_construct_url
+// ***
+// This function forms part of Faucet HTTP v1.0
+// https://github.com/TazeTSchnitzel/Faucet-HTTP-Extension
+//
+// Copyright (c) 2013-2014, Andrea Faulds