GophHub - zajo/appler/src/EMULATE.ASM


Raw File

;  _____________________________________________
; |                                             |
; |  Project:   APPLER                          |
; |  File:      EMULATE.ASM                     |
; |  Compiler:  16-bit TASM (2.5)               |
; |                                             |
; |  Subject:   I/O Switches Emulation          |
; |                                             |
; |  Authors:   Alexander & Emil                |
; |_____________________________________________|

                include GLOBALS.INC
                include INTERFAC.INC

                ReadAllFreeSpace

Emulate         segment common
                assume  CS:Emulate,DS:Apple,ES:Video,SS:Data

                UseNextFreeSpace
AppleFlags      db      00110000b
                even
AppleSP         dw      StackPage*100h + 0FFh

SaveStack       dw      0
ResetFlag       db      0

C000            db      0
C050            db      0000b
C080            db      1000b

HGRcolor        db      07h
		even
Port3?4h        dw      3D4h
                CheckAddress

                UseNextFreeSpace
SetScrEntry     Proc    far                     ; Set Screen mode.
                mov     si,ax                   ; AL - mode.
                xor     al,1b
                mov     ah,C050
                ror     ax,1
                rol     ah,1
                mov     C050,ah
                mov     dx,50h
SetScrEntry10:  shr     si,1
                mov     bx,dx
                adc     bl,0
                shl     bx,1
                mov     di,offset SetScrEntry20
                jmp     SS:C0XXRead[bx]
SetScrEntry20:  add     dl,2
                cmp     dl,58h
                jb      SetScrEntry10
                ret
SetScrEntry     Endp
                CheckAddress

                UseNextFreeSpace
PowerON         Proc    far                     ; Initial Test entry point
                mov     ax,Apple
                mov     bx,Video
                mov     ds,ax
                mov     es,bx
                mov     al,0
                call    SetScrEntry
                jmp     RESET
PowerON         Endp
                CheckAddress

                UseNextFreeSpace
RESET           Proc    far                     ; Reset Pressed entry point
                xor     eax,eax
                push    ax
                popf
                mov     ax,Data
                mov     ss,ax
                mov     sp,CS:[SaveStack]
                call    SystemRESET
RESET_Wait:     sti
                test    CS:[ResetFlag],00000001b
                jnz     RESET_Wait

                mov     ax,Apple
                mov     bx,Video
                mov     ds,ax
                mov     es,bx
                xor     ax,ax
                mov     bx,ax
                mov     cx,ax
                mov     dx,ax
                mov     di,ax
                mov     bp,ax
                sahf
                mov     si,DS:[RESETvector]
                DoNext
RESET           Endp
                CheckAddress

                UseNextFreeSpace
ChangeTEXTcolor Proc    far
                Save    ax cx di es
                mov     di,ss
		mov     es,di
                mov     di,offset TEXTchars + 1
                mov     cx,40h
                mov     ah,al
                shl     al,4
		cld
TC_Loop1:       stosb
                inc     di
                loop    TC_Loop1
                or      al,10000000b
                mov     cx,40h
TC_Loop2:       stosb
                inc     di
                loop    TC_Loop2
                mov     cx,80h
		mov     al,ah
TC_Loop3:       stosb
                inc     di
                loop    TC_Loop3
                Restore ax cx di es
                ret
ChangeTEXTcolor Endp
                CheckAddress


;-------------- Keyboard emulation entries & subroutines -----------------------

                UseNextFreeSpace
C000r:          call    key_taken
                call    synchronize
                mov     al,C000
                mov     bl,ch
                jmp     di
C000w:          call    synchronize
                sahf
                DoNext
C010r:          call    synchronize
                and     byte ptr C000,01111111b
                call    GetBuffer
                mov     bl,ch
                jmp     di
C010w:          call    synchronize
                and     byte ptr C000,01111111b
                call    GetBuffer
		sahf
                DoNext

ResetKeyboard   Proc    far
                mov     C000,0
                call    ClearBuffer
                ret
ResetKeyboard   Endp
                CheckAddress

;-------------- Speaker emulation entries & subroutines ------------------------

                UseNextFreeSpace
C030r:          call    synchronize
                in      al,61h
                xor     al,00000010b
                out     61h,al
                mov     bl,ch
                jmp     di
C030w:          call    synchronize
                in      al,61h
                xor     al,00000010b
                out     61h,al
                sahf
                DoNext

C020r:          call    synchronize
                mov     al,cs:C020bit
                xor     al,80h
                mov     cs:C020bit,al
                push    dx
                mov     dx,378h
                out     dx,al
                pop     dx
                mov     bl,ch
                jmp     di
C020w:          call    synchronize
                mov     al,cs:C020bit
                xor     al,80h
                mov     cs:C020bit,al
                push    dx
                mov     dx,378h
                out     dx,al
                pop     dx
                sahf
                DoNext
C020bit         db      0

ResetSpeaker    Proc    far
                in      al,61h
                and     al,11111100b
                out     61h,al
                mov     cs:C020bit,0
                ret
ResetSpeaker    Endp
                CheckAddress

;-------------- Digital Outputs emulation entries & subroutines ----------------

                UseNextFreeSpace
C05Or:          call    synchronize
                mov     bl,al
                and     bx,111b
                mov     al,PPortBuffer
                and     al,DOmasks[bx]
                or      al,DOvalues[bx]
                mov     PPortBuffer,al
                mov     bx,dx
                mov     dx,PPortBase
                out     dx,al
                mov     dx,bx
                mov     bl,ch
                jmp     di
C05Ow:          call    synchronize
                mov     bl,al
                and     bx,111b
                mov     al,PPortBuffer
                and     al,DOmasks[bx]
                or      al,DOvalues[bx]
                mov     PPortBuffer,al
                mov     bx,dx
                mov     dx,PPortBase
                out     dx,al
                mov     dx,bx
                mov     bl,ch
                sahf
                DoNext

DOmasks         db      11111110b,11111110b,11111101b,11111101b
                db      11111011b,11111011b,11110111b,11110111b
DOvalues        db      0000b,0001b,0000b,0010b,0000b,0100b,0000b,1000b

ResetDigOutputs Proc    far
                mov     al,PPortBuffer
                and     al,11110000b
                mov     PPortBuffer,al
                mov     dx,PPortBase
                out     dx,al
                ret
ResetDigOutputs Endp

                even
PPortBase       dw      3BCh
PPortBuffer     db      00001111b               ; 0 - Inputs, 1 - Outputs
                CheckAddress

;-------------- Joystick emulation entries & subroutines -----------------------

                UseNextFreeSpace

C061r:          mov     al,cs:JoyButton1
                mov     bl,ch
                jmp     di

C062r:          mov     al,cs:JoyButton2
                mov     bl,ch
                jmp     di

JoyButton1      db      7Fh
JoyButton2      db      7Fh
joy_pos1        dw      0
joy_pos2        dw      0
JoyStick        db      0
JoyEnd          label   word
JoyEx           db      0
JoyEy           db      0
Joy_Table       dw      1400,0,2800,1400

C064r:          mov     ebx,eax
                sub     ebx,cs:C07X_eax
                shr     ebx,16
                cmp     bx,cs:joy_pos1
                mov     al,0FEh
                rcr     al,1
                xchg    al,cs:JoyEx
                or      al,cs:JoyEx
                mov     bl,ch
                jmp     di

C065r:          mov     ebx,eax
                sub     ebx,cs:C07X_eax
                shr     ebx,16
                cmp     bx,cs:joy_pos2
                mov     al,0FEh
                rcr     al,1
                xchg    al,cs:JoyEy
                or      al,cs:JoyEy
                mov     bl,ch
                jmp     di

                CheckAddress
                UseNextFreeSpace

C07Xr:          mov     cs:C07X_eax,eax
                xor     bx,bx
                mov     cs:JoyEnd,bx
                mov     bl,cs:JoyStick
                shl     bl,1
                and     bl,6
                mov     ax,cs:Joy_Table[bx]
                mov     cs:joy_pos1,ax
                mov     bl,cs:JoyStick
                shr     bl,1
                and     bl,6
                mov     ax,cs:Joy_Table[bx]
                mov     cs:joy_pos2,ax
                mov     al,0FFh
                mov     bl,ch
                jmp     di

C0612r:         mov     al,7Fh
                mov     bl,ch
                jmp     di

C0645r:         mov     al,0FFh
                mov     bl,ch
                jmp     di

C07X_eax        dd      0

C061w:
C062w:
C07Xw:          sahf
                DoNext

                CheckAddress

;-------------- N/A entries & subroutines --------------------------------------

                UseNextFreeSpace
C0NAr:          mov     bl,ch
                jmp     di
C0NAw:          sahf
                DoNext
                CheckAddress

;-------------- Synchronization Subroutines ------------- MacroSoft & IvoSoft---

                UseNextFreeSpace
; Entry:
;   EAH - 65C02 clocks sinse last call to synchronize
synchronize     proc    near
synchro_push_ax label   byte
                cli
                push    ax bx cx dx
                lahf
                push    ax
                mov     ebx,eax
                sub     eax,cs:old_eax
                mov     al,00000100b            ; 00000110b
                out     43h,al
                jmp     $+2
                shr     eax,16                  ; 10
                mul     cs:O75
                shr     eax,6                   ; 12
                mov     bx,ax                   ; 65C02 clocks in timer ticks
                in      al,40h
                jmp     $+2
                jmp     $+2
                jmp     $+2
                mov     ah,al
                in      al,40h
                jmp     $+2
                jmp     $+2
                jmp     $+2
                xchg    al,ah
                mov     cx,cs:old_timer
                sub     cx,ax                   ; cx-time passed since last call
                sub     bx,cx                   ; bx-time to wait
                jbe     synch_xit               ; don't wait
                sub     cx,bx
synch_loop:
                mov     cx,ax
                mov     al,00000100b
                cli
                out     43h,al
                jmp     $+2
                jmp     $+2
                jmp     $+2
                in      al,40h
                jmp     $+2
                jmp     $+2
                jmp     $+2
                mov     ah,al
                in      al,40h
                sti
                xchg    al,ah
                sub     cx,ax
                sub     bx,cx
                jnb     synch_loop
                cli
synch_xit:
                mov     cs:old_timer,ax
                mov     cs:old_eax,ebx
                mov     eax,ebx
                pop     ax
                sahf
                pop     dx cx bx ax
                sti
                ret
old_timer       dw      0
O75             dd      75
old_eax         dd      0
synchronize     endp
                CheckAddress

;-------------- Include peripheral devices emulation files ---------------------

                include Video.ASM
                include DRAM.INC
                include Floppy.INC
                include PhisFlop.INC

Emulate         ends

;-------------------------------------------------------------------------------

Peripher        segment public
                assume  CS:Peripher,DS:Nothing,ES:Nothing

OldTimer        dd      0

TimerINIT       Proc    near
                mov     ax,3508h
                int     21h
                mov     word ptr OldTimer,bx
                mov     word ptr OldTimer+2,es
                push    cs
                pop     ds
                mov     dx,offset TimerCntr
                mov     ax,2508h
                int     21h
                ret
TimerINIT       Endp

TimerTINI       Proc    near
                lds     dx,OldTimer
                mov     ax,2508h
                int     21h
                ret
TimerTINI       Endp

		even
Tcounters       dw      Tlen dup (0)
Tadrs           dd      Tlen dup (0)

TimerReq        Proc    far                     ; CX:DX-Proc address, AX-Count
                Save    bx
                pushf
                cli
                xor     bx,bx
TimerReq10:     cmp     word ptr Tadrs[BX],dx
                jne     TimerReq20
                cmp     word ptr Tadrs[BX]+2,cx
                je      TimerReq50
TimerReq20:     add     bx,4
                cmp     bx,Tlen*4
                jb      TimerReq10
                xor     bx,bx
TimerReq30:     cmp     Tcounters[BX],0
                je      TimerReq40
                add     bx,2
                cmp     bx,Tlen*2
                jb      TimerReq30
                jmp     TimerReqExit            ; ERROR: Tlen must be increased
TimerReq40:     shl     bx,1
                mov     word ptr Tadrs[BX],dx
                mov     word ptr Tadrs[BX]+2,cx
TimerReq50:     shr     bx,1
                mov     Tcounters[BX],ax
TimerReqExit:   popf
                Restore bx
                ret
TimerReq        Endp

TimerCntr       Proc    far
                Save    ax bx
                cli
                xor     ax,ax
                mov     bx,ax
TimerCntr10:    cmp     Tcounters[bx],0
                je      TimerCntr20
                inc     ax
                dec     Tcounters[bx]
                jnz     TimerCntr20
                SaveAll
                shl     bx,1
                call    Tadrs[bx]
                RestoreAll
TimerCntr20:    add     bx,2
                cmp     bx,Tlen*2
                jb      TimerCntr10
                or      ax,ax
comment         %
                mov     al,20h
                out     20h,al
                %
                jnz     TimerCntr30
comment         %
                in      al,21h
                or      al,00000001b
                out     21h,al
                %
TimerCntr30:    xchg    bp,sp
                xor     ax,ax
                xchg    ax,cs:TimerFlags
                or      [bp+8],ax
                xchg    sp,bp
                Restore ax bx
                jmp     cs:[OldTimer]
;               iret
TimerFlags      dw      0
TimerCntr       Endp



SystemINIT      Proc    far
                mov     al,00001100b
                mov     dx,3F2h
                out     dx,al
                mov     al,IRQmasks
                out     21h,al
                call    TimerINIT
                call    FloppyINIT
                call    PhisFloppyINIT
                ret
SystemINIT      Endp


SystemTINI      Proc    far
                call    PhisFloppyTINI
                call    FloppyTINI
                call    TimerTINI
                mov     al,0
                out     21h,al
                ret
SystemTINI      Endp


SystemRESET     Proc    far                     ; Registers state:
                call    ResetDRAM               ; SS -> Data
                call    ResetKeyboard           ; IF = 0
                call    ResetSpeaker            ; All others are unknown
                call    ResetDigOutputs         ; and may be modified.
                call    ResetVideo
                call    ResetFloppy
                call    ResetPhisFloppy
                ret
SystemRESET     Endp

Peripher        ends

;===============================================================================

Data            segment stack 'stack'
		even
C0xxRead        dw      10h dup ( C000r )
                dw      10h dup ( C010r )
                dw      10h dup ( C020r )               ; C020
                dw      10h dup ( C030r )
                dw      10h dup ( C0NAr )               ; C040
                dw      C050r, C051r
                dw      C052r, C053r
                dw      C054r, C055r
                dw      C056r, C057r
                dw      8 dup ( C05Or )
                dw      C0NAr,C0612r,C0612r,C0NAr       ; C060
                dw      C0645r,C0645r
                dw      2 dup ( C0NAr )
                dw      4 dup ( C0NAr )
                dw      4 dup ( C0NAr )
                dw      10h dup ( C07Xr )               ; C070
                dw      10h dup ( C08Xr )
                dw      10h dup ( C0NAr )               ; C090
                dw      10h dup ( C0NAr )               ; C0A0
                dw      10h dup ( C0NAr )               ; C0B0
                dw      10h dup ( C0NAr )               ; C0C0
                dw      10h dup ( C0NAr )               ; C0D0
                dw      C0E0r,C0E1r,C0E2r,C0E3r,C0E4r,C0E5r,C0E6r,C0E7r
                dw      C0E8r,C0E9r,C0EAr,C0EBr,C0ECr,C0EDr,C0EEr,C0EFr
                dw      10h dup ( C0NAr )               ; C0F0

C0xxWrite       dw      10h dup ( C000w )
                dw      10h dup ( C010w )
                dw      10h dup ( C020w )               ; C020
                dw      10h dup ( C030w )
                dw      10h dup ( C0NAw )               ; C040
                dw      C050w, C051w                    ; C050
                dw      C052w, C053w
                dw      C054w, C055w
                dw      C056w, C057w
                dw      8 dup ( C05Ow )
                dw      C0NAw,C061w,C062w,C0NAw         ; C060
                dw      4 dup ( C0NAw )
                dw      4 dup ( C0NAw )
                dw      4 dup ( C0NAw )
                dw      10h dup ( C07Xw )               ; C070
                dw      10h dup ( C08Xw )               ; C080
                dw      10h dup ( C0NAw )               ; C090
                dw      10h dup ( C0NAw )               ; C0A0
                dw      10h dup ( C0NAw )               ; C0B0
                dw      10h dup ( C0NAw )               ; C0C0
                dw      10h dup ( C0NAw )               ; C0D0
                dw      C0E0w,C0E1w,C0E2w,C0E3w,C0E4w,C0E5w,C0E6w,C0E7w
                dw      C0E8w,C0E9w,C0EAw,C0EBw,C0ECw,C0EDw,C0EEw,C0EFw
                dw      10h dup ( C0NAw )               ; C0F0

Data            ends

                End

Generated by GNU Enscript 1.6.6, and GophHub 1.3.