CosmosEx - SLM Printer Emulation

News, questions and bugs reports about CosmosEx by Jookie. Now we have a Raspberry Pi in our machines!

Moderators: Jookie, Moderator Team

User avatar
1st1
Atari Super Hero
Atari Super Hero
Posts: 685
Joined: Mon May 07, 2012 11:48 am

CosmosEx - SLM Printer Emulation

Postby 1st1 » Mon Apr 11, 2016 6:38 pm

Hello, as there is interest on implementing the ATARI SLM laser printer as an emulation into CosmosEx, I open this topic. The idea is that the CosmosEx reacts on ACSI under another ID (usually #5) the same like an ATARI SLM 804/605 laserprinter. CosmosEx takes the bitmap from computer, converts it to something CUPS can work with and forwards it to an attached modern printer. The modern printer then can be anything supported by CUPS, connected locally through USB, connected via network or server share (LPR, SMB). Even bitmapped (or vectorized?) postscript or PDF output would be possible.

That's the idea. The difficult part is how an ATARI talks to the SLM. There is no documentation online, maybe even not preserved anywhere? The only thing is the service manual for the SLM 804 which can be found on devdocs. Out of this we know that inside the SLMC 804 ACSI to laserprinter interface an Motoroloa 6801 embedded microprocessor is running, with 2 kB of internal ROM. It does all the work. It would be quite difficult to read out that ROM as the 6801 has to be set to diagnostics mode that it runs code from external ROM which then outputs the internal ROM to an IO-port, and something must take over these datas and store it for analyzing. Sounds complicate and it is. Some peoples have done this for the bit similar MOS 6501 processor found in Commodore MPS 1520 plotter and Commodore Amiga keyboard controller.

SLM 804 Service Manual: http://dev-docs.atariforge.org/files/SL ... Manual.pdf
6801 embeddes microprocessor: http://dev-docs.atariforge.org/files/SL ... Manual.pdf
Reading ROM of MOS 6501 embedded microprozessor: http://e4aws.silverdr.com/hacks/6500_1/

I have contacted calamus.net if they still have some documents about it, no they don't, even not the source code of the SLM printer driver module for old Calamus versions, sad. But they had a hot tipp. Linux. Linux 68K to be exact...

I think it should include everything is needed to know. But this is the opposite side, the printer driver, which would send the data to the SLM emulator. Anyhow, to understand how it works, I think this could be useful.

Folder: https://www.kernel.org/pub/linux/kernel ... ers/block/
Source: https://www.kernel.org/pub/linux/kernel ... acsi_slm.c

Code: Select all

/*
 * acsi_slm.c -- Device driver for the Atari SLM laser printer
 *
 * Copyright 1995 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file COPYING in the main directory of this archive for
 * more details.
 *
 */

/*

Notes:

The major number for SLM printers is 28 (like ACSI), but as a character
device, not block device. The minor number is the number of the printer (if
you have more than one SLM; currently max. 2 (#define-constant) SLMs are
supported). The device can be opened for reading and writing. If reading it,
you get some status infos (MODE SENSE data). Writing mode is used for the data
to be printed. Some ioctls allow to get the printer status and to tune printer
modes and some internal variables.

A special problem of the SLM driver is the timing and thus the buffering of
the print data. The problem is that all the data for one page must be present
in memory when printing starts, else --when swapping occurs-- the timing could
not be guaranteed. There are several ways to assure this:

 1) Reserve a buffer of 1196k (maximum page size) statically by
    atari_stram_alloc(). The data are collected there until they're complete,
   and then printing starts. Since the buffer is reserved, no further
   considerations about memory and swapping are needed. So this is the
   simplest method, but it needs a lot of memory for just the SLM.

    An striking advantage of this method is (supposed the SLM_CONT_CNT_REPROG
   method works, see there), that there are no timing problems with the DMA
   anymore.
   
 2) The other method would be to reserve the buffer dynamically each time
    printing is required. I could think of looking at mem_map where the
   largest unallocted ST-RAM area is, taking the area, and then extending it
   by swapping out the neighbored pages, until the needed size is reached.
   This requires some mm hacking, but seems possible. The only obstacle could
   be pages that cannot be swapped out (reserved pages)...

 3) Another possibility would be to leave the real data in user space and to
    work with two dribble buffers of about 32k in the driver: While the one
   buffer is DMAed to the SLM, the other can be filled with new data. But
   to keep the timing, that requires that the user data remain in memory and
   are not swapped out. Requires mm hacking, too, but maybe not so bad as
   method 2).

*/

#include <linux/module.h>

#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/fs.h>
#include <linux/major.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/time.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/smp_lock.h>

#include <asm/pgtable.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/atarihw.h>
#include <asm/atariints.h>
#include <asm/atari_acsi.h>
#include <asm/atari_stdma.h>
#include <asm/atari_stram.h>
#include <asm/atari_SLM.h>


#undef   DEBUG

/* Define this if the page data are continuous in physical memory. That
 * requires less reprogramming of the ST-DMA */
#define   SLM_CONTINUOUS_DMA

/* Use continuous reprogramming of the ST-DMA counter register. This is
 * --strictly speaking-- not allowed, Atari recommends not to look at the
 * counter register while a DMA is going on. But I don't know if that applies
 * only for reading the register, or also writing to it. Writing only works
 * fine for me... The advantage is that the timing becomes absolutely
 * uncritical: Just update each, say 200ms, the counter reg to its maximum,
 * and the DMA will work until the status byte interrupt occurs.
 */
#define   SLM_CONT_CNT_REPROG

#define MAJOR_NR ACSI_MAJOR

#define CMDSET_TARG_LUN(cmd,targ,lun)         \
    do {                              \
      cmd[0] = (cmd[0] & ~0xe0) | (targ)<<5;   \
      cmd[1] = (cmd[1] & ~0xe0) | (lun)<<5;   \
   } while(0)

#define   START_TIMER(to)   mod_timer(&slm_timer, jiffies + (to))
#define   STOP_TIMER()   del_timer(&slm_timer)


static char slmreqsense_cmd[6] = { 0x03, 0, 0, 0, 0, 0 };
static char slmprint_cmd[6]    = { 0x0a, 0, 0, 0, 0, 0 };
static char slminquiry_cmd[6]  = { 0x12, 0, 0, 0, 0, 0x80 };
static char slmmsense_cmd[6]   = { 0x1a, 0, 0, 0, 255, 0 };
#if 0
static char slmmselect_cmd[6]  = { 0x15, 0, 0, 0, 0, 0 };
#endif


#define   MAX_SLM      2

static struct slm {
   unsigned   target;         /* target number */
   unsigned   lun;         /* LUN in target controller */
   unsigned   wbusy : 1;      /* output part busy */
   unsigned   rbusy : 1;      /* status part busy */
} slm_info[MAX_SLM];

int N_SLM_Printers = 0;

/* printer buffer */
static unsigned char   *SLMBuffer;   /* start of buffer */
static unsigned char   *BufferP;   /* current position in buffer */
static int            BufferSize;   /* length of buffer for page size */

typedef enum { IDLE, FILLING, PRINTING } SLMSTATE;
static SLMSTATE         SLMState;
static int            SLMBufOwner;   /* SLM# currently using the buffer */

/* DMA variables */
#ifndef SLM_CONT_CNT_REPROG
static unsigned long   SLMCurAddr;      /* current base addr of DMA chunk */
static unsigned long   SLMEndAddr;      /* expected end addr */
static unsigned long   SLMSliceSize;   /* size of one DMA chunk */
#endif
static int            SLMError;

/* wait queues */
static DECLARE_WAIT_QUEUE_HEAD(slm_wait);   /* waiting for buffer */
static DECLARE_WAIT_QUEUE_HEAD(print_wait);   /* waiting for printing finished */

/* status codes */
#define   SLMSTAT_OK      0x00
#define   SLMSTAT_ORNERY   0x02
#define   SLMSTAT_TONER   0x03
#define   SLMSTAT_WARMUP   0x04
#define   SLMSTAT_PAPER   0x05
#define   SLMSTAT_DRUM   0x06
#define   SLMSTAT_INJAM   0x07
#define   SLMSTAT_THRJAM   0x08
#define   SLMSTAT_OUTJAM   0x09
#define   SLMSTAT_COVER   0x0a
#define   SLMSTAT_FUSER   0x0b
#define   SLMSTAT_IMAGER   0x0c
#define   SLMSTAT_MOTOR   0x0d
#define   SLMSTAT_VIDEO   0x0e
#define   SLMSTAT_SYSTO   0x10
#define   SLMSTAT_OPCODE   0x12
#define   SLMSTAT_DEVNUM   0x15
#define   SLMSTAT_PARAM   0x1a
#define   SLMSTAT_ACSITO   0x1b   /* driver defined */
#define   SLMSTAT_NOTALL   0x1c   /* driver defined */

static char *SLMErrors[] = {
   /* 0x00 */   "OK and ready",
   /* 0x01 */   NULL,
   /* 0x02 */   "ornery printer",
   /* 0x03 */   "toner empty",
   /* 0x04 */   "warming up",
   /* 0x05 */   "paper empty",
   /* 0x06 */   "drum empty",
   /* 0x07 */   "input jam",
   /* 0x08 */   "through jam",
   /* 0x09 */   "output jam",
   /* 0x0a */   "cover open",
   /* 0x0b */   "fuser malfunction",
   /* 0x0c */   "imager malfunction",
   /* 0x0d */   "motor malfunction",
   /* 0x0e */   "video malfunction",
   /* 0x0f */   NULL,
   /* 0x10 */   "printer system timeout",
   /* 0x11 */   NULL,
   /* 0x12 */   "invalid operation code",
   /* 0x13 */   NULL,
   /* 0x14 */   NULL,
   /* 0x15 */   "invalid device number",
   /* 0x16 */   NULL,
   /* 0x17 */   NULL,
   /* 0x18 */   NULL,
   /* 0x19 */   NULL,
   /* 0x1a */   "invalid parameter list",
   /* 0x1b */   "ACSI timeout",
   /* 0x1c */   "not all printed"
};

#define   N_ERRORS   (sizeof(SLMErrors)/sizeof(*SLMErrors))

/* real (driver caused) error? */
#define   IS_REAL_ERROR(x)   (x > 0x10)


static struct {
   char   *name;
   int    w, h;
} StdPageSize[] = {
   { "Letter", 2400, 3180 },
   { "Legal",  2400, 4080 },
   { "A4",     2336, 3386 },
   { "B5",     2016, 2914 }
};

#define   N_STD_SIZES      (sizeof(StdPageSize)/sizeof(*StdPageSize))

#define   SLM_BUFFER_SIZE   (2336*3386/8)   /* A4 for now */
#define   SLM_DMA_AMOUNT   255            /* #sectors to program the DMA for */

#ifdef   SLM_CONTINUOUS_DMA
# define   SLM_DMA_INT_OFFSET   0      /* DMA goes until seccnt 0, no offs */
# define   SLM_DMA_END_OFFSET   32      /* 32 Byte ST-DMA FIFO */
# define   SLM_SLICE_SIZE(w)    (255*512)
#else
# define   SLM_DMA_INT_OFFSET   32      /* 32 Byte ST-DMA FIFO */
# define   SLM_DMA_END_OFFSET   32      /* 32 Byte ST-DMA FIFO */
# define   SLM_SLICE_SIZE(w)   ((254*512)/(w/8)*(w/8))
#endif

/* calculate the number of jiffies to wait for 'n' bytes */
#ifdef SLM_CONT_CNT_REPROG
#define   DMA_TIME_FOR(n)      50
#define   DMA_STARTUP_TIME   0
#else
#define   DMA_TIME_FOR(n)      (n/1400-1)
#define   DMA_STARTUP_TIME   650
#endif

/***************************** Prototypes *****************************/

static char *slm_errstr( int stat );
static int slm_getstats( char *buffer, int device );
static ssize_t slm_read( struct file* file, char *buf, size_t count, loff_t
                         *ppos );
static void start_print( int device );
static void slm_interrupt(int irc, void *data, struct pt_regs *fp);
static void slm_test_ready( unsigned long dummy );
static void set_dma_addr( unsigned long paddr );
static unsigned long get_dma_addr( void );
static ssize_t slm_write( struct file *file, const char *buf, size_t count,
                          loff_t *ppos );
static int slm_ioctl( struct inode *inode, struct file *file, unsigned int
                      cmd, unsigned long arg );
static int slm_open( struct inode *inode, struct file *file );
static int slm_release( struct inode *inode, struct file *file );
static int slm_req_sense( int device );
static int slm_mode_sense( int device, char *buffer, int abs_flag );
#if 0
static int slm_mode_select( int device, char *buffer, int len, int
                            default_flag );
#endif
static int slm_get_pagesize( int device, int *w, int *h );

/************************* End of Prototypes **************************/


static struct timer_list slm_timer = { function: slm_test_ready };

static struct file_operations slm_fops = {
   owner:      THIS_MODULE,
   read:      slm_read,
   write:      slm_write,
   ioctl:      slm_ioctl,
   open:      slm_open,
   release:   slm_release,
};


/* ---------------------------------------------------------------------- */
/*                        Status Functions                       */


static char *slm_errstr( int stat )

{   char *p;
   static char   str[22];

   stat &= 0x1f;
   if (stat >= 0 && stat < N_ERRORS && (p = SLMErrors[stat]))
      return( p );
   sprintf( str, "unknown status 0x%02x", stat );
   return( str );
}


static int slm_getstats( char *buffer, int device )

{   int          len = 0, stat, i, w, h;
   unsigned char   buf[256];
   
   stat = slm_mode_sense( device, buf, 0 );
   if (IS_REAL_ERROR(stat))
      return( -EIO );
   
#define SHORTDATA(i)      ((buf[i] << 8) | buf[i+1])
#define   BOOLDATA(i,mask)   ((buf[i] & mask) ? "on" : "off")

   w = SHORTDATA( 3 );
   h = SHORTDATA( 1 );
      
   len += sprintf( buffer+len, "Status\t\t%s\n",
               slm_errstr( stat ) );
   len += sprintf( buffer+len, "Page Size\t%dx%d",
               w, h );

   for( i = 0; i < N_STD_SIZES; ++i ) {
      if (w == StdPageSize[i].w && h == StdPageSize[i].h)
         break;
   }
   if (i < N_STD_SIZES)
      len += sprintf( buffer+len, " (%s)", StdPageSize[i].name );
   buffer[len++] = '\n';

   len += sprintf( buffer+len, "Top/Left Margin\t%d/%d\n",
               SHORTDATA( 5 ), SHORTDATA( 7 ) );
   len += sprintf( buffer+len, "Manual Feed\t%s\n",
               BOOLDATA( 9, 0x01 ) );
   len += sprintf( buffer+len, "Input Select\t%d\n",
               (buf[9] >> 1) & 7 );
   len += sprintf( buffer+len, "Auto Select\t%s\n",
               BOOLDATA( 9, 0x10 ) );
   len += sprintf( buffer+len, "Prefeed Paper\t%s\n",
               BOOLDATA( 9, 0x20 ) );
   len += sprintf( buffer+len, "Thick Pixels\t%s\n",
               BOOLDATA( 9, 0x40 ) );
   len += sprintf( buffer+len, "H/V Resol.\t%d/%d dpi\n",
               SHORTDATA( 12 ), SHORTDATA( 10 ) );
   len += sprintf( buffer+len, "System Timeout\t%d\n",
               buf[14] );
   len += sprintf( buffer+len, "Scan Time\t%d\n",
               SHORTDATA( 15 ) );
   len += sprintf( buffer+len, "Page Count\t%d\n",
               SHORTDATA( 17 ) );
   len += sprintf( buffer+len, "In/Out Cap.\t%d/%d\n",
               SHORTDATA( 19 ), SHORTDATA( 21 ) );
   len += sprintf( buffer+len, "Stagger Output\t%s\n",
               BOOLDATA( 23, 0x01 ) );
   len += sprintf( buffer+len, "Output Select\t%d\n",
               (buf[23] >> 1) & 7 );
   len += sprintf( buffer+len, "Duplex Print\t%s\n",
               BOOLDATA( 23, 0x10 ) );
   len += sprintf( buffer+len, "Color Sep.\t%s\n",
               BOOLDATA( 23, 0x20 ) );

   return( len );
}


static ssize_t slm_read( struct file *file, char *buf, size_t count,
                   loff_t *ppos )

{
   struct inode *node = file->f_dentry->d_inode;
   loff_t pos = *ppos;
   unsigned long page;
   int length;
   int end;

   if (count < 0)
      return( -EINVAL );
   if (!(page = __get_free_page( GFP_KERNEL )))
      return( -ENOMEM );
   
   length = slm_getstats( (char *)page, MINOR(node->i_rdev) );
   if (length < 0) {
      count = length;
      goto out;
   }
   if (pos != (unsigned) pos || pos >= length) {
      count = 0;
      goto out;
   }
   if (count > length - pos)
      count = length - pos;
   end = count + pos;
   if (copy_to_user(buf, (char *)page + pos, count)) {
      count = -EFAULT;
      goto out;
   }
   *ppos = end;
out:   free_page( page );
   return( count );
}


/* ---------------------------------------------------------------------- */
/*                           Printing                          */


static void start_print( int device )

{   struct slm *sip = &slm_info[device];
   unsigned char   *cmd;
   unsigned long   paddr;
   int            i;
   
   stdma_lock( slm_interrupt, NULL );

   CMDSET_TARG_LUN( slmprint_cmd, sip->target, sip->lun );
   cmd = slmprint_cmd;
   paddr = virt_to_phys( SLMBuffer );
   dma_cache_maintenance( paddr, virt_to_phys(BufferP)-paddr, 1 );
   DISABLE_IRQ();

   /* Low on A1 */
   dma_wd.dma_mode_status = 0x88;
   MFPDELAY();

   /* send the command bytes except the last */
   for( i = 0; i < 5; ++i ) {
      DMA_LONG_WRITE( *cmd++, 0x8a );
      udelay(20);
      if (!acsi_wait_for_IRQ( HZ/2 )) {
         SLMError = 1;
         return; /* timeout */
      }
   }
   /* last command byte */
   DMA_LONG_WRITE( *cmd++, 0x82 );
   MFPDELAY();
   /* set DMA address */
   set_dma_addr( paddr );
   /* program DMA for write and select sector counter reg */
   dma_wd.dma_mode_status = 0x192;
   MFPDELAY();
   /* program for 255*512 bytes and start DMA */
   DMA_LONG_WRITE( SLM_DMA_AMOUNT, 0x112 );

#ifndef SLM_CONT_CNT_REPROG
   SLMCurAddr = paddr;
   SLMEndAddr = paddr + SLMSliceSize + SLM_DMA_INT_OFFSET;
#endif
   START_TIMER( DMA_STARTUP_TIME + DMA_TIME_FOR( SLMSliceSize ));
#if !defined(SLM_CONT_CNT_REPROG) && defined(DEBUG)
   printk( "SLM: CurAddr=%#lx EndAddr=%#lx timer=%ld\n",
         SLMCurAddr, SLMEndAddr, DMA_TIME_FOR( SLMSliceSize ) );
#endif
   
   ENABLE_IRQ();
}


/* Only called when an error happened or at the end of a page */

static void slm_interrupt(int irc, void *data, struct pt_regs *fp)

{   unsigned long   addr;
   int            stat;
   
   STOP_TIMER();
   addr = get_dma_addr();
   stat = acsi_getstatus();
   SLMError = (stat < 0)             ? SLMSTAT_ACSITO :
             (addr < virt_to_phys(BufferP)) ? SLMSTAT_NOTALL :
                               stat;

   dma_wd.dma_mode_status = 0x80;
   MFPDELAY();
#ifdef DEBUG
   printk( "SLM: interrupt, addr=%#lx, error=%d\n", addr, SLMError );
#endif

   wake_up( &print_wait );
   stdma_release();
   ENABLE_IRQ();
}


static void slm_test_ready( unsigned long dummy )

{
#ifdef SLM_CONT_CNT_REPROG
   /* program for 255*512 bytes again */
   dma_wd.fdc_acces_seccount = SLM_DMA_AMOUNT;
   START_TIMER( DMA_TIME_FOR(0) );
#ifdef DEBUG
   printk( "SLM: reprogramming timer for %d jiffies, addr=%#lx\n",
         DMA_TIME_FOR(0), get_dma_addr() );
#endif
   
#else /* !SLM_CONT_CNT_REPROG */

   unsigned long   flags, addr;
   int            d, ti;
#ifdef DEBUG
   struct timeval start_tm, end_tm;
   int            did_wait = 0;
#endif

   save_flags(flags);
   cli();
   
   addr = get_dma_addr();
   if ((d = SLMEndAddr - addr) > 0) {
      restore_flags(flags);
      
      /* slice not yet finished, decide whether to start another timer or to
       * busy-wait */
      ti = DMA_TIME_FOR( d );
      if (ti > 0) {
#ifdef DEBUG
         printk( "SLM: reprogramming timer for %d jiffies, rest %d bytes\n",
               ti, d );
#endif
         START_TIMER( ti );
         return;
      }
      /* wait for desired end address to be reached */
#ifdef DEBUG
      do_gettimeofday( &start_tm );
      did_wait = 1;
#endif
      cli();
      while( get_dma_addr() < SLMEndAddr )
         barrier();
   }

   /* slice finished, start next one */
   SLMCurAddr += SLMSliceSize;

#ifdef SLM_CONTINUOUS_DMA
   /* program for 255*512 bytes again */
   dma_wd.fdc_acces_seccount = SLM_DMA_AMOUNT;
#else
   /* set DMA address;
    * add 2 bytes for the ones in the SLM controller FIFO! */
   set_dma_addr( SLMCurAddr + 2 );
   /* toggle DMA to write and select sector counter reg */
   dma_wd.dma_mode_status = 0x92;
   MFPDELAY();
   dma_wd.dma_mode_status = 0x192;
   MFPDELAY();
   /* program for 255*512 bytes and start DMA */
   DMA_LONG_WRITE( SLM_DMA_AMOUNT, 0x112 );
#endif
   
   restore_flags(flags);

#ifdef DEBUG
   if (did_wait) {
      int ms;
      do_gettimeofday( &end_tm );
      ms = (end_tm.tv_sec*1000000+end_tm.tv_usec) -
          (start_tm.tv_sec*1000000+start_tm.tv_usec);
      printk( "SLM: did %ld.%ld ms busy waiting for %d bytes\n",
            ms/1000, ms%1000, d );
   }
   else
      printk( "SLM: didn't wait (!)\n" );
#endif

   if ((unsigned char *)PTOV( SLMCurAddr + SLMSliceSize ) >= BufferP) {
      /* will be last slice, no timer necessary */
#ifdef DEBUG
      printk( "SLM: CurAddr=%#lx EndAddr=%#lx last slice -> no timer\n",
            SLMCurAddr, SLMEndAddr );
#endif
   }
   else {
      /* not last slice */
      SLMEndAddr = SLMCurAddr + SLMSliceSize + SLM_DMA_INT_OFFSET;
      START_TIMER( DMA_TIME_FOR( SLMSliceSize ));
#ifdef DEBUG
      printk( "SLM: CurAddr=%#lx EndAddr=%#lx timer=%ld\n",
            SLMCurAddr, SLMEndAddr, DMA_TIME_FOR( SLMSliceSize ) );
#endif
   }
#endif /* SLM_CONT_CNT_REPROG */
}


static void set_dma_addr( unsigned long paddr )

{   unsigned long   flags;
   
   save_flags(flags); 
   cli();
   dma_wd.dma_lo = (unsigned char)paddr;
   paddr >>= 8;
   MFPDELAY();
   dma_wd.dma_md = (unsigned char)paddr;
   paddr >>= 8;
   MFPDELAY();
   if (ATARIHW_PRESENT( EXTD_DMA ))
      st_dma_ext_dmahi = (unsigned short)paddr;
   else
      dma_wd.dma_hi = (unsigned char)paddr;
   MFPDELAY();
   restore_flags(flags);
}


static unsigned long get_dma_addr( void )

{   unsigned long   addr;
   
   addr = dma_wd.dma_lo & 0xff;
   MFPDELAY();
   addr |= (dma_wd.dma_md & 0xff) << 8;
   MFPDELAY();
   addr |= (dma_wd.dma_hi & 0xff) << 16;
   MFPDELAY();

   return( addr );
}


static ssize_t slm_write( struct file *file, const char *buf, size_t count,
                    loff_t *ppos )

{
   struct inode *node = file->f_dentry->d_inode;
   int      device = MINOR( node->i_rdev );
   int      n, filled, w, h;

   while( SLMState == PRINTING ||
         (SLMState == FILLING && SLMBufOwner != device) ) {
      interruptible_sleep_on( &slm_wait );
      if (signal_pending(current))
         return( -ERESTARTSYS );
   }
   if (SLMState == IDLE) {
      /* first data of page: get current page size  */
      if (slm_get_pagesize( device, &w, &h ))
         return( -EIO );
      BufferSize = w*h/8;
      if (BufferSize > SLM_BUFFER_SIZE)
         return( -ENOMEM );

      SLMState = FILLING;
      SLMBufOwner = device;
   }

   n = count;
   filled = BufferP - SLMBuffer;
   if (filled + n > BufferSize)
      n = BufferSize - filled;

   if (copy_from_user(BufferP, buf, n))
      return -EFAULT;
   BufferP += n;
   filled += n;

   if (filled == BufferSize) {
      /* Check the paper size again! The user may have switched it in the
       * time between starting the data and finishing them. Would end up in
       * a trashy page... */
      if (slm_get_pagesize( device, &w, &h ))
         return( -EIO );
      if (BufferSize != w*h/8) {
         printk( KERN_NOTICE "slm%d: page size changed while printing\n",
               device );
         return( -EAGAIN );
      }

      SLMState = PRINTING;
      /* choose a slice size that is a multiple of the line size */
#ifndef SLM_CONT_CNT_REPROG
      SLMSliceSize = SLM_SLICE_SIZE(w);
#endif
      
      start_print( device );
      sleep_on( &print_wait );
      if (SLMError && IS_REAL_ERROR(SLMError)) {
         printk( KERN_ERR "slm%d: %s\n", device, slm_errstr(SLMError) );
         n = -EIO;
      }

      SLMState = IDLE;
      BufferP = SLMBuffer;
      wake_up_interruptible( &slm_wait );
   }
   
   return( n );
}


/* ---------------------------------------------------------------------- */
/*                        ioctl Functions                       */


static int slm_ioctl( struct inode *inode, struct file *file,
                 unsigned int cmd, unsigned long arg )

{   int      device = MINOR( inode->i_rdev ), err;
   
   /* I can think of setting:
    *  - manual feed
    *  - paper format
    *  - copy count
    *  - ...
    * but haven't implemented that yet :-)
    * BTW, has anybody better docs about the MODE SENSE/MODE SELECT data?
    */
   switch( cmd ) {

     case SLMIORESET:      /* reset buffer, i.e. empty the buffer */
      if (!(file->f_mode & 2))
         return( -EINVAL );
      if (SLMState == PRINTING)
         return( -EBUSY );
      SLMState = IDLE;
      BufferP = SLMBuffer;
      wake_up_interruptible( &slm_wait );
      return( 0 );
      
     case SLMIOGSTAT: {   /* get status */
      int stat;
      char *str;

      stat = slm_req_sense( device );
      if (arg) {
         str = slm_errstr( stat );
         if (put_user(stat,
                                 (long *)&((struct SLM_status *)arg)->stat))
                            return -EFAULT;
         if (copy_to_user( ((struct SLM_status *)arg)->str, str,
                   strlen(str) + 1))
            return -EFAULT;
      }
      return( stat );
     }
      
     case SLMIOGPSIZE: {   /* get paper size */
      int w, h;
      
      if ((err = slm_get_pagesize( device, &w, &h ))) return( err );
      
              if (put_user(w, (long *)&((struct SLM_paper_size *)arg)->width))
         return -EFAULT;
      if (put_user(h, (long *)&((struct SLM_paper_size *)arg)->height))
         return -EFAULT;
      return( 0 );
     }
      
     case SLMIOGMFEED:   /* get manual feed */
      return( -EINVAL );

     case SLMIOSPSIZE:   /* set paper size */
      return( -EINVAL );

     case SLMIOSMFEED:   /* set manual feed */
      return( -EINVAL );

   }
   return( -EINVAL );
}


/* ---------------------------------------------------------------------- */
/*                      Opening and Closing                    */


static int slm_open( struct inode *inode, struct file *file )

{   int device;
   struct slm *sip;
   
   device = MINOR(inode->i_rdev);
   if (device >= N_SLM_Printers)
      return( -ENXIO );
   sip = &slm_info[device];

   if (file->f_mode & 2) {
      /* open for writing is exclusive */
      if (sip->wbusy)
         return( -EBUSY );
      sip->wbusy = 1;
   }
   if (file->f_mode & 1) {
      /* open for writing is exclusive */
      if (sip->rbusy)
         return( -EBUSY );
      sip->rbusy = 1;
   }

   return( 0 );
}


static int slm_release( struct inode *inode, struct file *file )

{   int device;
   struct slm *sip;
   
   device = MINOR(inode->i_rdev);
   sip = &slm_info[device];

   lock_kernel();
   if (file->f_mode & 2)
      sip->wbusy = 0;
   if (file->f_mode & 1)
      sip->rbusy = 0;
   unlock_kernel();
   
   return( 0 );
}


/* ---------------------------------------------------------------------- */
/*                   ACSI Primitives for the SLM                 */


static int slm_req_sense( int device )

{   int         stat, rv;
   struct slm *sip = &slm_info[device];
   
   stdma_lock( NULL, NULL );

   CMDSET_TARG_LUN( slmreqsense_cmd, sip->target, sip->lun );
   if (!acsicmd_nodma( slmreqsense_cmd, 0 ) ||
      (stat = acsi_getstatus()) < 0)
      rv = SLMSTAT_ACSITO;
   else
      rv = stat & 0x1f;

   ENABLE_IRQ();
   stdma_release();
   return( rv );
}


static int slm_mode_sense( int device, char *buffer, int abs_flag )

{   unsigned char   stat, len;
   int            rv = 0;
   struct slm      *sip = &slm_info[device];
   
   stdma_lock( NULL, NULL );

   CMDSET_TARG_LUN( slmmsense_cmd, sip->target, sip->lun );
   slmmsense_cmd[5] = abs_flag ? 0x80 : 0;
   if (!acsicmd_nodma( slmmsense_cmd, 0 )) {
      rv = SLMSTAT_ACSITO;
      goto the_end;
   }

   if (!acsi_extstatus( &stat, 1 )) {
      acsi_end_extstatus();
      rv = SLMSTAT_ACSITO;
      goto the_end;
   }
   
   if (!acsi_extstatus( &len, 1 )) {
      acsi_end_extstatus();
      rv = SLMSTAT_ACSITO;
      goto the_end;
   }
   buffer[0] = len;
   if (!acsi_extstatus( buffer+1, len )) {
      acsi_end_extstatus();
      rv = SLMSTAT_ACSITO;
      goto the_end;
   }
   
   acsi_end_extstatus();
   rv = stat & 0x1f;

  the_end:
   ENABLE_IRQ();
   stdma_release();
   return( rv );
}


#if 0
/* currently unused */
static int slm_mode_select( int device, char *buffer, int len,
                     int default_flag )

{   int         stat, rv;
   struct slm   *sip = &slm_info[device];
   
   stdma_lock( NULL, NULL );

   CMDSET_TARG_LUN( slmmselect_cmd, sip->target, sip->lun );
   slmmselect_cmd[5] = default_flag ? 0x80 : 0;
   if (!acsicmd_nodma( slmmselect_cmd, 0 )) {
      rv = SLMSTAT_ACSITO;
      goto the_end;
   }

   if (!default_flag) {
      unsigned char c = len;
      if (!acsi_extcmd( &c, 1 )) {
         rv = SLMSTAT_ACSITO;
         goto the_end;
      }
      if (!acsi_extcmd( buffer, len )) {
         rv = SLMSTAT_ACSITO;
         goto the_end;
      }
   }
   
   stat = acsi_getstatus();
   rv = (stat < 0 ? SLMSTAT_ACSITO : stat);

  the_end:
   ENABLE_IRQ();
   stdma_release();
   return( rv );
}
#endif


static int slm_get_pagesize( int device, int *w, int *h )

{   char   buf[256];
   int      stat;
   
   stat = slm_mode_sense( device, buf, 0 );
   ENABLE_IRQ();
   stdma_release();

   if (stat != SLMSTAT_OK)
      return( -EIO );

   *w = (buf[3] << 8) | buf[4];
   *h = (buf[1] << 8) | buf[2];
   return( 0 );
}


/* ---------------------------------------------------------------------- */
/*                        Initialization                       */


int attach_slm( int target, int lun )

{   static int   did_register;
   int         len;

   if (N_SLM_Printers >= MAX_SLM) {
      printk( KERN_WARNING "Too much SLMs\n" );
      return( 0 );
   }
   
   /* do an INQUIRY */
   udelay(100);
   CMDSET_TARG_LUN( slminquiry_cmd, target, lun );
   if (!acsicmd_nodma( slminquiry_cmd, 0 )) {
     inq_timeout:
      printk( KERN_ERR "SLM inquiry command timed out.\n" );
     inq_fail:
      acsi_end_extstatus();
      return( 0 );
   }
   /* read status and header of return data */
   if (!acsi_extstatus( SLMBuffer, 6 ))
      goto inq_timeout;

   if (SLMBuffer[1] != 2) { /* device type == printer? */
      printk( KERN_ERR "SLM inquiry returned device type != printer\n" );
      goto inq_fail;
   }
   len = SLMBuffer[5];
   
   /* read id string */
   if (!acsi_extstatus( SLMBuffer, len ))
      goto inq_timeout;
   acsi_end_extstatus();
   SLMBuffer[len] = 0;

   if (!did_register) {
      did_register = 1;
   }

   slm_info[N_SLM_Printers].target = target;
   slm_info[N_SLM_Printers].lun    = lun;
   slm_info[N_SLM_Printers].wbusy  = 0;
   slm_info[N_SLM_Printers].rbusy  = 0;
   
   printk( KERN_INFO "  Printer: %s\n", SLMBuffer );
   printk( KERN_INFO "Detected slm%d at id %d lun %d\n",
         N_SLM_Printers, target, lun );
   N_SLM_Printers++;
   return( 1 );
}

static devfs_handle_t devfs_handle;

int slm_init( void )

{
   if (devfs_register_chrdev( MAJOR_NR, "slm", &slm_fops )) {
      printk( KERN_ERR "Unable to get major %d for ACSI SLM\n", MAJOR_NR );
      return -EBUSY;
   }
   
   if (!(SLMBuffer = atari_stram_alloc( SLM_BUFFER_SIZE, "SLM" ))) {
      printk( KERN_ERR "Unable to get SLM ST-Ram buffer.\n" );
      devfs_unregister_chrdev( MAJOR_NR, "slm" );
      return -ENOMEM;
   }
   BufferP = SLMBuffer;
   SLMState = IDLE;
   
   devfs_handle = devfs_mk_dir (NULL, "slm", NULL);
   devfs_register_series (devfs_handle, "%u", MAX_SLM, DEVFS_FL_DEFAULT,
                MAJOR_NR, 0, S_IFCHR | S_IRUSR | S_IWUSR,
                &slm_fops, NULL);
   return 0;
}

#ifdef MODULE

/* from acsi.c */
void acsi_attach_SLMs( int (*attach_func)( int, int ) );

int init_module(void)
{
   int err;

   if ((err = slm_init()))
      return( err );
   /* This calls attach_slm() for every target/lun where acsi.c detected a
    * printer */
   acsi_attach_SLMs( attach_slm );
   return( 0 );
}

void cleanup_module(void)
{
   devfs_unregister (devfs_handle);
   if (devfs_unregister_chrdev( MAJOR_NR, "slm" ) != 0)
      printk( KERN_ERR "acsi_slm: cleanup_module failed\n");
   atari_stram_free( SLMBuffer );
}
#endif


I hope, this is is usefull.

If someone finds other helpfull documentgs, they can be attached here.
Last edited by 1st1 on Tue Apr 12, 2016 11:46 am, edited 3 times in total.
Power without the Price. It's not a bug. It's a feature. _/|\_ATARI

1040STFM in PC-Tower (PAK68/2, OvrScn, 4 MB, 1GB SCSI, CD-ROM...) * 2x Falcon 030 32GB/14MB+ScrnBlstrIII * 2x TT030 73GB/20MB+Nova * 520/1040STFM * 520/1040STE * 260/520ST/+ * some Mega ST * 2x Mega STE 500MB/4MB+M.CoCo * Stacy * STBook * SLM605 * SLM804 * SLM605 * SMM804 * SH 204/205 * Megafile 30/44/60 * SF314 * SF354 * 5x Pofo * PC3

User avatar
Jookie
Hardware Guru
Hardware Guru
Posts: 1245
Joined: Wed Feb 04, 2004 6:54 pm
Location: Kosice, Slovakia
Contact:

Re: CosmosEx - SLM Printer Emulation

Postby Jookie » Tue Apr 12, 2016 12:18 am

Hello 1st1,

I had a look at that acsi_slm.c and it looks very good. Now, to do that I need 2 things:
  • free time - I'm drowning in all the things that need to be done to support new user with issues, with fixing stuff, and with finishing stuff I have already promised - I can't promise anything for the next 3 months or so
  • a working ST app, which really prints on SLM - e.g. some very old Calamus, even trial version if it can print. Without this testing (and fixing) my not tested implementation will be useless, as even the smallest bug might (and will) break it completely

I guess the bigger problem might be the free time for this one.

Jookie

User avatar
1st1
Atari Super Hero
Atari Super Hero
Posts: 685
Joined: Mon May 07, 2012 11:48 am

Re: CosmosEx - SLM Printer Emulation

Postby 1st1 » Tue Apr 12, 2016 11:24 am

Hello, take your time, one thing after the other. ... I will provide you with test software.

One more thing the community could help you is about support. What kind of questions do you get by users? Basic (setup) questions or complicated ones, or real bugs which need to be fixed? I think the basic questions could be handeled here in the forum to get some load away from you.
Power without the Price. It's not a bug. It's a feature. _/|\_ATARI

1040STFM in PC-Tower (PAK68/2, OvrScn, 4 MB, 1GB SCSI, CD-ROM...) * 2x Falcon 030 32GB/14MB+ScrnBlstrIII * 2x TT030 73GB/20MB+Nova * 520/1040STFM * 520/1040STE * 260/520ST/+ * some Mega ST * 2x Mega STE 500MB/4MB+M.CoCo * Stacy * STBook * SLM605 * SLM804 * SLM605 * SMM804 * SH 204/205 * Megafile 30/44/60 * SF314 * SF354 * 5x Pofo * PC3

ldv-01
Atari maniac
Atari maniac
Posts: 94
Joined: Wed Jun 01, 2011 10:14 pm
Location: Italy

Re: CosmosEx - SLM Printer Emulation

Postby ldv-01 » Tue Apr 12, 2016 11:06 pm

A SLMC804 Controller Command Summary (Appendix C) is in SLM804 Owner's manual. If needed, I can scan / upload the document.

User avatar
1st1
Atari Super Hero
Atari Super Hero
Posts: 685
Joined: Mon May 07, 2012 11:48 am

Re: CosmosEx - SLM Printer Emulation

Postby 1st1 » Wed Apr 13, 2016 6:27 am

Hello, yes please. Can you scan and upload the whole manual? I think this is quite rare. We can put it to dev-docs.
Power without the Price. It's not a bug. It's a feature. _/|\_ATARI

1040STFM in PC-Tower (PAK68/2, OvrScn, 4 MB, 1GB SCSI, CD-ROM...) * 2x Falcon 030 32GB/14MB+ScrnBlstrIII * 2x TT030 73GB/20MB+Nova * 520/1040STFM * 520/1040STE * 260/520ST/+ * some Mega ST * 2x Mega STE 500MB/4MB+M.CoCo * Stacy * STBook * SLM605 * SLM804 * SLM605 * SMM804 * SH 204/205 * Megafile 30/44/60 * SF314 * SF354 * 5x Pofo * PC3

User avatar
Jookie
Hardware Guru
Hardware Guru
Posts: 1245
Joined: Wed Feb 04, 2004 6:54 pm
Location: Kosice, Slovakia
Contact:

Re: CosmosEx - SLM Printer Emulation

Postby Jookie » Wed Apr 13, 2016 8:55 am

1st1 wrote:What kind of questions do you get by users? Basic (setup) questions or complicated ones, or real bugs which need to be fixed?


The questions are from all the possible levels of difficulty:
  • General info: What can it do? how much does it cost? do I really need a Raspberry Pi? Which Raspberry Pi model I need? What can it do without Raspberry Pi?
  • basic setup info: How to I use floppy emulation? Where do I upload the floppy images? Do I need to connect floppy cable? Do I need to connect ACSI cable? How do I connect floppy cable from outside? How do I connect ACSI cable from inside? Is it for internal / extrnal use? What power supply do I need? If I connect it externally, can it behave as drive A:? What do I need for setting it as drive A: from outside? Do you sell / know where to get that external floppy connector? Do you sell that Falcon SCSI connector / cable? Where can I get the Falcon external SCSI connector / cable? What ACSI / SCSI IDs do I need? Can they collide with other devices? Does it work with other devices on the ACSI / SCSI bus? What driver do you recommend for SD card? What SD card do you recommend? Why doesn't my MMC card work? What partitions types and sizes should I have? Why the CE_DD isn't loaded when HDDRIVER is loaded first? Why doesn't my outdated CE_DD from SD card communicate with the device? Will this USB mouse / keyboard / joystick work with it? Can you add support for PlayStation gamepads? How do I switch between SCSI and ACSI mode? Why there is an empty SD card adapter in my package? What power supply do I need?
  • Solving issues: My device doesn't have power. My device doesn't boot linux, all the 3 floppy LEDs are on. The device boots, but it doesn't load the CE_DD driver from it, other drivers can't see it. The device boots, CE_DD is loaded, but PRGs can't be started from translated drives when SD card + some other driver is present. Floppy emulation doesn't work (at all, or with this game). IKDB injection doesn't work at all. The device can't see my USB mouse / keyboard / joy. Wifi doesn't work. Conenction through wifi isn't probably working. There is data corruption when doing transfers. The partitions got lost. The screen resolution on my STE isn't right after restart. I don't see the config drive. I can't set the boot drive in config. There is some other weird problem with data transfer. I can't fit the device into box because the power switch is in the way. I can't connect to external ACSI connector from inside. I can't connect to internal FDD connector from outside. Why are your config apps so ugly? Why they are just text ones, and not GEM ones? How do I mount the device in STacy / STbook / Mega ST / Mega STE? Why the newer Raspberry Pi isn't supported yet? My network shared folder doesn't work. How do I set up shared folder from Windows? (and many others, I can't remember them all now)
  • New feature requests / delivery state inquiries:Floppy write support, more floppy images format, HD floppy support, STiNG, SLM printing, GDOS printing, CUPS printing, Raspbian transition (and thus RPi 2 and RPi 3 support), faster boot, power outage backup capacitor for Raspberry Pi, mp3 playback on ST, video playback on ST, faster web browsing on ST, some plugin / extension support for demos / games.

For the first 2 - there definitely needs to be a guide for dummies, but for real dummies :-D With this I'm not implying that users are dummies, it's more about that they don't have the idea how things work and this aren't explained in a simple way nowhere. There is a 'CosmosEx guide for dummies' from DrCoolZic which is very good and also has many pages, but it's not really for dummies / beginners as it's too technical, so there should be something even simpler than that. Many people who got CosmosEx never had ST before, and they come from Amiga-land, or had the computer 20 years ago and they forgot everything. I would need at least a week to write everything down, and I guess I forgot to mention at least 30% of what people ask and want.

The other problem is that many of them don't use forum, but ask through mail directly, and that keeps me repeating stuff over and over again, and keeps me under the load.

1st1 wrote:I think the basic questions could be handled here in the forum to get some load away from you.


Yes, some definitely are solved here, thank you all who participate on helping people and keeping the load off my back :cheers:

ldv-01
Atari maniac
Atari maniac
Posts: 94
Joined: Wed Jun 01, 2011 10:14 pm
Location: Italy

Re: CosmosEx - SLM Printer Emulation

Postby ldv-01 » Wed Apr 13, 2016 7:02 pm

Attached the Appendix C from the SLM user's manual. Later I'll scan the complete manual (+the Diablo 630 emulator user's manual) for the Documentation Archive.

1st1 wrote:Hello, yes please. Can you scan and upload the whole manual? I think this is quite rare. We can put it to dev-docs.


slm_appc.pdf
You do not have the required permissions to view the files attached to this post.

User avatar
1st1
Atari Super Hero
Atari Super Hero
Posts: 685
Joined: Mon May 07, 2012 11:48 am

Re: CosmosEx - SLM Printer Emulation

Postby 1st1 » Wed Apr 13, 2016 7:34 pm

Not neccessary to scan, somebody did already, just got the tipp in atari-home.de:

804 manual: http://www.atarian.nl/images/doc_guides ... rinter.pdf
605 manual: http://www.atarian.nl/images/doc_guides ... rinter.pdf
diabolo emulator manual: http://www.atarian.nl/images/doc_guides ... ulator.pdf

But there must also be something more detailed. When somebody registered at ATARI as developper he got always a thick pack of papers, technical documentations, release notes and all kind of this stuff. I have this partially, but not complete, just the update papers from 1989/90. But it has a complete table of content and there is a SLMC-804 documentation from 1988 listed. Does anybody have this?
Power without the Price. It's not a bug. It's a feature. _/|\_ATARI

1040STFM in PC-Tower (PAK68/2, OvrScn, 4 MB, 1GB SCSI, CD-ROM...) * 2x Falcon 030 32GB/14MB+ScrnBlstrIII * 2x TT030 73GB/20MB+Nova * 520/1040STFM * 520/1040STE * 260/520ST/+ * some Mega ST * 2x Mega STE 500MB/4MB+M.CoCo * Stacy * STBook * SLM605 * SLM804 * SLM605 * SMM804 * SH 204/205 * Megafile 30/44/60 * SF314 * SF354 * 5x Pofo * PC3

User avatar
1st1
Atari Super Hero
Atari Super Hero
Posts: 685
Joined: Mon May 07, 2012 11:48 am

Re: CosmosEx - SLM Printer Emulation

Postby 1st1 » Wed Apr 13, 2016 7:43 pm

Jookie wrote:For the first 2 - there definitely needs to be a guide for dummies, but for real dummies :-D


I fully understand. Instead of answerring every time the same, you should sit one evening and just add these questions with answers (!) to your website. Then, at your email adress link first to these FAQs. Tell, that you will not answer if someone ask for these questions. You also should link to this forum for user to user help. Currently also in atari-home.de forum is the idea to open a special sub forum for Cosmos ex, this could also help, because then for german users it will be easier asking their questions in german forum than in english emails.
Power without the Price. It's not a bug. It's a feature. _/|\_ATARI

1040STFM in PC-Tower (PAK68/2, OvrScn, 4 MB, 1GB SCSI, CD-ROM...) * 2x Falcon 030 32GB/14MB+ScrnBlstrIII * 2x TT030 73GB/20MB+Nova * 520/1040STFM * 520/1040STE * 260/520ST/+ * some Mega ST * 2x Mega STE 500MB/4MB+M.CoCo * Stacy * STBook * SLM605 * SLM804 * SLM605 * SMM804 * SH 204/205 * Megafile 30/44/60 * SF314 * SF354 * 5x Pofo * PC3

ldv-01
Atari maniac
Atari maniac
Posts: 94
Joined: Wed Jun 01, 2011 10:14 pm
Location: Italy

Re: CosmosEx - SLM Printer Emulation

Postby ldv-01 » Wed Apr 13, 2016 8:56 pm

Good finding!

ROM distributed the Heatseeker SLM interface for the Falcon. This interface was developed by Laurenz Pruessner. Altough this was a while back, you may ask them if they have some dev doc left.

1st1 wrote:Not neccessary to scan, somebody did already, just got the tipp in atari-home.de:

804 manual: http://www.atarian.nl/images/doc_guides ... rinter.pdf
605 manual: http://www.atarian.nl/images/doc_guides ... rinter.pdf
diabolo emulator manual: http://www.atarian.nl/images/doc_guides ... ulator.pdf

But there must also be something more detailed. When somebody registered at ATARI as developper he got always a thick pack of papers, technical documentations, release notes and all kind of this stuff. I have this partially, but not complete, just the update papers from 1989/90. But it has a complete table of content and there is a SLMC-804 documentation from 1988 listed. Does anybody have this?

User avatar
1st1
Atari Super Hero
Atari Super Hero
Posts: 685
Joined: Mon May 07, 2012 11:48 am

Re: CosmosEx - SLM Printer Emulation

Postby 1st1 » Wed Apr 13, 2016 9:39 pm

Would be interesting to know if that SLM SCSI interface for Falcon was working with the original driver from ATARI and DMC. That would make hope that the SLM also could be emulated over SCSI in CosmosEx.
Power without the Price. It's not a bug. It's a feature. _/|\_ATARI

1040STFM in PC-Tower (PAK68/2, OvrScn, 4 MB, 1GB SCSI, CD-ROM...) * 2x Falcon 030 32GB/14MB+ScrnBlstrIII * 2x TT030 73GB/20MB+Nova * 520/1040STFM * 520/1040STE * 260/520ST/+ * some Mega ST * 2x Mega STE 500MB/4MB+M.CoCo * Stacy * STBook * SLM605 * SLM804 * SLM605 * SMM804 * SH 204/205 * Megafile 30/44/60 * SF314 * SF354 * 5x Pofo * PC3

User avatar
Jookie
Hardware Guru
Hardware Guru
Posts: 1245
Joined: Wed Feb 04, 2004 6:54 pm
Location: Kosice, Slovakia
Contact:

Re: CosmosEx - SLM Printer Emulation

Postby Jookie » Wed Apr 13, 2016 10:40 pm

1st1 wrote:Instead of answerring every time the same, you should sit one evening and just add these questions with answers (!) to your website. Then, at your email adress link first to these FAQs.


I want to do that, but this will taky more than one evening ;) I guess it would take days. I got at least a bit of it covered in the Q&A page (http://joo.kie.sk/?page_id=634) but that is covering more the repeating questions about the orders, status, and so on. Definitely need one on this noobs thing.

1st1 wrote:Currently also in atari-home.de forum is the idea to open a special sub forum for Cosmos ex, this could also help, because then for german users it will be easier asking their questions in german forum than in english emails.


Yes, that might help, too, although I'm worried that it will end up with me doing most of the support even there, but in my very broken german language :-D (as I haven't been using it for like 15 years - on the other hand - it might help me to practice it, hmmmm).

ldv-01
Atari maniac
Atari maniac
Posts: 94
Joined: Wed Jun 01, 2011 10:14 pm
Location: Italy

Re: CosmosEx - SLM Printer Emulation

Postby ldv-01 » Fri Apr 15, 2016 1:44 pm

Took a while, and finally found the Heatseeker manual(in German)/HD Floppy. This interface is for the DSP port. The disk contains a FONTGDOS/DIABL630 setup likely specific to the Heatseeker (a SLM_HS.SYS GDOS driver is available). Unfortunately, no technical/programming details are included.
1st1 wrote:Would be interesting to know if that SLM SCSI interface for Falcon was working with the original driver from ATARI and DMC. That would make hope that the SLM also could be emulated over SCSI in CosmosEx.

mikro
Atari God
Atari God
Posts: 1287
Joined: Sat Sep 10, 2005 11:11 am
Location: Brisbane, Queensland, Australia
Contact:

Re: CosmosEx - SLM Printer Emulation

Postby mikro » Mon Jun 20, 2016 2:57 am

This is a pretty cool idea.

User avatar
1st1
Atari Super Hero
Atari Super Hero
Posts: 685
Joined: Mon May 07, 2012 11:48 am

Re: CosmosEx - SLM Printer Emulation

Postby 1st1 » Tue Nov 08, 2016 6:18 pm

Hello, is there already some progress in this?
Power without the Price. It's not a bug. It's a feature. _/|\_ATARI

1040STFM in PC-Tower (PAK68/2, OvrScn, 4 MB, 1GB SCSI, CD-ROM...) * 2x Falcon 030 32GB/14MB+ScrnBlstrIII * 2x TT030 73GB/20MB+Nova * 520/1040STFM * 520/1040STE * 260/520ST/+ * some Mega ST * 2x Mega STE 500MB/4MB+M.CoCo * Stacy * STBook * SLM605 * SLM804 * SLM605 * SMM804 * SH 204/205 * Megafile 30/44/60 * SF314 * SF354 * 5x Pofo * PC3

User avatar
mfro
Atari Super Hero
Atari Super Hero
Posts: 677
Joined: Thu Aug 02, 2012 10:33 am
Location: SW Germany

Re: CosmosEx - SLM Printer Emulation

Postby mfro » Tue Nov 08, 2016 7:00 pm

1st1 wrote:But there must also be something more detailed.


You don't need anything more than just the printer manual to implement a driver.

It must understand the 6 commands from the manual, that's it.

The Atari printers were pretty dumb, basically just printing plain bit patterns sent by the host (which needed to make sure the controller's fifo buffer was always filled).

User avatar
Jookie
Hardware Guru
Hardware Guru
Posts: 1245
Joined: Wed Feb 04, 2004 6:54 pm
Location: Kosice, Slovakia
Contact:

Re: CosmosEx - SLM Printer Emulation

Postby Jookie » Wed Nov 09, 2016 4:38 am

1st1 wrote:Hello, is there already some progress in this?


Hello, well, nothing yet here :( Some time has been invested in moving from Yocto linux distro to Raspbian, which in the end might help with the output of the emulated printer...

Jookie

User avatar
1st1
Atari Super Hero
Atari Super Hero
Posts: 685
Joined: Mon May 07, 2012 11:48 am

Re: CosmosEx - SLM Printer Emulation

Postby 1st1 » Wed Nov 09, 2016 1:04 pm

Ok, waiting... looking forward to it! :)
Power without the Price. It's not a bug. It's a feature. _/|\_ATARI

1040STFM in PC-Tower (PAK68/2, OvrScn, 4 MB, 1GB SCSI, CD-ROM...) * 2x Falcon 030 32GB/14MB+ScrnBlstrIII * 2x TT030 73GB/20MB+Nova * 520/1040STFM * 520/1040STE * 260/520ST/+ * some Mega ST * 2x Mega STE 500MB/4MB+M.CoCo * Stacy * STBook * SLM605 * SLM804 * SLM605 * SMM804 * SH 204/205 * Megafile 30/44/60 * SF314 * SF354 * 5x Pofo * PC3

nanard
Obsessive compulsive Atari behavior
Obsessive compulsive Atari behavior
Posts: 109
Joined: Mon Apr 04, 2016 2:11 pm

Re: CosmosEx - SLM Printer Emulation

Postby nanard » Sun Nov 27, 2016 1:14 pm

can you provide me a test printing tool so I can test on my ST ?
4MB STE + CosmosEx /|\ MegaST4 + MegaFile 44

User avatar
1st1
Atari Super Hero
Atari Super Hero
Posts: 685
Joined: Mon May 07, 2012 11:48 am

Re: CosmosEx - SLM Printer Emulation

Postby 1st1 » Wed Dec 07, 2016 9:10 pm

File link sent throuh PN.
Power without the Price. It's not a bug. It's a feature. _/|\_ATARI

1040STFM in PC-Tower (PAK68/2, OvrScn, 4 MB, 1GB SCSI, CD-ROM...) * 2x Falcon 030 32GB/14MB+ScrnBlstrIII * 2x TT030 73GB/20MB+Nova * 520/1040STFM * 520/1040STE * 260/520ST/+ * some Mega ST * 2x Mega STE 500MB/4MB+M.CoCo * Stacy * STBook * SLM605 * SLM804 * SLM605 * SMM804 * SH 204/205 * Megafile 30/44/60 * SF314 * SF354 * 5x Pofo * PC3

nanard
Obsessive compulsive Atari behavior
Obsessive compulsive Atari behavior
Posts: 109
Joined: Mon Apr 04, 2016 2:11 pm

Re: CosmosEx - SLM Printer Emulation

Postby nanard » Sun Dec 11, 2016 11:09 pm

does someone know which inquiry string responds the SLM printers ?
4MB STE + CosmosEx /|\ MegaST4 + MegaFile 44

User avatar
Jookie
Hardware Guru
Hardware Guru
Posts: 1245
Joined: Wed Feb 04, 2004 6:54 pm
Location: Kosice, Slovakia
Contact:

Re: CosmosEx - SLM Printer Emulation

Postby Jookie » Mon Dec 12, 2016 7:19 am

nanard wrote:does someone know which inquiry string responds the SLM printers ?


I'm not sure if anyone here knows. When trying to figure things like this it would help a lot to have sources of the thing on ST that prints using SLM, and / or the real printer... The printer would now be hard to get, but at least sources of something which prints to it maybe could be downloaded?

User avatar
1st1
Atari Super Hero
Atari Super Hero
Posts: 685
Joined: Mon May 07, 2012 11:48 am

Re: CosmosEx - SLM Printer Emulation

Postby 1st1 » Mon Dec 12, 2016 8:07 am

I have working SLM 804, but drum kit is bad, so it basically prints, but allmost no toner on paper. But I would need to set it up, it's stored deep in my collection and it needs a lot of space to setup a test environement.

Does the Linux 68K code linked above does not help in this question? And what do you mean with inquiry string? The device name of the prinrer when ACSI is scanned for desvices? Maybe there is even no, as far as I remember some harddisk drivers must exclude the printer's ACSI id from scan at harddisk driver bootup-
Power without the Price. It's not a bug. It's a feature. _/|\_ATARI

1040STFM in PC-Tower (PAK68/2, OvrScn, 4 MB, 1GB SCSI, CD-ROM...) * 2x Falcon 030 32GB/14MB+ScrnBlstrIII * 2x TT030 73GB/20MB+Nova * 520/1040STFM * 520/1040STE * 260/520ST/+ * some Mega ST * 2x Mega STE 500MB/4MB+M.CoCo * Stacy * STBook * SLM605 * SLM804 * SLM605 * SMM804 * SH 204/205 * Megafile 30/44/60 * SF314 * SF354 * 5x Pofo * PC3

User avatar
Jookie
Hardware Guru
Hardware Guru
Posts: 1245
Joined: Wed Feb 04, 2004 6:54 pm
Location: Kosice, Slovakia
Contact:

Re: CosmosEx - SLM Printer Emulation

Postby Jookie » Mon Dec 12, 2016 8:42 am

1st1 wrote:I have working SLM 804, but drum kit is bad, so it basically prints, but allmost no toner on paper. But I would need to set it up, it's stored deep in my collection and it needs a lot of space to setup a test environement.


If it communicates with ST and you could see at least a bit what it printed, then it would be enough. But I think we talked about it before - it's no use to me at your place ;) I would rather buy one from eBay if it appears for a reasonable price.

1st1 wrote:Does the Linux 68K code linked above does not help in this question?


Hard to say, but maybe it will... In this moment this all is more for nanard, as I'm trying to solve and fix other issues....

nanard
Obsessive compulsive Atari behavior
Obsessive compulsive Atari behavior
Posts: 109
Joined: Mon Apr 04, 2016 2:11 pm

Re: CosmosEx - SLM Printer Emulation

Postby nanard » Wed Dec 14, 2016 9:25 am

1st1 wrote:I have working SLM 804, but drum kit is bad, so it basically prints, but allmost no toner on paper. But I would need to set it up, it's stored deep in my collection and it needs a lot of space to setup a test environement.

Does the Linux 68K code linked above does not help in this question? And what do you mean with inquiry string? The device name of the prinrer when ACSI is scanned for desvices? Maybe there is even no, as far as I remember some harddisk drivers must exclude the printer's ACSI id from scan at harddisk driver bootup-

The linux 68K code only check the "periphera device type" field of inquiry response to be 02h = Printer.
diabolo630 SDUMP checks at least for some "PAGE PRINTER" string somewhere in the INQUIRY response.

It looks to me that INQUIRY response from SLMxx printer is not conformant to the SCSI standards ;)

Anyway I'm afraid my test don't give anything because of some ACSI timing problem or something.
@Jookie: I can send you software that print using SLM printer. and also update my slm_emul branch with my findings ;)
@1sts1: your SLM804 can help us. I can write a test program that send commands to it and log response.
you will mail back the logs so we can advance.
But the better would be that you lend it to jookie ;) he's the master in understanding the ACSI protocols ! :)
4MB STE + CosmosEx /|\ MegaST4 + MegaFile 44


Social Media

     

Return to “CosmosEx”

Who is online

Users browsing this forum: No registered users and 4 guests