fx9860-emulator-playground/fx9860-emulator/syscalls/bdisp.c

110 lines
2.9 KiB
C

#include "../headers/syscalls/bdisp.h"
// Clear the content of the screen
void syscall_Bdisp_AllClr_DD(cpu_t* cpu) {
// Does nothing for now
}
// Clear the content of the VRAM
void syscall_Bdisp_AllClr_VRAM(cpu_t* cpu) {
for (int i = 0; i < VRAM_SIZE; i++) {
cpu->disp->vram[i] = 0;
}
}
// Clear the content of the VRAM and the screen
void syscall_Bdisp_AllClr_DDVRAM(cpu_t* cpu) {
syscall_Bdisp_AllClr_DD(cpu);
syscall_Bdisp_AllClr_VRAM(cpu);
}
// Transfer the contents of VRAM to the screen.
void syscall_Bdisp_PutDisp_DD(cpu_t* cpu) {
// printf("Run syscall: Bdisp_PutDisp_DD\n");
#ifdef USE_EMSCRIPT
EM_ASM({
window.refreshScreen();
});
#endif
}
/**
* Set or erase a dot at the specified position of VRAM and/or DD (Display Driver).
* @param x (0~127) This is the x coordinate of the specified position.
* @param y (0~63) This is the y coordinate of the specified position.
* @param point If you set point to 1 then the dot is made black. If you set point to 0 then the dot is cleared.
*/
void syscall_Bdisp_SetPoint_VRAM(cpu_t* cpu, uint32_t x, uint32_t y, uint32_t point) {
uint32_t vramID = x/8 + y * 16;
uint8_t bit = 7 - x % 8;
if (vramID < 0 || vramID >= VRAM_SIZE) return;
cpu->disp->vram[vramID] = (cpu->disp->vram[vramID] & ~(1 << bit)) | (point << bit);
}
/**
* Draws a line to VRAM.
* Code from the MonochromeLib library's ML_Line() function.
* @param x1 (0 ~ 127) x starting point
* @param y1 (0 ~ 63) y starting point
* @param x2 (0 ~ 127) x ending point
* @param y2 (0 ~ 63) y ending point
*/
void syscall_Bdisp_DrawLine_VRAM(cpu_t* cpu, int x1, int y1, int x2, int y2) {
int x = x1;
int y = y1;
int dx = x2 - x1;
int dy = y2 - y1;
int sx = dx < 0 ? -1 : 1;
int sy = dy < 0 ? -1 : 1;
dx = abs(dx);
dy = abs(dy);
syscall_Bdisp_SetPoint_VRAM(cpu, x, y, 1);
if(dx > dy) {
int cumul = dx / 2;
for(int i = 1; i < dx; i++) {
x += sx;
cumul += dy;
if(cumul > dx) {
cumul -= dx;
y += sy;
}
syscall_Bdisp_SetPoint_VRAM(cpu, x, y, 1);
}
}
else {
int cumul = dy / 2;
for(int i = 1; i < dy; i++) {
y += sy;
cumul += dx;
if(cumul > dy) {
cumul -= dy;
x += sx;
}
syscall_Bdisp_SetPoint_VRAM(cpu, x, y, 1);
}
}
}
/**
* Saves a screen image in the system area.
* @param num SAVEDISP_PAGE1 - SAVEDISP_PAGE3.
* @remarks The screen image is copied from VRAM.
*/
void syscall_SaveDisp(cpu_t* cpu, unsigned char num) {
num = num == SAVEDISP_PAGE1 ? num - 1 : num - 4;
memcpy(cpu->disp->saved_disps + VRAM_SIZE*num, cpu->disp->vram, VRAM_SIZE);
}
/**
* Restores a screen image from the system area.
* @param num SAVEDISP_PAGE1 - SAVEDISP_PAGE3.
* @remarks The screen image is copied to VRAM.
*/
void syscall_RestoreDisp(cpu_t* cpu, unsigned char num) {
num = num == SAVEDISP_PAGE1 ? num - 1 : num - 4;
memcpy(cpu->disp->vram, cpu->disp->saved_disps + VRAM_SIZE*num, VRAM_SIZE);
}