@@ 0,0 1,104 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "tema.h"
+#include "screen.h"
+
+void composite(TScreen *scr) {
+ uint8 *bg = scr->l0.data;
+ uint8 *fg = scr->l1.data;
+
+ for(int y=0;y<scr->hgt;y++) {
+ for(int x=0;x<scr->wid;x++) {
+ int idx = y*scr->wid+x;
+ uint8 *source = fg[idx] ? fg : bg ;
+ scr->comp[y*scr->wid+x] = source[idx] ? 0x00FFFF00 : 0x00000000;
+ }
+ }
+}
+
+void blit_sprite(TScreen* t, uint8* l, uint16 xpos, uint16 ypos, uint8 *dat) {
+
+ uint8 cols = min(t->wid-xpos,8);
+
+ for(int r=ypos;r<min(ypos+8,t->hgt);r++) {
+ for(uint8 sp=0;sp<cols;sp++) {
+ l[r*t->wid+xpos+sp] = *dat&(0x80>>sp) ? 0xFF : 0x00; //! this should be a color index
+ }
+ dat++;
+ }
+}
+
+void set_pixel(TScreen* t, uint8* l, uint8 cidx, uint16 xpos, uint16 ypos) {
+ //printf("set pixel at %d,%d to 0x%02X @ offset %d\n",xpos, ypos,cidx,ypos*t->wid+xpos);
+ l[ypos*t->wid+xpos] = cidx;
+}
+
+// display_write expects TeMa pointer, port number, value to write.
+void display_write(TeMa *t,uint8 p,uint8 v) {
+ //printf("display_write port: 0x%02X\n",p);
+ uint8 *d = &t->device[0x20];
+ switch(p) {
+ case 0x02: case 0x03: { // set tema display width
+ uint16 wid = BYTES2SHORT(d+0x02);
+ printf("display_write received display width: 0x%02X\n",wid);
+ if(wid > MAXTWID) { printf("WARNING: display width of %d exceeds maximum of %d\n",wid,MAXTWID); break; }
+ size_tscreen(wid,scr.hgt);
+ //update_window();
+ break;
+ }
+ case 0x04: case 0x05: {
+ uint16 hgt = BYTES2SHORT(d+0x04);
+ printf("display_write received display height: 0x%02X\n",hgt);
+ if(hgt > MAXTHGT) { printf("WARNING: display height of %d exceeds maximum of %d\n",hgt,MAXTHGT); break; }
+ size_tscreen(scr.wid,hgt);
+ //update_window();
+ break;
+ }
+ case 0x0E: { // cidx (and x, y position)
+ // at this point the display device buffer is assumed to contain the x and y positions
+ uint16 xpos = BYTES2SHORT(d+0x08), ypos = BYTES2SHORT(d+0x0A);
+ Layer* layer = *(d+0x0E) & 0x4 ? &scr.l1 : &scr.l0;
+ //printf("display_write received clut info: about to place a pixel of clut idx 0x%02X at 0x%04X,0x%04X\n",v,xpos,ypos);
+ if(xpos>=scr.wid || ypos>=scr.hgt) break;
+ set_pixel(&scr, layer->data,v, xpos, ypos);
+ layer->dirty = 1;
+ break;
+ }
+ case 0x0F: // dma
+ {
+ // at this point the display device buffer is assumed to contain the x and y positions and an address
+ uint16 xpos = BYTES2SHORT(d+0x08), ypos = BYTES2SHORT(d+0x0A), adr = BYTES2SHORT(d+0x0C);
+ Layer* layer = *(d+0x0F) & 0x4 ? &scr.l1 : &scr.l0;
+ //char* layerid = *(d+0x0F) & 0x4 ? "fg" : "bg";
+ //printf("display_write received dma: about to blit %s at %d,%d\n",layerid,xpos,ypos);
+ if(xpos>=scr.wid || ypos>=scr.hgt) break;
+
+ blit_sprite(&scr, layer->data, xpos, ypos,&t->ram[adr]) ;
+ layer->dirty = 1;
+ break;
+ }
+ }
+}
+
+void tdisplay_clean() {
+ free(scr.l0.data);
+ free(scr.l1.data);
+ free(scr.comp);
+}
+
+void size_tscreen(uint16 wid, uint16 hgt) {
+ printf("size_tscreen\n");
+ scr.bpp = sizeof(uint32); // RGB8888
+ if(wid < 0x8 || wid > 0x400 || hgt < 0x8 || hgt > 0x400) return;
+
+ uint8* l0 = realloc(scr.l0.data,wid*hgt);
+ uint8* l1 = realloc(scr.l1.data,wid*hgt);
+ uint32* comp = realloc(scr.comp,wid*hgt*scr.bpp);
+
+ if(!l0 || !l1 || !comp) return;
+
+ scr.wid = wid; scr.hgt = hgt;
+ scr.l0.data = l0; scr.l1.data = l1; scr.comp = comp;
+ scr.bodge = 1;
+ printf("thres %d, tvres %d, bodge %d\n",scr.wid,scr.hgt,scr.bodge);
+}
@@ 1,8 1,10 @@
-#include "tema.h"
#include <stdio.h>
#include <stdlib.h>
#include <SDL2/SDL.h>
+#include "tema.h"
+#include "screen.h"
+
//device ids
// host 0x00
// console 0x10
@@ 18,60 20,15 @@
static uint16 whres = 640;
static uint16 wvres = 480;
-// The default resolution of TeMa inside the host window
-static uint16 thres = 640;
-static uint16 tvres = 480;
-#define MAXTWID 0x400
-#define MAXTHGT 0x400
//static uint8 bpp=4; // default bits per pixel
static uint8 wresx = 1;
void update_window();
-void size_tscreen(uint16 wid, uint16 hgt);
-#define min(a,b) \
- ({ __typeof__ (a) _a = (a); \
- __typeof__ (b) _b = (b); \
- _a < _b ? _a : _b; })
- #define max(a,b) \
- ({ __typeof__ (a) _a = (a); \
- __typeof__ (b) _b = (b); \
- _a > _b ? _a : _b; })
SDL_Renderer *renderer;
SDL_Window *window;
SDL_Texture *texture;
-//! move TScreen code to a separate file once finalized
-
-typedef struct {
- uint8* data;
- uint8 dirty;
-} Layer;
-
-typedef struct {
- uint16 wid, hgt;
- uint8 bpp;
- Layer l0, l1;
- Uint32* comp;
-} TScreen;
-
-
-TScreen scr;
-
-void composite(TScreen *scr) {
- uint8 *bg = scr->l0.data;
- uint8 *fg = scr->l1.data;
-
- for(int y=0;y<scr->hgt;y++) {
- for(int x=0;x<scr->wid;x++) {
- int idx = y*scr->wid+x;
- uint8 *source = fg[idx] ? fg : bg ;
- scr->comp[y*scr->wid+x] = source[idx] ? 0x00FFFF00 : 0x00000000;
- }
- }
-}
-
-
void window_init(uint16 win_hres, uint16 win_vres, uint16 tema_hres, uint16 tema_vres) {
SDL_Init(SDL_INIT_VIDEO);
SDL_ShowCursor(SDL_DISABLE);
@@ 80,23 37,6 @@ void window_init(uint16 win_hres, uint16 win_vres, uint16 tema_hres, uint16 tema
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE );
}
-void blit_sprite(TScreen* t, uint8* l, uint16 xpos, uint16 ypos, uint8 *dat) {
-
- uint8 cols = min(t->wid-xpos,8);
-
- for(int r=ypos;r<min(ypos+8,t->hgt);r++) {
- for(uint8 sp=0;sp<cols;sp++) {
- l[r*t->wid+xpos+sp] = *dat&(0x80>>sp) ? 0xFF : 0x00; //! this should be a color index
- }
- dat++;
- }
-}
-
-void set_pixel(TScreen* t, uint8* l, uint8 cidx, uint16 xpos, uint16 ypos) {
- //printf("set pixel at %d,%d to 0x%02X @ offset %d\n",xpos, ypos,cidx,ypos*t->wid+xpos);
- l[ypos*t->wid+xpos] = cidx;
-}
-
void window_clean() {
// Clean up
SDL_DestroyTexture(texture); texture = NULL;
@@ 105,7 45,6 @@ void window_clean() {
SDL_Quit();
}
-
static void host_write(TeMa *t,uint8 p,uint8 v) {
switch(p) {
case 0x08: // red components of host 4-colour (4 bits per colour) clut
@@ 136,54 75,6 @@ static void console_write(uint8 p,uint8 v) {
fflush(f);
}
-// display_write expects TeMa pointer, port number, value to write.
-static void display_write(TeMa *t,uint8 p,uint8 v) {
- //printf("display_write port: 0x%02X\n",p);
- uint8 *d = &t->device[0x20];
- switch(p) {
- case 0x02: case 0x03: { // set tema display width
- uint16 wid = BYTES2SHORT(d+0x02);
- printf("display_write received display width: 0x%02X\n",wid);
- if(wid > MAXTWID) { printf("WARNING: display width of %d exceeds maximum of %d\n",wid,MAXTWID); break; }
- thres = wid;
- size_tscreen(wid,scr.hgt);
- update_window();
- break;
- }
- case 0x04: case 0x05: {
- uint16 hgt = BYTES2SHORT(d+0x04);
- printf("display_write received display height: 0x%02X\n",hgt);
- if(hgt > MAXTHGT) { printf("WARNING: display height of %d exceeds maximum of %d\n",hgt,MAXTHGT); break; }
- tvres = hgt;
- size_tscreen(scr.wid,hgt);
- update_window();
- break;
- }
- case 0x0E: { // cidx (and x, y position)
- // at this point the display device buffer is assumed to contain the x and y positions
- uint16 xpos = BYTES2SHORT(d+0x08), ypos = BYTES2SHORT(d+0x0A);
- Layer* layer = *(d+0x0E) & 0x4 ? &scr.l1 : &scr.l0;
- //printf("display_write received clut info: about to place a pixel of clut idx 0x%02X at 0x%04X,0x%04X\n",v,xpos,ypos);
- if(xpos>=scr.wid || ypos>=scr.hgt) break;
- set_pixel(&scr, layer->data,v, xpos, ypos);
- layer->dirty = 1;
- break;
- }
- case 0x0F: // dma
- {
- // at this point the display device buffer is assumed to contain the x and y positions and an address
- uint16 xpos = BYTES2SHORT(d+0x08), ypos = BYTES2SHORT(d+0x0A), adr = BYTES2SHORT(d+0x0C);
- Layer* layer = *(d+0x0F) & 0x4 ? &scr.l1 : &scr.l0;
- //char* layerid = *(d+0x0F) & 0x4 ? "fg" : "bg";
- //printf("display_write received dma: about to blit %s at %d,%d\n",layerid,xpos,ypos);
- if(xpos>=scr.wid || ypos>=scr.hgt) break;
-
- blit_sprite(&scr, layer->data, xpos, ypos,&t->ram[adr]) ;
- layer->dirty = 1;
- break;
- }
- }
-}
// TeMu -> TeMa
@@ 264,8 155,8 @@ void update_bit(uint8* val, uint8 bit, uint8 set) {
static uint8 controller_state = 0;
void update_controller(int sym, uint8* state, uint8 set) {
switch(sym) {
- case SDLK_LCTRL: case SDLK_RCTRL: update_bit(state, 0x01, set); break;
- case SDLK_LALT: case SDLK_RALT: update_bit(state, 0x02, set); break;
+ case SDLK_LCTRL: case SDLK_RCTRL: update_bit(state, 0x01, set); break;
+ case SDLK_LALT: case SDLK_RALT: update_bit(state, 0x02, set); break;
case SDLK_LSHIFT: case SDLK_RSHIFT: update_bit(state, 0x04, set); break;
case SDLK_HOME: update_bit(state, 0x08, set); break;
case SDLK_UP: update_bit(state, 0x10, set); break;
@@ 362,10 253,11 @@ int temu_run(TeMa* tema) {
// should we read the vector outside the loop? It would mean TeMa could change it without effect, so probably no.
uint16 display_handler = BYTES2SHORT(&tema->device[0x20]);
+
+ if(scr.bodge == 1) { printf("updating window\n"); update_window(); scr.bodge=0; }
if(display_handler) {
run(tema, display_handler);
-
if(scr.l0.dirty || scr.l1.dirty) {
composite(&scr);
@@ 391,32 283,13 @@ int temu_run(TeMa* tema) {
return 1;
}
-void tdisplay_clean() {
- free(scr.l0.data);
- free(scr.l1.data);
- free(scr.comp);
-}
-
-void size_tscreen(uint16 wid, uint16 hgt) {
-
- scr.bpp = sizeof(Uint32); // RGB8888
- if(wid < 0x8 || wid > 0x400 || hgt < 0x8 || hgt > 0x400) return;
-
- uint8* l0 = realloc(scr.l0.data,wid*hgt);
- uint8* l1 = realloc(scr.l1.data,wid*hgt);
- Uint32* comp = realloc(scr.comp,wid*hgt*scr.bpp);
-
- if(!l0 || !l1 || !comp) return;
-
- scr.wid = wid; scr.hgt = hgt;
- scr.l0.data = l0; scr.l1.data = l1; scr.comp = comp;
-}
-
-
void update_window() {
+ printf("update_window !!!!!!!!!!\n");
+ uint16 thres = scr.wid; uint16 tvres = scr.hgt;
whres = thres*wresx; wvres = tvres*wresx;
if( texture != NULL ) SDL_DestroyTexture(texture);
+ printf("wresx is %d: setting whres and wvres to %d,%d\n",wresx,whres,wvres);
// renderer is the size of the insides of the host window.
SDL_RenderSetLogicalSize(renderer, thres, tvres);
@@ 437,7 310,7 @@ int main(int argc, char *argv[]) {
char *rompath= argv[1];
// init stuff
-
+ scr.wid = 640; scr.hgt = 480;
TeMa tema;
// calloc inits to 0
inittema(&tema, (uint8 *)calloc(RAMBYTES, sizeof(uint8)), inbus, outbus);
@@ 455,6 328,7 @@ int main(int argc, char *argv[]) {
//db_ramprint(tema.ram.data,0x0000, romsize,0x8);
// create display
+ uint16 thres = scr.wid; uint16 tvres = scr.hgt;
whres = thres*wresx; wvres = tvres*wresx;
window_init(whres, wvres, thres, tvres);
size_tscreen(thres, tvres);