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