DISKIV  = $E450         ;vector to initialize DIO
 DSKINV  = $E453         ;vector to DIO
 .if .defined(__ATARIXL__)
-CIOV   = $C0
-SIOV   = $C3
+.ifndef SHRAM_HANDLERS
+.import CIO_handler, SIO_handler, SETVBV_handler
+.endif
+.define CIOV    CIO_handler
+.define SIOV    SIO_handler
+.define SETVBV  SETVBV_handler
 CIOV_org    = $E456         ;vector to CIO
 SIOV_org    = $E459         ;vector to SIO
+SETVBV_org  = $E45C         ;vector to set VBLANK parameters
 .else
 CIOV    = $E456         ;vector to CIO
 SIOV    = $E459         ;vector to SIO
-.endif
 SETVBV  = $E45C         ;vector to set VBLANK parameters
+.endif
 SYSVBV  = $E45F         ;vector to process immediate VBLANK
 XITVBV  = $E462         ;vector to process deferred VBLANK
 SIOINV  = $E465         ;vector to initialize SIO
 
 
 IRQStub:
         cld                             ; Just to be sure
+.if .defined(__ATARIXL__)
+       pha
+       lda     PORTB
+       pha
+       and     #$fe
+       sta     PORTB                   ; disable ROM  @@@ TODO: update CHARGEN
+.endif
         jsr     callirq                 ; Call the functions
+.if .defined(__ATARIXL__)
+       pla
+       sta     PORTB
+       pla
+.endif
         jmp     IRQInd                  ; Jump to the saved IRQ vector
 
 ; ------------------------------------------------------------------------
 
 
 em_libref       := _exit
 joy_libref      := _exit
+.if .defined(__ATARIXL__)
+        .import CIO_handler
+tgi_libref      := CIO_handler
+.else
 tgi_libref      := _exit
+.endif
 
 
 .if .defined(__ATARIXL__)
 
+       SHRAM_HANDLERS  = 1
         .include        "atari.inc"
        .include        "save_area.inc"
         .include        "zeropage.inc"
 
        .export         sram_init
        .export         KEYBDV_wrapper
+       .export         CIO_handler
+       .export         SIO_handler
+       .export         SETVBV_handler
 
-BUFSZ          =       256             ; bounce buffer size
+BUFSZ          =       128             ; bounce buffer size
+BUFSZ_SIO      =       256
 
 .macro disable_rom
        lda     PORTB
        lda     #>my_NMI_han
        sta     $fffb
 
-; setup pointers to CIOV and SIOV wrappers
-       lda     #$4C            ; JMP opcode
-       sta     CIOV
-       lda     #<my_CIOV
-       sta     CIOV+1
-       lda     #>my_CIOV
-       sta     CIOV+2
-       lda     #$4C            ; JMP opcode
-       sta     SIOV
-       lda     #<my_SIOV
-       sta     SIOV+1
-       lda     #>my_SIOV
-       sta     SIOV+2
-
 ; enable interrupts
        lda     #$40
        sta     NMIEN
 .segment "LOWBUFS"
 
 ; bounce buffers for CIO and SIO calls
-bounce_buffer: .res    BUFSZ
+bounce_buffer: .res    BUFSZ_SIO
 
 
 .segment "LOWCODE"
 ;
 ; FIXME: Currently only the requests used by the runtime lib are handled.
 
-my_CIOV:
+CIO_handler:
 
 ; @@@ TODO: check X for valid IOCB index ((X < $80) and ((X & $F) == 0))
 
 ; These are the only functions used by the runtime library currently.
 ; For other function we return NVALID status code.
 
-my_SIOV:
+SIO_handler:
        lda     DCOMND                  ; get command
        cmp     #SIO_STAT
        beq     SIO_stat
 ;                CF - 0/1 for larger/not larger
 cmp_sio_len_bnc_bufsz:
        sec
-       lda     #<BUFSZ
+       lda     #<BUFSZ_SIO
        sbc     DBYTLO
-       lda     #>BUFSZ
+       lda     #>BUFSZ_SIO
        sbc     DBYTHI
        rts
 
        pla
        rts
 
+;---------------------------------------------------------
+
+SETVBV_handler:
+
+       pha
+       lda     PORTB
+       sta     cur_SETVBV_PORTB
+       enable_rom
+       pla
+       jsr     SETVBV_org
+       php
+       pha
+       lda     cur_SETVBV_PORTB
+       sta     PORTB
+       pla
+       plp
+       rts
+
 CIO_a:                 .res    1
 CIO_x:                 .res    1
 CIO_y:                 .res    1
 cur_CIOV_PORTB:                .res    1
 cur_SIOV_PORTB:                .res    1
 cur_KEYBDV_PORTB:      .res    1
+cur_SETVBV_PORTB:      .res    1
 orig_ptr:              .res    2
 orig_len:              .res    2
 req_len:               .res    2
 
 
         ldx     lowadr
         stx     MEMTOP
-        stx     APPMHI
         lda     lowadr+1
         sta     MEMTOP+1
-        sta     APPMHI+1
         lda     lodadr+1
         sta     RAMTOP
 
+       ; set APPMHI to MEMLO (+ 1 for sanity)
+        lda     MEMLO
+        clc
+        adc     #1
+        sta     APPMHI
+        lda     MEMLO+1
+        adc     #0
+        sta     APPMHI+1
+
 
 ; ... issue a GRAPHICS 0 call (copied'n'pasted from TGI drivers)
 
 
 
 .macpack longbranch
 
+.if .defined(__ATARIXL__)
+        CIO_vec := my_CIOV
+.else
+        CIO_vec := CIOV
+.endif
+
 ; ******************************************************************************
 
         ; ----------------------------------------------------------------------
 
         .byte   $74, $67, $69           ; "tgi"
         .byte   TGI_API_VERSION         ; TGI API version number
-        .addr   $0000                   ; Library reference
+libref: .addr   $0000                   ; Library reference
         .word   x_res                   ; X resolution
         .word   y_res                   ; Y resolution
         .byte   colors                  ; Number of drawing colors
         text_dir:
                 .byte   0       ; Text direction,
 
+.if .defined(__ATARIXL__)
+        my_CIOV:
+                .byte   $4C, 0, 0
+.endif
 .code
 
 ; ******************************************************************************
 
         stx     mask
 
+.if .defined(__ATARIXL__)
+
+        ; setup pointer to CIO
+
+        lda     libref
+        sta     my_CIOV+1
+        lda     libref+1
+        sta     my_CIOV+2
+.endif
+
+
         ; Find a free IOCB
         lda     #$70
 search: tax
         sta     ICBLL,x
         lda     #>screen_device_length
         sta     ICBLH,x
-        jsr     CIOV
+        jsr     CIO_vec
 
 .if ::pages = 2
         ; Reserve 8K of high memory
         ; Close and reopen graphics
         lda     #CLOSE
         sta     ICCOM,x
-        jsr     CIOV
+        jsr     CIO_vec
         ; Reopen graphics
         lda     #OPEN
         sta     ICCOM,x
         sta     ICBLL,x
         lda     #>screen_device_length
         sta     ICBLH,x
-        jsr     CIOV
+        jsr     CIO_vec
         ; Save screen pointers
         lda     SAVMSC + 1
         sta     p0scr
         ; Close the S: device
         lda     #CLOSE
         sta     ICCOM,x
-        jsr     CIOV
+        jsr     CIO_vec
 
         ; Reopen it in Graphics 0
         lda     #OPEN
         sta     ICBLL,x
         lda     #>screen_device_length
         sta     ICBLH,x
-        jsr     CIOV
+        jsr     CIO_vec
 
         ; Now close it again; we don't need it anymore :)
         lda     #CLOSE
         sta     ICCOM,x
-        jmp     CIOV
+        jmp     CIO_vec
 .endproc
 
 ; ******************************************************************************
 .endif
 
         sta     ATACHR
-        jmp     CIOV
+        jmp     CIO_vec
 
 .else   ; USE_CIO_LINE