Category: Blog

  • flying-circus

    PyPI release Python versions Build Status Documentation Status Downloads Code style: black

    flying-circus

    Flying Circus is a tool for describing AWS infrastructure as code (using Python). It uses the same data structures as the AWS Cloud Formation service, except described as Python objects instead of the usual YAML. The Python program generates a YAML template, which is passed across to Cloud Formation in the usual manner.

    It is a bit unusual to use a full programming language to describe infrastructure, instead of a static configuration file like many of us are used to (whether or not we also utilise a templating tool). We hope that the Flying Circus library can empower DevOps folk by unlocking some of the techniques that are available for software code, like named variables and techniques to structure code independently of the output format, libraries to allow code re-use with versioning, automated refactoring tools and so on.

    You can learn how to use Flying Circus yourself by reading the documentation

    Installation

    Install Flying Circus through the Python packaging system:

    pip install flying-circus

    Many people also use the Amazon Web Services command line tools to deploy their CloudFormation stacks. If you want this, a good way to install an up-to-date version is also with pip:

    # Optional
    pip install awscli

    Example

    Here is a simple example of how you can use Flying Circus to describe some EC2 instances and deploy them using the AWS CloudFormation service.

    First, create a python script (called my_ec2_stack.py in this case) to describe your infrastructure. Any valid Python can be used to create the Flying Circus objects, along with any valid CloudFormation properties and attributes.

    This example is intentionally simplistic – it just creates two EC2 instances with varying configuration, and outputs the internal IP for one. However, it does hint at some of the more complex and powerful usage patterns.

    import os
    
    from flyingcircus.core import Stack, Output
    from flyingcircus.intrinsic_function import GetAtt
    from flyingcircus.service.ec2 import *
    
    
    def create_ec2_instance(name, instance_type="t2.micro"):
        instance = Instance(Properties=InstanceProperties(
            ImageId="ami-942dd1f6",
            InstanceType=instance_type,
            Monitoring=False,
        ))
        instance.name = name
        return instance
    
    
    if __name__ == "__main__":
        stack = Stack()
    
        stack.Resources["WebServer"] = create_ec2_instance("webserver")
        stack.Resources["DatabaseServer"] = dbserver = create_ec2_instance("dbserver", "t2.medium")
        dbserver.DeletionPolicy = "Retain"
    
        stack.Outputs["DatabaseServerIp"] = Output(
            Description=f"Internal IP address for the database server",
            Value=GetAtt(dbserver, "PrivateIp"),
        )
    
        stack.tag(application="api-service", environment="test", owner=os.environ.get("USER"))
    
        print(stack.export("yaml"))

    Now generate CloudFormation YAML from your Python script. Note that the result will always be valid well-formatted YAML, and internal checks mean that it is also difficult to generate invalid CloudFormation.

    Finally, use the AWS command line tools to create/update a stack and it’s associated resources.

    python my_ec2_stack.py > my_ec2_stack.yaml
    aws cloudformation deploy --stack-name demo-flying-circus-ec2 --template-file my_ec2_stack.yaml

    You could do these steps in your Continuous Integration server 😉

    Is/Is Not

    There’s a lot of tools for managing Infrastructure as Code, often with subtle differences and passionate advocates. A quick discussion of our scope may help you understand where Flying Circus fits into this ecosystem, and whether it can help you. This is presented in the simple “Is/Is Not” format.

    Flying Circus Is…

    • …a Pythonic DSL for writing fully featured Python code
    • …for Amazon Web Services infrastructure
    • …built on top of AWS Cloud Formation templates
    • …a generator that always produces valid, consistent, human-readable, good-practice YAML

    Flying Circus Is Not…

    • …YAML or JSON. It’s Python.
    • …a tool to make it easier to write YAML or JSON. You write Python, and YAML is an output format.
    • …a DSL with a completely new syntax. You use normal Python syntax with all of it’s features and nothing changed.
    • …a templating language, like Jinja2.
    • …a template management tool, like Ansible.
    • …an independent implementation of infrastructure management, like AWS Cloud Formation stacks, or Terraform.
    • …a cloud-agnostic abstraction layer.
    • …multi-cloud – although it could become this in the future. The current implementation is focused on representing AWS infrastructure using the CloudFormation data model. Other cloud providers have similar native data models, so it is feasible that we could re-use the concepts and tooling to support Google Cloud Platform, etc.
    • …a tool for interacting with the Cloud Formation service. There are other tools that can do this for you (such as boto3 or the AWS CLI, for starters)
    • …a validation tool – although it could become this in the future, and already has elements of validation as a by-product of presenting a helpful interface to users.

    Sounds Great, Can I Use It?

    Sure, of course you can. The documentation will get you started.

    Flying Circus is currently in Beta. This means it is expected to work, and is in use by real customers. However, there is a possibility that the details of the interface may change in an incompatible way.

    How Do I Help?

    Just use it!

    Visit original content creator repository https://github.com/garyd203/flying-circus
  • nes-quantum-disassembly

    nes-quantum-disassembly

    Note: This project has been moved to Codeberg. This version will no longer be updated.

    An unofficial disassembly of the Nintendo Entertainment System (NES) demo Quantum Disco Brothers by wAMMA. Assembles with ASM6.

    Table of contents

    Notes

    • This disassembly is at an early stage.
    • I have not been involved with wAMMA or in the making of this demo.

    How to get the original files

    1. Download the original Quantum Disco Brothers file from e.g. pouet.net.
    2. If the file is compressed, extract it to get an iNES ROM file (quantum_disco_brothers_by_wAMMA.nes, MD5 hash 2c932e9e8ae7859517905e2539565a89).
    3. Generate the CHR ROM data from chr*.png with nes_chr_encode.py from my NES utilities; see assemble.sh for details.

    How to assemble

    1. asm6 quantum.asm "quantum-reassembled_(e).nes" (the (e) in the filename tells FCEUX to start the ROM in PAL mode)
    2. Verify that the .nes file is identical to the original:
    • diff -q quantum_disco_brothers_by_wAMMA.nes "quantum-reassembled_(e).nes" (on Linux)
    • fc /b quantum_disco_brothers_by_wAMMA.nes "quantum-reassembled_(e).nes" (on Windows)

    Note: the Linux script assemble.sh is intended for my personal use. Do not run it before reading it.

    iNES ROM header info

    • mapper: CNROM (iNES mapper number 3)
    • PRG ROM: 32 KiB (1 × 32 KiB)
    • CHR ROM: 32 KiB (4 × 8 KiB)
    • name table mirroring: horizontal
    • no trainer
    • no save RAM

    The parts of the demo

    • Screenshots from FCEUX in PAL mode.
    • Frame numbers: FCEUX’s Frame Display in PAL mode.
    • The internal part numbers are at RAM address 0x0001.

    1st part (internally part 0, starts at frame ~6): “GREETINGS! WE COME FROM…”; uses CHR bank 0

    2nd part (internally part 2, starts at frame 1156): “wAMMA – QUANTUM DISCO BROTHERS”; uses CHR bank 0

    3rd part (internally part 11, starts at frame 1923): red&purple gradients; uses CHR bank 1

    4th part (internally part 1, starts at frame 2690): horizontal color bars; uses CHR bank 1

    5th part (internally part 4, starts at frame 3458): a woman; uses CHR bank 3

    6th part (internally part 5, starts at frame 4481): “IT IS FRIDAY…”; uses CHR bank 0

    7th part (internally part 7, starts at frame 6362): Coca Cola cans; uses CHR bank 2

    8th part (internally part 6, starts at frame 7304): Bowser’s spaceship; uses CHR bank 2

    9th part (internally part 3, starts at frame 8071): credits; uses CHR bank 1

    10th part (internally part 10, starts at frame 9692): a checkered wavy animation; uses CHR bank 1

    11th part (internally part 12, starts at frame 10380): “GREETS TO ALL NINTENDAWGS”; uses CHR bank 2

    12th part (internally part 13, starts at frame 11298): “GAME OVER – CONTINUE?”; uses CHR bank 2

    13th part (internally part 9, starts at frame 14018): more horizontal color bars; uses CHR bank 2

    The demo should probably end at this point, as on this YouTube video. However, on FCEUX, it starts to glitch from frame ~17603 on. I omitted the glitchy part from the code/data log file.

    An unused part of the demo

    There is an unused ninja-themed sequence in the demo. It was probably meant to be used in place of the 6th part of the demo which displays the same text.

    The relevant subroutines are $ec99 and $ed4b (labels init_ninja and anim_ninja in my disassembly). To see the hidden sequence (although glitched) in place of the second part of the demo, replace jsr init_title and jsr anim_title with calls to those subroutines or use Game Genie codes OPPYKX + KTPYSX + LGPYNX + STPNEX.

    A hidden crescent moon

    In the Bowser’s spaceship part, you can make another smaller crescent moon appear with Game Genie code YILVEY:

    Code/data log

    I created a code/data log file (.cdl) of the ROM using the Code/Data Logger in FCEUX. The file is in quantum.cdl.gz (gz compressed).

    I also converted the CDL file into a human-readable format using my cdl-summary:

    • python3 cdl_summary.py --prg-size 32 --part p --bank-size 32 quantum.cdl > cdl-summary-raw-prg.csv
    • python3 cdl_summary.py --prg-size 32 --part c --bank-size 8 quantum.cdl > cdl-summary-raw-chr.csv

    PRG ROM

    Below is the manually-edited PRG CDL data. Columns: CPU start address in hexadecimal, length in hexadecimal, description.

    8000 (  34): unaccessed
    8034 ( 123): code
    8157 (   2): unaccessed
    8159 (   4): code
    815d (   2): unaccessed
    815f (  6c): code
    81cb (   2): unaccessed
    81cd (  6e): code
    823b (   d): unaccessed
    8248 (  22): code
    826a (   d): unaccessed
    8277 (  10): code
    8287 (   2): unaccessed
    8289 (   6): code
    828f (  42): unaccessed
    82d1 (  bd): code
    838e (  25): unaccessed
    83b3 (  61): code
    8414 (   3): unaccessed
    8417 (  1c): code
    8433 (   3): unaccessed
    8436 (  42): code
    8478 (   3): unaccessed
    847b (  1a): code
    8495 (   1): unaccessed
    8496 (  62): code
    84f8 (  15): unaccessed
    850d (  41): code
    854e (   d): unaccessed
    855b (   3): code
    855e (  53): unaccessed
    85b1 (  7c): code
    862d (  25): unaccessed
    8652 (  2f): code
    8681 (  21): unaccessed
    86a2 (  f6): code
    8798 (   2): unaccessed
    879a ( 16c): code
    8906 (  1b): unaccessed
    8921 (   4): code
    8925 (   b): unaccessed
    8930 (   3): code
    8933 (   1): unaccessed
    8934 (   5): code
    8939 (   2): unaccessed
    893b (   f): code
    
    894a (  11): unaccessed
    895b (  10): data
    896b (   1): unaccessed
    896c (   8): data
    8974 (   1): unaccessed
    8975 (   7): data
    897c (   1): unaccessed
    897d (   9): data
    8986 (   1): unaccessed
    8987 (   1): data
    8988 (   f): unaccessed
    8997 (   1): data
    8998 (   f): unaccessed
    89a7 (   1): data
    89a8 (   f): unaccessed
    89b7 (   1): data
    89b8 (   f): unaccessed
    89c7 (   1): data
    89c8 (   f): unaccessed
    89d7 (   1): data
    89d8 (   f): unaccessed
    89e7 (   1): data
    89e8 (   f): unaccessed
    89f7 (   1): data
    89f8 (   f): unaccessed
    8a07 (   1): data
    8a08 (   f): unaccessed
    8a17 (   1): data
    8a18 (   1): unaccessed
    8a19 (   1): data
    8a1a (   d): unaccessed
    8a27 (   1): data
    8a28 (   f): unaccessed
    8a37 (   1): data
    8a38 (   f): unaccessed
    8a47 (   1): data
    8a48 (   f): unaccessed
    8a57 (   1): data
    8a58 (   e): unaccessed
    8a66 (   2): data
    8a68 (   f): unaccessed
    8a77 (   1): data
    8a78 (  11): unaccessed
    8a89 (   1): data
    8a8a (   2): unaccessed
    8a8c (   2): data
    8a8e (   2): unaccessed
    8a90 (   3): data
    8a93 (   1): unaccessed
    8a94 (   4): data
    8a98 (   1): unaccessed
    8a99 (   d): data
    8aa6 (   1): unaccessed
    8aa7 (   2): data
    8aa9 (   1): unaccessed
    8aaa (   1): data
    8aab (   1): unaccessed
    8aac (   b): data
    8ab7 (   1): unaccessed
    8ab8 (   6): data
    8abe (   1): unaccessed
    8abf (   4): data
    8ac3 (   1): unaccessed
    8ac4 (   1): data
    8ac5 (   2): unaccessed
    8ac7 (   1): data
    8ac8 (  21): unaccessed
    8ae9 (   1): data
    8aea (   2): unaccessed
    8aec (   2): data
    8aee (   2): unaccessed
    8af0 (   3): data
    8af3 (   1): unaccessed
    8af4 (   4): data
    8af8 (   1): unaccessed
    8af9 (   d): data
    8b06 (   1): unaccessed
    8b07 (   2): data
    8b09 (   1): unaccessed
    8b0a (   1): data
    8b0b (   1): unaccessed
    8b0c (   b): data
    8b17 (   1): unaccessed
    8b18 (   6): data
    8b1e (   1): unaccessed
    8b1f (   4): data
    8b23 (   1): unaccessed
    8b24 (   1): data
    8b25 (   2): unaccessed
    8b27 (   1): data
    8b28 (  1e): unaccessed
    8b46 (   2): data
    8b48 (  23): unaccessed
    8b6b (   2): data (indirectly accessed)
    8b6d (   2): unaccessed
    8b6f (   6): data (indirectly accessed)
    8b75 (   3): unaccessed
    8b78 (  38): data (indirectly accessed)
    8bb0 (   8): unaccessed
    8bb8 (  30): data (indirectly accessed)
    8be8 (  10): unaccessed
    8bf8 (   3): data (indirectly accessed)
    8bfb (   1): unaccessed
    8bfc (   3): data (indirectly accessed)
    8bff (   1): unaccessed
    8c00 (   3): data (indirectly accessed)
    8c03 (   1): unaccessed
    8c04 (   3): data (indirectly accessed)
    8c07 (   1): unaccessed
    8c08 (   3): data (indirectly accessed)
    8c0b (   1): unaccessed
    8c0c (   3): data (indirectly accessed)
    8c0f (   1): unaccessed
    8c10 (   3): data (indirectly accessed)
    8c13 (   1): unaccessed
    8c14 (   3): data (indirectly accessed)
    8c17 (   1): unaccessed
    8c18 (   3): data (indirectly accessed)
    8c1b (   1): unaccessed
    8c1c (   3): data (indirectly accessed)
    8c1f (   1): unaccessed
    8c20 (   3): data (indirectly accessed)
    8c23 (   1): unaccessed
    8c24 (   3): data (indirectly accessed)
    8c27 (   1): unaccessed
    8c28 (   3): data (indirectly accessed)
    8c2b (   1): unaccessed
    8c2c (   3): data (indirectly accessed)
    8c2f (   1): unaccessed
    8c30 (   3): data (indirectly accessed)
    8c33 (   1): unaccessed
    8c34 (   3): data (indirectly accessed)
    8c37 (   1): unaccessed
    8c38 (   3): data (indirectly accessed)
    8c3b (   1): unaccessed
    8c3c (   3): data (indirectly accessed)
    8c3f (   1): unaccessed
    8c40 (   3): data (indirectly accessed)
    8c43 (   1): unaccessed
    8c44 (   3): data (indirectly accessed)
    8c47 (   1): unaccessed
    8c48 (   3): data (indirectly accessed)
    8c4b (   1): unaccessed
    8c4c (   3): data (indirectly accessed)
    8c4f (   1): unaccessed
    8c50 (   3): data (indirectly accessed)
    8c53 (   1): unaccessed
    8c54 (   3): data (indirectly accessed)
    8c57 (   1): unaccessed
    8c58 (   3): data (indirectly accessed)
    8c5b (   1): unaccessed
    8c5c (   3): data (indirectly accessed)
    8c5f (   1): unaccessed
    8c60 (   3): data (indirectly accessed)
    8c63 (   1): unaccessed
    8c64 (   3): data (indirectly accessed)
    8c67 (   1): unaccessed
    8c68 (   3): data (indirectly accessed)
    8c6b (   1): unaccessed
    8c6c (   3): data (indirectly accessed)
    8c6f (   1): unaccessed
    8c70 (   3): data (indirectly accessed)
    8c73 (   1): unaccessed
    8c74 (   3): data (indirectly accessed)
    8c77 (   1): unaccessed
    8c78 (   3): data (indirectly accessed)
    8c7b (   1): unaccessed
    8c7c (   3): data (indirectly accessed)
    8c7f (   1): unaccessed
    8c80 (   3): data (indirectly accessed)
    8c83 (   1): unaccessed
    8c84 (   3): data (indirectly accessed)
    8c87 (   1): unaccessed
    8c88 (   3): data (indirectly accessed)
    8c8b (   1): unaccessed
    8c8c (   3): data (indirectly accessed)
    8c8f (   1): unaccessed
    8c90 (   3): data (indirectly accessed)
    8c93 (   1): unaccessed
    8c94 (   3): data (indirectly accessed)
    8c97 (   1): unaccessed
    8c98 (   3): data (indirectly accessed)
    8c9b (   1): unaccessed
    8c9c (   3): data (indirectly accessed)
    8c9f (   1): unaccessed
    8ca0 (   3): data (indirectly accessed)
    8ca3 (   1): unaccessed
    8ca4 (   3): data (indirectly accessed)
    8ca7 (   1): unaccessed
    8ca8 (   3): data (indirectly accessed)
    8cab (   1): unaccessed
    8cac (   3): data (indirectly accessed)
    8caf (   1): unaccessed
    8cb0 (   3): data (indirectly accessed)
    8cb3 (   1): unaccessed
    8cb4 (   3): data (indirectly accessed)
    8cb7 (   1): unaccessed
    8cb8 (   3): data (indirectly accessed)
    8cbb (   1): unaccessed
    8cbc (   3): data (indirectly accessed)
    8cbf (   1): unaccessed
    8cc0 (   3): data (indirectly accessed)
    8cc3 (   1): unaccessed
    8cc4 (   3): data (indirectly accessed)
    8cc7 (   1): unaccessed
    8cc8 (   3): data (indirectly accessed)
    8ccb (   1): unaccessed
    8ccc (   3): data (indirectly accessed)
    8ccf (   1): unaccessed
    8cd0 (   3): data (indirectly accessed)
    8cd3 (   1): unaccessed
    8cd4 (   3): data (indirectly accessed)
    8cd7 (   1): unaccessed
    8cd8 (   3): data (indirectly accessed)
    8cdb (   1): unaccessed
    8cdc (   3): data (indirectly accessed)
    8cdf (   1): unaccessed
    8ce0 (   3): data (indirectly accessed)
    8ce3 (   5): unaccessed
    8ce8 (   2): data (indirectly accessed)
    8cea (   2): unaccessed
    8cec (  38): data (indirectly accessed)
    8d24 (   8): unaccessed
    8d2c (   8): data (indirectly accessed)
    8d34 (   2): unaccessed
    8d36 (  3c): data (indirectly accessed)
    8d72 (   2): unaccessed
    8d74 (  4c): data (indirectly accessed)
    8dc0 (  53): unaccessed
    8e13 (127a): data (indirectly accessed)
    a08d (1f73): unaccessed
    
    c000 (  a8): code
    
    c0a8 (   e): data
    c0b6 (   2): unaccessed
    c0b8 (  70): data (indirectly accessed)
    c128 (  10): unaccessed
    c138 ( 116): data
    c24e (   6): unaccessed
    c254 (  20): data
    c274 (   c): unaccessed
    c280 ( fa1): data (PCM audio)
    d221 (   4): unaccessed
    d225 ( 2e9): data
    d50e (   2): unaccessed
    d510 (   5): data
    d515 (   1): unaccessed
    d516 (   4): data
    d51a (   1): unaccessed
    d51b (   1): data
    d51c (   3): unaccessed
    d51f (   1): data
    d520 (   2): unaccessed
    d522 (   2): data
    d524 (   c): unaccessed
    d530 ( 50d): data
    da3d (  48): unaccessed
    da85 (  65): data
    daea (  31): unaccessed
    db1b (   d): data
    db28 (   2): unaccessed
    db2a (  78): data
    dba2 (   f): unaccessed
    dbb1 (   4): data
    dbb5 (  1a): unaccessed
    dbcf (  4d): data
    dc1c (   5): unaccessed
    dc21 (   b): data
    dc2c (   5): unaccessed
    dc31 (   b): data
    dc3c (   5): unaccessed
    dc41 (   b): data
    dc4c (   6): unaccessed
    dc52 (  40): data
    dc92 (   4): unaccessed
    
    dc96 (  14): code
    dcaa (  25): unaccessed
    dccf (  53): code
    dd22 (  2d): unaccessed
    dd4f ( 251): code
    dfa0 (   1): code, data
    dfa1 (  72): code
    e013 (   3): unaccessed
    e016 (  bd): code
    e0d3 (  d2): unaccessed
    e1a5 (  b8): code
    e25d (   1): code, data
    e25e ( 214): code
    e472 (   1): code, data
    e473 ( 164): code
    e5d7 (   1): code, data
    e5d8 ( 4a7): code
    ea7f (   1): code, data
    ea80 ( 1c7): code
    ec47 (   1): code, data
    ec48 (  51): code
    ec99 ( 262): unaccessed
    eefb ( 195): code
    f090 (   1): code, data
    f091 (  80): code
    f111 (   5): unaccessed
    f116 ( 176): code
    f28c (   1): code, data
    f28d ( 1be): code
    f44b (   1): code, data
    f44c (  ad): code
    f4f9 (   b): unaccessed
    f504 ( 17c): code
    f680 (   1): code, data
    f681 ( 14f): code
    f7d0 (  2d): unaccessed
    f7fd ( 183): code
    f980 (   3): unaccessed
    f983 (  30): code
    f9b3 (   4): unaccessed
    f9b7 ( 17e): code
    fb35 (   8): unaccessed
    fb3d (  e9): code
    fc26 ( 3d4): unaccessed
    
    fffa (   4): data (NMI and reset vectors)
    fffe (   2): unaccessed (IRQ vector)
    

    CHR ROM

    No CHR data was read programmatically via $2007. See also the chapter “CHR ROM banks” below.

    CHR ROM banks

    See also the chapter “Code/data log” above.

    Bank 0

    Used by the 1st, 2nd and 6th part of the demo.

    An unused cat in the first half. Colored by me.

    Some digits, letters and duplicates of stars are also unused.

    Bank 1

    Used by the 3rd, 4th, 9th and 10th part of the demo.

    No interesting unused tiles.

    Bank 2

    Used by the 7th, 8th, 11th, 12th and 13th part of the demo.

    Three unused ninja animation frames in the first half. Colored by me. See “an unused part of the demo” above.

    Same as above but animated by me at 5 fps in order 1, 2, 3, 2.

    An unused small crescent moon in the first half. See “a hidden crescent moon” above.

    Unused big asteroids (fireballs?) in the first half. Here, colored the same as the small asteroids/fireballs used in the 8th part of the demo.

    Unused eyes of a ninja in the second half. Colored by me. See “an unused part of the demo” above.

    Bank 3

    Used by the 5th part of the demo.

    No interesting unused tiles.

    References

    Software used

    Visit original content creator repository https://github.com/qalle2/nes-quantum-disassembly