1 ; **************************************************************************** 2 ; star97pm.s (TRDOS 386, TRDOS v2.0 - sample binary file, 'star97pm.prg') 3 ; ---------------------------------------------------------------------------- 4 ; STAR97PM.PRG ! TEST program ! TRDOS 386 VGA Functionality test ! 5 ; 6 ; 03/10/2016 7 ; 8 ; [ Last Modification: 03/10/2016 ] 9 ; 10 ; Derived from source code of 'STAR97.COM' (MSDOS) intro file 11 ; (Source: STAR97.ASM, 15/05/1997, 97 bytes) 12 ; 13 ; STAR97.ASM by Deathlock / Assembler (TASM4) 14 ; NASM version of STAR97.ASM: Erdogan Tan, 02/10/2016 (star97.s) 15 ; 16 ; Assembler: NASM 2.11 17 ; 18 ; (Original -msdos- code has been modifed for TRDOS 386 system calls and 19 ; other protected mode (TRDOS 386) interrupts.) 20 ; **************************************************************************** 21 22 ; 19/05/2016 23 ; 29/04/2016 24 ; TRDOS 386 system calls (temporary list!) 25 _ver equ 0 26 _exit equ 1 27 _fork equ 2 28 _read equ 3 29 _write equ 4 30 _open equ 5 31 _close equ 6 32 _wait equ 7 33 _creat equ 8 34 _link equ 9 35 _unlink equ 10 36 _exec equ 11 37 _chdir equ 12 38 _time equ 13 39 _mkdir equ 14 40 _chmod equ 15 41 _chown equ 16 42 _break equ 17 43 _stat equ 18 44 _seek equ 19 45 _tell equ 20 46 _mount equ 21 47 _umount equ 22 48 _setuid equ 23 49 _getuid equ 24 50 _stime equ 25 51 _quit equ 26 52 _intr equ 27 53 _fstat equ 28 54 _emt equ 29 55 _mdate equ 30 56 _video equ 31 57 _audio equ 32 58 _timer equ 33 59 _sleep equ 34 60 _msg equ 35 61 _geterr equ 36 62 _rsrvd1 equ 37 63 _pri equ 38 64 _rele equ 39 65 66 %macro sys 1-4 67 ; 29/04/2016 - TRDOS 386 (TRDOS v2.0) 68 ; 03/09/2015 69 ; 13/04/2015 70 ; Retro UNIX 386 v1 system call. 71 %if %0 >= 2 72 mov ebx, %2 73 %if %0 >= 3 74 mov ecx, %3 75 %if %0 = 4 76 mov edx, %4 77 %endif 78 %endif 79 %endif 80 mov eax, %1 81 ;int 30h 82 int 40h ; TRDOS 386 (TRDOS v2.0) 83 %endmacro 84 85 ; TRDOS 386 (and Retro UNIX 386 v1) system call format: 86 ; sys systemcall (eax) , , 87 88 ; STAR97.S (NASM version of STAR97.ASM) 89 ; 90 ; [ STARFIELD '97 ] 91 ; 92 ; [ Explanation ] 93 ; 94 ; well, here's an explanation of what's going on. first off we generate the 95 ; starfeild data, star structures are qword aligned for easy offset calc's, 96 ; and a floating random number seed is used. the initial random seed is mov'd 97 ; into the very last star structure, and the next random seed is stored in 98 ; the structure below, and this routine is followed to the very first star 99 ; structure. instead using the modulus of the random number and using it as 100 ; the saved value we mask off all the unwanted bits in the random number, and 101 ; then modify the values to fit in the ranges we need. i was looking for a 4 102 ; layer field (00000011b), and 16 scales of white (00001111b). nifty both 103 ; numbers are binary constants, lucky me! most things don't work out so well. 104 ; 105 ; [ Excuses ] 106 ; 107 ; ok, your saying "Big woop!, i've seen 20 byte starfields". well this is 108 ; true, so have i. however all those starfields are just random color shit. 109 ; not only is the randomness shitty, but they don't check for a keypress, and 110 ; they don't even look like a starfield, otherwise there not usable at all! 111 ; this routine has parallax style scrolling of a 4 layer starfield, 16 random 112 ; shades of stars, a fairly random placement of stars, it's fast, and it even 113 ; checks for vertical retrace and keypress! 114 ; 115 ; [ Questions / Answers ] 116 ; 117 ; you may be scratching your head on some of the sections of this code, so 118 ; let me give you my reasoning before you call me a dumbshit. 119 ; 120 ; Q: why don't you use 'in ax,40h' as a random number routine rather than 121 ; using imul and such? 122 ; 123 ; A: well 'in ax,40h' sucks, it's not random enough, try it. you'll see my 124 ; reasoning, the method used is much better. btw i got the random routine 125 ; i'm using by simplifying the random routine used by borland turbo c 3.0 126 ; i just disassembled the lib call and this is pretty much what i got. 127 ; otherwise i had no idea how to make random numbers, this concept was new 128 ; to me!, wow a learning experience. 129 ; 130 ; Q: why don't you use a 4 byte structure, a word for the address, and a byte 131 ; for the speed, and another byte for the color? 132 ; 133 ; A: well in the main loop you'll see that i add the speed to the address, 134 ; and that i store the address in di, well this means that if i wanted to 135 ; add anything to a 16bit register i would have to use another 16bit mem 136 ; location or register, and i can't otherwise it screws up. i wish there 137 ; was some kind of addzx instruction which added the contents of a smaller 138 ; register but internally masked it to the same size as the destination 139 ; with zero's extended. ohh well there are too many instructions anyways. 140 ; 141 ; Q: only 255 stars? 142 ; 143 ; A: it looks ok doesn't it?!, you can use up to something like 8000 stars if 144 ; you change the 'mov cl,NSTARS' to 'mov cx,NSTARS'. however the code size 145 ; will increase two bytes (this was my origional goal 99 bytes), however i 146 ; was told it would be "cooler" to release something that referenced the 147 ; current year?? 148 ; 149 ; Q: my god your a moron, i could make this much smaller, and still retain 150 ; all of the kewl features you talk about. 151 ; 152 ; A: great, please do, and send me your changes to brandt@europa.com. i tried 153 ; to the best of my ability to make it smaller, i even got it to 87 bytes 154 ; using the 'in ax,40h', and commenting out the random number seed setup, 155 ; and the imul, along with the following mov. but like i said a couple of 156 ; questions above 'in ax,40h' looks shitty. 157 ; 158 ; ohh, one last thing i do use the following 80386 instructions: 159 ; 160 ; shl reg16,immediate > 1 161 ; imul reg16,mem | reg16,reg16 | immediate 162 ; 163 ; deathlock ; brandt@europa.com 164 165 ; NASM version: Erdogan Tan, 03/10/2016 166 167 NSTARS EQU 255 ; number of stars to draw 168 169 [Bits 32] ; Protected Mode (TRDOS 386) Program 170 171 [org 0] ; TRDOS 386 PRG File 172 173 start: 174 ; DIRECT VGA MEMORY ACCESS 175 ;xor ebx, ebx 176 00000000 B705 mov bh, 5 ; Direct access/map to VGA memory (0A0000h) 177 ;mov eax, _video ; 1Fh 178 00000002 B01F mov al, 1Fh ; sys _video ; TRDOS 386 Video functions 179 00000004 CD40 int 40h ; TRDOS 386 system call 180 181 ; eax = 0A0000h 182 00000006 21C0 and eax, eax 183 00000008 7475 jz terminate ; error (eax = 0) 184 185 0000000A 89C7 mov edi, eax ; 0A0000h ; es = 0A000h ; VGA memory (frame buffer) address 186 187 0000000C B013 mov al,13h ; function 00h, mode 13h 188 ;int 10h ; bios video interrupt 189 0000000E CD31 int 31h ; TRDOS 386 - Video interrupt 190 191 ;[ initialize starfield variables ]------------------------------------------ 192 193 00000010 B1FF mov cl,NSTARS ; cx = number of stars to initialize 194 00000012 C605[88080000]01 mov byte [NSTARS*8+stars+8],1 ; set the begining random number seed 195 196 loop1: 197 00000019 6689CB mov bx,cx ; copy cx to bx for indexing 198 0000001C 66C1E303 shl bx,3 ; multiply bx by 8 (structure size) 199 00000020 6681C3[8800] add bx,stars ; add the start offset of stars to bx 200 201 00000025 66694308354E imul ax,word [ebx+8],4E35h ; multiply to get next random number 202 0000002B 668903 mov word [ebx],ax ; stars[cx].addr = ax 203 0000002E 66250F03 and ax,0000001100001111b ; mask off unwanted values 204 00000032 040E add al,14 ; make sure al < 30 & al > 14 205 00000034 66894302 mov word [ebx+2],ax ; stars[cx].col = ax 206 00000038 66C1E808 shr ax,8 ; shift hi byte to low byte 207 0000003C FEC0 inc al ; stars[cx].spd can't be zero 208 0000003E 66894304 mov word [ebx+4],ax ; stars[cx].spd = ax 209 00000042 E2D5 loop loop1 ; do this again for the next star 210 211 ;[ the main loop, holy shit! ]----------------------------------------------- 212 213 drawstars: 214 215 vend: 216 00000044 66BADA03 mov dx,03DAh ; vga status port for retrace 217 ;in al,dx ; al = vga status byte (03DAh) 218 ;mov ah,0 ; in (byte) 219 00000048 CD34 int 34h ; TRDOS 386 - IOCTL interrupt 220 0000004A 2408 and al,08h ; keep the vretrace status bit 221 0000004C 74F6 jz short vend ; not equal to 1?, check again 222 223 0000004E B1FF mov cl,NSTARS ; lets draw NSTARS to the screen 224 225 loop2: 226 00000050 6689CB mov bx,cx ; copy cx to bx for indexing again 227 00000053 66C1E303 shl bx,3 ; multiply bx by 8 (structure size) 228 00000057 6681C3[8800] add bx,stars ; add start offset of stars to bx 229 0000005C 668B3B mov di,word [ebx] ; di = stars.addr 230 0000005F 8827 mov [edi],ah ; erase star (ah = 0) 231 00000061 66037B04 add di,word [ebx+4] ; stars.addr = stars.addr + stars.spd 232 00000065 8A4302 mov al,byte [ebx+2] ; al = stars.col 233 00000068 8807 mov [edi],al ; draw new star to the screen 234 0000006A 66893B mov word [ebx],di ; save the updated star posistion 235 0000006D E2E1 loop loop2 ; erase/draw all NSTARS to the screen 236 237 ;in al,60h ; al = port 60h, keyboard 238 0000006F 66BA6000 mov dx,60h 239 00000073 B400 mov ah,0 ; in (byte) 240 00000075 CD34 int 34h ; TRDOS 386 - IOCTL interrupt 241 00000077 3C01 cmp al,1 ; escape key pressed? 242 00000079 75C9 jnz short drawstars ; was escape pressed, no do it again 243 244 0000007B B003 mov al,03h ; escape was pressed, lets quit 245 ;int 10h ; al = 03h text mode, int 10 video 246 0000007D CD31 int 31h ; TRDOS 386 - Video interrupt 247 248 terminate: 249 sys _exit ; INT 40h 250 <1> 251 <1> 252 <1> 253 <1> 254 <1> %if %0 >= 2 255 <1> mov ebx, %2 256 <1> %if %0 >= 3 257 <1> mov ecx, %3 258 <1> %if %0 = 4 259 <1> mov edx, %4 260 <1> %endif 261 <1> %endif 262 <1> %endif 263 0000007F B801000000 <1> mov eax, %1 264 <1> 265 00000084 CD40 <1> int 40h 266 here: 267 00000086 EBFE jmp short here 268 269 stars: ; start of starfield structure