Mirror of CollapseOS
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

84 lines
2.2KB

  1. #include <string.h>
  2. #include "vdp.h"
  3. void vdp_init(VDP *vdp)
  4. {
  5. memset(vdp->vram, 0, VDP_VRAM_SIZE);
  6. memset(vdp->regs, 0, 0x10);
  7. vdp->has_cmdlsb = false;
  8. vdp->curaddr = 0;
  9. }
  10. uint8_t vdp_cmd_rd(VDP *vdp)
  11. {
  12. return 0;
  13. }
  14. void vdp_cmd_wr(VDP *vdp, uint8_t val)
  15. {
  16. if (!vdp->has_cmdlsb) {
  17. vdp->cmdlsb = val;
  18. vdp->has_cmdlsb = true;
  19. return;
  20. }
  21. vdp->has_cmdlsb = false;
  22. if ((val & 0xc0) == 0x80) {
  23. // set register
  24. vdp->regs[val&0xf] = vdp->cmdlsb;
  25. } else if ((val & 0xc0) == 0xc0) {
  26. // palette RAM
  27. vdp->curaddr = 0x4000 + (vdp->cmdlsb&0x1f);
  28. } else {
  29. // VRAM
  30. vdp->curaddr = ((val&0x3f) << 8) + vdp->cmdlsb;
  31. }
  32. }
  33. uint8_t vdp_data_rd(VDP *vdp)
  34. {
  35. uint8_t res = vdp->vram[vdp->curaddr];
  36. if (vdp->curaddr < VDP_VRAM_SIZE) {
  37. vdp->curaddr++;
  38. }
  39. return res;
  40. }
  41. void vdp_data_wr(VDP *vdp, uint8_t val)
  42. {
  43. vdp->vram[vdp->curaddr] = val;
  44. if (vdp->curaddr < VDP_VRAM_SIZE) {
  45. vdp->curaddr++;
  46. }
  47. }
  48. // Returns a 8-bit RGB value (0b00bbggrr)
  49. uint8_t vdp_pixel(VDP *vdp, uint16_t x, uint16_t y)
  50. {
  51. if (x >= VDP_SCREENW) {
  52. return 0;
  53. }
  54. if (y >= VDP_SCREENH) {
  55. return 0;
  56. }
  57. // name table offset
  58. uint16_t offset = (vdp->regs[2] & 0xe) << 10;
  59. offset += ((y/8) << 6) + ((x/8) << 1);
  60. uint16_t tableval = vdp->vram[offset] + (vdp->vram[offset+1] << 8);
  61. uint16_t tilenum = tableval & 0x1ff;
  62. // is palette select bit on? if yes, use sprite palette instead
  63. uint8_t palettemod = tableval & 0x800 ? 0x10 : 0;
  64. // tile offset this time. Each tile is 0x20 bytes long.
  65. offset = tilenum * 0x20;
  66. // Each 4 byte is a row. Find row first.
  67. offset += ((y%8) * 4);
  68. uint8_t bitnum = 7 - (x%8);
  69. // Now, let's compose the result by pushing the right bit of our 4 bytes
  70. // into our result.
  71. uint8_t palette_id = ((vdp->vram[offset] >> bitnum) & 1) + \
  72. (((vdp->vram[offset+1] >> bitnum) & 1) << 1) + \
  73. (((vdp->vram[offset+2] >> bitnum) & 1) << 2) + \
  74. (((vdp->vram[offset+3] >> bitnum) & 1) << 3);
  75. uint8_t rgb = vdp->vram[0x4000+palettemod+palette_id];
  76. return rgb;
  77. }