1 ; _____________________________________________ 2 ; | | 3 ; | Project: APPLER | 4 ; | File: EMULATE.ASM | 5 ; | Compiler: 16-bit TASM (2.5) | 6 ; | | 7 ; | Subject: I/O Switches Emulation | 8 ; | | 9 ; | Authors: Alexander & Emil | 10 ; |_____________________________________________| 11 12 include GLOBALS.INC 13 include INTERFAC.INC 14 15 ReadAllFreeSpace 16 17 Emulate segment common 18 assume CS:Emulate,DS:Apple,ES:Video,SS:Data 19 20 UseNextFreeSpace 21 AppleFlags db 00110000b 22 even 23 AppleSP dw StackPage*100h + 0FFh 24 25 SaveStack dw 0 26 ResetFlag db 0 27 28 C000 db 0 29 C050 db 0000b 30 C080 db 1000b 31 32 HGRcolor db 07h 33 even 34 Port3?4h dw 3D4h 35 CheckAddress 36 37 UseNextFreeSpace 38 SetScrEntry Proc far ; Set Screen mode. 39 mov si,ax ; AL - mode. 40 xor al,1b 41 mov ah,C050 42 ror ax,1 43 rol ah,1 44 mov C050,ah 45 mov dx,50h 46 SetScrEntry10: shr si,1 47 mov bx,dx 48 adc bl,0 49 shl bx,1 50 mov di,offset SetScrEntry20 51 jmp SS:C0XXRead[bx] 52 SetScrEntry20: add dl,2 53 cmp dl,58h 54 jb SetScrEntry10 55 ret 56 SetScrEntry Endp 57 CheckAddress 58 59 UseNextFreeSpace 60 PowerON Proc far ; Initial Test entry point 61 mov ax,Apple 62 mov bx,Video 63 mov ds,ax 64 mov es,bx 65 mov al,0 66 call SetScrEntry 67 jmp RESET 68 PowerON Endp 69 CheckAddress 70 71 UseNextFreeSpace 72 RESET Proc far ; Reset Pressed entry point 73 xor eax,eax 74 push ax 75 popf 76 mov ax,Data 77 mov ss,ax 78 mov sp,CS:[SaveStack] 79 call SystemRESET 80 RESET_Wait: sti 81 test CS:[ResetFlag],00000001b 82 jnz RESET_Wait 83 84 mov ax,Apple 85 mov bx,Video 86 mov ds,ax 87 mov es,bx 88 xor ax,ax 89 mov bx,ax 90 mov cx,ax 91 mov dx,ax 92 mov di,ax 93 mov bp,ax 94 sahf 95 mov si,DS:[RESETvector] 96 DoNext 97 RESET Endp 98 CheckAddress 99 100 UseNextFreeSpace 101 ChangeTEXTcolor Proc far 102 Save ax cx di es 103 mov di,ss 104 mov es,di 105 mov di,offset TEXTchars + 1 106 mov cx,40h 107 mov ah,al 108 shl al,4 109 cld 110 TC_Loop1: stosb 111 inc di 112 loop TC_Loop1 113 or al,10000000b 114 mov cx,40h 115 TC_Loop2: stosb 116 inc di 117 loop TC_Loop2 118 mov cx,80h 119 mov al,ah 120 TC_Loop3: stosb 121 inc di 122 loop TC_Loop3 123 Restore ax cx di es 124 ret 125 ChangeTEXTcolor Endp 126 CheckAddress 127 128 129 ;-------------- Keyboard emulation entries & subroutines ----------------------- 130 131 UseNextFreeSpace 132 C000r: call key_taken 133 call synchronize 134 mov al,C000 135 mov bl,ch 136 jmp di 137 C000w: call synchronize 138 sahf 139 DoNext 140 C010r: call synchronize 141 and byte ptr C000,01111111b 142 call GetBuffer 143 mov bl,ch 144 jmp di 145 C010w: call synchronize 146 and byte ptr C000,01111111b 147 call GetBuffer 148 sahf 149 DoNext 150 151 ResetKeyboard Proc far 152 mov C000,0 153 call ClearBuffer 154 ret 155 ResetKeyboard Endp 156 CheckAddress 157 158 ;-------------- Speaker emulation entries & subroutines ------------------------ 159 160 UseNextFreeSpace 161 C030r: call synchronize 162 in al,61h 163 xor al,00000010b 164 out 61h,al 165 mov bl,ch 166 jmp di 167 C030w: call synchronize 168 in al,61h 169 xor al,00000010b 170 out 61h,al 171 sahf 172 DoNext 173 174 C020r: call synchronize 175 mov al,cs:C020bit 176 xor al,80h 177 mov cs:C020bit,al 178 push dx 179 mov dx,378h 180 out dx,al 181 pop dx 182 mov bl,ch 183 jmp di 184 C020w: call synchronize 185 mov al,cs:C020bit 186 xor al,80h 187 mov cs:C020bit,al 188 push dx 189 mov dx,378h 190 out dx,al 191 pop dx 192 sahf 193 DoNext 194 C020bit db 0 195 196 ResetSpeaker Proc far 197 in al,61h 198 and al,11111100b 199 out 61h,al 200 mov cs:C020bit,0 201 ret 202 ResetSpeaker Endp 203 CheckAddress 204 205 ;-------------- Digital Outputs emulation entries & subroutines ---------------- 206 207 UseNextFreeSpace 208 C05Or: call synchronize 209 mov bl,al 210 and bx,111b 211 mov al,PPortBuffer 212 and al,DOmasks[bx] 213 or al,DOvalues[bx] 214 mov PPortBuffer,al 215 mov bx,dx 216 mov dx,PPortBase 217 out dx,al 218 mov dx,bx 219 mov bl,ch 220 jmp di 221 C05Ow: call synchronize 222 mov bl,al 223 and bx,111b 224 mov al,PPortBuffer 225 and al,DOmasks[bx] 226 or al,DOvalues[bx] 227 mov PPortBuffer,al 228 mov bx,dx 229 mov dx,PPortBase 230 out dx,al 231 mov dx,bx 232 mov bl,ch 233 sahf 234 DoNext 235 236 DOmasks db 11111110b,11111110b,11111101b,11111101b 237 db 11111011b,11111011b,11110111b,11110111b 238 DOvalues db 0000b,0001b,0000b,0010b,0000b,0100b,0000b,1000b 239 240 ResetDigOutputs Proc far 241 mov al,PPortBuffer 242 and al,11110000b 243 mov PPortBuffer,al 244 mov dx,PPortBase 245 out dx,al 246 ret 247 ResetDigOutputs Endp 248 249 even 250 PPortBase dw 3BCh 251 PPortBuffer db 00001111b ; 0 - Inputs, 1 - Outputs 252 CheckAddress 253 254 ;-------------- Joystick emulation entries & subroutines ----------------------- 255 256 UseNextFreeSpace 257 258 C061r: mov al,cs:JoyButton1 259 mov bl,ch 260 jmp di 261 262 C062r: mov al,cs:JoyButton2 263 mov bl,ch 264 jmp di 265 266 JoyButton1 db 7Fh 267 JoyButton2 db 7Fh 268 joy_pos1 dw 0 269 joy_pos2 dw 0 270 JoyStick db 0 271 JoyEnd label word 272 JoyEx db 0 273 JoyEy db 0 274 Joy_Table dw 1400,0,2800,1400 275 276 C064r: mov ebx,eax 277 sub ebx,cs:C07X_eax 278 shr ebx,16 279 cmp bx,cs:joy_pos1 280 mov al,0FEh 281 rcr al,1 282 xchg al,cs:JoyEx 283 or al,cs:JoyEx 284 mov bl,ch 285 jmp di 286 287 C065r: mov ebx,eax 288 sub ebx,cs:C07X_eax 289 shr ebx,16 290 cmp bx,cs:joy_pos2 291 mov al,0FEh 292 rcr al,1 293 xchg al,cs:JoyEy 294 or al,cs:JoyEy 295 mov bl,ch 296 jmp di 297 298 CheckAddress 299 UseNextFreeSpace 300 301 C07Xr: mov cs:C07X_eax,eax 302 xor bx,bx 303 mov cs:JoyEnd,bx 304 mov bl,cs:JoyStick 305 shl bl,1 306 and bl,6 307 mov ax,cs:Joy_Table[bx] 308 mov cs:joy_pos1,ax 309 mov bl,cs:JoyStick 310 shr bl,1 311 and bl,6 312 mov ax,cs:Joy_Table[bx] 313 mov cs:joy_pos2,ax 314 mov al,0FFh 315 mov bl,ch 316 jmp di 317 318 C0612r: mov al,7Fh 319 mov bl,ch 320 jmp di 321 322 C0645r: mov al,0FFh 323 mov bl,ch 324 jmp di 325 326 C07X_eax dd 0 327 328 C061w: 329 C062w: 330 C07Xw: sahf 331 DoNext 332 333 CheckAddress 334 335 ;-------------- N/A entries & subroutines -------------------------------------- 336 337 UseNextFreeSpace 338 C0NAr: mov bl,ch 339 jmp di 340 C0NAw: sahf 341 DoNext 342 CheckAddress 343 344 ;-------------- Synchronization Subroutines ------------- MacroSoft & IvoSoft--- 345 346 UseNextFreeSpace 347 ; Entry: 348 ; EAH - 65C02 clocks sinse last call to synchronize 349 synchronize proc near 350 synchro_push_ax label byte 351 cli 352 push ax bx cx dx 353 lahf 354 push ax 355 mov ebx,eax 356 sub eax,cs:old_eax 357 mov al,00000100b ; 00000110b 358 out 43h,al 359 jmp $+2 360 shr eax,16 ; 10 361 mul cs:O75 362 shr eax,6 ; 12 363 mov bx,ax ; 65C02 clocks in timer ticks 364 in al,40h 365 jmp $+2 366 jmp $+2 367 jmp $+2 368 mov ah,al 369 in al,40h 370 jmp $+2 371 jmp $+2 372 jmp $+2 373 xchg al,ah 374 mov cx,cs:old_timer 375 sub cx,ax ; cx-time passed since last call 376 sub bx,cx ; bx-time to wait 377 jbe synch_xit ; don't wait 378 sub cx,bx 379 synch_loop: 380 mov cx,ax 381 mov al,00000100b 382 cli 383 out 43h,al 384 jmp $+2 385 jmp $+2 386 jmp $+2 387 in al,40h 388 jmp $+2 389 jmp $+2 390 jmp $+2 391 mov ah,al 392 in al,40h 393 sti 394 xchg al,ah 395 sub cx,ax 396 sub bx,cx 397 jnb synch_loop 398 cli 399 synch_xit: 400 mov cs:old_timer,ax 401 mov cs:old_eax,ebx 402 mov eax,ebx 403 pop ax 404 sahf 405 pop dx cx bx ax 406 sti 407 ret 408 old_timer dw 0 409 O75 dd 75 410 old_eax dd 0 411 synchronize endp 412 CheckAddress 413 414 ;-------------- Include peripheral devices emulation files --------------------- 415 416 include Video.ASM 417 include DRAM.INC 418 include Floppy.INC 419 include PhisFlop.INC 420 421 Emulate ends 422 423 ;------------------------------------------------------------------------------- 424 425 Peripher segment public 426 assume CS:Peripher,DS:Nothing,ES:Nothing 427 428 OldTimer dd 0 429 430 TimerINIT Proc near 431 mov ax,3508h 432 int 21h 433 mov word ptr OldTimer,bx 434 mov word ptr OldTimer+2,es 435 push cs 436 pop ds 437 mov dx,offset TimerCntr 438 mov ax,2508h 439 int 21h 440 ret 441 TimerINIT Endp 442 443 TimerTINI Proc near 444 lds dx,OldTimer 445 mov ax,2508h 446 int 21h 447 ret 448 TimerTINI Endp 449 450 even 451 Tcounters dw Tlen dup (0) 452 Tadrs dd Tlen dup (0) 453 454 TimerReq Proc far ; CX:DX-Proc address, AX-Count 455 Save bx 456 pushf 457 cli 458 xor bx,bx 459 TimerReq10: cmp word ptr Tadrs[BX],dx 460 jne TimerReq20 461 cmp word ptr Tadrs[BX]+2,cx 462 je TimerReq50 463 TimerReq20: add bx,4 464 cmp bx,Tlen*4 465 jb TimerReq10 466 xor bx,bx 467 TimerReq30: cmp Tcounters[BX],0 468 je TimerReq40 469 add bx,2 470 cmp bx,Tlen*2 471 jb TimerReq30 472 jmp TimerReqExit ; ERROR: Tlen must be increased 473 TimerReq40: shl bx,1 474 mov word ptr Tadrs[BX],dx 475 mov word ptr Tadrs[BX]+2,cx 476 TimerReq50: shr bx,1 477 mov Tcounters[BX],ax 478 TimerReqExit: popf 479 Restore bx 480 ret 481 TimerReq Endp 482 483 TimerCntr Proc far 484 Save ax bx 485 cli 486 xor ax,ax 487 mov bx,ax 488 TimerCntr10: cmp Tcounters[bx],0 489 je TimerCntr20 490 inc ax 491 dec Tcounters[bx] 492 jnz TimerCntr20 493 SaveAll 494 shl bx,1 495 call Tadrs[bx] 496 RestoreAll 497 TimerCntr20: add bx,2 498 cmp bx,Tlen*2 499 jb TimerCntr10 500 or ax,ax 501 comment % 502 mov al,20h 503 out 20h,al 504 % 505 jnz TimerCntr30 506 comment % 507 in al,21h 508 or al,00000001b 509 out 21h,al 510 % 511 TimerCntr30: xchg bp,sp 512 xor ax,ax 513 xchg ax,cs:TimerFlags 514 or [bp+8],ax 515 xchg sp,bp 516 Restore ax bx 517 jmp cs:[OldTimer] 518 ; iret 519 TimerFlags dw 0 520 TimerCntr Endp 521 522 523 524 SystemINIT Proc far 525 mov al,00001100b 526 mov dx,3F2h 527 out dx,al 528 mov al,IRQmasks 529 out 21h,al 530 call TimerINIT 531 call FloppyINIT 532 call PhisFloppyINIT 533 ret 534 SystemINIT Endp 535 536 537 SystemTINI Proc far 538 call PhisFloppyTINI 539 call FloppyTINI 540 call TimerTINI 541 mov al,0 542 out 21h,al 543 ret 544 SystemTINI Endp 545 546 547 SystemRESET Proc far ; Registers state: 548 call ResetDRAM ; SS -> Data 549 call ResetKeyboard ; IF = 0 550 call ResetSpeaker ; All others are unknown 551 call ResetDigOutputs ; and may be modified. 552 call ResetVideo 553 call ResetFloppy 554 call ResetPhisFloppy 555 ret 556 SystemRESET Endp 557 558 Peripher ends 559 560 ;=============================================================================== 561 562 Data segment stack 'stack' 563 even 564 C0xxRead dw 10h dup ( C000r ) 565 dw 10h dup ( C010r ) 566 dw 10h dup ( C020r ) ; C020 567 dw 10h dup ( C030r ) 568 dw 10h dup ( C0NAr ) ; C040 569 dw C050r, C051r 570 dw C052r, C053r 571 dw C054r, C055r 572 dw C056r, C057r 573 dw 8 dup ( C05Or ) 574 dw C0NAr,C0612r,C0612r,C0NAr ; C060 575 dw C0645r,C0645r 576 dw 2 dup ( C0NAr ) 577 dw 4 dup ( C0NAr ) 578 dw 4 dup ( C0NAr ) 579 dw 10h dup ( C07Xr ) ; C070 580 dw 10h dup ( C08Xr ) 581 dw 10h dup ( C0NAr ) ; C090 582 dw 10h dup ( C0NAr ) ; C0A0 583 dw 10h dup ( C0NAr ) ; C0B0 584 dw 10h dup ( C0NAr ) ; C0C0 585 dw 10h dup ( C0NAr ) ; C0D0 586 dw C0E0r,C0E1r,C0E2r,C0E3r,C0E4r,C0E5r,C0E6r,C0E7r 587 dw C0E8r,C0E9r,C0EAr,C0EBr,C0ECr,C0EDr,C0EEr,C0EFr 588 dw 10h dup ( C0NAr ) ; C0F0 589 590 C0xxWrite dw 10h dup ( C000w ) 591 dw 10h dup ( C010w ) 592 dw 10h dup ( C020w ) ; C020 593 dw 10h dup ( C030w ) 594 dw 10h dup ( C0NAw ) ; C040 595 dw C050w, C051w ; C050 596 dw C052w, C053w 597 dw C054w, C055w 598 dw C056w, C057w 599 dw 8 dup ( C05Ow ) 600 dw C0NAw,C061w,C062w,C0NAw ; C060 601 dw 4 dup ( C0NAw ) 602 dw 4 dup ( C0NAw ) 603 dw 4 dup ( C0NAw ) 604 dw 10h dup ( C07Xw ) ; C070 605 dw 10h dup ( C08Xw ) ; C080 606 dw 10h dup ( C0NAw ) ; C090 607 dw 10h dup ( C0NAw ) ; C0A0 608 dw 10h dup ( C0NAw ) ; C0B0 609 dw 10h dup ( C0NAw ) ; C0C0 610 dw 10h dup ( C0NAw ) ; C0D0 611 dw C0E0w,C0E1w,C0E2w,C0E3w,C0E4w,C0E5w,C0E6w,C0E7w 612 dw C0E8w,C0E9w,C0EAw,C0EBw,C0ECw,C0EDw,C0EEw,C0EFw 613 dw 10h dup ( C0NAw ) ; C0F0 614 615 Data ends 616 617 End