diff --git a/src/video.c b/src/video.c index 5045fac..f5e893c 100644 --- a/src/video.c +++ b/src/video.c @@ -1,20 +1,63 @@ #include "video.h" +#include "io.h" + #include char *const VIDEO_MEMORY = (char *)0xd000; static uint16_t offset = 0; +static bool hstretch = false; +static bool vstretch = false; + +void video_locate(uint8_t row, uint8_t column) { + offset = (uint16_t)row * 80 + column; +} + +void video_enableHorizontalStretch(bool enable) { + hstretch = enable; +} + +void video_enableVerticalStretch(bool enable) { + vstretch = enable; +} void video_putchar(char c) { + // TODO(giomba): this function is not very consistent :sweat: if (c == '\n' || c == '\r') { offset += 80 - (offset % 80); - - } else if (c == '\t') { - offset += 8 - offset % 8; - } else { - *(VIDEO_MEMORY + offset++) = c; + goto end; } + if (hstretch) { + io_out(0x81, io_in(0x81) | 0x80); + *(VIDEO_MEMORY + offset) |= 0x08; + io_out(0x81, io_in(0x81) & ~0x80); + } + + if (c == '\t') { + offset += 8 - offset % 8; + goto end; + } + + *(VIDEO_MEMORY + offset) = c; + + if (vstretch) { + *(VIDEO_MEMORY + offset + 80) = c; + + io_out(0x81, io_in(0x81) | 0x80); + *(VIDEO_MEMORY + offset) |= 0x60; + *(VIDEO_MEMORY + offset + 80) |= 0x70; + if (hstretch) + *(VIDEO_MEMORY + offset + 80) |= 0x08; + io_out(0x81, io_in(0x81) & ~0x80); + } + + ++offset; + + if (hstretch) + ++offset; + +end: offset = offset % 2000; } diff --git a/src/video.h b/src/video.h index 0d23cef..e251617 100644 --- a/src/video.h +++ b/src/video.h @@ -1,12 +1,16 @@ #ifndef CEDA_PRINT_H #define CEDA_PRINT_H +#include #include extern char *const VIDEO_MEMORY; void video_cls(void); void video_put(uint8_t x, uint8_t y, char c); +void video_locate(uint8_t row, uint8_t column); +void video_enableHorizontalStretch(bool enable); +void video_enableVerticalStretch(bool enable); void video_putchar(char c); #endif // CEDA_PRINT_H diff --git a/src/video_a.asm b/src/video_a.asm index 56508ca..61751a1 100644 --- a/src/video_a.asm +++ b/src/video_a.asm @@ -7,6 +7,7 @@ _video_cls: push de push hl + ; clear chars ld hl,$d000 ld de,2000 ld c,$20 @@ -18,6 +19,28 @@ _video_cls_loop: or e jp nz,_video_cls_loop + ; enable attr video bank + in a,($81) + or a,$80 + out ($81),a + + ; clear attributes + ld hl,$d000 + ld de,2000 + ld c,$00 +_video_attr_cls_loop: + ld (hl),c + inc hl + dec de + ld a,d + or e + jp nz,_video_attr_cls_loop + + ; restore char video bank + in a,($81) + and a,$7f + out ($81),a + pop hl pop de pop bc