diff --git a/HTML5-CDGPlayer_files/cdgmagic_cdgdecoder_lowresource.go b/HTML5-CDGPlayer_files/cdgmagic_cdgdecoder_lowresource.go
new file mode 100644
index 0000000..6342d1d
--- /dev/null
+++ b/HTML5-CDGPlayer_files/cdgmagic_cdgdecoder_lowresource.go
@@ -0,0 +1,187 @@
+package main
+
+import "fmt"
+
+/*
+ * This file is part of CD+Graphics Magic.
+ *
+ * CD+Graphics Magic 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 2 of the
+ * License, or (at your option) any later version.
+ *
+ * CD+Graphics Magic 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 CD+Graphics Magic. If not, see .
+ *
+ */
+
+/*
+ * This class instantiates an HTML5/Canvas CD+Graphics decoder object.
+ *
+ * This is the "low resource" version, and should be very close
+ * to as fast as possible with JavaScript.
+ *
+ * The difference between the "low resource" and normal version
+ * is that this one packs each 6 pixel font line in to one
+ * array value, unrolling some loops and minimizing array lookups.
+ *
+ * The only concession made is lack of H/V "offset" support used
+ * for smooth scrolling.
+ * Block based scrolls *are* still supported, however, so the basic
+ * intent of the graphics is presented, but less than ideally.
+ *
+ * It is recommended for CPU constrained (eg. mobile or embedded) devices.
+ *
+ */
+
+// Useful enums for CD+Graphics...
+
+const (
+ VRAM_SIZE = 300 * 216 // Total linear size of VRAM, in pixels.
+ VRAM_WIDTH = 300 // Width (or pitch) of VRAM, in pixels.
+ VRAM_HEIGHT = 216 // Height of VRAM, in pixels.
+ VISIBLE_SIZE = 288 * 192 // Total linear size of visible screen, in pixels.
+ VISIBLE_WIDTH = 288 // Width (or pitch) of visible screen, in pixels.
+ VISIBLE_HEIGHT = 192 // Height of visible screen, in pixels.
+ FONT_WIDTH = 6 // Width of one "font" (or block).
+ FONT_HEIGHT = 12 // Height of one "font" (or block).
+ NUM_X_FONTS = 50 // Number of horizontal fonts contained in VRAM.
+ NUM_Y_FONTS = 18 // Number of vertical fonts contained in VRAM.
+ PALETTE_ENTRIES = 16 // Number of CLUT palette entries.
+ TV_GRAPHICS = 0x09 // 50x18 (48x16) 16 color TV graphics mode.
+ MEMORY_PRESET = 0x01 // Set all VRAM to palette index.
+ BORDER_PRESET = 0x02 // Set border to palette index.
+ LOAD_CLUT_LO = 0x1E // Load Color Look Up Table index 0 through 7.
+ LOAD_CLUT_HI = 0x1F // Load Color Look Up Table index 8 through 15.
+ COPY_FONT = 0x06 // Copy 12x6 pixel font to screen.
+ XOR_FONT = 0x26 // XOR 12x6 pixel font with existing VRAM values.
+ SCROLL_PRESET = 0x14 // Update scroll offset, copying if 0x20 or 0x10.
+ SCROLL_COPY = 0x18 // Update scroll offset, setting color if 0x20 or 0x10.
+)
+
+var (
+ internal_palette = make([]byte, PALETTE_ENTRIES)
+ internal_vram = make([]byte, NUM_X_FONTS*VRAM_HEIGHT)
+ internal_dirty_blocks = make([]byte, 900)
+
+ internal_border_index = 0x00 // The current border palette index.
+ internal_current_pack = 0x00 //
+
+ internal_border_dirty = false
+ internal_screen_dirty = false
+)
+
+func main() {
+ fmt.Println("Compiles baby!")
+}
+
+func resetCDGState() {
+ internal_current_pack = 0x00
+ internal_border_index = 0x00
+ clearPalette()
+ clearVRAM(0x00)
+ clearDirtyBlocks()
+}
+
+func clearPalette() {
+ for idx := 0; idx < PALETTE_ENTRIES; idx++ {
+ internal_palette[idx] = 0x00
+ }
+}
+
+func get_current_pack() byte {
+ //casting: must test!!!
+ return byte(internal_current_pack)
+}
+
+/* Possibly not needed!
+func set_dirtyrect(requested_value) {
+ internal_usedirtyrect = requested_value
+}
+*/
+
+func redrawCanvas() {
+
+ if internal_border_dirty || internal_screen_dirty {
+ // render_screen_to_rgb()
+ // internal_screen_dirty = 0
+ // clear_dirty_blocks()
+ // internal_rgba_context.putImageData(internal_rgba_imagedata, 0, 0)
+ } else {
+ var local_context = internal_rgba_context
+ var local_rgba_imagedata = internal_rgba_imagedata
+
+ update_needed := false
+ var blk = 0x00
+
+ //NOTE: test the post-increment (Go does not have pre, so had to change it)
+
+ for y_blk := 1; y_blk <= 16; y_blk++ {
+
+ blk = y_blk*NUM_X_FONTS + 1
+
+ for x_blk := 1; x_blk <= 48; x_blk++ {
+
+ if internal_dirty_blocks[blk] {
+
+ render_block_to_rgb(x_blk, y_blk)
+
+ if internal_usedirtyrect == 0x01 {
+ local_context.putImageData(local_rgba_imagedata, 0, 0,
+ (x_blk-1)*FONT_WIDTH,
+ (y_blk-1)*FONT_HEIGHT,
+ FONT_WIDTH,
+ FONT_HEIGHT)
+ } else {
+ update_needed = 0x01
+ }
+
+ internal_dirty_blocks[blk] = 0x00
+ }
+ //Note: test the post-increment
+ blk++
+ }
+ }
+ // Update the whole screen for browsers where dirty rect isn't supported.
+ // Since this can't be detected(???) in any way, it has to be User Agent selected, or an actual user option.
+ // TODO: See if a dirty rect-based partial update of known pixel values combined with a getImageData
+ // call could be used to determine if it works correctly *without* evil browser sniffing.
+ if update_needed {
+ //local_context.putImageData(local_rgba_imagedata, 0, 0);
+ }
+ }
+}
+
+func clearVRAM(colorIndex byte) {
+
+ packed_line_value := fill_line_with_palette_index(colorIndex)
+
+ for pxl := 0; pxl < len(internal_vram); pxl++ {
+ internal_vram[pxl] = packed_line_value
+ }
+
+ internal_screen_dirty = true
+}
+
+func clearDirtyBlocks() {
+ for blk := 0; blk < 900; blk++ {
+ internal_dirty_blocks[blk] = 0x00
+ }
+}
+
+func fill_line_with_palette_index(requested_index byte) byte {
+
+ adjusted_value := requested_index // Pixel 0
+ adjusted_value |= (requested_index << 004) // Pixel 1
+ adjusted_value |= (requested_index << 010) // Pixel 2
+ adjusted_value |= (requested_index << 014) // Pixel 3
+ adjusted_value |= (requested_index << 020) // Pixel 4
+ adjusted_value |= (requested_index << 024) // Pixel 5
+
+ return adjusted_value
+}