zxdiv: split video.s into video and video-banked
authorAlan Cox <alan@linux.intel.com>
Wed, 28 Nov 2018 22:35:22 +0000 (22:35 +0000)
committerAlan Cox <alan@linux.intel.com>
Wed, 28 Nov 2018 22:35:22 +0000 (22:35 +0000)
The existing one is banked, but we will want an unbanked variant of it for
some platforms.

Kernel/dev/zx/video-banked.s [new file with mode: 0644]
Kernel/dev/zx/video.s
Kernel/platform-zxdiv/zxvideo.s

diff --git a/Kernel/dev/zx/video-banked.s b/Kernel/dev/zx/video-banked.s
new file mode 100644 (file)
index 0000000..ef87e25
--- /dev/null
@@ -0,0 +1,371 @@
+;
+;        zx128 vt primitives
+;
+        ; exported symbols
+        .globl zx_plot_char
+        .globl zx_scroll_down
+        .globl zx_scroll_up
+        .globl zx_cursor_on
+        .globl zx_cursor_off
+       .globl zx_cursor_disable
+        .globl zx_clear_lines
+        .globl zx_clear_across
+        .globl zx_do_beep
+       .globl _fontdata_8x8
+       .globl _curattr
+       .globl _vtattr
+
+videopos:
+        ld a,e
+        and #7
+        rrca
+        rrca
+        rrca 
+        add a,d
+        ld d,e
+        ld e,a
+        ld a,d
+        and #0x18
+        or #0x40           ; Standard screen
+        ld d,a
+        ret
+
+videoattr:
+       ;                       32 x E + D into HL
+       ld a,e
+       rrca
+       rrca
+       rrca                    ; A is now 32xE with the top bits overflowed
+                               ; into the low 2 bits
+       ld l,a
+       and #3                  ; Extract the low 2 bits for the high
+       add #0x58               ; Attributes start 0x5800
+       ld h,a
+       ld a,l
+       and #0xE0               ; mask the bits that are valid
+       add d                   ; add the low 5 bits from D
+       ld l,a                  ; and done (the add can't overflow)
+       ret
+
+       .if ZXVID_ONLY
+_plot_char:
+       .endif
+zx_plot_char:
+       pop iy
+        pop hl
+        pop de              ; D = x E = y
+        pop bc
+        push bc
+        push de
+        push hl
+       push iy
+
+       push de
+        call videopos
+
+        ld b, #0            ; calculating offset in font table
+        ld a, c
+       or a                ; clear carry
+        rla
+        rl b
+        rla
+        rl b
+        rla
+        rl b
+        ld c, a
+
+        ld hl, #_fontdata_8x8-32*8    ; font
+        add hl, bc          ; hl points to first byte of char data
+
+       ; We do underline for now - not clear italic or bold are useful
+       ; with the font we have.
+       ld bc,(_vtattr)     ; c is vt attributes
+
+        ; printing
+plot_char_loop:
+        ld a, (hl)
+        ld (de), a
+        inc l               ; next byte of char data
+        inc d               ; next screen line
+
+        ld a, (hl)
+        ld (de), a
+        inc l               ; next byte of char data
+        inc d               ; next screen line
+
+        ld a, (hl)
+        ld (de), a
+        inc l               ; next byte of char data
+        inc d               ; next screen line
+
+        ld a, (hl)
+        ld (de), a
+        inc l               ; next byte of char data
+        inc d               ; next screen line
+
+        ld a, (hl)
+        ld (de), a
+        inc l               ; next byte of char data
+        inc d               ; next screen line
+
+        ld a, (hl)
+        ld (de), a
+        inc l               ; next byte of char data
+        inc d               ; next screen line
+
+        ld a, (hl)
+        ld (de), a
+        inc l               ; next byte of char data
+        inc d               ; next screen line
+
+        ld a, (hl)
+       bit 1,c             ; underline ?
+       jr nz, last_ul
+plot_attr:
+        ld (de), a
+
+       pop de
+       call videoattr
+       ld a,(_curattr)
+       ld (hl),a
+        ret
+
+last_ul:
+       ld a,#0xff
+       jr plot_attr
+
+       .if ZXVID_ONLY
+_clear_lines:
+       .endif
+zx_clear_lines:
+       pop bc
+        pop hl
+        pop de              ; E = line, D = count
+        push de
+        push hl
+       push bc
+       ; This way we handle 0 correctly
+       inc d
+       jr nextline
+
+clear_next_line:
+        push de
+        ld d, #0            ; from the column #0
+        ld b, d             ; b = 0
+        ld c, #32           ; clear 32 cols
+        push bc
+        push de
+       push af
+        call _clear_across
+       pop af
+        pop hl              ; clear stack
+        pop hl
+
+        pop de
+        inc e
+nextline:
+        dec d
+        jr nz, clear_next_line
+
+        ret
+
+
+       .if ZXVID_ONLY
+_clear_across:
+       .endif
+zx_clear_across:
+       pop iy
+        pop hl
+        pop de              ; DE = coords 
+        pop bc              ; C = count
+        push bc
+        push de
+        push hl
+       push iy
+       ld a,c
+       or a
+       ret z               ; No work to do - bail out
+       push de
+       push bc
+        call videopos       ; first pixel line of first character in DE
+        push de
+        pop hl              ; copy to hl
+        xor a
+
+        ; no boundary checks. Assuming that D + C < SCREEN_WIDTH
+
+clear_line:
+        ld b, #8            ; 8 pixel lines to clear for this char
+clear_char:
+        ld (de), a
+        inc d
+        djnz clear_char
+
+        ex de, hl
+        inc de
+        push de
+        pop hl
+
+        dec c
+        jr nz, clear_line
+       pop bc
+       pop de
+       call videoattr
+       ld a,(_curattr)
+       ld b,c
+setattr:
+       ld (hl),a
+       inc hl
+       djnz setattr
+        ret
+
+copy_line:
+        ; HL - source, DE - destination
+
+        ; convert line coordinates to screen coordinates both for DE and HL
+        push de
+        ex de, hl
+        call videopos
+        ex de, hl
+        pop de
+        call videopos
+
+        ld c, #8
+
+copy_line_nextchar:
+        push hl
+        push de
+
+        ld b, #32
+
+copy_pixel_line:
+        ld a, (hl)
+        ld (de), a
+        inc e
+        inc l
+        djnz copy_pixel_line
+
+        pop de
+        pop hl
+        inc d
+        inc h
+        dec c
+        jr nz, copy_line_nextchar
+        ret
+
+        ; TODO: the LDIR way should be much faster
+
+       .if ZXVID_ONLY
+_scroll_down:
+       .endif
+zx_scroll_down:
+        ; set HL = (0,22), DE = (0, 23)
+        xor a
+        ld d, a
+        ld h, a
+        ld l, #22
+        ld e, #23
+        ld c, #23           ; 23 lines to move
+
+loop_scroll_down:
+        push hl
+        push de
+        push bc
+
+        call copy_line
+
+        pop bc
+        pop de
+        pop hl
+
+        dec l
+        dec e
+        dec c
+        jr nz, loop_scroll_down
+
+       ; Attributes
+       ld hl,#0x5ADF
+       ld de,#0x5AFF
+       ld bc,#0x02E0
+       lddr
+
+        ret
+
+
+       .if ZXVID_ONLY
+_scroll_up:
+       .endif
+zx_scroll_up:
+        ; set HL = (0,1), DE = (0, 0)
+        xor a
+        ld d, a
+        ld e, a
+        ld h, a
+        ld l, #1
+        ld c, #23           ; 23 lines to move
+
+loop_scroll_up:
+        push hl
+        push de
+        push bc
+
+        call copy_line
+
+        pop bc
+        pop de
+        pop hl
+
+        inc l
+        inc e
+        dec c
+        jr nz, loop_scroll_up
+
+       ld hl,#0x5820
+       ld de,#0x5800
+       ld bc,#0x02E0
+       ldir
+        ret
+
+       .if ZXVID_ONLY
+_cursor_on:
+       .endif
+zx_cursor_on:
+       pop bc
+        pop hl
+        pop de
+        push de
+        push hl
+       push bc
+        ld (cursorpos), de
+
+        call videopos
+        ld a, #7
+        add a, d
+        ld d, a
+        ld a, #0xFF
+        ld (de), a
+        ret
+       .if ZXVID_ONLY
+_cursor_disable:
+_cursor_off:
+       .endif
+zx_cursor_disable:
+zx_cursor_off:
+        ld de, (cursorpos)
+        call videopos
+        ld a, #7
+        add a, d
+        ld d, a
+        xor a
+        ld (de), a
+
+       .if ZXVID_ONLY
+_do_beep:
+       .endif
+zx_do_beep:
+        ret
+
+        .area _DATA
+
+cursorpos:
+        .dw 0
index ef87e25..2625f37 100644 (file)
@@ -51,14 +51,12 @@ videoattr:
 _plot_char:
        .endif
 zx_plot_char:
-       pop iy
         pop hl
         pop de              ; D = x E = y
         pop bc
         push bc
         push de
         push hl
-       push iy
 
        push de
         call videopos
@@ -138,12 +136,10 @@ last_ul:
 _clear_lines:
        .endif
 zx_clear_lines:
-       pop bc
         pop hl
         pop de              ; E = line, D = count
         push de
         push hl
-       push bc
        ; This way we handle 0 correctly
        inc d
        jr nextline
@@ -155,9 +151,7 @@ clear_next_line:
         ld c, #32           ; clear 32 cols
         push bc
         push de
-       push af
         call _clear_across
-       pop af
         pop hl              ; clear stack
         pop hl
 
@@ -174,14 +168,12 @@ nextline:
 _clear_across:
        .endif
 zx_clear_across:
-       pop iy
         pop hl
         pop de              ; DE = coords 
         pop bc              ; C = count
         push bc
         push de
         push hl
-       push iy
        ld a,c
        or a
        ret z               ; No work to do - bail out
@@ -330,12 +322,10 @@ loop_scroll_up:
 _cursor_on:
        .endif
 zx_cursor_on:
-       pop bc
         pop hl
         pop de
         push de
         push hl
-       push bc
         ld (cursorpos), de
 
         call videopos
index 78b4051..950cb76 100644 (file)
@@ -24,5 +24,5 @@ ZXVID_ONLY    .equ    1
 
         .area _VIDEO
 
-       .include "../dev/zx/video.s"
+       .include "../dev/zx/video-banked.s"