Jump to content

newcoleco

Members
  • Content Count

    1,351
  • Joined

  • Last visited

  • Days Won

    1

Posts posted by newcoleco


  1. I'm leaving here the first draft of a music I'm currently working on. It's based on a famous chiptune many should recognize. It took me about 3 hours to figure out the proper notes, sound effects and what overall feels nice to my ears (essentially means, I am able to listen without the feeling that something is out of place). Keep in mind that I code music note by note, no help of any music tracker, it's all done by hand which takes a lot of time, patience, a minimum of music knowledge, and listening to the original material over and over again.

    You can try to compile the music data in a program with the proper calls to the Coleco OS sound routines, check the coding guides, OS7 ColecoVision BIOS listing. It should also work with ADAM EOS sound routines since they are essentially the same. You can also try to use a keyboard and play the notes mentioned in the comments. You can also play directly the data with one of my sound tools without compiling anything.

    Hint: the capital letters HS refer to the words High Score.

    And for those who really can't try the music data listings, at least you can listen to the result.

     

    March 31, 2018 - MODIFIED (ROBHUBBARDIFY) MUSIC INTRO LEVEL commando-musicbox-2018-revJ.zip

    March 30, 2018 - ADDED FX-FREE, MUSIC INTRO LEVEL with FX-CHOPPA commando-musicbox-2018-revI.zip

    March 29, 2018 - ADDED FX-SUPPLY, FX-MOTOR commando-musicbox-2018-revH.zip

    March 26, 2018 - ADDED FX-LETTER commando-musicbox-2018-revG.zip
    March 21, 2018 - ADDED FX-LIFE commando-musicbox-2018-revF.zip
    March 20, 2018 - ADDED FX-GRENADE commando-musicbox-2018-revE.zip
    March 17, 2018 - ADDED AREA COMPLETE + FX-DEATH commando-musicbox-2018-revD.zip

    Version March 7, 2018 - Melody completed. Tweaked some volume-effects.

    ; Daniel Bienvenu
    ; March 7, 2018
    ; Music Data
    
    music_HS_ch0_A:
    .db 0x00,0x00,0x84,0x02
    .db 0x02,0x23,0x0e,0x12,0x21
    .db 0x00,0x00,0x64,0x01
    .db 0x00,0x00,0x33,0x0f
    .db 0x02,0x45,0x10,0x1c,0x21
    .db 0x00,0x00,0x84,0x02
    .db 0x02,0x23,0x0e,0x12,0x21
    .db 0x18
    
    music_HS_ch3_A:
    .db 0xc0,0x88,0xf0,0x80 ; A1
    .db 0xc0,0x98,0xf0,0x80 ; G1
    .db 0xc0,0x66,0xf0,0x80 ; D2
    .db 0xc0,0x5a,0xf0,0x80 ; E2
    ;;
    .db 0xc0,0x88,0xf0,0x80 ; A1
    .db 0xc0,0x98,0xf0,0x80 ; G1
    .db 0xc0,0x66,0xf0,0x80 ; D2
    .db 0xc0,0x5a,0xf0,0x80 ; E2
    ;;
    .db 0xc0,0x51,0xf0,0x80 ; F#2
    .db 0xc0,0x6c,0xf0,0x80 ; C#2
    .db 0xc0,0x66,0xf0,0x80 ; D2
    .db 0xc0,0x5a,0xf0,0x80 ; E2
    ;;
    .db 0xc0,0x88,0xf0,0x80 ; A1
    .db 0xc0,0x98,0xf0,0x80 ; G1
    .db 0xc0,0x66,0xf0,0x80 ; D2
    .db 0xc0,0x5a,0xf0,0x80 ; E2
    ;;
    .db 0xc0,0x88,0xf0,0x80 ; A1
    .db 0xc0,0x66,0xf0,0x40 ; D2
    .db 0xc0,0x5a,0xf0,0x40 ; E2
    ;;
    .db 0xc0,0x88,0xf0,0x80 ; A1
    .db 0xc0,0x66,0xf0,0x40 ; D2
    .db 0xc0,0x5a,0xf0,0x40 ; E2
    ;;
    .db 0xc0,0x88,0xf0,0x80 ; A1
    .db 0xc0,0x66,0xf0,0x40 ; D2
    .db 0xc0,0x5a,0xf0,0x40 ; E2
    ;;
    .db 0xc0,0x88,0xf0,0x80 ; A1
    .db 0xc0,0x66,0xf0,0x40 ; D2
    .db 0xc0,0x5a,0xf0,0x40 ; E2
    .db 0xd8
    
    music_HS_ch1_A:
    ;; A4
    .db 0x40,0xFE,0x80,0x01
    .db 0x40,0xFC,0x71,0x01
    .db 0x40,0xFE,0x70,0x01
    .db 0x40,0xFC,0x71,0x01
    .db 0x40,0xFE,0x70,0x01
    .db 0x40,0xFC,0x71,0x01
    .db 0x40,0xFE,0x70,0x01
    .db 0x40,0xFC,0x71,0x01
    .db 0x40,0xFE,0x70,0x01
    .db 0x40,0xFC,0x71,0x01
    .db 0x40,0xFE,0x70,0x01
    .db 0x40,0xFC,0x71,0x01
    .db 0x40,0x00,0xf0,0x04
    ;; E5
    .db 0x40,0xAA,0x80,0x01
    .db 0x40,0x53,0x71,0x01
    .db 0x40,0xAA,0x70,0x01
    .db 0x40,0x53,0x71,0x01
    .db 0x40,0xAA,0x70,0x01
    .db 0x40,0x53,0x71,0x01
    .db 0x40,0xAA,0x70,0x01
    .db 0x40,0x53,0x71,0x01
    .db 0x40,0xAA,0x70,0x01
    .db 0x40,0x53,0x71,0x01
    .db 0x40,0xAA,0x70,0x01
    .db 0x40,0x53,0x71,0x01
    .db 0x40,0x00,0xf0,0x04
    ;; A5
    .db 0x40,0x7F,0x80,0x01
    .db 0x40,0xFE,0x70,0x01
    .db 0x40,0x7F,0x70,0x01
    .db 0x40,0xFE,0x70,0x01
    .db 0x40,0x7F,0x70,0x01
    .db 0x40,0xFE,0x70,0x01
    .db 0x40,0x7F,0x70,0x01
    .db 0x40,0xFE,0x70,0x01
    .db 0x40,0x7F,0x70,0x01
    .db 0x40,0xFE,0x70,0x01
    .db 0x40,0x7F,0x70,0x01
    .db 0x40,0xFE,0x70,0x01
    .db 0x40,0x00,0xf0,0x04
    ;; E5
    .db 0x40,0xAA,0x80,0x01
    .db 0x40,0x53,0x71,0x01
    .db 0x40,0xAA,0x70,0x01
    .db 0x40,0x53,0x71,0x01
    .db 0x40,0xAA,0x70,0x01
    .db 0x40,0x53,0x71,0x01
    .db 0x40,0xAA,0x70,0x01
    .db 0x40,0x53,0x71,0x01
    .db 0x40,0xAA,0x70,0x01
    .db 0x40,0x53,0x71,0x01
    .db 0x40,0xAA,0x70,0x01
    .db 0x40,0x53,0x71,0x01
    .db 0x40,0x00,0xf0,0x04
    ;; A5
    .db 0x40,0x7F,0x70,0x01
    .db 0x40,0xFE,0x70,0x01
    .db 0x40,0x7F,0x70,0x01
    .db 0x40,0xFE,0x70,0x01
    .db 0x40,0x7F,0x70,0x01
    .db 0x40,0xFE,0x70,0x01
    .db 0x40,0x7F,0x70,0x01
    .db 0x40,0xFE,0x70,0x01
    .db 0x40,0x7F,0x70,0x01
    .db 0x40,0xFE,0x70,0x01
    .db 0x40,0x7F,0x70,0x01
    .db 0x40,0xFE,0x70,0x01
    .db 0x40,0x00,0xf0,0x04
    ;; A5
    .db 0x40,0x7F,0x70,0x01
    .db 0x40,0xFE,0x70,0x01
    .db 0x40,0x7F,0x70,0x01
    .db 0x40,0xFE,0x70,0x01
    .db 0x40,0x7F,0x70,0x01
    .db 0x40,0xFE,0x70,0x01
    .db 0x40,0x7F,0x70,0x01
    .db 0x40,0xFE,0x70,0x01
    .db 0x40,0x7F,0x70,0x01
    .db 0x40,0xFE,0x70,0x01
    .db 0x40,0x7F,0x70,0x01
    .db 0x40,0xFE,0x70,0x01
    .db 0x40,0x00,0xf0,0x04
    ;; E5
    .db 0x40,0xAA,0x80,0x01
    .db 0x40,0x53,0x71,0x01
    .db 0x40,0xAA,0x70,0x01
    .db 0x40,0x53,0x71,0x01
    .db 0x40,0xAA,0x70,0x01
    .db 0x40,0x53,0x71,0x01
    .db 0x40,0xAA,0x70,0x01
    .db 0x40,0x53,0x71,0x01
    .db 0x40,0xAA,0x70,0x01
    .db 0x40,0x53,0x71,0x01
    .db 0x40,0xAA,0x70,0x01
    .db 0x40,0x53,0x71,0x01
    .db 0x40,0x00,0xf0,0x04
    ;; A5
    .db 0x40,0x7F,0x80,0x01
    .db 0x40,0xFE,0x70,0x01
    .db 0x40,0x7F,0x70,0x01
    .db 0x40,0xFE,0x70,0x01
    .db 0x40,0x7F,0x70,0x01
    .db 0x40,0xFE,0x70,0x01
    .db 0x40,0x7F,0x70,0x01
    .db 0x40,0xFE,0x70,0x01
    .db 0x40,0x7F,0x70,0x01
    .db 0x40,0xFE,0x70,0x01
    .db 0x40,0x7F,0x70,0x01
    .db 0x40,0xFE,0x70,0x01
    .db 0x40,0x00,0xf0,0x04
    .db 0x58
    
    music_HS_ch2_A:
    ;; - 1 -
    .db 0x82,0xCA,0xc0,0x30,0xe4,0x11 ; C#5
    .db 0x81, 0xcd, 0x60, 0x03, 0x22, 0xFd
    .db 0x81, 0xC7, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0xcd, 0x60, 0x03, 0x22, 0xFd
    .db 0x81, 0xC7, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0xcd, 0x60, 0x03, 0x22, 0xFd
    .db 0x81, 0xC7, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0xcd, 0x60, 0x03, 0x22, 0xFd
    .db 0x81, 0xC7, 0x70, 0x03, 0x22, 0x03
    .db 0x82,0xE2,0xc0,0x20,0xe4,0x11 ; B4
    .db 0x82,0xBE,0xc0,0x10,0xe4,0x11 ; D5
    .db 0x82,0xCA,0xc0,0x20,0xe4,0x11 ; C#5
    .db 0x82,0xE2,0xc0,0x20,0xe4,0x11 ; B4
    .db 0x82,0xCA,0xc0,0x30,0xe4,0x11 ; C#5
    .db 0x82,0xFE,0xc0,0x30,0xe4,0x11 ; A4
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x70, 0x03, 0x22, 0x03
    .db 0x82,0xFE,0xc0,0x20,0xe4,0x11 ; A4
    .db 0x82,0xFE,0xc0,0x10,0xe4,0x11 ; A4
    .db 0x82,0x0D,0xc1,0x20,0xe4,0x11 ; Ab4
    .db 0x82,0x2E,0xc1,0x30,0xe4,0x11 ; F#4
    .db 0x82,0x0D,0xc1,0x10,0xe4,0x11 ; Ab4
    .db 0x82,0xFE,0xc0,0x10,0xe4,0x11 ; A4
    ;; - 2 -
    .db 0x82,0xCA,0xc0,0x30,0xe4,0x11 ; C#5
    .db 0x81, 0xcd, 0x60, 0x03, 0x22, 0xFd
    .db 0x81, 0xC7, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0xcd, 0x60, 0x03, 0x22, 0xFd
    .db 0x81, 0xC7, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0xcd, 0x60, 0x03, 0x22, 0xFd
    .db 0x81, 0xC7, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0xcd, 0x60, 0x03, 0x22, 0xFd
    .db 0x81, 0xC7, 0x70, 0x03, 0x22, 0x03
    .db 0x82,0xE2,0xc0,0x20,0xe4,0x11 ; B4
    .db 0x82,0xBE,0xc0,0x10,0xe4,0x11 ; D5
    .db 0x82,0xCA,0xc0,0x20,0xe4,0x11 ; C#5
    .db 0x82,0xE2,0xc0,0x20,0xe4,0x11 ; B4
    .db 0x82,0xCA,0xc0,0x30,0xe4,0x11 ; C#5
    .db 0x82,0xFE,0xc0,0x30,0xe4,0x11 ; A4
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x70, 0x03, 0x22, 0x03
    .db 0x82,0xFE,0xc0,0x20,0xe4,0x11 ; A4
    .db 0x82,0xFE,0xc0,0x10,0xe4,0x11 ; A4
    .db 0x82,0x0D,0xc1,0x20,0xe4,0x11 ; Ab4
    .db 0x82,0x2E,0xc1,0x20,0xe4,0x11 ; F#4
    .db 0x82,0x53,0xc1,0x30,0xe4,0x11 ; E4
    ;; - 3 -
    .db 0x82,0x53,0xc1,0x30,0xe4,0x11 ; E4
    .db 0x81, 0x56, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0x50, 0x61, 0x03, 0x22, 0x03
    .db 0x81, 0x56, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0x50, 0x61, 0x03, 0x22, 0x03
    .db 0x81, 0x56, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0x50, 0x61, 0x03, 0x22, 0x03
    .db 0x81, 0x56, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0x50, 0x61, 0x03, 0x22, 0x03
    .db 0x82,0x2e,0xc1,0x10,0xe4,0x11 ; F#4
    .db 0x82,0xFE,0xc0,0x10,0xe4,0x11 ; A4
    .db 0x82,0xFE,0xc0,0x20,0xe4,0x11 ; A4
    .db 0x82,0x0D,0xc1,0x10,0xe4,0x11 ; Ab4
    .db 0x81, 0x10, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0x0A, 0x61, 0x03, 0x22, 0x03
    .db 0x81, 0x10, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0x0A, 0x61, 0x03, 0x22, 0x03
    .db 0x81, 0x10, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0x0A, 0x61, 0x03, 0x22, 0x03
    .db 0x81, 0x10, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0x0A, 0x61, 0x03, 0x22, 0x03
    .db 0x82,0xFE,0xc0,0x10,0xe4,0x11 ; A4
    .db 0x82,0xE2,0xc0,0x10,0xe4,0x11 ; B4
    .db 0x82,0xCA,0xc0,0x20,0xe4,0x11 ; C#5
    .db 0x82,0xE2,0xc0,0x10,0xe4,0x11 ; B4
    .db 0x81, 0xE5, 0x60, 0x03, 0x22, 0xFd
    .db 0x81, 0xDF, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0xE5, 0x60, 0x03, 0x22, 0xFd
    .db 0x81, 0xDF, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0xE5, 0x60, 0x03, 0x22, 0xFd
    .db 0x81, 0xDF, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0xE5, 0x60, 0x03, 0x22, 0xFd
    .db 0x81, 0xDF, 0x60, 0x03, 0x22, 0x03
    .db 0x82,0xCA,0xc0,0x10,0xe4,0x11 ; C#5
    .db 0x82,0xBE,0xc0,0x10,0xe4,0x11 ; D5
    .db 0x82,0xBE,0xc0,0x20,0xe4,0x11 ; D5
    .db 0x82,0xCA,0xc0,0x20,0xe4,0x11 ; C#5
    .db 0x82,0xE2,0xc0,0x20,0xe4,0x11 ; B4
    .db 0x82,0xFE,0xc0,0x20,0xe4,0x11 ; A4
    ;; - 2 -
    .db 0x82,0xCA,0xc0,0x30,0xe4,0x11 ; C#5
    .db 0x81, 0xcd, 0x60, 0x03, 0x22, 0xFd
    .db 0x81, 0xC7, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0xcd, 0x60, 0x03, 0x22, 0xFd
    .db 0x81, 0xC7, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0xcd, 0x60, 0x03, 0x22, 0xFd
    .db 0x81, 0xC7, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0xcd, 0x60, 0x03, 0x22, 0xFd
    .db 0x81, 0xC7, 0x70, 0x03, 0x22, 0x03
    .db 0x82,0xE2,0xc0,0x20,0xe4,0x11 ; B4
    .db 0x82,0xBE,0xc0,0x10,0xe4,0x11 ; D5
    .db 0x82,0xCA,0xc0,0x20,0xe4,0x11 ; C#5
    .db 0x82,0xE2,0xc0,0x20,0xe4,0x11 ; B4
    .db 0x82,0xCA,0xc0,0x30,0xe4,0x11 ; C#5
    .db 0x82,0xFE,0xc0,0x30,0xe4,0x11 ; A4
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x70, 0x03, 0x22, 0x03
    .db 0x82,0xFE,0xc0,0x20,0xe4,0x11 ; A4
    .db 0x82,0xFE,0xc0,0x10,0xe4,0x11 ; A4
    .db 0x82,0x0D,0xc1,0x20,0xe4,0x11 ; Ab4
    .db 0x82,0x2E,0xc1,0x20,0xe4,0x11 ; F#4
    .db 0x82,0x53,0xc1,0x30,0xe4,0x11 ; E4
    ;; - 4 - 
    .db 0x82,0xFE,0xc0,0x20,0xe4,0x11 ; A4
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x70, 0x03, 0x22, 0x03
    .db 0x80,0x00,0xf0,0x10
    .db 0x82,0x7d,0xc1,0x10,0xe4,0x11 ; D4
    .db 0x82,0x53,0xc1,0x10,0xe4,0x11 ; E4
    .db 0x82,0x7d,0xc1,0x10,0xe4,0x11 ; D4
    .db 0x82,0xFE,0xc0,0x10,0xe4,0x11 ; A4
    .db 0x82,0x0d,0xc1,0x10,0xe4,0x11 ; Ab4
    .db 0x82,0x53,0xc1,0x10,0xe4,0x11 ; E4
    .db 0x82,0xE2,0xc0,0x10,0xe4,0x11 ; B4
    ;; - 5 - 
    .db 0x82,0xFE,0xc0,0x20,0xe4,0x11 ; A4
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x70, 0x03, 0x22, 0x03
    .db 0x80,0x00,0xf0,0x10
    .db 0x82,0x7d,0xc1,0x10,0xe4,0x11 ; D4
    .db 0x82,0x53,0xc1,0x10,0xe4,0x11 ; E4
    .db 0x82,0x7d,0xc1,0x10,0xe4,0x11 ; D4
    .db 0x82,0xFE,0xc0,0x10,0xe4,0x11 ; A4
    .db 0x82,0x0d,0xc1,0x10,0xe4,0x11 ; Ab4
    .db 0x82,0x53,0xc1,0x10,0xe4,0x11 ; E4
    .db 0x82,0x7d,0xc1,0x10,0xe4,0x11 ; D4
    ;; - 4 - 
    .db 0x82,0xFE,0xc0,0x20,0xe4,0x11 ; A4
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x70, 0x03, 0x22, 0x03
    .db 0x80,0x00,0xf0,0x10
    .db 0x82,0x7d,0xc1,0x10,0xe4,0x11 ; D4
    .db 0x82,0x53,0xc1,0x10,0xe4,0x11 ; E4
    .db 0x82,0x7d,0xc1,0x10,0xe4,0x11 ; D4
    .db 0x82,0xFE,0xc0,0x10,0xe4,0x11 ; A4
    .db 0x82,0x0d,0xc1,0x10,0xe4,0x11 ; Ab4
    .db 0x82,0x53,0xc1,0x10,0xe4,0x11 ; E4
    .db 0x82,0xE2,0xc0,0x10,0xe4,0x11 ; B4
    ;; - 5 - 
    .db 0x82,0xFE,0xc0,0x20,0xe4,0x11 ; A4
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x60, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x61, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x70, 0x03, 0x22, 0x03
    .db 0x80,0x00,0xf0,0x10
    .db 0x82,0x7d,0xc1,0x10,0xe4,0x11 ; D4
    .db 0x82,0x53,0xc1,0x10,0xe4,0x11 ; E4
    .db 0x82,0x7d,0xc1,0x10,0xe4,0x11 ; D4
    .db 0x82,0xFE,0xc0,0x10,0xe4,0x11 ; A4
    .db 0x82,0x0d,0xc1,0x10,0xe4,0x11 ; Ab4
    .db 0x82,0x53,0xc1,0x10,0xe4,0x11 ; E4
    .db 0x82,0x7d,0xc1,0x10,0xe4,0x11 ; D4
    .db 0x98
    
    

    Version February 28, 2018 - 1 more hour of work on it. Tweaked a little the volume and added more to the melody.

    ; Daniel Bienvenu
    ; February 28, 2018
    ; Music Data
    
    music_HS_ch0_A:
    .db 0x00,0x00,0x74,0x02
    .db 0x02,0x23,0x0e,0x1b,0x31
    .db 0x00,0x00,0x74,0x02
    .db 0x02,0x63,0x0e,0x1b,0x31
    .db 0x02,0x35,0x10,0x1c,0x21
    .db 0x00,0x00,0x74,0x02
    .db 0x02,0x23,0x0e,0x1b,0x21
    .db 0x18
    
    music_HS_ch3_A:
    .db 0xc0,0x88,0xf0,0x80 ; A1
    .db 0xc0,0x98,0xf0,0x80 ; G1
    .db 0xc0,0x66,0xf0,0x80 ; D2
    .db 0xc0,0x5a,0xf0,0x80 ; E2
    ;;
    .db 0xc0,0x88,0xf0,0x80 ; A1
    .db 0xc0,0x98,0xf0,0x80 ; G1
    .db 0xc0,0x66,0xf0,0x80 ; D2
    .db 0xc0,0x5a,0xf0,0x80 ; E2
    ;;
    .db 0xc0,0x51,0xf0,0x80 ; F#2
    .db 0xc0,0x6c,0xf0,0x80 ; C#2
    .db 0xc0,0x66,0xf0,0x80 ; D2
    .db 0xc0,0x5a,0xf0,0x80 ; E2
    .db 0xd8
    
    music_HS_ch1_A:
    .db 0x41, 0x7F, 0x70, 0x02, 0x11, 0x7F ; A5
    .db 0x41, 0x7F, 0x70, 0x02, 0x11, 0x7F
    .db 0x41, 0x7F, 0x70, 0x02, 0x11, 0x7F
    .db 0x41, 0x7F, 0x70, 0x02, 0x11, 0x7F
    .db 0x41, 0x7F, 0x70, 0x02, 0x11, 0x7F
    .db 0x41, 0x7F, 0x80, 0x02, 0x11, 0x7F
    .db 0x41, 0x7F, 0xa0, 0x02, 0x11, 0x7F
    .db 0x41, 0x7F, 0xd0, 0x02, 0x11, 0x7F
    ;
    .db 0x41, 0x55, 0x70, 0x02, 0x11, 0x55 ; E6
    .db 0x41, 0x55, 0x70, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0x70, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0x70, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0x70, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0x80, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0xa0, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0xd0, 0x02, 0x11, 0x55 
    ;
    .db 0x41, 0x40, 0x70, 0x02, 0x11, 0x40 ; A6
    .db 0x41, 0x40, 0x70, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x70, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x70, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x70, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x80, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0xa0, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0xd0, 0x02, 0x11, 0x40 
    ;
    .db 0x41, 0x55, 0x70, 0x02, 0x11, 0x55 ; E6
    .db 0x41, 0x55, 0x70, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0x70, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0x70, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0x70, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0x80, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0xa0, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0xd0, 0x02, 0x11, 0x55 
    ;
    .db 0x41, 0x40, 0x70, 0x02, 0x11, 0x40 ; A6
    .db 0x41, 0x40, 0x70, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x70, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x70, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x70, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x80, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0xa0, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0xd0, 0x02, 0x11, 0x40 
    ;
    .db 0x41, 0x40, 0x70, 0x02, 0x11, 0x40 ; A6
    .db 0x41, 0x40, 0x70, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x70, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x70, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x70, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x80, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0xa0, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0xd0, 0x02, 0x11, 0x40 
    ;
    .db 0x41, 0x55, 0x70, 0x02, 0x11, 0x55 ; E6
    .db 0x41, 0x55, 0x70, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0x70, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0x70, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0x70, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0x80, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0xa0, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0xd0, 0x02, 0x11, 0x55 
    ;
    .db 0x41, 0x40, 0x70, 0x02, 0x11, 0x40 ; A6
    .db 0x41, 0x40, 0x70, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x70, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x70, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x70, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x80, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0xa0, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0xd0, 0x02, 0x11, 0x40 
    .db 0x58
    
    music_HS_ch2_A:
    .db 0x82,0xCA,0xc0,0x30,0xe5,0x11 ; C#5
    .db 0x81, 0xcd, 0x40, 0x03, 0x22, 0xFd
    .db 0x81, 0xC7, 0x40, 0x03, 0x22, 0x03
    .db 0x81, 0xcd, 0x40, 0x03, 0x22, 0xFd
    .db 0x81, 0xC7, 0x40, 0x03, 0x22, 0x03
    .db 0x81, 0xcd, 0x40, 0x03, 0x22, 0xFd
    .db 0x81, 0xC7, 0x40, 0x03, 0x22, 0x03
    .db 0x81, 0xcd, 0x40, 0x03, 0x22, 0xFd
    .db 0x81, 0xC7, 0x70, 0x03, 0x22, 0x03
    ;
    .db 0x82,0xE2,0xc0,0x20,0xe5,0x11 ; B4
    .db 0x82,0xBE,0xc0,0x10,0xe5,0x11 ; D5
    .db 0x82,0xCA,0xc0,0x20,0xe5,0x11 ; C#5
    .db 0x82,0xE2,0xc0,0x20,0xe5,0x11 ; B4
    .db 0x82,0xCA,0xc0,0x30,0xe5,0x11 ; C#5
    .db 0x82,0xFE,0xc0,0x30,0xe5,0x11 ; A4
    .db 0x81, 0x01, 0x41, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x40, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x41, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x40, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x41, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x40, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x41, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x70, 0x03, 0x22, 0x03
    ;
    .db 0x82,0xFE,0xc0,0x20,0xe5,0x11 ; A4
    .db 0x82,0xFE,0xc0,0x10,0xe5,0x11 ; A4
    .db 0x82,0x0D,0xc1,0x20,0xe5,0x11 ; Ab4
    .db 0x82,0x2E,0xc1,0x30,0xe5,0x11 ; F#4
    .db 0x82,0x0D,0xc1,0x10,0xe5,0x11 ; Ab4
    .db 0x82,0xFE,0xc0,0x10,0xe5,0x11 ; A4
    ;;
    .db 0x82,0xCA,0xc0,0x30,0xe5,0x11 ; C#5
    .db 0x81, 0xcd, 0x40, 0x03, 0x22, 0xFd
    .db 0x81, 0xC7, 0x40, 0x03, 0x22, 0x03
    .db 0x81, 0xcd, 0x40, 0x03, 0x22, 0xFd
    .db 0x81, 0xC7, 0x40, 0x03, 0x22, 0x03
    .db 0x81, 0xcd, 0x40, 0x03, 0x22, 0xFd
    .db 0x81, 0xC7, 0x40, 0x03, 0x22, 0x03
    .db 0x81, 0xcd, 0x40, 0x03, 0x22, 0xFd
    .db 0x81, 0xC7, 0x70, 0x03, 0x22, 0x03
    ;
    .db 0x82,0xE2,0xc0,0x20,0xe5,0x11 ; B4
    .db 0x82,0xBE,0xc0,0x10,0xe5,0x11 ; D5
    .db 0x82,0xCA,0xc0,0x20,0xe5,0x11 ; C#5
    .db 0x82,0xE2,0xc0,0x20,0xe5,0x11 ; B4
    .db 0x82,0xCA,0xc0,0x30,0xe5,0x11 ; C#5
    .db 0x82,0xFE,0xc0,0x30,0xe5,0x11 ; A4
    .db 0x81, 0x01, 0x41, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x40, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x41, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x40, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x41, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x40, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x41, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x70, 0x03, 0x22, 0x03
    ;
    .db 0x82,0xFE,0xc0,0x20,0xe5,0x11 ; A4
    .db 0x82,0xFE,0xc0,0x10,0xe5,0x11 ; A4
    .db 0x82,0x0D,0xc1,0x20,0xe5,0x11 ; Ab4
    .db 0x82,0x2E,0xc1,0x20,0xe5,0x11 ; F#4
    .db 0x82,0x53,0xc1,0x30,0xe5,0x11 ; E4
    ;;
    .db 0x82,0x53,0xc1,0x30,0xe5,0x11 ; E4
    .db 0x81, 0x56, 0x41, 0x03, 0x22, 0xFd
    .db 0x81, 0x50, 0x41, 0x03, 0x22, 0x03
    .db 0x81, 0x56, 0x41, 0x03, 0x22, 0xFd
    .db 0x81, 0x50, 0x41, 0x03, 0x22, 0x03
    .db 0x81, 0x56, 0x41, 0x03, 0x22, 0xFd
    .db 0x81, 0x50, 0x41, 0x03, 0x22, 0x03
    .db 0x81, 0x56, 0x41, 0x03, 0x22, 0xFd
    .db 0x81, 0x50, 0x41, 0x03, 0x22, 0x03
    ;
    .db 0x82,0x2e,0xc1,0x10,0xe5,0x11 ; F#4
    .db 0x82,0xFE,0xc0,0x10,0xe5,0x11 ; A4
    .db 0x82,0xFE,0xc0,0x20,0xe5,0x11 ; A4
    ;
    .db 0x82,0x0D,0xc1,0x10,0xe5,0x11 ; Ab4
    .db 0x81, 0x10, 0x41, 0x03, 0x22, 0xFd
    .db 0x81, 0x0A, 0x41, 0x03, 0x22, 0x03
    .db 0x81, 0x10, 0x41, 0x03, 0x22, 0xFd
    .db 0x81, 0x0A, 0x41, 0x03, 0x22, 0x03
    .db 0x81, 0x10, 0x41, 0x03, 0x22, 0xFd
    .db 0x81, 0x0A, 0x41, 0x03, 0x22, 0x03
    .db 0x81, 0x10, 0x41, 0x03, 0x22, 0xFd
    .db 0x81, 0x0A, 0x41, 0x03, 0x22, 0x03
    ;
    .db 0x82,0xFE,0xc0,0x10,0xe5,0x11 ; A4
    .db 0x82,0xE2,0xc0,0x10,0xe5,0x11 ; B4
    .db 0x82,0xCA,0xc0,0x20,0xe5,0x11 ; C#5
    ;
    .db 0x82,0xE2,0xc0,0x10,0xe5,0x11 ; B4
    .db 0x81, 0xE5, 0x40, 0x03, 0x22, 0xFd
    .db 0x81, 0xDF, 0x40, 0x03, 0x22, 0x03
    .db 0x81, 0xE5, 0x40, 0x03, 0x22, 0xFd
    .db 0x81, 0xDF, 0x40, 0x03, 0x22, 0x03
    .db 0x81, 0xE5, 0x40, 0x03, 0x22, 0xFd
    .db 0x81, 0xDF, 0x40, 0x03, 0x22, 0x03
    .db 0x81, 0xE5, 0x40, 0x03, 0x22, 0xFd
    .db 0x81, 0xDF, 0x40, 0x03, 0x22, 0x03
    ;
    .db 0x82,0xCA,0xc0,0x10,0xe5,0x11 ; C#5
    .db 0x82,0xBE,0xc0,0x10,0xe5,0x11 ; D5
    .db 0x82,0xBE,0xc0,0x20,0xe5,0x11 ; D5
    .db 0x82,0xCA,0xc0,0x20,0xe5,0x11 ; C#5
    .db 0x82,0xE2,0xc0,0x20,0xe5,0x11 ; B4
    .db 0x82,0xFE,0xc0,0x20,0xe5,0x11 ; A4
    .db 0x98
    

    Version February 27, 2018 - First draft, 3 hours of work. Base line and 1st mesure of the melody.

    ; Daniel Bienvenu
    ; February 27, 2018
    ; Music Data
    
    music_HS_ch0_A:
    .db 0x00,0x00,0x74,0x02
    .db 0x02,0x23,0x0e,0x1b,0x31
    .db 0x00,0x00,0x74,0x02
    .db 0x02,0x63,0x0e,0x1b,0x31
    .db 0x02,0x25,0x10,0x1c,0x12
    .db 0x00,0x00,0x74,0x02
    .db 0x02,0x23,0x0e,0x1b,0x21
    .db 0x18
    
    music_HS_ch3_A:
    .db 0xc0,0x88,0xf0,0x80 ; A1
    .db 0xc0,0x98,0xf0,0x80 ; G1
    .db 0xc0,0x66,0xf0,0x80 ; D2
    .db 0xc0,0x5a,0xf0,0x80 ; E2
    .db 0xd8
    
    music_HS_ch1_A:
    .db 0x41, 0x7F, 0x50, 0x02, 0x11, 0x7F ; A5
    .db 0x41, 0x7F, 0x50, 0x02, 0x11, 0x7F
    .db 0x41, 0x7F, 0x50, 0x02, 0x11, 0x7F
    .db 0x41, 0x7F, 0x60, 0x02, 0x11, 0x7F
    .db 0x41, 0x7F, 0x70, 0x02, 0x11, 0x7F
    .db 0x41, 0x7F, 0x80, 0x02, 0x11, 0x7F
    .db 0x41, 0x7F, 0xa0, 0x02, 0x11, 0x7F
    .db 0x41, 0x7F, 0xd0, 0x02, 0x11, 0x7F
    ;
    .db 0x41, 0x55, 0x50, 0x02, 0x11, 0x55 ; E6
    .db 0x41, 0x55, 0x50, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0x50, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0x60, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0x70, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0x80, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0xa0, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0xd0, 0x02, 0x11, 0x55 
    ;
    .db 0x41, 0x40, 0x50, 0x02, 0x11, 0x40 ; A6
    .db 0x41, 0x40, 0x50, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x50, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x60, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x70, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x80, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0xa0, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0xd0, 0x02, 0x11, 0x40 
    ;
    .db 0x41, 0x55, 0x50, 0x02, 0x11, 0x55 ; E6
    .db 0x41, 0x55, 0x50, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0x50, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0x60, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0x70, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0x80, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0xa0, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0xd0, 0x02, 0x11, 0x55 
    ;
    .db 0x41, 0x40, 0x50, 0x02, 0x11, 0x40 ; A6
    .db 0x41, 0x40, 0x50, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x50, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x60, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x70, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x80, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0xa0, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0xd0, 0x02, 0x11, 0x40 
    ;
    .db 0x41, 0x40, 0x50, 0x02, 0x11, 0x40 ; A6
    .db 0x41, 0x40, 0x50, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x50, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x60, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x70, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x80, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0xa0, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0xd0, 0x02, 0x11, 0x40 
    ;
    .db 0x41, 0x55, 0x50, 0x02, 0x11, 0x55 ; E6
    .db 0x41, 0x55, 0x50, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0x50, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0x60, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0x70, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0x80, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0xa0, 0x02, 0x11, 0x55 
    .db 0x41, 0x55, 0xd0, 0x02, 0x11, 0x55 
    ;
    .db 0x41, 0x40, 0x50, 0x02, 0x11, 0x40 ; A6
    .db 0x41, 0x40, 0x50, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x50, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x60, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x70, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0x80, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0xa0, 0x02, 0x11, 0x40 
    .db 0x41, 0x40, 0xd0, 0x02, 0x11, 0x40 
    .db 0x58
    
    music_HS_ch2_A:
    .db 0x82,0xCA,0xc0,0x30,0xe5,0x11 ; C#5
    .db 0x81, 0xcd, 0x40, 0x03, 0x22, 0xFd
    .db 0x81, 0xC7, 0x40, 0x03, 0x22, 0x03
    .db 0x81, 0xcd, 0x40, 0x03, 0x22, 0xFd
    .db 0x81, 0xC7, 0x40, 0x03, 0x22, 0x03
    .db 0x81, 0xcd, 0x40, 0x03, 0x22, 0xFd
    .db 0x81, 0xC7, 0x40, 0x03, 0x22, 0x03
    .db 0x81, 0xcd, 0x40, 0x03, 0x22, 0xFd
    .db 0x81, 0xC7, 0x70, 0x03, 0x22, 0x03
    ;
    .db 0x82,0xE2,0xc0,0x20,0xe5,0x11 ; B4
    .db 0x82,0xBE,0xc0,0x10,0xe5,0x11 ; D5
    .db 0x82,0xCA,0xc0,0x20,0xe5,0x11 ; C#5
    .db 0x82,0xE2,0xc0,0x20,0xe5,0x11 ; B4
    .db 0x82,0xCA,0xc0,0x30,0xe5,0x11 ; C#5
    .db 0x82,0xFE,0xc0,0x30,0xe5,0x11 ; A4
    .db 0x81, 0x01, 0x41, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x40, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x41, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x40, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x41, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x40, 0x03, 0x22, 0x03
    .db 0x81, 0x01, 0x41, 0x03, 0x22, 0xFd
    .db 0x81, 0xFB, 0x70, 0x03, 0x22, 0x03
    ;
    .db 0x82,0xFE,0xc0,0x20,0xe5,0x11 ; A4
    .db 0x82,0xFE,0xc0,0x10,0xe5,0x11 ; A4
    .db 0x82,0x0D,0xc1,0x20,0xe5,0x11 ; Ab4
    .db 0x82,0x2E,0xc1,0x30,0xe5,0x11 ; F#4
    .db 0x82,0x0D,0xc1,0x10,0xe5,0x11 ; Ab4
    .db 0x82,0xFE,0xc0,0x10,0xe5,0x11 ; A4
    .db 0x98
    

    I hope someone will give it a try. Maybe someone new to Coleco programming will enjoy figure it out.

    Do not spoil the mystery! I will reveal when I am done composing the music.

    Leave a comment!

    • Like 3

  2. It's been more than a year now that Scubbly is down.

    After so much time not fixing this issue of "Where I'm gonna sell my ROM files?", I've decided to release the binary file freely of my original game:

     

    Title: ColecoVision Flora and the Ghost Mirror

    Author: Daniel Bienvenu

    Release Date: December 2012, but cartridges were released in 2013

    Info: Inspired by and dedicated to Gabriela Brindusa

     

    As explained in a previous post, this game is filled with personal Easter eggs since it'S all based on what my girlfriend of the time liked: Celtic music, Meditation, Fairies, Jewelry, Horoscope (it's not random placed stars, they are constellations), Living plants, Healing powers, and so on. No wonder this game looks so different than my other games and some "game logic" have sense only if you know her.

     

    Download: https://drive.google.com/file/d/1fHM-Exl3tJMwGz5m8P4SMmC6JdT0lJGH/view?usp=sharing

     

    *BONUS QUESTION*

     

    The game ends with a happy ending, everyone is dancing, with a message about being the first Flora game.

     

    What's your opinion about what should be the sequel to this game?

    • Like 11

  3. i did not manage to run the rom on BlueMSX emulator. :(

     

    Did somebody try the Rom?

    These ROM files are working just fine on real hardware, aka standard ColecoVision game system, and they work on BlueMSX (vanilla ColecoVision settings) on my computer just fine as well.

     

    Btw , in my games i use DAN0 format in general , from my experience it is alway lot of more efficient than Pletter. But it is surely specific how i build the image in my games.

     

    I've not tried the new format yet. But seeing rom size difference , i'm pretty sure that Dan0 will be still more efficient in case of my games.

    Depending on your data and your needs, one data compression method should work better than another. And it's not necessary to use "the best" option when you can use a method you like and still do the job.

     

    Side note: DAN0 is not a LZ77 variant, it's a boosted RLE with fixed Huffman encoding and a little extra bytes saving if it reuse common bytes between data tables. Pletter is a LZ77 variant without any optimization like a Huffman encoding. DAN1, DAN2 and DAN3 are LZ77 variants more focussed on saving bits than Pletter and with a fixed-Huffman encoding optimization, and RLE optimization for DAN1 and DAN3.

     

    They worked in CoolCV for me.

    Glad to hear CoolCV can run them just fine.


  4. DOWNLOAD

     

    ColecoVision SlideShow Sample in 5 formats: SLIDESHOW SAMPLE.ZIP

     

     

    README.TXT

     

    Hello everyone,

     

    My name is NewColeco and I'm gonna tell you what I've been worked on during the last 3 years.

    Not everyone is aware that graphics are very difficult to add in our beloved homebrew games, especially within the standard 32K cartridge size. To make things worse, some graphics cannot be compressed at all to keep the action fluid and fast.

     

    In order to add great looking bitmap screens and tilesets into our projects, we use data compression.

     

    I've been working very hard on lossless data compression for our graphics data. My new compressed formats are named DAN1, DAN2, and DAN3; they work especially well for big graphics like charset and bitmap screens. They are, technically speaking, LZ77 variants and developed based on our graphics need.

     

    The ZIP file in the download section contains 5 files of the exact same slideshow sample, the only difference is the data compression format used in each one of them.

     

    Information about the Slideshow ROM files:

    • in Pletter - ROM size 27730 bytes.
    • in ZX7 - ROM size 27665 bytes.
    • in DAN1 - ROM size 27094 bytes.
    • in DAN1 without RLE support - ROM size 27078 bytes.
    • in DAN3 - ROM size 26999 bytes.

    For this slideshow sample, saving about 700 bytes is a big deal; should be enough to add an extra picture without going over 32K.

     

    Now you know what I've been working on lately.

     

    Question?

     

    Thanks for reading!

    • Like 2

  5. WARNING

     

    MAJOR UPDATE JANUARY 26, 2018

     

    FIXED BUG IN RLE COMPRESSION - PLEASE UPDATE TO BUILD # 20180126

     

    An error of logic in the DAN3 compression tool causing no possible RLE compression resulting to artificially inflated compressed files, and also the decompression " -d " mode of the same tool refused to decode any RLE codes from the compressed files. Both problems are now fixed and should be quite bug-free.

     

    Sorry for any bad compression ratio you may have experienced with a previous bugged version of this tool.

     

    Have a nice day!


  6. UPDATE

     

    January 23, 2018

    Fixed DAN3 (de)compression tool final(?) version with source code.

    • Fixed the fast compression method "-f" to get better compression ratio.
    • Modified the help text "-h" to show DAN3 instead of DAN37.

    January 18, 2018

    Added DAN3 (de)compression tool final(?) version with source code.

    • Limit the maximum of bits used for large offset values. " -m 13 " (13 bits max which covers 8K like the ASM decompression code posted).
    • Remove support of RLE with " -r ".
    • Decompress a DAN3 file with " -d ".
    • Faster compression algorithm (experimental), less optimization, with " -f ".
    • The help information " -h " mentions this tool as "DAN37" which was its project branch name on my computer.

    REMINDER

    This is not a miracle solution. DAN3 performs better with elaborated graphics rather than simple and empty screens (use DAN2 in that case).

    I hope you enjoy the new version of this DAN3 tool. Recompile and adapt it based on your needs.

    I would love to hear news from people who actually used my compression tools since DAN1.


  7. Very happy to see the evolution of TeamPixelboy, the budget games and now this big release of ROM files and news of some more incoming games.

     

    I'll use my AtariMax Ultimate SD for ColecoVision with these games... any chance to get the manual txt files to put in the multicart as well? Playing with emulators is nice but I want to show this to my friends next time I see them with the real hardware and have a retro gaming party.


  8. Intellivision Graphics Compression with DZ-Jay

    After some talk with DZ-Jay, we figured out that bytes modifications "on the fly" were needed, and so it was better to do either a basic RLE data compression or, considering the particular graphics data structure and size, something like a fixed dictionary of 16-bits words in it that can be shared between multiple screens and referenced by simply 8-bits values (a byte).

     

    Pletter versus ZX7 (more...)

    I've done some more experiments with Pletter lately and I've noticed a lack of efficiency. The offset value is encoded in such a way that Pletter needs an extra bit for relative offsets larger than 127; ZX7 avoids this need. However, ZX7 lacks an adjustable size for big offset values which favors Pletter over ZX7 when the number of bits needed fixed in ZX7 is not already the best possible option. Also, I've tried to code a more aggressive Pletter data compression tool and the results only save like a bit which is insignificant (really, a bit isn't even enough to save a byte in most cases).


  9. By reusing what works from DAN1 and DAN2, I've missed an optimization with the DAN3 to VRAM routine. At the same time, why fix what is not broken. So, use the previous version that works just fine just to be sure.

     

    The optimization I've missed is the maximum sequence length allowed in DAN3, which is only 254 bytes, an 8-bits value, so there is no need for a full 16-bits pair register BC in the loop. So, we can remove the "pop bc" and "push bc" and get a smaller routine. It should not really improve the decompression speed considering how tricky dealing with Video RAM timing can be.

     

    According to the Z80 documentation, "DJNZ" is 13 cycles long when the register B is not equal to zero, and 3 NOPs (the typical delay) is 12 cycles, so this code here doesn't need an extra delay like "NOP" before the "DJNZ" opcode.

     

    *TESTED* IT WORKS ON A REAL COLECOVISION GAME SYSTEM JUST FINE

     

    *Updated: December 24, 2017 - fixed a few lines in order to use only B and not BC for match length value. Routine even smaller and faster now.

    ; dan3.s
    ; DAN3 Lossless Data Compression Format by Daniel Bienvenu
    
    ; DAN3 Decompression to VRAM 
    ; 24 December, 2017
    ; Size: 195 (?) bytes
    
    ; HL = SOURCE
    ; DE = DESTINATION
    
    	; global from this code
    	;================
    	.globl  _dan3
    	; void dan3 (void *data, unsigned vram_offset);
    	.globl  dan3 ;  HL = ADDR. TO COMPRESSED DATA , DE = DESTINATION IN VRAM
    
    ;	Wrapper to get values from parameters (register pairs)
    _dan3:
    	pop	bc
    	pop	de
    	pop	hl
    	push	hl
    	push	de
    	push	bc
    
    ; 	HL = SOURCE
    ;	DE = DESTINATION
    dan3:
    	; Set Write in VRAM at DE
    	ld	c,#0xbf
    	out	(c),e
    	set	6,d
    	out	(c),d
    	res	6,d
    	; Set A for reading a bit routine
    	ld	a,#0x80
    	; Important to save the IX register
    	push	ix
    	ld	ix, #get_bit_e+3
    dan3_offsetsize_loop:
    	dec	ix
    	dec	ix
    	dec	ix
    	call    get_bit            ; check next bit
    	jr	c,	dan3_offsetsize_loop
    
    ; Copy literal byte
    dan3_copy_byte:
    	ld	b,#0x01
    
    dan3_literal2main:
    	ld	c,#0xbe
    dan3_literals_loop:
    	outi
    	inc	de
    	jr	nz,	dan3_literals_loop
    
    ; Main loop
    dan3_main_loop:
    	call    get_bit            ; check next bit
    	jr	c,dan3_copy_byte
    
    ; Decode Exp-Golomb + Special Marker
    	push	de
    	ld	de, #0x0001
    	ld	b,e
    dan3_expgolomb_0:
    	inc	b
    	call    get_bit            ; check next bit
    	jr      c, dan3_expgolomb_value
    	bit	3,b
    	jr	z, dan3_expgolomb_0
    
    ; Special Marker
    	pop	de
    	call    get_bit            ; check next bit
    	jr	c, dan3_literals
    	pop	ix
    	ret	; EXIT
    dan3_literals:
    	ld      b, (hl)                 ; load counter value (8 bits)
    	inc	hl
    	inc	b
    	jr	dan3_literal2main
    
    dan3_expgolomb_value:
    	dec	b
    dan3_expgolomb_value_loop:
    	call	get_bit_e			; check next bit -> DE
    	djnz	dan3_expgolomb_value_loop
    	dec	e
        ld b, e
        dec    e
    	jr	z, dan3_offset1
    	
    	; D = 0, E = ??, B = LENGTH
    	
    ; Decode Offset value
    	ld	e,d				; e = 0
    	call	get_bit			; check next bit
    	jr	nc, dan3_offset3
    	call	get_bit
    	jr	nc, dan3_offset2
    	call	get_highbits_e		; read some bits -> E
    	inc	e
    	ld	d,e				; D = E + 1
    dan3_offset3:
    	ld      e, (hl)			; load offset offset value (8 bits)
    	inc     hl
    	ex	af, af'
    	ld	a,e
    	add	a,#0x20			; Skip the short offsets covered by 5 bits ones
    	ld	e,a
    	jr	nc, dan3_offset_nocarry
    	inc	d
    dan3_offset_nocarry:	
    	ex	af, af'
    	jr	dan3_copy_from_offset
    dan3_offset2:
    	call	get_5bits_e			; read 5 bits -> E
    	jr	dan3_copy_from_offset
    dan3_offset1:
    	call    get_bit            ; check next bit
    	jr	nc, dan3_copy_from_offset
    	call	get_bit_e
    	inc	e
    		
    ; Copy previously seen bytes
    dan3_copy_from_offset:
    	ex      (sp), hl                ; store source, restore destination
    	push    hl                      ; store destination
    	scf
    	sbc     hl, de                  ; HL = source = destination - offset - 1
    	pop     de                      ; DE = destination
    	; BC = count
    	; COPY BYTES
    	ex	af,af'
    	set	6,d
    	ld	c,#0xbf
    dan3_copybytes_loop:
    	out	(c),l
    	nop
    	out	(c),h
    	inc	hl
    	nop
    	nop
    	in	a,(#0xbe)
    	nop
    	nop
    	nop
    	out	(c),e
    	nop
    	out	(c),d
    	inc	de
    	nop
    	nop
    	out	(#0xbe),a
    	djnz	dan3_copybytes_loop
    	res	6,d
    	ex	af,af'
    	pop	hl		; restore source address (compressed data)
    	jp	dan3_main_loop
    
    get_highbits_e:
    	jp	(ix)
    
    ;	COVER 16K
    ;	call	get_bit_e	; get next bit -> E
    ;	COVER 8K
    get_5bits_e:
    	call	get_bit_e	; get next bit -> E
    	call	get_bit_e	; get next bit -> E
    	call	get_bit_e	; get next bit -> E
    	call	get_bit_e	; get next bit -> E
    get_bit_e:
    	call	get_bit	; get next bit
    	rl      e		; push bit into E
    	ret
    
    ; get a bit
    get_bit:
    	add	a,a
      	ret	nz
    	ld	a,(hl)
    	inc	hl
    	rla
    	ret
    
    • Like 1

  10. Sorry about all the confusion, I am not that knowledgeable about compression so I was kind of making it up, and I see I managed to take you down my confused path. icon_smile.gif

     

    I thought more like doing something fancy at the same time, so that as both bytes were being unpacked, they could be re-shited/joined on the fly. I don't even know if this is practical.

     

    However, it may be much more clever than is needed. At this point, even RLE would be an improvement since on the Intellivision, most home-brews just store the raw data.

     

    -dZ.

    Yes, you should try to use RLE compression first. There are a lot of RLE listings and once you get one that works for you, you can be creative and modify it.

     

    What can be interesting for your needs, since you were thinking of doing a fancy "on-the-fly", is to implement something like this, which is not a decompression but more a decoder of compressed data used (called) in a routine with the bit-shifting applied "on-the-fly":

     

    Initialize the necessary addresses and variables

    START LOOP

    *Get next "other"

    If byte "other" is an invalid value, END LOOP

    *Get next "card"

    Bit-shifting accordingly

    Load into memory

    END LOOP

    *Get next: Provide the next byte according to the compression method used. Should be an external routine to avoid repeating codes.

     

    Once you make this pseudo-code works with RAW data as a default compression method, you can improve with other compression methods. I don't think LZ77 method can work in this way, but some RLE and Huffman methods surely can.

     

    Enjoy!


  11. I'm not sure I understand. Are you asking if we can decompress the entire stream first into RAM and then do the bitshifting? I guess this is certainly possible, but I would prefer not having to commit that memory first. That's 240 words of RAM, which is considerable on the Intellivision.

     

    I may have misunderstood your question, though.

     

    -dZ.

    Surely I'm not understanding all that technical information.

     

    I was thinking that both the "card" and "other" data parts could repeat at different rates, so they could compress at varying ratios.

    That is a correct assumption.

     

    I then thought that as an initial step, the encoder could split these two parts out of the word (shifting the bits around to align them) and compress them each as an individual 8-bit byte. The decoder could then re-build the word as necessary after decompressing each part.

    And so I asked my question about bit-shifting after decompression because it seems to be what you were already implying here but I wasn't sure.

     

    So, let me try to explain what I think you were saying and you tell me if I'm wrong.

     

    Let's consider the data already split into 2 sets ( cards and others ) as you propose and use LZ compression on each set of bytes.

     

    Then the result is used in a project with the LZ decompression routine and an extra routine to reverse the bit-shifting effect after decompression is done.

     

    Is that what you are talking about or it's more gymnastic with things getting done at the same time?

     

    Since I've never coded for the Intellivision, I'm quite in the dark about what's possible and what isn't.

     

    We should probably have a talk in another thread. Let me free up a bit my mailbox here.


  12. Here's my first question.

     

    The Intellivision is not really an 8-bit system. It has a 16-bit CPU with 16-bit registers which can address 8-bit or 16-bit RAM and 10-bit or 16-bit ROM (this is due to historical reasons). Home-brews typically use 16-bit ROM. Screen graphics are tile-based, with a Background Table (BACKTAB) in 16-bit RAM that stores a word that defines each of 240 tiles (20 columns x 12 rows) on the screen.

     

    Each 16-bit word (actually, they only use 13-bits) in the BACKTAB contains the index of a graphics "card" to use (either from the built-in Graphics ROM, or the user-defined Graphics RAM), and various meta-data bits describing color and other properties.

     

    I was thinking that both the "card" and "other" data parts could repeat at different rates, so they could compress at varying ratios.

     

    I then thought that as an initial step, the encoder could split these two parts out of the word (shifting the bits around to align them) and compress them each as an individual 8-bit byte. The decoder could then re-build the word as necessary after decompressing each part.

     

    My question is, do you think this could be a good idea? For full context, below is the 16-bit word definition of BACKTAB cells for each of the two screen modes of the Intellivision:

    Color Stack Mode:
                                   Color/Other Data
               ___________________________|___________________________
       _______/______                                          _______\______
      /              \                                        /              \
        13   12    11   10    9    8    7    6    5    4    3    2    1    0   
      +----+-----+----+----+----+----+----+----+----+----+----+----+----+----+ 
      |Adv.|FG   |GRAM|           GRAM/GROM Card #            |   FG Color   | 
      |col |Bit3/|GROM|    (0-255 for GROM, 0-63 for GRAM)    |   Bits 0-2   | 
      |stck|     |    |                                       |              | 
      +----+-----+----+----+----+----+----+----+----+----+----+----+----+----+ 
                      \_______________________________________/
                                      Card Data
    
    
    
    
    Foreground/Background Mode:
                                   Color/Other Data
                    _______________________|_________________________
       ____________/__________                                _______\______
      /                       \                              /              \
        13   12   11   10    9    8    7    6    5    4    3    2    1    0   
      +----+----+----+----+----+----+----+----+----+----+----+----+----+----+ 
      |BG  |BG  |GRAM|BG  |BG  |      GRAM/GROM Card #       |   FG Color   | 
      |Bit2|Bit3|GROM|Bit1|Bit0|          (0 - 63)           |   Bits 0-2   | 
      +----+----+----+----+----+----+----+----+----+----+----+----+----+----+ 
                               \_____________________________/
                                           Card Data
    
    
    My idea is to shift the lower 3 bits out of the word, and add them back at the top, and split the "card" and "other" into two bytes.

     

    Since it's very technical and new to me, I trust your judgement on the matter. My question is: is it possible to let the data decompress into the memory at once before doing the bitshifting correction to get back valid data? If it's possible, then we can focus on analyzing your data bitshifted through my tools and see its effect on the results.

     

    What I can say is that splitting bytes into distinct groups helps the compression ratio. Many modern data compression technics use a "reset" code to change the encoding at any point (usually split into blocks) when the data seems to have a different need, to switch from one kind to another. As you know, text data don't look like graphics, graphics don't look like codes, etc. and sometimes a file can integrate multiple kinds of data in it, such as our graphics are usually split into tables of colors, patterns and tiles.


  13. As for compression, I was actually considering looking into Exomizer. My main concern is with decompression, not compression. I am working on a game development framework for the Intellivision, and I am looking to devise an efficient packing/compression format for background graphical scenes. These background scenes are composed of 16-bit words (well, actually 13-bit words), and the ROM is 16-bits wide.

    Your concerns are surely shared with homebrewers like me dealing with limited ROM and RAM memory space. It's the main reason why I've spent so much time into this, getting results without sacrificing memory space.

     

    My expectation is that the compression will be done "out of band" by a compiler as a pre-processing step prior to assemblage. Therefore, the use of extra resources for optimization during compression is not really a concern.

    Same with ColecoVision homebrew games, the data compression time is not a concern because it's not the part gamers do experience while playing our games.

     

    Moreover, the particular use-case I am looking to address is the initialization of levels or the generation of title and other static screens, which are not in the critical path of game-play. Therefore, the speed of decompression is also not a major concern.

    Same situation with ColecoVision homebrew games, the majority of the graphics are usually not rendered "on-the-fly" risking the fluidity of the game or even glitches. Graphics are initialized first then shown on screen with minor changes, usually tiles and sprites movement manipulations, based on what it's supposed to be going on screen.

     

    What is a major concern is the complexity of implementation, and the size and efficiency of the decompression scheme. While it doesn't need to be fast, it needs to be compact enough to not take too much precious memory either in ROM or RAM. Simplicity of the algorithm is also desired, mostly because I am not really that good at programming or maths, and I don't want to burn my brain implementing it. icon_smile.gif

    I'm glad I've burn my brain for the greater good.

     

    I'll take a look at your DAN1, DAN2, DAN3 algorithms to get a bit more context on them. Thanks again!

     

    -dZ.

    Ask your questions. Since I'm actually working on data compression, it's a hot topic for me these days.

     

    And if you want a collaboration, just provide me lots of raw data samples corresponding to Intellivision homebrew projects (real or fictional) to be compressed. I can take a look, analyze them, and come up with a LZ77 variant algorithm based on my work that should suit your needs, getting your expertise on Intellivision into consideration. If it needs to be a special format instead of the ones I've already come up with, I can make the adapted compression tool in C and the decompression routine in Z80 asm easily. Make it your own solution afterward, make the 6502 ASM routine, tweak it, adapt it, integrate it in your toolbox. And if you're having trouble coding, I'm sure enthusiasts will be happy to help.

     

    Have a nice weekend!


  14. Great stuff! Thanks for the effort put into this. I am in the process of devising a bespoke compression scheme for Intellivision graphics screens and your results certainly guides which algorithms to consider.

     

    {...Lenna in computer imaging history...}

     

    -dZ.

     

    Thanks for your comment.

     

    I'm glad you find this useful.

     

    This represents months of collecting data and working on my own tools on a large amount of fullscreen graphics that I believe to be the most memory consuming in our homebrew projects. I give freely my work, my tools, my knowledge, even my games. There is a lot of technical information in various PDF and forums posts that I've written and this is just one of them.

    During that time, I've learned a lot about what works and what doesn't, making my own formats, experimenting with ideas and testing them. You can see the following text as more rambling about what I've learned.

     

    LZ77 variants are dominating in popularity; GZIP is used in our daily internet communications. It's a very efficient lossless data compression that doesn't need extra memory to maintain a dictionary or any kind of dynamic data structure to help optimize the compression ratio. The main reasons why some tools give better compression than others are the algorithm used and the way the values are encoded in the compressed data format. Exomizer uses tables in order to minimize the number of bits to be encoded for each offset value; if the relative offset values are more likely to be in the same range, regardless if it's small or large values, the number of bits to encode them are simply the index value in a table, cutting bytes and bytes of data in a smart way.

     

    Because Exomizer uses extra memory to compute its tables, I felt unease to use it in my ColecoVision projects simply because there is only 1K RAM in the game console. So I used a various bits sizes method to encode offsets, and the steps of 4 bits or so gave me the best compression ratio results, avoiding to encode into lots and lots of 0 bits offset values for nearby matching sequences. Of course, my DAN1, DAN2 and DAN3 formats can't reach the same optimization as Exomizer in that regard, but since Exomizer needs space for the data to compute the table needed to get this optimization, and the fact that Exomizer do not care about matches of a single byte which, I've seen a few times my formats getting better results than Exomizer but it's rare, it depends on the data. I see the compression of a match of a single byte somewhat like a local fixed Huffman encoding, and Huffman encoding is used in modern data archives with LZ data compression to improve the compression ratio, like ZIP.

     

    During my search online for lossless data compression used for 8bit homebrew projects, I was surprised to see new tools using arithmetic data compression since it's based on floating point numbers, not integers. So, I've added the info in the APPENDIX section but I had not much time to experiment and couldn't be used for our projects, requiring just too much RAM memory to compute the necessary tables.

     

    I've studied computer science at University, with computer imaging in mind. I saw Lenna picture over and over in various papers, her picture became a reference, a standard of many pictures used to test and compare various results of algorithms such as edges detection, textures, and also data compression including lossy compression using DCT and wavelets. I firmly believe that her picture, her face, became a meme among computer scientists before memes were invented.

     

    PS: I've added a tiny section about SPACE VS SPEED just before the APPENDIX. It doesn't show all formats, but it gives an idea of what to expect.


  15. What is the Weissman score? icon_smile.gif

     

    A fan of Silicon Valley TV series. :)

    I still have to watch it, and my library has it to be watched freely, but I never find the time to do it.

     

    You can compare GZIP and DAN3 as being basically the same since they are both variants of LZ77/LZSS. If the TV series mention a score to GZIP, which is the format we use in our Internet communications, then you have basically the Weissman score of DAN3... if only I was not the only one working on this and many tools were done supporting DAN3 format for various needs.

     

    Since the compression time is meaningless compared to the resulting size to be used in our homebrew projects (decompression routine + data), I will not even try to give a Weissman score.

     

    My compression tool here is written in a way to try to optimize the compression ratio regardless the time it will take to do so. Once compressed, we put together the compressed data and the decompression routine in our homebrew projects, which is the part that affects the users' experience, to save in loading time if on tapes and disks, and to offer more content (graphics, levels, text) inside the limited space of the memory chips of our cartridges.

     

    As for the decompression time, it's about the same as the other LZ77-LZSS variants, sometimes faster, sometimes slower, making really the compression ratio the most important part and that's what I've focussed on.

     

    DAN3 compression ratio tends to be closer to PuCrunch and Exomizer than Pletter, ZX7, ApLib, MegaLZ and others, but it uses a format close to the latter group and it doesn't need extra memory space like Exomizer to set up a table of values in memory. I believe that the difference is mostly because DAN3 tries to even compress a single byte rather than just sequences of 2 or more bytes. At the extreme, DAN3 will give worse compression ratio results like MegaLZ will do for meaningless data like a text file with the only the letter Q thousands of times. But since I'm not concerned about meaningless data and expect DAN3 to be used to compress even better-detailed content (hi-res graphics and elaborated levels for example), I'm quite confident that DAN3 fits for our needs in average, even if not always the best solution.


  16. DAN3 Lossless Data Compression
    Programmed by Daniel Bienvenu, 2017.

    What is DAN3?
    DAN3 is a LZ77/LZSS variant using unary encoding, k=1 Exp-Golomb and various sizes relative offsets without the need for extra memory prios to decompress data. Details below.

    Ask questions, post comments, share experiences.

    Download

    DAN3 build 20180126 (de)compression tool final? (BIN + SRC) : dan3_20180126.zip

    DAN3 build 20180123 (de)compression tool *BUG* (BIN + SRC) : dan3_20180123.zip

    DAN3 build 20180118 (de)compression tool *BUG* (BIN + SRC) : dan3_20180118.zip

    (previous version) DAN3 compression tool *BUG* only experimental beta (BIN) : dan3beta.zip

    ColecoVision Slide Show Sample (SRC, BIN) : SLIDESHOWDAN3.zip

    Technical Information
    DAN3 is a LZ77/LZSS variant developed based on DAN1 and DAN2, which explains their similarities.
    The format starts, like in DAN2, with defining what's the size in bits for the large offset values used to identify a match with the following table with a unary code (sequence of bits that looks like this):

    • 0 : 9 bits long <- 512 bytes (characters on a screen).
    • 10 : 10 bits long <- 1K (character set, some bitmap screens)
    • 110 : 11 bits long <- 2K (most bitmap screens)
    • 1110 : 12 bits long <- 4K (dithered bitmap screens)
    • 11110 : 13 bits long <- 8K (my decompression routine limit as-is)
    • 111110 : 14 bits long <- 16K
    • 1111110 : 15 bits long <- 32K
    • 11111110 : 16 bits long <- 64K (only good for 32bits/64bits PC files at this point)
    • ... (no limit in theory)

    Then, like in DAN2, the first byte of the uncompressed data is stored as is.

    Afterward, things are a little different, which makes DAN3 different than the others; offering a better compression on average but not always.

    For each match, the size and the relative offset values are encoded. While DAN1 and DAN2 are using Elias Gamma to encode the size value, DAN3 is using a k=1 Exp-Golomb encoding instead, which somehow helps to optimize a little bit both in term of space and time to decode. As for the relative offset values, DAN3 is using a completely different set of possible bit-size offsets; using {5, 8, max} instead of {1, 4, 8, max} bits to encode offsets. As for the special case of a nearby single byte being the same as the current byte to encode, DAN3 limits to the first 3 nearest bytes, instead of the 18 nearest bytes, which limits its potential to find a match and save space, but since the big impact is with sequences of more than 2 bytes, this change has no impact besides offering a better compression than Pletter and the others that do not support sequences of a single byte, acting if you like as a local fixed Huffman encoding.

    Here's a comparison side by side of Elias Gamma and k=1 Exp-Golomb to show you what I mean by size and speed possible gain in DAN3 since reading fewer bits means taking less time to decode.

    Elias Gamma (DAN1 and DAN2) versus k=1 Exp-Golomb (DAN3)

    • 1 : 10 = size 1
    • 010 : 11 = size 2
    • 011 : 0100 = size 3
    • 00100 : 0101 = size 4
    • 00101 : 0110 = size 5
    • 00110 : 0111 = size 6
    • 00111 : 001000 = size 7
    • 0001000 : 001001 = size 8
    • 0001001 : 001010 = size 9
    • 0001010 : 001011 = size 10
    • 0001011 : 001100 = size 11
    • 0001100 : 001101 = size 12
    • 0001101 : 001110 = size 13
    • 0001110 : 001111 = size 14
    • 0001111 : 00010000 = size 15
    • 000010000 : 00010001 = size 16
    • ...
    • 000000011111110 : 00000011111111 = size 254

    In DAN3, the support of Exp-Golomb stops at 00000011111111 = size 254. There are 3 reasons for that:

    • It allows an optimization of decoding only into a single byte instead of supporting to carry the bits into a 16 bits register pair. In Z80 opcodes, that simplifies the decoding routine, making it faster and smaller.
    • It makes the specials markers for END OF DATA and RLE about a byte smaller and faster to read.
    • Very large sequences of nothingness sadly will need more than one match of size 254 each but since we're talking about compressing our elaborated graphics which are mostly not that empty, the limitation should be barely an issue and satisfy plenty our needs.

    Special Markers

    • 00000001 + byte : RLE - Copy raw the next (byte value + 1) bytes
    • 00000000 : END OF DATA

    Relative Offset
    For a size of 1 byte, the relative offset is either 0 (the byte just before), 1, or 2 encoded respectively as 0, 10, and 11. For sizes of 2 or more, the offset is encoded as follow:

    • 10 + 5 bits = 5-bits Offset
    • 0 + byte = 8-bits Offset = byte + 32
    • 11 + N bits + byte = large Offset = (N bits and byte together as a 9 or more bits value) + 288

    Listing
    Decompression to VRAM Routine for Z80, using BE and BF ports (ColecoVision)
    Written in SDCC style, to be added to your compression toolbox.
    DAN3 decompression routine is only 14 bytes bigger than DAN1 decompression.


    ; dan3.s
    ; DAN3 Lossless Data Compression Format by Daniel Bienvenu
    
    ; DAN3 Decompression to VRAM 
    ; 6 December, 2017
    ; Size: 201 bytes
    
    ; HL = SOURCE
    ; DE = DESTINATION
    
    	; global from this code
    	;================
    	.globl  _dan3
    	; void dan3 (void *data, unsigned vram_offset);
    	.globl  dan3 ;  HL = ADDR. TO COMPRESSED DATA , DE = DESTINATION IN VRAM
    
    ;	Wrapper to get values from parameters (register pairs)
    _dan3:
    	pop	bc
    	pop	de
    	pop	hl
    	push	hl
    	push	de
    	push	bc
    
    ; 	HL = SOURCE
    ;	DE = DESTINATION
    dan3:
    	; Set Write in VRAM at DE
    	ld	c,#0xbf
    	out	(c),e
    	set	6,d
    	out	(c),d
    	res	6,d
    	; Set A for reading a bit routine
    	ld	a,#0x80
    	; Important to save the IX register
    	push	ix
    	ld	ix, #get_bit_e+3
    dan3_offsetsize_loop:
    	dec	ix
    	dec	ix
    	dec	ix
    	call    get_bit            ; check next bit
    	jr	c,	dan3_offsetsize_loop
    
    ; Copy literal byte
    dan3_copy_byte:
    	ld	b,#0x01
    
    dan3_literal2main:
    	ld	c,#0xbe
    dan3_literals_loop:
    	outi
    	inc	de
    	jr	nz,	dan3_literals_loop
    
    ; Main loop
    dan3_main_loop:
    	call    get_bit            ; check next bit
    	jr	c,dan3_copy_byte
    
    ; Decode Exp-Golomb + Special Marker
    	push	de
    	ld	de, #0x0001
    	ld	b,e
    dan3_expgolomb_0:
    	inc	b
    	call    get_bit            ; check next bit
    	jr      c, dan3_expgolomb_value
    	bit	3,b
    	jr	z, dan3_expgolomb_0
    
    ; Special Marker
    	pop	de
    	call    get_bit            ; check next bit
    	jr	c, dan3_literals
    	pop	ix
    	ret	; EXIT
    dan3_literals:
    	ld      b, (hl)                 ; load counter value (8 bits)
    	inc	hl
    	inc	b
    	jr	dan3_literal2main
    
    dan3_expgolomb_value:
    	dec	b
    dan3_expgolomb_value_loop:
    	call	get_bit_e			; check next bit -> DE
    	djnz	dan3_expgolomb_value_loop
    	dec	e
    	push	de
    	pop	bc
    	jr	z, dan3_offset1
    	
    	; D = 0, E = ??, BC = LENGTH
    	
    ; Decode Offset value
    	ld	e,d				; e = 0
    	call	get_bit			; check next bit
    	jr	nc, dan3_offset3
    	call	get_bit
    	jr	nc, dan3_offset2
    	call	get_highbits_e		; read some bits -> E
    	inc	e
    	ld	d,e				; D = E + 1
    dan3_offset3:
    	ld      e, (hl)			; load offset offset value (8 bits)
    	inc     hl
    	ex	af, af'
    	ld	a,e
    	add	a,#0x20			; Skip the short offsets covered by 5 bits ones
    	ld	e,a
    	jr	nc, dan3_offset_nocarry
    	inc	d
    dan3_offset_nocarry:	
    	ex	af, af'
    	jr	dan3_copy_from_offset
    dan3_offset2:
    	call	get_5bits_e			; read 5 bits -> E
    	jr	dan3_copy_from_offset
    dan3_offset1:
    	call    get_bit            ; check next bit
    	jr	nc, dan3_copy_from_offset
    	call	get_bit_e
    	inc	e
    		
    ; Copy previously seen bytes
    dan3_copy_from_offset:
    	ex      (sp), hl                ; store source, restore destination
    	push    hl                      ; store destination
    	scf
    	sbc     hl, de                  ; HL = source = destination - offset - 1
    	pop     de                      ; DE = destination
    	; BC = count
    	; COPY BYTES
    	ex	af,af'
    	set	6,d
    dan3_copybytes_loop:
    	push	bc
    	ld	c,#0xbf
    	out	(c),l
    	nop
    	out	(c),h
    	inc	hl
    	nop
    	nop
    	in	a,(#0xbe)
    	nop
    	nop
    	nop
    	out	(c),e
    	nop
    	out	(c),d
    	inc	de
    	nop
    	nop
    	out	(#0xbe),a
    	pop	bc
    	dec	bc
    	ld	a,b
    	or	c
    	jr	nz, dan3_copybytes_loop
    	res	6,d
    	ex	af,af'
    	pop	hl		; restore source address (compressed data)
    	jp	dan3_main_loop
    
    get_highbits_e:
    	jp	(ix)
    
    ;	COVER 16K
    ;	call	get_bit_e	; get next bit -> E
    ;	COVER 8K
    get_5bits_e:
    	call	get_bit_e	; get next bit -> E
    	call	get_bit_e	; get next bit -> E
    	call	get_bit_e	; get next bit -> E
    	call	get_bit_e	; get next bit -> E
    get_bit_e:
    	call	get_bit	; get next bit
    	rl      e		; push bit into E
    	ret
    
    ; get a bit
    get_bit:
    	add	a,a
      	ret	nz
    	ld	a,(hl)
    	inc	hl
    	rla
    	ret
    

    Comparison with DAN1

    DAN3 to VRAM decompression routine is only 14 bytes more than the one for DAN1 to VRAM.

    As for the compression ratio, it really depends on the data.

    For example, here's a table showing the size obtained with DAN1 and DAN3 for each picture in the SlideShow sample.

    • awb1p: DAN1 3677+2298, DAN3 3689+2328
    • f1spp: DAN1 2366+1679, DAN3 2349+1664
    • h6exp: DAN1 3412+2313, DAN3 3398+2297
    • mgfap: DAN1 3554+1935, DAN3 3551+1928
    • sotbp: DAN1+ 3394+1956, DAN3 3381+1921

    Updates
    * Dec 5, 2017 - Added Offset encoding details.
    * Dec 6, 2017 - Bug-Fixed and optimized ASM decompression routine. Added comparison with DAN1 for the SlideShow sample.

    * Jan 18, 2018 - Updated (de)compression tool

    * Jan 23, 2018 - Fixed fast compression method "-f" to be closer to perfect compression optimization

    * Jan 26, 2018 - Fixed RLE compression, now provides the expected results for hard to compress data

    • Like 3

  17. Updated this post with DAN4 data compression tests results.

     

    DAN4 is an effort to make a slightly faster DAN3 with some optimizations here and there.

     

    Backstory: At the ADAMCon banquet in 2017, Mister Luc M., aka pixelboy, asked if DAN3 is fast enough to decompress data "on the fly". Knowing that RLE is the only fast data compression algorithm that I know, with maybe DAN0 as a close second in my opinion, I couldn't reply since I had no idea of what amount and kind of data we were talking about. Mister Dale W. replied that essentialy this with a mention that DAN data compression should be fast enough for the project idea Luc was talking about. The banquet ended and this talk made me think with this eternal dilema of SIZE versus SPEED. I've searched for solutions and juggled with ideas of my own, and it's in October and November of 2017 that I've started to code a variant of DAN3 with ideas of allowing reading bytes instead of bits for large numbers, at the cost of a bigger decompression routine, to allow faster decompression time. Also, to fight the lost of compression ratio, the idea of using less bits for hard to compress data granted this newly made DAN4 to somehow get results good enough to even beat from time to time DAN3.

     

    I will post DAN3 tools first before the end of 2017 since it's in average the useful version for our projects in general. DAN4 is more specific for special needs in time.

    • Like 2

  18. I don't know how to say it (keep in mind english is not my cup of tea) or where to say it, but...

     

    I didn't want to react about the Coleco Expo 2017 because I wasn't there and I knew too well that I would have over-reacted and feel bad about it.

     

    So, I've looked at what others who actually went there said about the Coleco Expo. I've took notes, and here's my opinion:

     

    Coleco Expo? The idea itself is exciting; a gaming expo based on Coleco, I would love to see that and still want to. Let's be honest, the presence of a ColecoVision game and a flashback console do not make it a Coleco Expo. The number of vendors and visitors was not as expected for a gaming expo, especially with the amount of adverts and months of hype. A lesson from the past, hype and exageration can be very damaging (ex.: E.T. for Atari 2600). Also, alienating the homebrew community that kept the scene alive for the last 20 years, causing trouble and confusion (stop pretending to be related to Coleco Industries), and lying to do "damage control" and to attract attendees (exagerating the number of visitors and success), it's not what we call a job well done. I see some time and effort put in the project to make money... but how about the passion, the fans? When visitors and their friends mock the name and say it was a waste of time, it's not a good sign. Perhaps someone else would do it right, if another expo is made possible.

     

    I'm not Coleco Industries, I'm just a guy who happens to care enough about what that rainbow logo represent to say :

     

    YOU ARE FIRED !

    • Like 12
×
×
  • Create New...