Invaders in 512 bytes of x86 assembler (boot sector)

Sdílet
Vložit
  • čas přidán 3. 06. 2019
  • I've created a Invaders game in 512 bytes of x86 assembler that can be run as a COM file or a boot sector from a floppy disk.
    You can download it with full source code at github.com/nanochess/Invaders
  • Věda a technologie

Komentáře • 38

  • @nanochess
    @nanochess  Před 4 lety +7

    Do you would like more details on the inner workings? This program is fully commented in my new book Programming Boot Sector Games and you'll also find a 8086/8088 crash course! Now available from Lulu:
    Soft-cover
    www.lulu.com/shop/oscar-toledo-gutierrez/programming-boot-sector-games/paperback/product-24188564.html
    Hard-cover
    www.lulu.com/shop/oscar-toledo-gutierrez/programming-boot-sector-games/hardcover/product-24188530.html

    • @digimorf
      @digimorf Před 3 lety

      Interesting! Is there an e-book version also? Maybe for Kindle?

    • @nanochess
      @nanochess  Před 3 lety

      @@digimorf only PDF available from my store ar nanochess.org/store.html

  • @hrford
    @hrford Před 3 lety +7

    I'm heavily into the weedas when it comes to detail. I'm also into 8-bit assembly programming. In my current job, I'm working on AWS, so I thought I'd slam your Bootsector game into an EC2 a reboot it ... errr, as expected, of course, it worked. Turns out EC2s are just another IBM PC complete with a functional BIOS. Now to confuse my colleagues with it ...

  • @digimorf
    @digimorf Před 3 lety +4

    All your works are absolutely great. The optimization of code and resources is cutting edge! Unfortunately nowadays the majority of programmers don't care much about it, maybe only at the high-end levels such as the aerospace industry, where resources must be limited. Anyway, great job!

  • @nyuundere
    @nyuundere Před 3 lety +2

    The one who disliked this don't know how to program on a boot sector.

  • @freecrac
    @freecrac Před 5 lety +7

    Hint: We can also use operand size/register size and address size prefixes within the real address mode since Intel 80386.
    Intel:
    Instruction prefixes can be used to override the default operand size and address size of a code segment. These prefixes can be used in real-address mode as well as in protected mode and virtual-8086 mode. An operand-size or address-size prefix only changes the size for the duration of the instruction.
    The following two instruction prefixes allow mixing of 32-bit and 16-bit operations within one segment:
    •The operand-size prefix (66H)
    •The address-size prefix (67H)
    These prefixes reverse the default size selected by the D flag in the code-segment descriptor. For example, the processor can interpret the (MOV mem, reg) instruction in any of four ways:
    •In a 32-bit code segment:
    -Moves 32 bits from a 32-bit register to memory using a 32-bit effective address.
    -If preceded by an operand-size prefix, moves 16 bits from a 16-bit register to memory using a 32-bit effective address.
    -If preceded by an address-size prefix, moves 32 bits from a 32-bit register to memory using a 16-bit effective address.
    -If preceded by both an address-size prefix and an operand-size prefix, moves 16 bits from a 16-bit register to memory using a 16-bit effective address.
    •In a 16-bit code segment:
    -Moves 16 bits from a 16-bit register to memory using a 16-bit effective address.
    -If preceded by an operand-size prefix, moves 32 bits from a 32-bit register to memory using a 16-bit effective address.
    -If preceded by an address-size prefix, moves 16 bits from a 16-bit register to memory using a 32-bit effective address.
    -If preceded by both an address-size prefix and an operand-size prefix, moves 32 bits from a 32-bit register to memory using a 32-bit effective address.
    The previous examples show that any instruction can generate any combination of operand size and address size regardless of whether the instruction is in a 16- or 32-bit segment. The choice of the 16- or 32-bit default for a code segment is normally based on the following criteria:
    •Performance - Always use 32-bit code segments when possible. They run much faster than 16-bit code segments on P6 family processors, and somewhat faster on earlier IA-32 processors.
    •The operating system the code segment will be running on - If the operating system is a 16-bit operating system, it may not support 32-bit program modules.
    •Mode of operation - If the code segment is being designed to run in real-address mode, virtual-8086 mode, or SMM, it must be a 16-bit code segment.
    •Backward compatibility to earlier IA-32 processors - If a code segment must be able to run on an Intel 8086 or Intel 286 processor, it must be a 16-bit code segment.
    The D flag in a code-segment descriptor determines the default operand-size and address-size for the instructions of a code segment. (In real-address mode and virtual-8086 mode, which do not use segment descriptors, the default is 16 bits.) A code segment with its D flag set is a 32-bit segment; a code segment with its D flag clear is a 16-bit segment.
    Executable code segment. The flag is called the D flag and it indicates the default length for effective addresses and operands referenced by instructions in the segment. If the flag is set, 32-bit addresses and 32-bit or 8-bit operands are assumed; if it is clear, 16-bit addresses and 16-bit or 8-bit operands are assumed.
    The instruction prefix 66H can be used to select an operand size other than the default, and the prefix 67H can be used select an address size other than the default.
    The 32-bit operand prefix can be used in real-address mode programs to execute the 32-bit forms of instructions. This prefix also allows real-address mode programs to use the processor’s 32-bit general-purpose registers.
    The 32-bit address prefix can be used in real-address mode programs, allowing 32-bit offsets.
    The IA-32 processors beginning with the Intel386 processor can generate 32-bit offsets using an address override prefix; however, in real-address mode, the value of a 32-bit offset may not exceed FFFFH without causing an exception.
    Assembler Usage:
    If a code segment that is going to run in real-address mode is defined, it must be set to a USE 16 attribute. If a 32-bit operand is used in an instruction in this code segment (for example, MOV EAX, EBX), the assembler automatically generates an operand prefix for the instruction that forces the processor to execute a 32-bit operation, even though its default code-segment attribute is 16-bit.
    The 32-bit operand prefix allows a real-address mode program to use the 32-bit general-purpose registers (EAX, EBX, ECX, EDX, ESP, EBP, ESI, and EDI).
    When moving data in 32-bit mode between a segment register and a 32-bit general-purpose
    register, the Pentium Pro processor does not require the use of a 16-bit operand size prefix;
    however, some assemblers do require this prefix. The processor assumes that the 16 least-significant
    bits of the general-purpose register are the destination or source operand. When moving a
    value from a segment selector to a 32-bit register, the processor fills the two high-order bytes of
    the register with zeros.
    --------------------------------------------------
    AMD:
    3.3.2. 32-Bit vs. 16-Bit Address and Operand Sizes
    The processor can be configured for 32-bit or 16-bit address and operand sizes. With 32-bit
    address and operand sizes, the maximum linear address or segment offset is FFFFFFFFH
    (232-1), and operand sizes are typically 8 bits or 32 bits. With 16-bit address and operand sizes,
    the maximum linear address or segment offset is FFFFH (216-1), and operand sizes are typically
    8 bits or 16 bits.
    When using 32-bit addressing, a logical address (or far pointer) consists of a 16-bit segment
    selector and a 32-bit offset; when using 16-bit addressing, it consists of a 16-bit segment selector
    and a 16-bit offset.
    Instruction prefixes allow temporary overrides of the default address and/or operand sizes from
    within a program.
    When operating in protected mode, the segment descriptor for the currently executing code
    segment defines the default address and operand size. A segment descriptor is a system data
    structure not normally visible to application code. Assembler directives allow the default
    addressing and operand size to be chosen for a program. The assembler and other tools then set
    up the segment descriptor for the code segment appropriately.
    When operating in real-address mode, the default addressing and operand size is 16 bits. An
    address-size override can be used in real-address mode to enable 32-bit addressing; however, the
    maximum allowable 32-bit linear address is still 000FFFFFH (220-1).
    3.6. OPERAND-SIZE AND ADDRESS-SIZE ATTRIBUTES
    When the processor is executing in protected mode, every code segment has a default operandsize
    attribute and address-size attribute. These attributes are selected with the D (default size)
    flag in the segment descriptor for the code segment (see Chapter 3, Protected-Mode Memory
    Management, in the Intel Architecture Software Developer’s Manual, Volume 3). When the D
    flag is set, the 32-bit operand-size and address-size attributes are selected; when the flag is clear,
    the 16-bit size attributes are selected. When the processor is executing in real-address mode,
    virtual-8086 mode, or SMM, the default operand-size and address-size attributes are always 16
    bits.
    The operand-size attribute selects the sizes of operands that instructions operate on. When the
    16-bit operand-size attribute is in force, operands can generally be either 8 bits or 16 bits, and
    when the 32-bit operand-size attribute is in force, operands can generally be 8 bits or 32 bits.
    The address-size attribute selects the sizes of addresses used to address memory: 16 bits or 32
    bits. When the 16-bit address-size attribute is in force, segment offsets and displacements are 16
    bits. This restriction limits the size of a segment that can be addressed to 64 KBytes. When the
    32-bit address-size attribute is in force, segment offsets and displacements are 32 bits, allowing
    segments of up to 4 GBytes to be addressed.
    The default operand-size attribute and/or address-size attribute can be overridden for a particular
    instruction by adding an operand-size and/or address-size prefix to an instruction (see
    “Instruction Prefixes” in Chapter 2 of the Intel Architecture Software Developer’s Manual,
    Volume 3). The effect of this prefix applies only to the instruction it is attached to.
    Table 3-1 shows effective operand size and address size (when executing in protected mode)
    depending on the settings of the D flag and the operand-size and address-size prefixes.

    • @nanochess
      @nanochess  Před 5 lety

      On purpose I've avoided 386 instructions.

    • @freecrac
      @freecrac Před 5 lety +1

      @@nanochess It´s OK. No problem. I learned the x86 instructions on an Intel 80286.

    • @timothylegg
      @timothylegg Před 5 lety

      What I am curious about is how was the timing worked out? There is a very wide variance in clock cycle timing between different generations of hardware. I remember some of the games on my XT were unplayably fast on my 286.

    • @nanochess
      @nanochess  Před 5 lety +3

      @@timothylegg I'm based on BIOS clock data, it gives you a granularity of 18.2 hz. Programming the timer can give you any frequency you need. In the old times I used to be based on 03DAH register bit 3 of VGA to wait for vertical retrace bit.

  • @mariogutierrez4989
    @mariogutierrez4989 Před 5 lety +2

    Kudos!! I probably spent more than 512 quarters on that game

  • @shanmugapriyas7670
    @shanmugapriyas7670 Před 4 lety +1

    You created a super game in bootsector It is very challenging to create under 512 bytes

  • @earthsteward70
    @earthsteward70 Před 5 lety +11

    Man if only there was a good tutorial or resource on x86 assembly.

    • @nanochess
      @nanochess  Před 3 lety +2

      Now you can get my book Programming Boot Sector Games, it includes a crash course on x86 programming

    • @earthsteward70
      @earthsteward70 Před 3 lety +2

      @@nanochess doooope, x86 has been unnaproachable for me, even a 6502 routine is straightforward.

  • @Lucas-mq2pd
    @Lucas-mq2pd Před 3 lety +2

    Thats insane!

  • @iDrDolphin
    @iDrDolphin Před 5 lety +6

    This is awesome

  • @JimmyNavioTV
    @JimmyNavioTV Před 5 lety +3

    Well done!

  • @Akira625
    @Akira625 Před rokem

    I didn't think it could be possible to write a game with only half a kilobyte of space. Even the old Atari 2600 games were larger than this, written to fit on a 4K cartridge.

    • @nanochess
      @nanochess  Před rokem +1

      This is easier in 8086 because there are more complex instructions for 16-bit addition, while in 6502 it is required several short instructions. Also we have direct memory addressing of pixels, while in Atari 2600 we need different code for each screen row. As a reference my own implementation of Invaders for Atari 2600 sizes at 1637 bytes (still to be published).

  • @CrazyBossDK
    @CrazyBossDK Před 4 lety +1

    Crazy :)

  • @intel386DX
    @intel386DX Před 4 lety +4

    I love the colors! what kind of video mode it this? what are the system requirements :) ? I am downloading this too! :)))

    • @nanochess
      @nanochess  Před 4 lety +1

      8088 plus VGA card. Mode 0x13 320x200x256 colors.

    • @intel386DX
      @intel386DX Před 4 lety +1

      @@nanochess cool! ,but the resolution looks like lower then 320x240 :D

    • @nanochess
      @nanochess  Před 4 lety +2

      @@intel386DX it's using a pixel doubler. So you're right, it looks like 160x100

    • @intel386DX
      @intel386DX Před 4 lety

      @@nanochess :))) look amazing! BTW the controls are bit strange, what is the purpose of that? left alt, shoot -shift

    • @nanochess
      @nanochess  Před 4 lety +1

      @@intel386DX these are the only keys that can be tested for pressed/depressed by BIOS

  • @tarstarkusz
    @tarstarkusz Před 4 lety +1

    How does the end user put it in the boot sector? Presumably it will work on a 5150 PC?

    • @nanochess
      @nanochess  Před 4 lety

      The easiest way is a IMG file for an emulator like VirtualBox or qEmu. The complicated way is to install a physical drive and write directly the sector onto the disk. The most complicated way is to use the 5150 PC and use DEBUG to enter manually the machine code and save it onto the boot sector with a small code calling INT 13. Of course you need a 8-bit VGA video card.

    • @tarstarkusz
      @tarstarkusz Před 4 lety +1

      @@nanochess Ah, yeah, gold old debug. I forgot about that. I haven't used it over 25 years!

  • @hiimdaisy946
    @hiimdaisy946 Před 2 lety

    nothing but a bunch of graliens! lel