11/* F018 DMA core emulation for MEGA65
22 Part of the Xemu project. https://github.com/lgblgblgb/xemu
3- Copyright (C)2016-2024 LGB (Gábor Lénárt) <[email protected] > 3+ Copyright (C)2016-2025 LGB (Gábor Lénárt) <[email protected] > 44
55This program is free software; you can redistribute it and/or modify
66it under the terms of the GNU General Public License as published by
@@ -195,18 +195,21 @@ static XEMU_INLINE void address_stepping ( struct dma_channel_st *const channel
195195 // otherwise, we must deal with LDM. The following code is based
196196 // on ideas found in a sample C implementation written by btoschi. THANKS!!
197197 // WARNING: in Xemu, I use a single variable for "addr" and lower 8 bit is the fractional part!!
198+ channel -> ldm .slope_accu += channel -> ldm .slope ;
198199 if (channel -> ldm .slope_type & 0x40 ) {
199200 channel -> addr += 0x800U ; // +8 -> we always step in Y
201+ // Not sure it's correct at all. TODO: need some test material using this
202+ if ((channel -> addr & (7 << (3 + 8 ))) == (7 << (3 + 8 )))
203+ channel -> addr += channel -> ldm .y_col ;
200204 if (channel -> ldm .slope_accu > 0xFFFFU ) {
201205 channel -> ldm .slope_accu &= 0xFFFFU ;
202206 if (channel -> ldm .slope_type & 0x20 )
203207 channel -> addr -= ((channel -> addr & 0x700 ) == 0 ) ? channel -> ldm .x_col + 0x100 : 0x100 ;
204208 else
205- channel -> addr += ((channel -> addr & 0x700 ) == 0 ) ? channel -> ldm .x_col + 0x100 : 0x100 ;
209+ channel -> addr += ((channel -> addr & 0x700 ) == 0x700 ) ? channel -> ldm .x_col + 0x100 : 0x100 ;
206210 }
207211 } else {
208212 channel -> addr += ((channel -> addr & 0x700 ) == 0x700 ) ? channel -> ldm .x_col + 0x100 : 0x100 ;
209- channel -> ldm .slope_accu += channel -> ldm .slope ;
210213 if (channel -> ldm .slope_accu > 0xFFFFU ) {
211214 channel -> ldm .slope_accu &= 0xFFFFU ;
212215 channel -> addr += (channel -> ldm .slope_type & 0x20 ) ? -0x800 : 0x800 ;
@@ -342,8 +345,9 @@ void dma_write_reg ( int addr, Uint8 data )
342345 source .mbyte = 0 ; // source MB
343346 target .mbyte = 0 ; // target MB
344347 length_byte3 = 0 ; // length byte for >=64K DMA sessions
345- source .ldm .slope_type = 0 ; // source: line drawing mode, slope type, do not enable line drawing mode by default
346- target .ldm .slope_type = 0 ; // target: -- "" --
348+ // zero out LDM-specific options by default
349+ memset (& source .ldm , 0 , sizeof source .ldm );
350+ memset (& target .ldm , 0 , sizeof target .ldm );
347351 mb_cross = mb_cross_global ; // allow to cross megabyte boundaries
348352 if (enhanced_mode )
349353 DEBUGDMA ("DMA: initiation of ENCHANCED MODE DMA!!!!\n" );
@@ -439,10 +443,10 @@ int dma_update ( void )
439443 target .ldm .x_col = (target .ldm .x_col & 0x00FF00U ) + (optval << 16 ); // Xemu integer + 8 bit fractional part arithmetic!
440444 break ;
441445 case 0x89 : // DMA line drawing mode TARGET - Row Y col (LSB)
442- target .ldm .y_col = (target .ldm .y_col & 0xFF00U ) + optval ;
446+ target .ldm .y_col = (target .ldm .y_col & 0xFF0000U ) + ( optval << 8 ); // Xemu integer + 8 bit fractional part arithmetic!
443447 break ;
444448 case 0x8A : // DMA line drawing mode TARGET - Row Y col (MSB)
445- target .ldm .y_col = (target .ldm .y_col & 0x00FFU ) + (optval << 8 );
449+ target .ldm .y_col = (target .ldm .y_col & 0x00FF00U ) + (optval << 16 ); // Xemu integer + 8 bit fractional part arithmetic!
446450 break ;
447451 case 0x8B : // DMA line drawing mode TARGET - Slope (LSB)
448452 target .ldm .slope = (target .ldm .slope & 0xFF00U ) + optval ;
@@ -469,10 +473,10 @@ int dma_update ( void )
469473 source .ldm .x_col = (source .ldm .x_col & 0x00FF00U ) + (optval << 16 ); // Xemu integer + 8 bit fractional part arithmetic!
470474 break ;
471475 case 0x99 : // DMA line drawing mode SOURCE - Row Y col (LSB)
472- source .ldm .y_col = (source .ldm .y_col & 0xFF00U ) + optval ;
476+ source .ldm .y_col = (source .ldm .y_col & 0xFF0000U ) + ( optval << 8 ); // Xemu integer + 8 bit fractional part arithmetic!
473477 break ;
474478 case 0x9A : // DMA line drawing mode SOURCE - Row Y col (MSB)
475- source .ldm .y_col = (source .ldm .y_col & 0x00FFU ) + (optval << 8 );
479+ source .ldm .y_col = (source .ldm .y_col & 0x00FF00U ) + (optval << 16 ); // Xemu integer + 8 bit fractional part arithmetic!
476480 break ;
477481 case 0x9B : // DMA line drawing mode SOURCE - Slope (LSB)
478482 source .ldm .slope = (source .ldm .slope & 0xFF00U ) + optval ;
0 commit comments