     1                                  ; STAR97.S (NASM version of STAR97.ASM)
     2                                  ;
     3                                  ;                              [ STARFIELD '97 ]
     4                                  ;
     5                                  ; [ Explanation ]
     6                                  ;
     7                                  ; well, here's an explanation of what's going on. first off we generate the
     8                                  ; starfeild data, star structures are qword aligned for easy offset calc's,
     9                                  ; and a floating random number seed is used. the initial random seed is mov'd
    10                                  ; into the very last star structure, and the next random seed is stored in
    11                                  ; the structure below, and this routine is followed to the very first star
    12                                  ; structure. instead using the modulus of the random number and using it as
    13                                  ; the saved value we mask off all the unwanted bits in the random number, and
    14                                  ; then modify the values to fit in the ranges we need. i was looking for a 4
    15                                  ; layer field (00000011b), and 16 scales of white (00001111b). nifty both
    16                                  ; numbers are binary constants, lucky me! most things don't work out so well.
    17                                  ;
    18                                  ; [ Excuses ]
    19                                  ;
    20                                  ; ok, your saying "Big woop!, i've seen 20 byte starfields". well this is
    21                                  ; true, so have i. however all those starfields are just random color shit.
    22                                  ; not only is the randomness shitty, but they don't check for a keypress, and
    23                                  ; they don't even look like a starfield, otherwise there not usable at all!
    24                                  ; this routine has parallax style scrolling of a 4 layer starfield, 16 random
    25                                  ; shades of stars, a fairly random placement of stars, it's fast, and it even
    26                                  ; checks for vertical retrace and keypress!
    27                                  ;
    28                                  ; [ Questions / Answers ]
    29                                  ;
    30                                  ; you may be scratching your head on some of the sections of this code, so
    31                                  ; let me give you my reasoning before you call me a dumbshit.
    32                                  ;
    33                                  ; Q: why don't you use 'in ax,40h' as a random number routine rather than
    34                                  ;    using imul and such?
    35                                  ;
    36                                  ; A: well 'in ax,40h' sucks, it's not random enough, try it. you'll see my
    37                                  ;    reasoning, the method used is much better. btw i got the random routine
    38                                  ;    i'm using by simplifying the random routine used by borland turbo c 3.0
    39                                  ;    i just disassembled the lib call and this is pretty much what i got.
    40                                  ;    otherwise i had no idea how to make random numbers, this concept was new
    41                                  ;    to me!, wow a learning experience.
    42                                  ;
    43                                  ; Q: why don't you use a 4 byte structure, a word for the address, and a byte
    44                                  ;    for the speed, and another byte for the color?
    45                                  ;
    46                                  ; A: well in the main loop you'll see that i add the speed to the address,
    47                                  ;    and that i store the address in di, well this means that if i wanted to
    48                                  ;    add anything to a 16bit register i would have to use another 16bit mem
    49                                  ;    location or register, and i can't otherwise it screws up. i wish there
    50                                  ;    was some kind of addzx instruction which added the contents of a smaller
    51                                  ;    register but internally masked it to the same size as the destination
    52                                  ;    with zero's extended. ohh well there are too many instructions anyways.
    53                                  ;
    54                                  ; Q: only 255 stars?
    55                                  ;
    56                                  ; A: it looks ok doesn't it?!, you can use up to something like 8000 stars if
    57                                  ;    you change the 'mov cl,NSTARS' to 'mov cx,NSTARS'. however the code size
    58                                  ;    will increase two bytes (this was my origional goal 99 bytes), however i
    59                                  ;    was told it would be "cooler" to release something that referenced the
    60                                  ;    current year??
    61                                  ;
    62                                  ; Q: my god your a moron, i could make this much smaller, and still retain
    63                                  ;    all of the kewl features you talk about.
    64                                  ;
    65                                  ; A: great, please do, and send me your changes to brandt@europa.com. i tried
    66                                  ;    to the best of my ability to make it smaller, i even got it to 87 bytes
    67                                  ;    using the 'in ax,40h', and commenting out the random number seed setup,
    68                                  ;    and the imul, along with the following mov. but like i said a couple of
    69                                  ;    questions above 'in ax,40h' looks shitty.
    70                                  ;
    71                                  ; ohh, one last thing i do use the following 80386 instructions:
    72                                  ;
    73                                  ; shl    reg16,immediate > 1
    74                                  ; imul   reg16,mem | reg16,reg16 | immediate
    75                                  ;
    76                                  ;                                      deathlock ; brandt@europa.com
    77                                  
    78                                  ; NASM version: Erdogan Tan, 03/10/2016
    79                                  
    80                                  NSTARS  EQU     255                     ; number of stars to draw
    81                                  
    82                                  [Bits 16]   ; Real Mode (MSDOS) Program
    83                                  
    84                                  [org 100h]  ; MSDOS COM File
    85                                  
    86                                  start:
    87                                  
    88 00000000 B013                     mov    al,13h                          ; function 00h, mode 13h 
    89 00000002 CD10                     int    10h                             ; bios video interrupt
    90 00000004 BADA03                   mov    dx,03DAh                        ; vga status port for retrace
    91 00000007 6800A0                   push   0A000h                          ; use es for segment overrides
    92 0000000A 07                       pop    es                              ; when writing to the screen
    93                                  
    94                                  ;[ initialize starfield variables ]------------------------------------------
    95                                  
    96 0000000B B1FF                     mov    cl,NSTARS                       ; cx = number of stars to initialize
    97 0000000D C606[6108]01             mov    byte [NSTARS*8+stars+8],1       ; set the begining random number seed
    98                                  
    99                                  loop1:
   100 00000012 89CB                     mov    bx,cx                           ; copy cx to bx for indexing
   101 00000014 C1E303                   shl    bx,3                            ; multiply bx by 8 (structure size)
   102 00000017 81C3[6100]               add    bx,stars                        ; add the start offset of stars to bx
   103                                  
   104 0000001B 694708354E               imul   ax,word [bx+8],4E35h            ; multiply to get next random number
   105 00000020 8907                     mov    word [bx],ax                    ; stars[cx].addr = ax
   106 00000022 250F03                   and    ax,0000001100001111b            ; mask off unwanted values
   107 00000025 040E                     add    al,14                           ; make sure al < 30 & al > 14
   108 00000027 894702                   mov    word [bx+2],ax                  ; stars[cx].col = ax
   109 0000002A C1E808                   shr    ax,8                            ; shift hi byte to low byte
   110 0000002D FEC0                     inc    al                              ; stars[cx].spd can't be zero
   111 0000002F 894704                   mov    word [bx+4],ax                  ; stars[cx].spd = ax
   112 00000032 E2DE                     loop   loop1                           ; do this again for the next star
   113                                  
   114                                  ;[ the main loop, holy shit! ]-----------------------------------------------
   115                                  
   116                                  drawstars:
   117                                  
   118                                  vend:
   119 00000034 EC                       in     al,dx                           ; al = vga status byte (03DAh)
   120 00000035 2408                     and    al,08h                          ; keep the vretrace status bit
   121 00000037 74FB                     jz     short vend                      ; not equal to 1?, check again
   122                                  
   123 00000039 B1FF                     mov    cl,NSTARS                       ; lets draw NSTARS to the screen
   124                                  
   125                                  loop2:
   126 0000003B 89CB                     mov    bx,cx                           ; copy cx to bx for indexing again
   127 0000003D C1E303                   shl    bx,3                            ; multiply bx by 8 (structure size)
   128 00000040 81C3[6100]               add    bx,stars                        ; add start offset of stars to bx
   129 00000044 8B3F                     mov    di,word [bx]                    ; di = stars.addr
   130 00000046 268825                   mov    [es:di],ah                      ; erase star (ah isn't ever used)
   131 00000049 037F04                   add    di,word [bx+4]                  ; stars.addr = stars.addr + stars.spd
   132 0000004C 8A4702                   mov    al,byte [bx+2]                  ; al = stars.col
   133 0000004F 268805                   mov    [es:di],al                      ; draw new star to the screen
   134 00000052 893F                     mov    word [bx],di                    ; save the updated star posistion 
   135 00000054 E2E5                     loop   loop2                           ; erase/draw all NSTARS to the screen
   136                                  
   137 00000056 E460                     in     al,60h                          ; al = port 60h, keyboard
   138 00000058 3C01                     cmp    al,1                            ; escape key pressed?
   139 0000005A 75D8                     jnz    short drawstars                 ; was escape pressed, no do it again
   140                                  
   141 0000005C B003                     mov    al,03h                          ; escape was pressed, lets quit
   142 0000005E CD10                     int    10h                             ; al = 03h text mode, int 10 video
   143 00000060 C3                       retn                                   ; com file trick to exit to dos
   144                                  
   145                                  stars:                                  ; start of starfield structure
