@@ -90,10 +90,13 @@ struct NeXTPC {
9090
9191 uint32_t scr1 ;
9292 uint32_t scr2 ;
93- uint8_t scsi_csr_1 ;
94- uint8_t scsi_csr_2 ;
9593 uint32_t int_mask ;
9694 uint32_t int_status ;
95+ uint8_t scsi_csr_1 ;
96+ uint8_t scsi_csr_2 ;
97+
98+ qemu_irq scsi_reset ;
99+ qemu_irq scsi_dma ;
97100
98101 NextRtc rtc ;
99102};
@@ -466,7 +469,7 @@ static void scr_writeb(NeXTPC *s, hwaddr addr, uint32_t value)
466469 DPRINTF ("SCSICSR FIFO Flush\n" );
467470 /* will have to add another irq to the esp if this is needed */
468471 /* esp_puflush_fifo(esp_g); */
469- /* qemu_irq_pulse(s->scsi_dma); */
472+ qemu_irq_pulse (s -> scsi_dma );
470473 }
471474
472475 if (value & SCSICSR_ENABLE ) {
@@ -486,20 +489,21 @@ static void scr_writeb(NeXTPC *s, hwaddr addr, uint32_t value)
486489 if (value & SCSICSR_RESET ) {
487490 DPRINTF ("SCSICSR Reset\n" );
488491 /* I think this should set DMADIR. CPUDMA and INTMASK to 0 */
489- /* qemu_irq_raise(s->scsi_reset); */
490- /* s->scsi_csr_1 &= ~(SCSICSR_INTMASK |0x80| 0x1); */
491-
492+ qemu_irq_raise (s -> scsi_reset );
493+ s -> scsi_csr_1 &= ~(SCSICSR_INTMASK | 0x80 | 0x1 );
494+ qemu_irq_lower ( s -> scsi_reset );
492495 }
493496 if (value & SCSICSR_DMADIR ) {
494497 DPRINTF ("SCSICSR DMAdir\n" );
495498 }
496499 if (value & SCSICSR_CPUDMA ) {
497500 DPRINTF ("SCSICSR CPUDMA\n" );
498501 /* qemu_irq_raise(s->scsi_dma); */
499-
500502 s -> int_status |= 0x4000000 ;
501503 } else {
504+ /* fprintf(stderr,"SCSICSR CPUDMA disabled\n"); */
502505 s -> int_status &= ~(0x4000000 );
506+ /* qemu_irq_lower(s->scsi_dma); */
503507 }
504508 if (value & SCSICSR_INTMASK ) {
505509 DPRINTF ("SCSICSR INTMASK\n" );
@@ -828,6 +832,103 @@ static void next_irq(void *opaque, int number, int level)
828832 }
829833}
830834
835+ static void nextdma_write (void * opaque , uint8_t * buf , int size , int type )
836+ {
837+ uint32_t base_addr ;
838+ int irq = 0 ;
839+ uint8_t align = 16 ;
840+ NeXTState * next_state = NEXT_MACHINE (qdev_get_machine ());
841+
842+ if (type == NEXTDMA_ENRX || type == NEXTDMA_ENTX ) {
843+ align = 32 ;
844+ }
845+ /* Most DMA is supposedly 16 byte aligned */
846+ if ((size % align ) != 0 ) {
847+ size -= size % align ;
848+ size += align ;
849+ }
850+
851+ /*
852+ * prom sets the dma start using initbuf while the bootloader uses next
853+ * so we check to see if initbuf is 0
854+ */
855+ if (next_state -> dma [type ].next_initbuf == 0 ) {
856+ base_addr = next_state -> dma [type ].next ;
857+ } else {
858+ base_addr = next_state -> dma [type ].next_initbuf ;
859+ }
860+
861+ cpu_physical_memory_write (base_addr , buf , size );
862+
863+ next_state -> dma [type ].next_initbuf = 0 ;
864+
865+ /* saved limit is checked to calculate packet size by both, rom and netbsd */
866+ next_state -> dma [type ].saved_limit = (next_state -> dma [type ].next + size );
867+ next_state -> dma [type ].saved_next = (next_state -> dma [type ].next );
868+
869+ /*
870+ * 32 bytes under savedbase seems to be some kind of register
871+ * of which the purpose is unknown as of yet
872+ */
873+ /* stl_phys(s->rx_dma.base-32,0xFFFFFFFF); */
874+
875+ if (!(next_state -> dma [type ].csr & DMA_SUPDATE )) {
876+ next_state -> dma [type ].next = next_state -> dma [type ].start ;
877+ next_state -> dma [type ].limit = next_state -> dma [type ].stop ;
878+ }
879+
880+ /* Set dma registers and raise an irq */
881+ next_state -> dma [type ].csr |= DMA_COMPLETE ; /* DON'T CHANGE THIS! */
882+
883+ switch (type ) {
884+ case NEXTDMA_SCSI :
885+ irq = NEXT_SCSI_DMA_I ;
886+ break ;
887+ }
888+
889+ next_irq (opaque , irq , 1 );
890+ next_irq (opaque , irq , 0 );
891+ }
892+
893+ static void nextscsi_read (void * opaque , uint8_t * buf , int len )
894+ {
895+ DPRINTF ("SCSI READ: %x\n" , len );
896+ abort ();
897+ }
898+
899+ static void nextscsi_write (void * opaque , uint8_t * buf , int size )
900+ {
901+ DPRINTF ("SCSI WRITE: %i\n" , size );
902+ nextdma_write (opaque , buf , size , NEXTDMA_SCSI );
903+ }
904+
905+ static void next_scsi_init (DeviceState * pcdev , M68kCPU * cpu )
906+ {
907+ struct NeXTPC * next_pc = NEXT_PC (pcdev );
908+ DeviceState * dev ;
909+ SysBusDevice * sysbusdev ;
910+ SysBusESPState * sysbus_esp ;
911+ ESPState * esp ;
912+
913+ dev = qdev_new (TYPE_SYSBUS_ESP );
914+ sysbus_esp = SYSBUS_ESP (dev );
915+ esp = & sysbus_esp -> esp ;
916+ esp -> dma_memory_read = nextscsi_read ;
917+ esp -> dma_memory_write = nextscsi_write ;
918+ esp -> dma_opaque = pcdev ;
919+ sysbus_esp -> it_shift = 0 ;
920+ esp -> dma_enabled = 1 ;
921+ sysbusdev = SYS_BUS_DEVICE (dev );
922+ sysbus_realize_and_unref (sysbusdev , & error_fatal );
923+ sysbus_connect_irq (sysbusdev , 0 , qdev_get_gpio_in (pcdev , NEXT_SCSI_I ));
924+ sysbus_mmio_map (sysbusdev , 0 , 0x2114000 );
925+
926+ next_pc -> scsi_reset = qdev_get_gpio_in (dev , 0 );
927+ next_pc -> scsi_dma = qdev_get_gpio_in (dev , 1 );
928+
929+ scsi_bus_legacy_handle_cmdline (& esp -> bus );
930+ }
931+
831932static void next_escc_init (DeviceState * pcdev )
832933{
833934 DeviceState * dev ;
@@ -1021,6 +1122,7 @@ static void next_cube_init(MachineState *machine)
10211122 /* TODO: */
10221123 /* Network */
10231124 /* SCSI */
1125+ next_scsi_init (pcdev , cpu );
10241126
10251127 /* DMA */
10261128 memory_region_init_io (dmamem , NULL , & dma_ops , machine , "next.dma" , 0x5000 );
@@ -1033,6 +1135,7 @@ static void next_machine_class_init(ObjectClass *oc, void *data)
10331135
10341136 mc -> desc = "NeXT Cube" ;
10351137 mc -> init = next_cube_init ;
1138+ mc -> block_default_type = IF_SCSI ;
10361139 mc -> default_ram_size = RAM_SIZE ;
10371140 mc -> default_ram_id = "next.ram" ;
10381141 mc -> default_cpu_type = M68K_CPU_TYPE_NAME ("m68040" );
0 commit comments