; ---------------------------------------------------------------------------
New0001:    Mov   Bl,[1]
            Xor   Bl,[Last1]
            And   Bl,7
            Je    @@5
            Push  Ax
            Push  Bx
            Push  Cx
            Push  Dx
            Push  Bp
            Mov   Bp,2000h
            Test  Bl,1
            Jne   @@jx1
            Jmp   @@2
@@jx1:
; ------------------------------------- A000-BFFF
            Mov   Cx,2000h/4
            Mov   Di,[Swapseg]
            Sub   Di,0A000h/10h
            Mov   Es,Di
            Mov   Di,0A000h
            Test  [Last1],1
            Je    @@1a
                                       ; Map A-Ram in
Align 10h
@@1b:       Mov   Eax,[Es:Di]
            Mov   [Di],Eax
            Mov   Eax,[Es:Di+Bp]
            Mov   [Gs:Di],Eax
            Add   Di,4
            Dec   Cx
            Jne   @@1b
            Mov   [Aramdirect],Ds
            Mov   [Aramlayout],Gs
            Jmp   @@2

@@1a:       Mov   Ax,[Aromseg]           ; Map A-Ram out and A-Rom in
            Sub   Ax,0A000h/10h
            Mov   Fs,Ax
            Mov   Edx,01010101h*Typ_Arom
Align 10h
@@1c:       Mov   Eax,[Fs:Di]
            Xchg  Eax,[Di]
            Mov   [Es:Di],Eax
            Mov   Eax,[Gs:Di]
            Mov   [Es:Di+Bp],Eax
            Mov   [Gs:Di],Edx
            Add   Di,4
            Dec   Cx
            Jne   @@1c
            Mov   [Aramdirect],Es
            Mov   Ax,Es
            Add   Ax,200h
            Mov   [Aramlayout],Ax

; ------------------------------------- E000-FFFF
@@2:        Test  Bl,2
            Je    @@3

            Mov   Di,[Swapseg]
            Sub   Di,(0E000h-4000h)/10h
            Mov   Es,Di
            Add   Di,2000h/10h
            Mov   Fs,Di
            Mov   Di,0E000h
            ;Mov   Cx,2000h/4
            Test  [Last1],2
            Je    @@2a
                                       ; Map E-Ram in
Align 10h
@@2b:       Mov   Eax,[Es:Di]
            Mov   [Di],Eax
            Mov   Eax,[Fs:Di]
            Mov   [Gs:Di],Eax
            Add   Di,4
            ;Dec   Cx
            Jne   @@2b
            Mov   [Eramdirect],Ds
            Mov   [Eramlayout],Gs
            Jmp   @@3

@@2a:       Mov   Ax,Fs                ; Map E-Ram out and E-Rom in
            Mov   Es,Ax
            Mov   Ax,[Eromseg]
            Sub   Ax,0E000h/10h
            Mov   Fs,Ax
            Mov   Edx,01010101h*Typ_Erom
Align 10h
@@2c:       Mov   Eax,[Fs:Di]
            Xchg  Eax,[Di]
            Mov   [Es:Di-2000h],Eax
            Mov   Eax,[Gs:Di]
            Mov   [Es:Di],Eax
            Mov   [Gs:Di],Edx
            Add   Di,4
            ;Dec   Cx
            Jne   @@2c
            Mov   [Eramlayout],Es
            Mov   Ax,Es
            Sub   Ax,200h
            Mov   [Eramdirect],Ax

; ------------------------------------- D000-DFFF
@@3:        Mov   Bl,[1]
            And   Bl,7
            Mov   Al,[Dmap0001+Bx]
            Mov   Bl,[Last1]
            And   Bl,7
            Mov   Ah,[Dmap0001+Bx]
            Cmp   Al,Ah
            Je    @@4

            Push  Ax
            Mov   Cx,1000h/4           
            Mov   Di,0D000h
            Cmp   Ah,1
            Jne   @@3a
            Mov   Ax,[Swapseg]         ; Map D-Ram out
            Sub   Ax,(0D000h-8000h)/10h
            Mov   Es,Ax
Align 10h
@@3b:       Mov   Eax,[Di]
            Mov   [Es:Di],Eax
            Mov   Eax,[Gs:Di]
            Mov   [Es:Di+Bp],Eax
            Add   Di,4
            Dec   Cx
            Jne   @@3b
            Mov   [Dramdirect],Es
            Mov   Ax,Es
            Add   Ax,200h
            Mov   [Dramlayout],Ax
            Jmp   @@3c

@@3a:       Cmp   Ah,2
            Jne   @@3c
            Mov   Ax,[Swapseg]         ; Map IO out
            Sub   Ax,(0D000h-9000h)/10h
            Mov   Es,Ax
Align 10h
@@3d:       Mov   Eax,[Di]
            Mov   [Es:Di],Eax
            Add   Di,4
            Dec   Cx
            Jne   @@3d
            Mov   [Iodirect],Es

@@3c:       Pop   Ax
            Mov   Cx,1000h/4
            Mov   Di,0D000h
            Cmp   Al,1
            Jb    @@3e
            Je    @@3f

            Mov   Ax,[Swapseg]         ; Map IO in
            Sub   Ax,(0D000h-9000h)/10h
            Mov   Es,Ax
            Mov   Edx,01010101h*Typ_Norm
            Mov   [Iodirect],Ds
Align 10h
@@3i:       Mov   Eax,[Es:Di]
            Mov   [Di],Eax
            Mov   [Gs:Di],Edx
            Add   Di,4
            Dec   Cx
            Jne   @@3i
            Mov   Eax,01010101h*Typ_Video2
            Mov   Di,0D800h
            Mov   Cx,1000d/4
Align 10h
@@3i2:      Mov   [Gs:Di],Eax
            Add   Di,4
            Dec   Cx
            Jne   @@3i2

            Mov   Cx,Ds
            Mov   Ax,Gs
            Mov   Ds,Ax
            Mov   Eax,01010101h*Typ_Cia1
            Mov   Di,0DC00h
            Rept  10h/4
            Mov   [Di],Eax
            Add   Di,4
            Endm
            Mov   Eax,01010101h*Typ_Cia2
            Mov   Di,0DD00h
            Rept  10h/4
            Mov   [Di],Eax
            Add   Di,4
            Endm
            Mov   Eax,01010101h*Typ_Sid
            Mov   Di,0D400h
            Rept  20h/4
            Mov   [Di],Eax
            Add   Di,4
            Endm
            Mov   Eax,01010101h*Typ_Vic
            Mov   Di,0D000h
            Rept  30h/4
            Mov   [Di],Eax
            Add   Di,4
            Endm
            Mov   Ds,Cx
            Jmp   @@4

@@3f:       Mov   Ax,[Swapseg]         ; Map D-Ram in
            Sub   Ax,(0D000h-8000h)/10h
            Mov   Es,Ax
            Mov   [Dramdirect],Ds
            Mov   [Dramlayout],Gs
Align 10h
@@3h:       Mov   Eax,[Es:Di]
            Mov   [Di],Eax
            Mov   Eax,[Es:Di+Bp]
            Mov   [Gs:Di],Eax
            Add   Di,4
            Dec   Cx
            Jne   @@3h
            Jmp   @@4
@@3e:       Mov   Es,[Dromdirect]      ; Map D-Rom in
            Mov   Edx,01010101h*Typ_Drom
Align 10h
@@3g:       Mov   Eax,[Es:Di]
            Mov   [Di],Eax
            Mov   [Gs:Di],Edx
            Add   Di,4
            Dec   Cx
            Jne   @@3g

@@4:        Pop   Bp
            Pop   Dx
            Pop   Cx
            Pop   Bx
            Pop   Ax
            Mov   Fs,[Iodirect]
            Call  Videoremap
@@5:        Mov   Bl,[1]
            Mov   [Last1],Bl
            Ret
; ---------------------------------------------------------------------------
If Debug
Align 10h
Store:
            Mov   Bl,Al
            Mov   Al,6
            Int   80h
            Mov   Al,Bl
            Mov   Bl,[Gs:Di]
            Jmp   [St_Table+Bx]
Endif
; ---------------------------------------------------------------------------
Align 10h
St_Arom:    Mov   Es,[Aramdirect]
            Mov   [Es:Di],Al
            Jmp   Next
St_Drom:    Mov   Es,[Dramdirect]
            Mov   [Es:Di],Al
            Jmp   Next
St_Erom:    Mov   Es,[Eramdirect]
            Mov   [Es:Di],Al
            Jmp   Next
St_0001:    Mov   Bl,[0000h]
            And   Al,Bl
            Not   Bl
            And   Bl,[Di]
            Or    Al,Bl
            Mov   [Di],Al
            Call  New0001
            Jmp   Next
; ---------------------------------------------------------------------------
Align 10h
Irqjump:    Jmp   Irq
Align 4
Nmijump:    Jmp   Nmi
Align 4
Resetjump:  Jmp   Reset
Align 4
Haltjump:   Jmp   Halt
Align 4
Refreshjump:Jmp   Refresher
Align 4
Spritejump: Jmp   Refreshsprite

Nextpatch    = 1C8Ah                                   ; Mov   Bl,[Reg_Pc]
Irqpatch     = (100h-(Next+2-Irqjump)) Shl 8+0EBh      ; Jmp   IrqJump
Nmipatch     = (100h-(Next+2-Nmijump)) Shl 8+0EBh      ; Jmp   NmiJump
Resetpatch   = (100h-(Next+2-Resetjump)) Shl 8+0EBh    ; Jmp   ResetJump
Haltpatch    = (100h-(Next+2-Haltjump)) Shl 8+0EBh     ; Jmp   HaltJump
Refreshpatch = (100h-(Next+2-Refreshjump)) Shl 8+0EBh  ; Jmp   RefreshJump
Spritepatch  = (100h-(Next+2-Spritejump)) Shl 8+0EBh   ; Jmp   SpriteJump
; ---------------------------------------------------------------------------
Align 10h
            Db    14 Dup (90h)
St_Norm:    Mov   [Di],Al
; ---------------------------------------------------------------------------
Align 10h
Next:       Mov   Bl,[Reg_Pc]

If Debug Eq 2
            Push  Ds Es Di Cx
            Push  Si
            Mov   Cx,Cs
            Mov   Ds,Cx
            Mov   Es,Cx
            Lea   Si,[Sipath+2]
            Lea   Di,[Sipath]
            Cld
            Mov   Cx,50-1
            Rep   Movsw
            Pop   Si
            Mov   [Es:Di],Si
            Pop   Cx Di Es Ds
Endif

If Debug Eq 3
            Mov   Di,Fs
            Cmp   Di,[Iodirect]
            Jne   @@2
            Cmp   Bh,0
            Jne   @@2
            Cmp   Reg_C,0
            Je    @@3
            Cmp   Reg_C,-1
            Jne   @@2
@@3:        Call  Calcstatus
            Push  Bp
            Mov   Di,Bx
            Mov   Bp,[Emultable+Di+Bx]
            Mov   Di,Ax
            Mov   Al,5
            Int   80h
            Pop   Bp
            Cmp   Reg_Pc,0812h
            Jne   @@1
            Int   3
@@1:
Endif
            Mov   Di,Bx
            Inc   Reg_Pc
            Jmp   [Emultable+Di+Bx]
If Debug Eq 3
@@2:        Call  Calcstatus
            Mov   Al,3
            Int   80h
            Int   3
            Jmp   @@3
Endif
; ---------------------------------------------------------------------------
;           76543210
;           sv?bdizc
; Reg_C            x
; Reg_z           x
; [Flags]    xxxxx
; Reg_S     x

Calcstatus: Mov   Al,[Flags]
            Get_C
            Adc   Al,Bh
            Or    Reg_S,Reg_S
            Jns   @@2
            Or    Al,Flag_S
@@2:        Or    Reg_Z,Reg_Z
            Jne   @@1
            Or    Al,Flag_Z
@@1:        Ret
; ---------------------------------------------------------------------------
Setstatus:  Shr   Al,1
            Set_C
            Shl   Al,1
            Mov   Reg_S,Al
            Mov   Reg_Z,Al
            And   Reg_Z,Flag_Z
            Xor   Reg_Z,Flag_Z
            And   Al,01101100b
            Or    Al,Flag_5
            Mov   [Flags],Al
            Ret
; ---------------------------------------------------------------------------
Interrupt:  Call  Calcstatus           ; Push flags and Reg_Pc
            Push  Ax                   
            Mov   Bx,[Word SPtr]       
            Mov   Ax,Reg_Pc
            Mov   [Bx],Ah
            Dec   Bl
            Mov   [Bx],Al
            Dec   Bl
            Pop   Ax
            Mov   [Bx],Al
            Sub   [SPtr],3
            Dec   Bh
            Or    [Flags],Flag_I
            Ret
; ---------------------------------------------------------------------------
Irq:        Mov   [Word Next],Nextpatch
            Call  Interrupt
            Mov   Reg_Pc,[0FFFEh]
            Jmp   Next
; ---------------------------------------------------------------------------
Nmi:        Mov   [Word Next],Nextpatch
            Call  Interrupt
            Mov   Reg_Pc,[0FFFAh]
            Jmp   Next
; ---------------------------------------------------------------------------
Refresher:  Mov   [Word Next],Nextpatch
            Mov   Al,[Video_Lock]
            Push  Ax
            Mov   [Video_Lock],Bh
            Call  Setpalette
            Call  Refresh
            Pop   Ax
            Mov   [Video_Lock],Al
            Jmp   Next
; ---------------------------------------------------------------------------
Refreshsprite:
            Mov   [Word Next],Nextpatch
            Call  Reshowsprites
            Jmp   Next
; ---------------------------------------------------------------------------
Reset:      Mov   Bh,0
            Mov   Ds,[Ramseg]
            Mov   Gs,[Layoutseg]
            Mov   [Byte 0],2Fh
            Mov   [Byte 1],37h
            Call  New0001
            Call  Timer_Reset
            Call  Cia_Reset
            Call  Vic_Reset
            Mov   Reg_Pc,[0FFFCh]
            Mov   Reg_X,0
            Mov   Reg_Y,0
            Mov   Reg_A,0
            Mov   Al,Flag_I+Flag_5+Flag_Z
            Call  Setstatus
            Mov   [SPtr],0FFh
            Mov   [Word Next],Nextpatch
            Mov   [Video_Lock],0
            ;Int   3
            Call  Flagrefresh
            Jmp   Next
; ---------------------------------------------------------------------------
Init:       Pop   Si
            Pop   Di
            Pop   [Layoutseg]
            Pop   [Swapseg]
            Pop   [Ramseg]
            Pop   [Eromseg]
            Pop   [Dromseg]
            Pop   [Aromseg]
            Push  Di
            Push  Si
            Mov   [Bpsave],Bp
            Mov   [Dssave],Ds

            Mov   Ax,0
            Mov   Di,Ax
            Mov   Cx,200
@@1:        Mov   [Mul320+Di],Ax
            Add   Di,2
            Add   Ax,320
            Dec   Cx
            Jne   @@1

            Mov   Ax,0
            Mov   Di,Ax
@@2:        Mov   Cx,40
@@3:        Mov   [Remap1000+Di],Ax
            Add   Ax,8
            Add   Di,2
            Dec   Cx
            Jne   @@3
            Add   Ax,320*8-40*8
            Cmp   Di,26*40*2
            Jne   @@2

            Mov   Ax,[Dromseg]
            Sub   Ax,0D000h/10h
            Mov   [Dromdirect],Ax

            Mov   Es,[Swapseg]
            Mov   Ax,0
            Mov   Di,Ax
            Mov   Cx,0B000h/2
            Cld
            Rep   Stosw

            Mov   Ax,[Layoutseg]
            Mov   Gs,Ax
            Mov   Es,Ax
            Mov   [Byte Es:0],Typ_Norm
            Mov   [Byte Es:1],Typ_0001
            Cld
            Mov   Di,2
            Mov   Cx,0FFFEh/2
            Mov   Ax,101h*Typ_Norm
            Rep   Stosw
            Mov   Es,[Ramseg]
            Mov   Ax,0
            Mov   Di,Ax
            Mov   Cx,0FFFFh/2+1                   ;10000h/02h
            Rep   Stosw
            Mov   [Last1],34h
            Mov   Ds,[Ramseg]
            Mov   [Byte 1],34h
            Mov   Ax,[Swapseg]
            Sub   Ax,(0D000h-9000h)/10h
            Mov   [Iodirect],Ax
            Mov   Fs,Ax

            Call  Videoinit
            Call  Timer_Install
            Call  Key_Install

            Jmp   Reset
; ---------------------------------------------------------------------------
Halt:       Call  Key_Restore
            Call  Timer_Restore

            Mov   Bp,[Bpsave]
            Mov   Ds,[Dssave]
            Retf
; ---------------------------------------------------------------------------
