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.

86 line
2.4KB

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