Advertisement
Guest User

Untitled

a guest
Sep 11th, 2014
267
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Copyright 2006, 2007 Dennis van Weeren
  2. //
  3. // This file is part of Minimig
  4. //
  5. // Minimig is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation; either version 3 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // Minimig is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17. //
  18. //
  19. //
  20. // This is Denise
  21. // This module  is a complete implementation of the Amiga OCS Denise chip
  22. // It supports all OCS modes including HAM, EHB and interlaced video
  23. //
  24. // 11-05-2005   -started coding
  25. // 15-05-2005   -added local beamcounter
  26. //              -added bitplanes module
  27. //              -added color registers
  28. //              -first experimental version
  29. // 22-05-2005   -added diwstrt/diwstop
  30. // 12-06-2005   -started integrating sprites module
  31. // 21-06-2005   -done more work on integrating sprites module
  32. // 22-06-2005   -done more work on completing denise
  33. // 27-06-2005   -added main priority logic (sprites vs playfields)
  34. // 28-06-2005   -added hold and modify mode
  35. //              -added delay register and video multiplexers
  36. //              -added video output register
  37. // 29-06-2005   -added collision detection, Denise is now complete! (but untested)
  38. //              -(later this day) Denise works! (hires,interlaced,playfield,sprites)
  39. // 07-08-2005   -added deniseid register
  40. // 02-10-2005   -fixed bit 15 of CLXDAT high
  41. // 19-10-2005   -code now uses sol signal to synchronize local beam counter
  42. // 11-01-2006   -added blanking circuit
  43. // 22-01-2006   -added vertical window clipping
  44. // ----------
  45. // JB:
  46. // 2008-07-08   - added hires output (for scandoubler)
  47. //              - changed Denise ID (sometimes Show Config detected wrong chip type)
  48. // 2008-11-23   - playfield collision detection fix
  49. //              - changed horizontal counter counting range (fixes problems with overscan: Stardust, Forgoten Worlds)
  50. //              - added strhor signal to synchronize local horizontal counter
  51. // 2009-01-09   - added sprena signal (disables display of sprites until BPL1DAT is written)
  52. // 2009-03-08   - removed sof and sol inputs as they are no longer used
  53. // 2009-05-24   - clean-up & renaming
  54. // 2009-10-04   - implemented DIWHIGH register, pixel pipeline moved to clk28m domain, implemented super hires, changed ID to ECS
  55. // 2009-12-16   - added ECS enable input (only chip id is affected)
  56. // 2009-12-20   - DIWHIGH is written only in ECS mode
  57. // 2010-04-22   - ECS border blank implemented
  58.  
  59. module Denise
  60. (
  61.     input   clk28m,             // 35ns pixel clock
  62.     input   clk,                // bus clock / lores pixel clock
  63.     input   c1 ,                    // 35ns clock enable signals (for synchronization with clk)
  64.     input   c3,
  65.     input   cck,                    // colour clock enable
  66.     input   reset,              // reset
  67.     input       strhor,             // horizontal strobe
  68.     input   [8:1] reg_address_in,   // register address inputs
  69.     input   [15:0] data_in,         // bus data in
  70.     output  [15:0] data_out,    // bus data out
  71.     input       blank,              // blanking input
  72.     output  [7:0] red,          // red componenent video out
  73.     output  [7:0] green,        // green component video out
  74.     output  [7:0] blue,         // blue component video out
  75.     input       ecs,                    // enables ECS chipset features
  76.     input   a1k,                // control EHB chipset feature
  77.     output  reg hires           // hires
  78. );
  79.  
  80. //register names and adresses      
  81. parameter DIWSTRT  = 9'h08E;
  82. parameter DIWSTOP  = 9'h090;
  83. parameter DIWHIGH  = 9'h1E4;
  84. parameter BPLCON0  = 9'h100;       
  85. parameter BPLCON2  = 9'h104;
  86. parameter BPLCON3  = 9'h106;
  87. parameter BPLCON4  = 9'h10C;
  88. parameter DENISEID = 9'h07C;
  89. parameter BPL1DAT  = 9'h110;
  90.  
  91. //local signals
  92. reg     [8:0] hpos;         // horizontal beamcounter
  93. reg     shres;              // super high resolution select
  94. reg     homod;              // HAM mode select
  95. reg     dblpf;              // double playfield select
  96. reg     [3:0] bpu;          // bitplane enable
  97. reg     [3:0] l_bpu;        // latched bitplane enable
  98. reg     enaecs;             // enable ECS features like border blank (bplcon0.0)
  99. reg     [15:0] bplcon2; // bplcon2 (playfield video priority) register
  100. reg     [15:0] bplcon3; // bplcon3 register (border blank)  (palette bank for writes), low word enable
  101. reg     [15:0] bplcon4; // Palette offset - upper 8 bits xored with bitplane data.
  102.  
  103. wire        brdrblnk;           // border blank enable
  104.  
  105. reg     [8:0] hdiwstrt; // horizontal display window start position
  106. reg     [8:0] hdiwstop; // horizontal display window stop position
  107.  
  108. wire    [8:1] bpldata_out;  // bitplane serial data out from shifters
  109. wire    [8:1] bpldata;          // raw bitplane serial video data
  110. wire    [3:0] sprdata;          // sprite serial video data
  111. wire    [7:0] plfdata;          // playfield serial video data
  112. wire    [2:1] nplayfield;       // playfield 1,2 valid data signals
  113. wire    [7:0] nsprite;          // sprite 0-7 valid data signals
  114. wire    sprsel;                 // sprite select
  115.  
  116. reg [7:0] clut_data;        // colour table colour select in
  117. wire    [23:0] clut_rgb;        // colour table rgb data out
  118. wire    [23:0] ham_rgb;     // hold and modify mode RGB video data
  119.  
  120. wire    [23:0] out_rgb;     // final multiplexer rgb output data
  121.  
  122. reg window;                 // window enable signal
  123.  
  124. wire    [15:0] deniseid_out; // deniseid data_out
  125. wire    [15:0] col_out;     // colision detection data_out
  126.  
  127. reg display_ena;            // in OCS sprites are visible between first write to BPL1DAT and end of scanline
  128.  
  129. //--------------------------------------------------------------------------------------
  130.  
  131. // data out mulitplexer
  132. assign data_out = col_out | deniseid_out;
  133.  
  134. //--------------------------------------------------------------------------------------
  135.  
  136. // Denise horizontal counter counting range: $01-$E3 CCKs (2-455 lores pixels)
  137. always @(posedge clk)
  138.     if (strhor)
  139.         hpos <= 9'd2;
  140.     else
  141.         hpos <= hpos + 9'd1;
  142.  
  143. //--------------------------------------------------------------------------------------
  144.  
  145. // sprite display enable signal - sprites are visible after the first write to the BPL1DAT register in a scanline
  146. always @(posedge clk)
  147.     if (reset || hpos[8:0]==8)
  148.         display_ena <= 0;
  149.     else if (reg_address_in[8:1]==BPL1DAT[8:1])
  150.         display_ena <= 1;
  151.  
  152. // bpu is updated when bpl1dat register is written
  153. always @(posedge clk)
  154.     if (reg_address_in[8:1]==BPL1DAT[8:1])
  155.         l_bpu <= bpu;
  156.  
  157. // BPLCON0 register
  158. always @(posedge clk)
  159.     if (reset)
  160.     begin
  161.         hires <= 1'b0;
  162.         shres <= 1'b0;
  163.         homod <= 1'b0;
  164.         dblpf <= 1'b0;
  165.         bpu <= 4'b0000;
  166.         enaecs <= 1'b0;
  167.     end
  168.     else if (reg_address_in[8:1]==BPLCON0[8:1])
  169.     begin
  170.         hires <= data_in[15];
  171.         shres <= data_in[6];
  172.         homod <= data_in[11];
  173.         dblpf <= data_in[10];
  174.         bpu <= {data_in[4],data_in[14:12]};
  175.         enaecs <= data_in[0];
  176.     end
  177.  
  178. // BPLCON2 register
  179. always @(posedge clk)
  180.     if (reset)
  181.         bplcon2 <= 16'h00_00;
  182.     else if (reg_address_in[8:1]==BPLCON2[8:1])
  183.         bplcon2[15:0] <= data_in[15:0];
  184.  
  185. // BPLCON3 register
  186. // LOCT - bit 9
  187. // BANK - 15:13
  188. always @(posedge clk)
  189.     if (reset)
  190.         bplcon3 <= 16'b0000_1100_0000_0000;
  191.     else if (reg_address_in[8:1]==BPLCON3[8:1])
  192.         bplcon3[15:0] <= data_in[15:0];
  193.  
  194. assign brdrblnk = bplcon3[5];
  195.  
  196.  
  197. // BPLCON4 register - bitplane and sprite palette offsets (xored)
  198. always @(posedge clk)
  199.     if (reset)
  200.         bplcon4 <= 16'b0000_0000_0001_0001;
  201.     else if (reg_address_in[8:1]==BPLCON4[8:1])
  202.         bplcon4[15:0] <= data_in[15:0];
  203.  
  204.        
  205. // DIWSTART and DIWSTOP registers (vertical and horizontal limits of display window)
  206.    
  207. // HDIWSTRT
  208. always @(posedge clk)
  209.     if (reg_address_in[8:1]==DIWSTRT[8:1])
  210.         hdiwstrt[7:0] <= data_in[7:0];
  211.  
  212. always @(posedge clk)
  213.     if (reg_address_in[8:1]==DIWSTRT[8:1])
  214.         hdiwstrt[8] <= 1'b0; // diwstop H9 = 0
  215.     else if (reg_address_in[8:1]==DIWHIGH[8:1] && ecs)
  216.         hdiwstrt[8] <= data_in[5];
  217.  
  218. // HDIWSTOP
  219. always @(posedge clk)
  220.     if (reg_address_in[8:1]==DIWSTOP[8:1])
  221.         hdiwstop[7:0] <= data_in[7:0];
  222.  
  223. always @(posedge clk)
  224.     if (reg_address_in[8:1]==DIWSTOP[8:1])
  225.         hdiwstop[8] <= 1'b1; // diwstop H8 = 1
  226.     else if (reg_address_in[8:1]==DIWHIGH[8:1] && ecs)
  227.         hdiwstop[8] <= data_in[13];    
  228.  
  229. // Denise ID.
  230. // NOTE: Low bits are 0xFF for OCS, 0xFC for ECS, and 0xF8 for AGA.
  231. // Apparently, the older LISA chip also had the LSB set, so would be 0xF9? Best to stick with 0xF8 for AGA though. OzOnE
  232. //
  233. //assign deniseid_out = reg_address_in[8:1]==DENISEID[8:1] ? ecs ? 16'hFF_FC : 16'hFF_FF : 16'h00_00;
  234. assign deniseid_out = reg_address_in[8:1]==DENISEID[8:1] ? ecs ? 16'hFF_F8 : 16'hFF_FF : 16'h00_00; // Force Denise ID to AGA when ECS enabled! OzOnE
  235.  
  236. //--------------------------------------------------------------------------------------
  237.  
  238. // generate window enable signal
  239. // true when beamcounter satisfies horizontal diwstrt/diwstop limits
  240. always @(posedge clk)
  241.     if (hpos[8:0]==hdiwstrt[8:0])
  242.         window <= 1;
  243.     else if (hpos[8:0]==hdiwstop[8:0])
  244.         window <= 0;
  245.  
  246. reg window_ena;    
  247. always @(posedge clk)
  248.     window_ena <= window;
  249.    
  250. //--------------------------------------------------------------------------------------
  251.  
  252. // instantiate bitplane module
  253. bitplanes bplm0
  254. (
  255.     .clk(clk),
  256.     .clk28m(clk28m),
  257.     .c1(c1),
  258.     .c3(c3),
  259.     .reg_address_in(reg_address_in),
  260.     .data_in(data_in),
  261.     .hires(hires),
  262.     .shres(shres & ecs),
  263.     .hpos(hpos),
  264.     .bpldata(bpldata_out)  
  265. );
  266.  
  267. assign bpldata[1] = l_bpu > 0 ? bpldata_out[1] : 1'b0;
  268. assign bpldata[2] = l_bpu > 1 ? bpldata_out[2] : 1'b0;
  269. assign bpldata[3] = l_bpu > 2 ? bpldata_out[3] : 1'b0;
  270. assign bpldata[4] = l_bpu > 3 ? bpldata_out[4] : 1'b0;
  271. assign bpldata[5] = l_bpu > 4 ? bpldata_out[5] : 1'b0;
  272. assign bpldata[6] = l_bpu > 5 ? bpldata_out[6] : 1'b0;
  273. assign bpldata[7] = l_bpu > 6 ? bpldata_out[7] : 1'b0;
  274. assign bpldata[8] = l_bpu > 7 ? bpldata_out[8] : 1'b0;
  275.  
  276. // instantiate playfield module
  277. playfields plfm0
  278. (
  279.     .bpldata(bpldata),
  280.     .dblpf(dblpf),
  281.     .bplcon2(bplcon2[6:0]),
  282.     .nplayfield(nplayfield),
  283.     .plfdata(plfdata)  
  284. );
  285.  
  286. // instantiate sprite module
  287. sprites sprm0
  288. (
  289.     .clk(clk),
  290.     .reset(reset),
  291.     .ecs(1'b0),
  292.     .reg_address_in(reg_address_in),
  293.     .hpos(hpos),
  294.     .data_in(data_in),
  295.     .sprena(display_ena),
  296.     .nsprite(nsprite),
  297.     .sprdata(sprdata)  
  298. );
  299.  
  300. // instantiate video priority logic module
  301. sprpriority spm0
  302. (
  303.     .bplcon2(bplcon2[5:0]),
  304.     .nplayfield(nplayfield),
  305.     .nsprite(nsprite),
  306.     .sprsel(sprsel)
  307. );
  308.  
  309. // instantiate colour look up table
  310. colortable clut0
  311. (
  312.     .clk(clk),
  313.     .clk28m(clk28m),
  314.     .bank(bplcon3[15:13]),
  315.     .reg_address_in(reg_address_in),
  316.     .data_in(data_in[11:0]),
  317.     .loct(bplcon3[9]),  // (LOCT bit.)
  318. //  .select(clut_data ^ bplcon4[15:8]), // Apply palette offset. (added extra two bits for bitplane 7+8. AGA stuff. OzOnE.)
  319.     .select(clut_data),
  320.    .a1k(a1k),
  321.     .rgb(clut_rgb) // RGB data is delayed by one clk28m clock cycle
  322. );
  323.  
  324. // instantiate HAM (hold and modify) module
  325. hamgenerator ham0
  326. (
  327.     .clk(clk),
  328.     .clk28m(clk28m),
  329.     .bank(bplcon3[15:13]),
  330.     .reg_address_in(reg_address_in),
  331.     .data_in(data_in[11:0]),
  332.     .bpldata(bpldata),
  333.     .ham8( (l_bpu > 7) && homod),   // BPU=8 when all 8 bitplanes are enabled, plus check the HOMOD bit! (AGA HAM8 extensions. OzOnE.)
  334.     .loct(bplcon3[9]),              // (LOCT bit.)
  335.     .ham_rgb(ham_rgb)
  336. );
  337.  
  338. // instantiate collision detection module
  339. collision col0
  340. (
  341.     .clk(clk),
  342.     .reset(reset),
  343.     .reg_address_in(reg_address_in),
  344.     .data_in(data_in),
  345.     .data_out(col_out),
  346.     .dblpf(dblpf),
  347.     .bpldata(bpldata),
  348.     .nsprite(nsprite)  
  349. );
  350.  
  351. //--------------------------------------------------------------------------------------
  352.  
  353. //
  354. always @(sprsel or window_ena or sprdata or plfdata)
  355. begin
  356.     if (!window_ena) // we are outside of the visible window region, display border colour
  357.         clut_data = 8'b00000000;
  358.     else if (sprsel) // select sprites
  359.         clut_data = {4'b0001,sprdata[3:0]}; // Not sure what this 1 bit does yet? OzOnE
  360.     else // select playfield
  361.         clut_data = plfdata;
  362. end
  363.  
  364. reg window_del;
  365. reg sprsel_del;
  366.  
  367. always @(posedge clk28m)
  368. begin
  369.     window_del <= window_ena;
  370.     sprsel_del <= sprsel;
  371. end
  372.  
  373. // ham_rgb / clut_rgb multiplexer
  374. assign out_rgb = (homod && window_del && !sprsel_del) ? ham_rgb : clut_rgb;     //if no HAM mode, always select normal (table selected) rgb data
  375.                                                                                                         //
  376.                                                                                                         //ham_rgb is now 24-bit, with the lowest 4-bits of each colour set to zero in HAM6 mode. OzOnE
  377.  
  378. //--------------------------------------------------------------------------------------
  379.  
  380. wire t_blank;
  381.  
  382. assign t_blank = blank | ecs & enaecs & brdrblnk & (~window_del | ~display_ena);
  383.  
  384. // RGB video output
  385. assign {red,green,blue} = t_blank ? 24'h000000 : out_rgb;   // out_rgb is 24-bit now (AGA. OzOnE.)
  386.  
  387. endmodule
  388.  
  389. //--------------------------------------------------------------------------------------
  390. //--------------------------------------------------------------------------------------
  391.  
  392. // this is the 32-colour 12-bit colour table (now 256-colour, 24-bit! AMR / OzONE)
  393. // because this module also supports EHB (extra half brite) mode,
  394. // it actually has a 6bit colour select input
  395. // the 6th bit selects EHB colour while the lower 5 bit select the actual colour register
  396.  
  397. module colortable
  398. (
  399.     input   wire clk,               // bus clock / lores pixel clock
  400.     input   wire clk28m,                // 35ns pixel clock
  401.     input   wire [2:0] bank,            // Write bank from bplcon3
  402.     input   wire [8:1] reg_address_in,  // register address inputs
  403.     input   wire [11:0] data_in,            // bus data in
  404.     input   wire loct,              // data should be written to the 4 LSBs of each gun... (LOCT bit input.)
  405.     input   wire [7:0] select,  // colour select input
  406.     input   wire a1k,               // EHB control
  407. //  output reg [11:0] rgb       // RGB output
  408.     output wire [23:0] rgb      // RGB output
  409. );
  410.  
  411. // register names and adresses     
  412. parameter COLORBASE = 9'h180;       // colour table base address
  413.  
  414. // local signals
  415. //reg   [11:0] colortable [31:0];   // colour table
  416. //wire  [11:0] selcolor;            // selected colour register output
  417.  
  418. ColourtableDPBlockram ctbram    // Colourtable for High-order colour bits (normal OCS/ECS).
  419. (
  420.     .wraddress({bank,reg_address_in[5:1]}),
  421.     .rdaddress(select),
  422.     .rdclock(clk28m),
  423.     .wrclock(clk),
  424.     .data(data_in),
  425.     .wren((loct==0) && reg_address_in[8:6]==COLORBASE[8:6]),    // If the LOCT bit is CLEARED, both the High-order and Low-order colortable entries will get written to.
  426.     .q({rgb[23:20],rgb[15:12],rgb[7:4]})
  427. );
  428.  
  429.  
  430. ColourtableDPBlockram ctbram_lo // Colourtable for Low-order colour bits (AGA extension).
  431. (
  432.     .wraddress({bank,reg_address_in[5:1]}),
  433.     .rdaddress(select),
  434.     .rdclock(clk28m),
  435.     .wrclock(clk),
  436.     .data(data_in),
  437.     .wren((reg_address_in[8:6]==COLORBASE[8:6])),   // Writes to the normal High-order colortable bits (above) write to the Low-order bits as well if LOCT is cleared.
  438.     .q({rgb[19:16],rgb[11:8],rgb[3:0]})                 // So, you have to clear the LOCT bit first, write the High bits, set LOCT, write the Low bits. ;) OzOnE.
  439. );
  440.  
  441.  
  442. // writing of colour table from bus (implemented using dual port distributed ram)
  443. //always @(posedge clk)
  444. //  if (reg_address_in[8:6]==COLORBASE[8:6])
  445. //      colortable[reg_address_in[5:1]] <= data_in[11:0];
  446.    
  447. // reading of colour table
  448. //assign selcolor = colortable[select[4:0]];  
  449.  
  450. // extra half brite mode shifter
  451. //always @(posedge clk28m)
  452. //  if (select[5] && !a1k) // half bright, shift every component 1 position to the right
  453. //      rgb <= {1'b0,selcolor[11:9],1'b0,selcolor[7:5],1'b0,selcolor[3:1]};
  454. //  else // normal colour select
  455. //      if (reg_address_in[8:1]=={COLORBASE[8:6],select[4:0]}) // read-during-write...
  456. //          rgb <= data_in[11:0];
  457. //      else
  458. //          rgb <= selcolor;
  459.  
  460. endmodule
  461.  
  462. //--------------------------------------------------------------------------------------
  463. //--------------------------------------------------------------------------------------
  464.  
  465. // sprite priority logic module
  466. // this module checks the playfields and sprites video status and
  467. // determines if playfield or sprite data must be sent to the video output
  468. // sprite/playfield priority is configurable through the bplcon2 bits              
  469. module sprpriority
  470. (
  471.     input wire  [5:0] bplcon2,          // playfields vs sprites priority setting
  472.     input   wire [2:1] nplayfield,  // playfields video status
  473.     input   wire [7:0] nsprite,     // sprites video status
  474.     output reg  sprsel              // sprites select signal output
  475. );
  476.  
  477. // local signals
  478. reg [2:0] sprcode;          // sprite code
  479. wire    [3:0] sprgroup;     // grouped sprites
  480. wire    pf1front;               // playfield 1 is on front of sprites
  481. wire    pf2front;               // playfield 2 is on front of sprites
  482.  
  483. // group sprites together
  484. assign  sprgroup[0] = (nsprite[1:0]==2'd0) ? 1'b0 : 1'b1;
  485. assign  sprgroup[1] = (nsprite[3:2]==2'd0) ? 1'b0 : 1'b1;
  486. assign  sprgroup[2] = (nsprite[5:4]==2'd0) ? 1'b0 : 1'b1;
  487. assign  sprgroup[3] = (nsprite[7:6]==2'd0) ? 1'b0 : 1'b1;
  488.  
  489. // sprites priority encoder
  490. always @(sprgroup)
  491.     if (sprgroup[0])
  492.         sprcode = 3'd1;
  493.     else if (sprgroup[1])
  494.         sprcode = 3'd2;
  495.     else if (sprgroup[2])
  496.         sprcode = 3'd3;
  497.     else if (sprgroup[3])
  498.         sprcode = 3'd4;
  499.     else
  500.         sprcode = 3'd7;
  501.  
  502. // check if playfields are in front of sprites
  503. assign pf1front = sprcode[2:0]>bplcon2[2:0] ? 1'b1 : 1'b0;
  504. assign pf2front = sprcode[2:0]>bplcon2[5:3] ? 1'b1 : 1'b0;
  505.  
  506. // generate final playfield/sprite select signal
  507. always @(sprcode or pf1front or pf2front or nplayfield)
  508. begin
  509.     if (sprcode[2:0]==3'd7) // if no valid sprite data, always select playfields
  510.         sprsel = 1'b0;
  511.     else if (pf1front && nplayfield[1]) // else if pf1 in front and valid data, select playfields
  512.         sprsel = 1'b0;
  513.     else if (pf2front && nplayfield[2]) // else if pf2 in front and valid data, select playfields
  514.         sprsel = 1'b0;   
  515.     else // else select sprites
  516.         sprsel = 1'b1;
  517. end
  518.  
  519. endmodule
  520.  
  521. //--------------------------------------------------------------------------------------
  522. //--------------------------------------------------------------------------------------
  523.  
  524. // This module handles the hold and modify mode (HAM).
  525. // The module has its own colour palette bank, this is to let
  526. // the sprites run simultanously with a HAM playfield.
  527. //
  528. module hamgenerator
  529. (
  530.     input wire  clk,                    // bus clock
  531.     input wire  clk28m,                 // 35ns pixel clock
  532.    
  533.     input wire [8:1] reg_address_in,    // register address inputs
  534.     input wire [11:0] data_in,          // bus data in
  535.     input   wire [7:0] bpldata,         // bitplane data input
  536.    
  537.     input   wire ham8,                      // Enable HAM8 mode. (enabled when BPU[3] and HOMOD bits are set. OzOnE.)
  538.     input wire [2:0] bank,              // Bank bits. (bank[0] allows access to second group of color table entries in HAM8 mode.)
  539.                                                 // Extra bank bits brought in for future use. OzOnE
  540.    
  541.     input wire  loct,                       // LOCT bit.
  542.    
  543.     output reg [23:0] ham_rgb           // RGB output (24-bit packed, RRRRRRRRGGGGGGGGBBBBBBBB.)
  544. );
  545.  
  546. //register names and adresses      
  547. parameter COLORBASE = 9'h180;  // colour table base address
  548.  
  549. //local signals
  550. reg     [11:0] colortable_high [63:0];  // colour table. (Extended from 16 to 64 entries. AGA stuff. OzOnE.)
  551.                                                     // Note: HAM6 mode only accesses palette entries 0 to 15!
  552.  
  553. reg     [11:0] colortable_low [63:0];       // colour table. (Lower 12-bits, for AGA. OzOnE.)
  554.  
  555. wire    [23:0] selcolor;                        // selected colour output from colour table
  556.  
  557. //--------------------------------------------------------------------------------------
  558.  
  559. //writing of HAM colour table from bus (implemented using dual port distributed ram)
  560. //
  561. //     (LOCT bit Low, OCS/ECS)       (LOCT bit High, AGA only)
  562. //               ||                             ||
  563. //  Only 16 entries for OCS/ECS!        64 Entries for AGA!
  564. //   [Colour table - HIGH bits]      [Colour tablet, LOW bits]
  565. //
  566. // 1  [11,10,9,8,7,6,5,4,3,2,1,0]   [11,10,9,8,7,6,5,4,3,2,1,0]
  567. // 2  [11,10,9,8,7,6,5,4,3,2,1,0]   [11,10,9,8,7,6,5,4,3,2,1,0]
  568. // 3  [11,10,9,8,7,6,5,4,3,2,1,0]   [11,10,9,8,7,6,5,4,3,2,1,0]
  569. // .
  570. // .
  571. // 13 [11,10,9,8,7,6,5,4,3,2,1,0]   [11,10,9,8,7,6,5,4,3,2,1,0]
  572. // 14 [11,10,9,8,7,6,5,4,3,2,1,0]   [11,10,9,8,7,6,5,4,3,2,1,0]
  573. // 15 [11,10,9,8,7,6,5,4,3,2,1,0]   [11,10,9,8,7,6,5,4,3,2,1,0]
  574. //
  575. // NOTE: HAM6 only uses palette entries 0 to 15.
  576. //
  577. //
  578. // NOTE2: HAM8 can use palette entries 0 to 63.
  579. //
  580. // 16 [11,10,9,8,7,6,5,4,3,2,1,0]   [11,10,9,8,7,6,5,4,3,2,1,0]
  581. // 17 [11,10,9,8,7,6,5,4,3,2,1,0]   [11,10,9,8,7,6,5,4,3,2,1,0]
  582. // 18 [11,10,9,8,7,6,5,4,3,2,1,0]   [11,10,9,8,7,6,5,4,3,2,1,0]
  583. // .
  584. // .
  585. // 29 [11,10,9,8,7,6,5,4,3,2,1,0]   [11,10,9,8,7,6,5,4,3,2,1,0]
  586. // 30 [11,10,9,8,7,6,5,4,3,2,1,0]   [11,10,9,8,7,6,5,4,3,2,1,0]
  587. // 31 [11,10,9,8,7,6,5,4,3,2,1,0]   [11,10,9,8,7,6,5,4,3,2,1,0]
  588. //
  589. // 2nd Bank. (Bank0 bit High, AGA only)...
  590. //
  591. // 32 [11,10,9,8,7,6,5,4,3,2,1,0]   [11,10,9,8,7,6,5,4,3,2,1,0]
  592. // 33 [11,10,9,8,7,6,5,4,3,2,1,0]   [11,10,9,8,7,6,5,4,3,2,1,0]
  593. // 34 [11,10,9,8,7,6,5,4,3,2,1,0]   [11,10,9,8,7,6,5,4,3,2,1,0]
  594. // .
  595. // .
  596. // 61 [11,10,9,8,7,6,5,4,3,2,1,0]   [11,10,9,8,7,6,5,4,3,2,1,0]
  597. // 62 [11,10,9,8,7,6,5,4,3,2,1,0]   [11,10,9,8,7,6,5,4,3,2,1,0]
  598. // 63 [11,10,9,8,7,6,5,4,3,2,1,0]   [11,10,9,8,7,6,5,4,3,2,1,0]
  599. //
  600. //
  601. // COLORxx 180-1BE W COLOR table xx
  602. // There are thirty-two (32) of these registers
  603. // (xx=00~31) and together with the banking bits they
  604. // address the 256 locations in the Color Palette.
  605. // There are actually 2 sets of color registers,
  606. // selection of which is controlled by the LOCT
  607. // register bit. When LOCT=0, the 4 MSB of
  608. // RED,GREEEN, and BLUE video data are selected along
  609. // with the ZD bit for Genlocks. The low-order set of
  610. // registers is also selected simultaneously, so that
  611. // the 4 bit values are automatically extended to 8
  612. // bits. This provides compatibility with old
  613. // software. If the full range of palette values are
  614. // desired, then LOCT can be set high and independent
  615. // values for the 4 LSB of RED,GREEN, and BLUE can be
  616. // written. The low-order color registers do not
  617. // contain a transparency(T) bit. The Table below
  618. // shows the color register bit usage.
  619. //
  620. // (Our data bus is only 12-bits atm, so data bits 15:12 don't exist on Minimig yet. OzOnE.)
  621. //
  622. // BIT *  15,14,13,12, 11,10,09,08, 07,06,05,04, 03,02,01,00
  623. // LOCT=0  T  X  X  X  R7 R6 R5 R4  G7 G6 G5 G4  B7 B6 B5 B4  (colortable_high, LOCT=0 !)
  624. // LOCT=1  X  X  X  X  R3 R2 R1 R0  G3 G2 G1 GO  B3 B2 B1 HO  (colortable_low, LOCT=1 !)
  625. //
  626. // T = TRANSPARENCY   R = RED   G = GREEN   B = BLUE   X = UNUSED
  627. //
  628. //
  629.  
  630. wire [6:1] ct_addr = (ham8==1'b1) ? {bank[0],reg_address_in[5:1]} : {2'b00,reg_address_in[4:1]};
  631.  
  632. always @(posedge clk)
  633. //  if (reg_address_in[8:6]==COLORBASE[8:6]) begin  // True for Reg Addr 0x180 up to 0x1BE.
  634. //                                                                  // (colour table entries 0 to 31.) OzOnE.
  635.  
  636. //  if (reg_address_in[8:5]==COLORBASE[8:5]) begin  // True for Reg Addr 0x180 up to 0x19E.
  637. //                                                                  // (colour table entries 0 to 15.) OzOnE.
  638.  
  639.         if (ham8==1'b1 && reg_address_in[8:6]==COLORBASE[8:6]) begin    // HAM8 mode, and Reg Addr between 0x180 and 0x1BE...
  640.                                                                                             // (color table entries 0 to 31) OzOnE.
  641.             if (loct==1'b0) begin
  642.                 colortable_high[ct_addr] <= data_in[11:0];  // In HAM8 mode, writes with LOCT set LOW go to both the
  643.                 colortable_low[ct_addr] <= data_in[11:0];       // upper and lower 12-bits of the colour table....
  644.             end
  645.             else begin
  646.                 colortable_low[ct_addr] <= data_in[11:0];   // ...Writes with LOCT set HIGH go to the LOWER 12-bits of the colour table only.
  647.             end
  648.         end
  649.         else if (ham8==1'b0 && reg_address_in[8:5]==COLORBASE[8:5]) begin       // HAM6 mode, and Reg Addr between 0x180 and 0x19E...
  650.                                                                                                     // (color table entries 0 to 15). OzOnE.
  651.  
  652.             colortable_high[ct_addr]  <= data_in[11:0]; // HAM6 has no bank bit(s), and it only accesses entries 0 to 15 of the color table.
  653.         end                                                         // ...(and only writes to the Upper 12-bits of each color table entry. I think?)
  654. //  end
  655.  
  656. //reading of colour table
  657. //
  658. // In HAM8 mode, the two extra bitplane bits are then used to access colour table entries 0 to 63.
  659. // The upper and lower 12-bit colour tables are also combined for output.
  660. //
  661. assign selcolor = (ham8==1'b1) ? { colortable_high[bpldata[7:2]], colortable_low[bpldata[7:2]] } :  // HAM8 - extra 2 bitplane bits (6 total) can access all 64 palette entries.
  662.  
  663.                                           { colortable_high[{2'b00,bpldata[3:0]}], colortable_high[{2'b00,bpldata[3:0]}] }; // HAM6 (duplicated the 12-bit output to both halves). OzOnE.
  664.                                                                                                                                                         // HAM6 only access the first 16 color table entries, so padding the top two bits of the address.
  665. //--------------------------------------------------------------------------------------
  666. // HAM selcolor...
  667. //
  668. //      Color Table HIGH (HAM6 and HAM8)                Color Table LOW (HAM8 only)
  669. //
  670. // [11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]   [11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
  671. // [R7,R6,R5,R4,G7,G6,G5,G4,B7,B6,B5,B4]   [R3,R2,R1,R0,G3,G2,G1,G0,B3,B2,B1,B0]
  672. //
  673. //
  674. //HAM instruction decoder/processor
  675.  
  676. always @(posedge clk28m)
  677. begin
  678.     if (ham8==1'b1) begin   // HAM8 mode enabled....
  679.         case (bpldata[1:0]) // Note: HAM8 uses the two LOW bits of the bitplane data as the control bits!
  680.  
  681.             // NOTE: Take care when unpacking the correct bits from the color table output! OzOnE...
  682.             2'b00://Load (set) RGB output wite color table. R=[23:20]+[11:8]. G=[19:16]+[7:4]. B=[15:12]+[3:0].
  683.                 ham_rgb <= {selcolor[23:20],selcolor[11:8], selcolor[19:16],selcolor[7:4], selcolor[15:12],selcolor[3:0]};
  684.             2'b01://HOLD red and green, MODIFY Blue
  685.                 ham_rgb <= {ham_rgb[23:8]   ,bpldata[7:2],ham_rgb[1:0]};
  686.             2'b10://HOLD green and blue, MODIFY Red
  687.                 ham_rgb <= {bpldata[7:2],ham_rgb[17:16],   ham_rgb[15:0]};
  688.             2'b11://HOLD red and blue, MODIFY Green
  689.                 ham_rgb <= {ham_rgb[23:16]   ,bpldata[7:2],ham_rgb[9:8],   ,ham_rgb[7:0]};
  690.         endcase
  691.     end
  692.     else begin                  // HAM6 mode enabled... (D Paint V definitely using HAM6 for the "Elke_Mund.HAM" file). OzOnE
  693.         case (bpldata[5:4]) // Note: HAM6 uses the two HIGH bits of the bitplane data as the control bits!
  694.            
  695.             2'b00://Load (set) RGB output with color from table
  696.                 ham_rgb <= {selcolor[23:20],4'b0000, selcolor[19:16],4'b0000, selcolor[15:12],4'b0000};
  697.             2'b01://HOLD red and green, MODIFY Blue
  698.                 ham_rgb <= {ham_rgb[23:20],4'b0000,  ham_rgb[19:16],4'b0000,  bpldata[3:0],4'b0000};    // Lower 4 bits of each colour padded with zeros. OzOnE
  699.             2'b10://HOLD green and blue, MODIFY Red
  700.                 ham_rgb <= {bpldata[3:0],4'b0000,  ham_rgb[19:16],4'b0000,  ham_rgb[15:12],4'b0000};
  701.             2'b11://HOLD red and blue, MODIFY Green
  702.                 ham_rgb <= {ham_rgb[23:20],4'b0000,  bpldata[3:0],4'b0000,  ham_rgb[15:12],4'b0000};
  703.         endcase
  704.     end
  705. end
  706.  
  707.  
  708. endmodule
  709.  
  710. //--------------------------------------------------------------------------------------
  711. //--------------------------------------------------------------------------------------
  712.  
  713. //this is the collision detection module
  714. module collision
  715. (
  716.     input wire  clk,                    //bus clock / lores pixel clock
  717.     input   wire reset,                 //reset
  718.     input wire [8:1] reg_address_in,    //register address inputs
  719.     input wire [15:0] data_in,          //bus data in
  720.     output wire [15:0] data_out,        //bus data out
  721.     input   wire dblpf,                 //dual playfield signal, required to support undocumented feature
  722.     input   wire [7:0] bpldata,     //bitplane serial video data in
  723.     input   wire [7:0] nsprite
  724. );
  725.  
  726. //register names and adresses
  727. parameter CLXCON = 9'h098;
  728. parameter CLXCON2 = 9'h10E;
  729. parameter CLXDAT = 9'h00E;
  730.  
  731. //local signals
  732. reg [15:0] clxcon;      //collision detection control register
  733. reg [15:0] clxcon2; //collision detection control 2 register -AGA extensions. OzOnE.
  734. reg [14:0] clxdat;      //collision detection data register
  735. wire    [3:0] sprmatch; //sprite group matches clxcon settings
  736. wire    oddmatch;           //odd bitplane data matches clxcon settings
  737. wire    evenmatch;          //even bitplane data matches clxcon settings
  738.  
  739. //--------------------------------------------------------------------------------------
  740.  
  741. //CLXCON register
  742. always @(posedge clk)
  743.     if (reset) //reset to safe value
  744.         clxcon <= 16'h0fff;
  745.     else if (reg_address_in[8:1]==CLXCON[8:1])
  746.         clxcon <= data_in;
  747.  
  748. //CLXCON2 register (AGA extensions for bitplane 7 and 8. OzOnE).
  749. always @(posedge clk)
  750.     if (reset) //reset to safe value
  751.         clxcon2 <= 16'h00c3;
  752.     else if (reg_address_in[8:1]==CLXCON2[8:1])
  753.         clxcon2 <= data_in;
  754.        
  755. //--------------------------------------------------------------------------------------
  756.  
  757. //generate bitplane match signal
  758. wire [7:0] bm;
  759. assign bm = (bpldata[7:0] ^ ~{clxcon2[1:0],clxcon[5:0]} ) | (~{clxcon2[7:6],clxcon[11:6]}); // JB: playfield collision detection fix
  760.                                                                                                                           // (Extra bits for AGA added by OzOnE.)
  761.  
  762. // this is the implementation of an undocumented function in the real Denise chip, developed by Yaqube.
  763. // trigger was the game Rotor. mentioned in WinUAE sources to be the only known game needing this feature.
  764. // it also fixes the Spaceport instantly helicopter crash at takeoff
  765. // and Archon-1 'sticky effect' of player sprite at the battlefield.
  766. // the OCS mystery is cleaning up :)
  767. assign oddmatch = bm[6] & bm[4] & bm[2] & bm[0] & (dblpf | evenmatch);
  768. assign evenmatch = bm[7] & bm[5] & bm[3] & bm[1];
  769.  
  770. //generate sprite group match signal
  771. assign sprmatch[0] = nsprite[0] | (nsprite[1] & clxcon[12]);
  772. assign sprmatch[1] = nsprite[2] | (nsprite[3] & clxcon[13]);
  773. assign sprmatch[2] = nsprite[4] | (nsprite[5] & clxcon[14]);
  774. assign sprmatch[3] = nsprite[6] | (nsprite[7] & clxcon[15]);
  775.  
  776. //--------------------------------------------------------------------------------------
  777.  
  778. //detect collisions
  779. wire [14:0] cl;
  780. reg clxdat_read_del;
  781.  
  782. assign cl[0]  = evenmatch   & oddmatch;     //odd to even bitplanes
  783. assign cl[1]  = oddmatch    & sprmatch[0];  //odd bitplanes to sprite 0(or 1)
  784. assign cl[2]  = oddmatch    & sprmatch[1];  //odd bitplanes to sprite 2(or 3)
  785. assign cl[3]  = oddmatch    & sprmatch[2];  //odd bitplanes to sprite 4(or 5)
  786. assign cl[4]  = oddmatch    & sprmatch[3];  //odd bitplanes to sprite 6(or 7)
  787. assign cl[5]  = evenmatch   & sprmatch[0];  //even bitplanes to sprite 0(or 1)
  788. assign cl[6]  = evenmatch   & sprmatch[1];  //even bitplanes to sprite 2(or 3)
  789. assign cl[7]  = evenmatch   & sprmatch[2];  //even bitplanes to sprite 4(or 5)
  790. assign cl[8]  = evenmatch   & sprmatch[3];  //even bitplanes to sprite 6(or 7)
  791. assign cl[9]  = sprmatch[0] & sprmatch[1];  //sprite 0(or 1) to sprite 2(or 3)
  792. assign cl[10] = sprmatch[0] & sprmatch[2];  //sprite 0(or 1) to sprite 4(or 5)
  793. assign cl[11] = sprmatch[0] & sprmatch[3];  //sprite 0(or 1) to sprite 6(or 7)
  794. assign cl[12] = sprmatch[1] & sprmatch[2];  //sprite 2(or 3) to sprite 4(or 5)
  795. assign cl[13] = sprmatch[1] & sprmatch[3];  //sprite 2(or 3) to sprite 6(or 7)
  796. assign cl[14] = sprmatch[2] & sprmatch[3];  //sprite 4(or 5) to sprite 6(or 7)
  797.  
  798. wire clxdat_read = (reg_address_in[8:1]==CLXDAT[8:1]);// clxdat read
  799.  
  800. always @(posedge clk)
  801.     clxdat_read_del <= clxdat_read;  
  802.    
  803. //register detected collisions
  804. always @(posedge clk)
  805. //  if (reg_address_in[8:1]==CLXDAT[8:1])       //if clxdat is read, clxdat is cleared to all zero's
  806.     if (!clxdat_read & clxdat_read_del) //if clxdat is read, clxdat is cleared to all zero's after read
  807.         clxdat <= 0;
  808.     else //else register collisions
  809.         clxdat <= clxdat[14:0] | cl[14:0];
  810.  
  811. //--------------------------------------------------------------------------------------
  812.  
  813. //reading of clxdat register
  814. assign data_out = reg_address_in[8:1]==CLXDAT[8:1] ? {1'b1,clxdat[14:0]} : 16'd0;
  815.  
  816. endmodule
Advertisement
RAW Paste Data Copied
Advertisement