1 ; **************************************************************************** 2 ; piano2.s (TRDOS 386, TRDOS v2.0 - sample binary file, 'piano2.prg') 3 ; ---------------------------------------------------------------------------- 4 ; PIANO2.PRG ! TEST program ! INT 34h (IOCTL functions) test ! 5 ; 6 ; 21/06/2016 7 ; 8 ; [ Last Modification: 22/06/2016 ] 9 ; 10 ; **************************************************************************** 11 12 ; 29/04/2016 13 ; TRDOS 386 system calls (temporary list!) 14 _ver equ 0 15 _exit equ 1 16 _fork equ 2 17 _read equ 3 18 _write equ 4 19 _open equ 5 20 _close equ 6 21 _wait equ 7 22 _creat equ 8 23 _link equ 9 24 _unlink equ 10 25 _exec equ 11 26 _chdir equ 12 27 _time equ 13 28 _mkdir equ 14 29 _chmod equ 15 30 _chown equ 16 31 _break equ 17 32 _stat equ 18 33 _seek equ 19 34 _tell equ 20 35 _mount equ 21 36 _umount equ 22 37 _setuid equ 23 38 _getuid equ 24 39 _stime equ 25 40 _quit equ 26 41 _intr equ 27 42 _fstat equ 28 43 _emt equ 29 44 _mdate equ 30 45 _stty equ 31 46 _gtty equ 32 47 _ilgins equ 33 48 _sleep equ 34 49 _msg equ 35 50 51 %macro sys 1-4 52 ; 29/04/2016 - TRDOS 386 (TRDOS v2.0) 53 ; 03/09/2015 54 ; 13/04/2015 55 ; Retro UNIX 386 v1 system call. 56 %if %0 >= 2 57 mov ebx, %2 58 %if %0 >= 3 59 mov ecx, %3 60 %if %0 = 4 61 mov edx, %4 62 %endif 63 %endif 64 %endif 65 mov eax, %1 66 ;int 30h 67 int 40h ; TRDOS 386 (TRDOS v2.0) 68 %endmacro 69 70 ; TRDOS 386 (and Retro UNIX 386 v1) system call format: 71 ; sys systemcall (eax) , , 72 73 [BITS 32] ; We need 32-bit intructions for protected mode 74 75 [ORG 0] 76 77 start: 78 00000000 E80E020000 call clrscr 79 00000005 E8EB010000 call toneon 80 start1: 81 0000000A E823000000 call show_panio 82 0000000F E868010000 call sound 83 00000014 E85D000000 call show_dot 84 00000019 B401 mov ah, 1 ; check keyboard buffer 85 0000001B CD32 int 32h ; TRDOS 386 Keyboard Interrupt 86 0000001D 74EB jz short start1 87 ; 88 0000001F E8E0010000 call toneoff 89 00000024 E8EA010000 call clrscr 90 91 terminate: 92 sys _exit ; INT 40h 92 <1> 92 <1> 92 <1> 92 <1> 92 <1> %if %0 >= 2 92 <1> mov ebx, %2 92 <1> %if %0 >= 3 92 <1> mov ecx, %3 92 <1> %if %0 = 4 92 <1> mov edx, %4 92 <1> %endif 92 <1> %endif 92 <1> %endif 92 00000029 B801000000 <1> mov eax, %1 92 <1> 92 0000002E CD40 <1> int 40h 93 here: 94 00000030 EBFE jmp short here 95 96 show_panio: 97 00000032 FE0D[47020000] dec byte [delay] 98 00000038 753B jnz short msg1 99 0000003A C605[47020000]40 mov byte [delay], 64 100 00000041 C605[48020000]04 mov byte [fig_r], 4 101 00000048 C605[49020000]00 mov byte [fig_c], 0 102 0000004F B909000000 mov ecx, 9 103 00000054 BE[4E020000] mov esi, msg 104 00000059 E800010000 call set_wp 105 0000005E E892000000 call bitmap_char 106 107 00000063 E8CB010000 call video_page_update 108 109 00000068 FE05[4A020000] inc byte [msgptr] 110 0000006E 8025[4A020000]1F and byte [msgptr], 011111b 111 msg1: 112 00000075 C3 retn 113 114 show_dot: 115 00000076 8B1D[D0020000] mov ebx, [counter] 116 0000007C 3B1D[CC020000] cmp ebx, [lastdot] 117 00000082 7470 je short dot1 118 119 00000084 8B1D[CC020000] mov ebx, [lastdot] 120 0000008A 8A83[B3020000] mov al, [ebx+melody] ; get code for nth of 121 00000090 FEC8 dec al 122 00000092 C0E003 shl al, 3 123 00000095 A2[49020000] mov [fig_c], al 124 0000009A C605[48020000]0E mov byte [fig_r], 14 125 126 000000A1 31C9 xor ecx, ecx 127 000000A3 FEC1 inc cl ; mov ecx, 1 128 000000A5 BE[59020000] mov esi, blnk 129 000000AA E8AF000000 call set_wp 130 000000AF E841000000 call bitmap_char 131 132 000000B4 E87A010000 call video_page_update 133 134 000000B9 BB[D0020000] mov ebx, counter 135 000000BE 891D[CC020000] mov [lastdot], ebx 136 000000C4 8A83[B3020000] mov al, [ebx+melody] ; get code for nth of 137 000000CA FEC8 dec al 138 000000CC C0E003 shl al, 3 139 000000CF A2[49020000] mov [fig_c], al 140 000000D4 C605[48020000]0E mov byte [fig_r], 14 141 142 000000DB B901000000 mov ecx, 1 143 000000E0 BE[58020000] mov esi, dot 144 000000E5 E874000000 call set_wp 145 000000EA E806000000 call bitmap_char 146 147 000000EF E83F010000 call video_page_update 148 dot1: 149 000000F4 C3 retn 150 151 bitmap_char: 152 each_character: 153 000000F5 51 push ecx 154 000000F6 0FB61E movzx ebx, byte [esi] ; BL is the character's ASCII code 155 000000F9 46 inc esi 156 000000FA 66C1E303 shl bx, 3 ; ebx = ebx * 8, because each 157 ; character's dot pattern occupys 8 bytes 158 000000FE 81C3[5A020000] add ebx, pattern 159 00000104 B208 mov dl, 8 ; ROW_LEN ;The dot pattern is 8 bytes (row) 160 each_row: 161 00000106 8A23 mov ah, [ebx] ; Get the byte which refers immediate row 162 00000108 43 inc ebx ; Pointer to next byte 163 00000109 B108 mov cl, 8 ; COL_LEN ;each row is 8 dots 164 each_dot: 165 0000010B D0C4 rol ah, 1 ; Bit 0 is the next bit we want 166 0000010D 88E0 mov al, ah 167 0000010F 2401 and al, 1 ; Mask other bits 168 00000111 F6D8 neg al ; If Bit 0 = 1 then AL = 0FFh 169 00000113 24DB and al, 0DBh ; If AL = 0FFh then AL = 0DBh else space 170 00000115 AA stosb ; Display AL = char 171 00000116 B006 mov al, 6 172 00000118 AA stosb ; Display AL = attribute 173 end_e_dot: 174 00000119 E2F0 loop each_dot 175 0000011B 57 push edi 176 0000011C 83EF02 sub edi, 2 177 0000011F FD std 178 00000120 B108 mov cl, 8 179 shadow: 180 00000122 66B80006 mov ax, 0600h 181 00000126 F366AF repe scasw 182 00000129 67E31C jcxz no_shadow 183 0000012C 83C704 add edi, 4 184 0000012F 66B8B205 mov ax, 05B2h 185 00000133 66AB stosw 186 00000135 83EF02 sub edi, 2 187 00000138 66B8DB06 mov ax, 06DBh 188 0000013C F366AF repe scasw 189 0000013F 7407 jz short no_shadow 190 00000141 FEC1 inc cl 191 00000143 83C702 add edi, 2 192 00000146 EBDA jmp shadow 193 no_shadow: 194 00000148 5F pop edi 195 00000149 81C790000000 add edi, 144 ; Pointer to next line on screen 196 0000014F FC cld 197 00000150 FECA dec dl 198 end_e_row: 199 00000152 75B2 jnz short each_row 200 00000154 81EFF0040000 sub edi, 1264 201 0000015A 59 pop ecx 202 end_e_char: 203 0000015B E298 loop each_character 204 0000015D C3 retn 205 206 set_wp: 207 0000015E B050 mov al, 80 ; number of columns * 2 208 00000160 F625[48020000] mul byte [fig_r] 209 00000166 0205[49020000] add al, [fig_c] 210 0000016C 80D400 adc ah, 0 211 0000016F 66D1E0 shl ax, 1 212 00000172 0FB7F8 movzx edi, ax 213 00000175 81C7[FC020000] add edi, video_buffer ; video page 0 214 0000017B C3 retn 215 216 sound: 217 0000017C 50 push eax 218 0000017D 53 push ebx 219 0000017E 51 push ecx 220 0000017F 52 push edx 221 00000180 56 push esi 222 00000181 57 push edi 223 00000182 8B35[D0020000] mov esi, [counter] ; initialize ptr to 224 ; melody/beat strings 225 ; check delay loop 226 00000188 BB[8A020000] mov ebx, beat ; get offset of beat 227 ; string 228 0000018D 0FB60C33 movzx ecx, byte [ebx+esi] ; get beat value for 229 ; note number ESI 230 231 00000191 8B1D[D4020000] mov ebx, [ticks] ; get timer tick count 232 00000197 01CB add ebx, ecx ; add beat count to 233 ; current tick count 234 00000199 B400 mov ah, 0 ; function to get 235 ; time-of-day count 236 0000019B CD35 int 35h ; TRDOS 386 Date&Time Interrupt 237 0000019D 39D9 cmp ecx, ebx ; cmp count with 238 ; end-of-note count 239 0000019F 7641 jbe short finish ; if not equal, continue 240 ; sound 241 000001A1 46 inc esi ; else, point to next 242 ; note 243 000001A2 FF05[D0020000] inc dword [counter] ; go get the next note 244 245 ;mov ah, 0 ; function to get 246 ; time-of-day count 247 000001A8 CD35 int 35h ; TRDOS 386 Date&Time Interrupt 248 249 000001AA 890D[D4020000] mov [ticks], ecx 250 251 000001B0 B401 mov ah, 1 ; out 252 000001B2 B0B6 mov al, 0B6h ; initialize channel 2 253 ; for mode 3 254 000001B4 66BA4300 mov dx, 43h ; port address/number 255 000001B8 CD34 int 34h ; TRDOS 386 IOCTL Interrupt 256 257 ; Look up a note, get it's frequeny, place in channel 2 258 next_note: 259 000001BA BB[B3020000] mov ebx, melody ; get offset of melody 260 ; string 261 000001BF 0FB60433 movzx eax, byte [ebx+esi] ; get code for nth of 262 ; the string 263 000001C3 3CFF cmp al, 0FFh ; is it FF? (end of 264 ; string marker) 265 000001C5 7422 je short no_more ; if so,jump to end of 266 ; routine 267 ; get the frequency 268 000001C7 BB[A3020000] mov ebx, frequency ; get offset of the 269 ; frequency table 270 000001CC FEC8 dec al ; EAX-1 so that counting 271 ; start from 0 272 000001CE D0E0 shl al, 1 ; double AX,since word- 273 ; length table 274 000001D0 89C7 mov edi, eax ; mov to EDI for 275 ; addressing 276 000001D2 668B0C3B mov cx, [ebx+edi] ; get the frequency 277 ; from the table 278 ; start the note playing 279 000001D6 B401 mov ah, 1 ; out 280 000001D8 88C8 mov al, cl ; prepare to send low 281 ; byte of frequency 282 ;mov dx, 42h ; send to latch 283 ; register (via I/O reg) 284 000001DA 664A dec dx 285 000001DC CD34 int 34h ; TRDOS 386 IOCTL Interrupt 286 287 000001DE 88E8 mov al, ch ; prepare high byte 288 ;mov dx, 42h ; send high byte 289 000001E0 CD34 int 34h ; TRDOS 386 IOCTL Interrupt 290 finish: 291 000001E2 5F pop edi 292 000001E3 5E pop esi 293 000001E4 5A pop edx 294 000001E5 59 pop ecx 295 000001E6 5B pop ebx 296 000001E7 58 pop eax 297 000001E8 C3 retn 298 299 no_more: 300 000001E9 C705[D0020000]0000- mov dword [counter], 0 300 000001F1 0000 301 000001F3 EBED jmp short finish 302 303 toneon: 304 ; Turn speaker and timer on 305 000001F5 B400 mov ah, 0 ; in 306 000001F7 66BA6100 mov dx, 61h ; get current status of Port B 307 000001FB CD34 int 34h ; TRDOS 386 IOCTL Interrupt 308 000001FD 0C03 or al, 3 ; enable the speaker and timer channel2 309 ;mov ah, 1 ; out 310 000001FF FEC4 inc ah ; replace the byte 311 00000201 CD34 int 34h ; TRDOS 386 IOCTL Interrupt 312 00000203 C3 retn 313 314 toneoff: 315 ; Turn off timer 2 316 00000204 B400 mov ah, 0 ; in 317 00000206 66BA6100 mov dx, 61h ; get the byte in Port_B 318 0000020A CD34 int 34h ; TRDOS 386 IOCTL Interrupt 319 0000020C 24FC and al, 0FCh ; turn off the speaker bits 320 ;mov ah, 1 ; out 321 0000020E FEC4 inc ah ; replace the byte in Port_B 322 00000210 CD34 int 34h ; TRDOS 386 IOCTL Interrupt 323 00000212 C3 retn 324 325 clrscr: 326 00000213 BF[FC020000] mov edi, video_buffer 327 00000218 B9D0070000 mov ecx, 80*25 328 0000021D 66B82007 mov ax, 0720h ; light gray char space (blank) 329 00000221 F366AB rep stosw 330 331 00000224 E80A000000 call video_page_update 332 333 00000229 6631D2 xor dx, dx ; column 0, row 0 334 335 ; DX = cursor position 336 0000022C B402 mov ah, 2 ; Set cursor position 337 0000022E 30FF xor bh, bh ; for video page 0 338 00000230 CD31 int 31h ; TRDOS 386 video interrupt 339 00000232 C3 retn 340 341 video_page_update: 342 ; copy video buffer content to video page 0 343 00000233 BB01000000 mov ebx, 1 ; BL = 1 = user to system 344 00000238 B200 mov dl, 0 ; video page 0 345 0000023A B9[FC020000] mov ecx, video_buffer 346 0000023F B81F000000 mov eax, 31 ; 'sysvideo' 347 00000244 CD40 int 40h ; TRDOS 386 system call 348 00000246 C3 retn 349 350 ; Data 351 352 00000247 01 delay: db 1 353 00000248 00 fig_r: db 0 354 00000249 00 fig_c: db 0 355 0000024A 00000000 msgptr: dd 0 356 0000024E 000102000102000102- msg: db 0,1,2,0,1,2,0,1,2,0 356 00000257 00 357 00000258 03 dot db 3 358 00000259 04 blnk db 4 359 0000025A FEFEFEFEFEFEFEFE pattern: db 0FEh, 0FEh, 0FEh, 0FEh, 0FEh, 0FEh, 0FEh, 0FEh 360 00000262 E0E0E0E0FEFEFEFE db 0E0h, 0E0h, 0E0h, 0E0h, 0FEh, 0FEh, 0FEh, 0FEh 361 0000026A 0E0E0E0EFEFEFEFE db 00Eh, 00Eh, 00Eh, 00Eh, 0FEh, 0FEh, 0FEh, 0FEh 362 00000272 1814121070906000 db 018h, 014h, 012h, 010h, 070h, 090h, 060h, 0000 363 0000027A 0000000000000000 db 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000 364 00000282 183C7EC3C37E3C18 db 018h, 03Ch, 07Eh, 0C3h, 0C3h, 07Eh, 03Ch, 018h 365 366 0000028A 06060C beat: db 6,6,12 ;duration of each 367 0000028D 06060C db 6,6,12 368 00000290 0606060606060C db 6,6,6,6,6,6,12 369 00000297 06060C db 6,6,12 370 0000029A 06060C db 6,6,12 371 0000029D 060606061800 db 6,6,6,6,24,0 372 ;note 373 frequency: 374 000002A3 E808EF071107AD06 dw 2280,2031,1809,1709 ;table of 375 000002AB F1054B05B7047304 dw 1521,1355,1207,1139 ;frequencies 376 377 melody: 378 000002B3 050303 db 5,3,3 ;,0FFH;frequency code 379 000002B6 040202 db 4,2,2 380 000002B9 01020304050505 db 1,2,3,4,5,5,5 381 000002C0 050303 db 5,3,3 382 000002C3 040202 db 4,2,2 383 000002C6 0103050501FF db 1,3,5,5,1,0FFh 384 ;of each note 385 000002CC 00000000 lastdot: dd 0 386 000002D0 00000000 counter: dd 0 387 000002D4 00000000 ticks: dd 0 388 389 000002D8 4572646F67616E2054- db 'Erdogan Tan - TRDOS 386 ' 389 000002E1 616E202D205452444F- 389 000002EA 532033383620 390 000002F0 32322F30362F323031- db '22/06/2016' 390 000002F9 36 391 000002FA 00 db 0 392 393 bss_start: 394 395 ABSOLUTE bss_start 396 397 000002FB alignb 2 398 399 video_buffer: 400 000002FC resb 4000 ; 80*25*2 401 402 ;bss_end: