Jump to content
IGNORED

SpartaDOS X and "custom" RAM Disk code


reifsnyderb

Recommended Posts

Hello,

 

I am working on a RAM Disk card and have a couple questions.  But, I should probably explain a little about the code that follows.

 

The code that follows is a little "rough".  For debugging purposes, it is compiled into a development XL/XE kernel.  At a later time, it will be on a ROM chip on a 1090 card and, being a parallel device, will be essentially inserted into the kernel at the same place.  This code is, like a parallel device, intercepting SIO commands on SIOV.  For debugging purposes, I am also using PORTB RAMBO banking.  Later on, the banking will be via a register on the card.  So, this is just a stage in the develoment process.  I've also used Page 6 to temporarily store a few bytes.  That will also change.  Once I get it working, I'll release the RAM Disk source code as it may help others in the future.  Also, the RAM Disk code is temporarily hard coded to D4:

 

At this time, I am able to create a RAM Disk in Atari's DOS 2.5 and it appears to work perfectly.  Loading, saving, running files, copying, etc., all looks good.  Disk Wizard shows the directory structure and VTOC seem to be working fine.  I am limited to Enhanced Density disks, though.

 

Now, about SpartaDOS-X.  I am trying to get large RAM Disks, such as 1MB or more in size.  I've added the PERCOM block code so that a PERCOM block can be read.  (The PERCOM block can be read propery from a BASIC program similar to that in an Insight Atari article.)  SDX's format program keeps giving me an error 138 with or without the PERCOM block code.  I am wondering if maybe SDX is more picky than DOS 2.5.  Maybe I need to handle something differently or have the status bytes wrong?

 

I've been using Altirra for development.  When I try to format via SDX, I've noticed that the profiler shows POKEY being accessed when I try to format.  Does SDX not use the OS for SIO access?  Using the Atari OS would make any parallel I/O transparent.  However, if the Atari OS is ignored, then SDX would need a driver.

 

Thanks!

 

Brian

 

Source code follows.....

 

 

 

 

; Use ABUFPT (4 bytes) for page zero.
; Use TMPPTR (2 bytes) for page zero.  -- TMPPTR is ABUFPT +2 & +3
; DUNIT is on stack when RDISK is called
;DVSTAT is at $2EA   ($80, $FF, $E0, $00)

RDBANK     EQU    ABUFPT            ; Calculated bank -- can later be used as RDTMPA after bank is set.
RDSLB        EQU    TMPPTR             ; Sector offset low byte
RDSHB        EQU    TMPPTR+1        ; Sector offset high byte
RDTMPA    EQU    ABUFPT            ; Temp byte
RDTMPB    EQU    ABUFPT+1        ; Temp byte


;FOMAT    EQU    '!'    ;format command
;PUTSEC    EQU    'P'    ;put sector command
;READ    EQU    'R'    ;read command
;STATC    EQU    'S'    ;status command
;WRITE    EQU    'W'    ;write command

 

RDISK = * ; entry
                LDA        DDEVIC
                CMP        #$31                ; If not for device #$31, clear carry and return
                BNE        RDISKF

                LDA        DUNIT            ; Get disk number
                CMP        #$04                ; Is this for disk 4?            !!!!!!!!!!!!!  HARDCODED FOR NOW
                BNE        RDISKF            ; No, it's not for disk 4.  Exit

                LDA        ABUFPT        ; Store ABUFPT  -- Temp use page 6
                STA        $0600
                LDA        ABUFPT+1
                STA        $0601
                LDA        ABUFPT+2
                STA        $0602
                LDA        ABUFPT+3
                STA        $0603


                LDA        DCOMND        ; Get the command to execute
                ; Standard SIO commands
                CMP        #FOMAT        ;#$21                ; "!", Format
                BNE        RDISK1
                JSR        RDFMT
                JMP        RDISK8
RDISK1                
                CMP        #PUTSEC        ;#$50                ; "P", Put Sector (No verify)
                BNE        RDISK2
                JSR        RDWT
                JMP        RDISK8
RDISK2                
                CMP        #READ            ;#$52                ; "R", Read
                BNE        RDISK3
                JSR        RDRD
                JMP        RDISK8
RDISK3
                CMP        #STATC        ;#$53                ; "S", Status
                BNE        RDISK4
                JSR        RDST
                JMP        RDISK8
RDISK4
                CMP        #WRITE            ;#$57                ; "W", Write with Verify
                BNE        RDISK5
                JSR        RDWT
                JMP        RDISK8

RDISKF                                            ; Clear carry to indicate I/O not handled by the RAM Disk
                CLC                                ; Clear carry when for other device
                RTS                                ; Note:  Placement of RDISKF is to stay within 128 byte range of branch instructions

RDISK5
                ; Extended SIO commands
                CMP        #$22                ; Format w/ Extended Density
                BNE        RDISK6
                JSR        RDFMT
                JMP        RDISK8
RDISK6
                CMP        #$4E                ; Read PERCOM Block
                BNE        RDISK7
                JSR        RDRPB
                JMP        RDISK8
RDISK7
                CMP        #$4F                ; Write PERCOM Block
                BNE        RDISKF
                JSR        RDWPB
                                                
RDISK8
                LDA        $0600            ;  Restore ABUFPT  -- Temp use page 6
                STA        ABUFPT
                LDA        $0601
                STA        ABUFPT+1
                LDA        $0602
                STA        ABUFPT+2
                LDA        $0603
                STA        ABUFPT+3

                SEC                                ; Set carry to indicate I/O handled by the RAM Disk
                RTS

 

; RAM Disk change memory bank
; NOTE:  PORTB banking is used for testing.
RDBKO
                ; Enable PORTB banking, use only bits 2,3,5,6, and set bank.
                LDA    RDBANK                ; Get the bank number
                AND    #%00001100        ; Set bits 5&6 first
                ASL    A
                ASL    A
                ASL    A
                STA    RDTMPB
                LDA    RDBANK                ; Set bits 2&3
                AND    #%00000011
                ASL    A
                ASL    A
                ORA    RDTMPB                ; Combine bits 2,3,5,6
                STA    RDTMPB
                            
                LDA    PORTB
                AND    #%10000011        ; Set bit 4 to 0 and clear bank bits
                ORA    RDTMPB                ; Add bank number
                STA    PORTB                    ; Turn on banking with correct bank set

                RTS


; RAM Disk Calculate Memory Address
RDCMA = *

;                    Temp:  Just use 8 16k banks for 128k  NOTE Added at edit:  There is no limiting code and this note about using 8 16k banks is pretty much meaningless.
;                    DAUX1 = sector low byte
;                    DAUX2 = sector high byte
;                    16k (16384) = 128 sectors of 128 bytes

                ; Calculate Bank
                LDA    DAUX1                ; Load sector low byte
                ASL    A                            ; Move bit 7 of the sector low byte into the carry flag
                STA    RDSLB                ; Store rotated sector low byte for later
                LDA    DAUX2                ; Load sector high byte
                ROL    A                            ; Rotate A left, Carry is now bit 0, A is now the bank number.
                STA    RDBANK            ; Store the bank number for now.
                
                ; Calculate offset RAM address given 128 byte sectors.
                LDA    #$00
                STA    RDSHB                ; Zero sector offset high byte.
                LDX    #$06                    ; Set X to loop through 7 more times to get offset RAM address below.
                CLC
RDCMA1                                        ; Finish rotating left offset RAM address for 128 byte sectors.
                ASL    RDSLB
                ROL    RDSHB
                DEX
                BNE    RDCMA1

                LDA    #$40                    ; Add $4000 to the sector offset byte in RAM
                ORA    RDSHB                ; (Bank is from $4000-$7FFF)
                STA    RDSHB

                RTS

; RAM Disk Format
RDFMT = *
; needs to zero all banks  -- first zero 16 banks w bank at pages $40-$7F
                LDA    #$0F                    ; Start with bank F.
                STA    RDBANK

                LDA    #$00                    ; Set low byte of page 0 address pointer
                STA    TMPPTR

                LDA    PORTB                ; Store PORTB
                PHA

RDFMT1
                JSR    RDBKO                ; Set bank
                LDA    #$00                    ; Set A to $00 to zero bank later
                LDX    #$80                    ; Use X for page byte of bank

RDFMT2
                DEX                                ; Set page byte (high byte) of  page 0 address pointer
                STX    TMPPTR+1

                LDY    #$00                    ; Use Y for address low byte of bank

RDFMT3
                DEY                                ; Set address low byte
                STA    (TMPPTR),Y        ; Zero the page
                BNE    RDFMT3            ; Zero the page until Y = 0

                CPX    #$40                    ; Finished zeroing bank?
                BNE    RDFMT2            

                CMP    RDBANK            ; A is already 0
                BEQ    RDFMT4            ; If bank is zero, exit
                DEC    RDBANK            ; Decrement to next bank
                JMP    RDFMT1

RDFMT4
                PLA                                ; Restore PORTB and turn off banking.
                STA    PORTB                

                LDY    #SUCCES
                STY    DSTATS

                RTS


; RAM Disk Read Sector
RDRD = *
                JSR     RDCMA                ; Calculate the Memory Address

                LDA    PORTB                ; Store PORTB
                PHA

                JSR    RDBKO                ; Set the bank
    
                LDA    DBUFLO            ; Set data buffer address in page zero for indexing
                STA    RDTMPA
                LDA    DBUFHI
                STA    RDTMPB

                LDY    #$80
RDRD1                                            ; Copy sector from RAM Disk to buffer.
                DEY
                LDA    (RDSLB),Y
                STA    (RDTMPA),Y
                CPY    #$00
                BNE    RDRD1

                PLA                                ; Restore PORTB and turn off banking.
                STA    PORTB

                LDY    #SUCCES        ;  #$01
                STY    DSTATS            ; Return status code of #$01

                RTS

; RAM Disk Read PERCOM Block
RDRPB = *
                LDA    #low RDPRCM    ; Set source location
                STA    RDTMPA
                LDA    #high RDPRCM
                STA    RDTMPA+1

                LDA    DBUFLO                ; Set destination buffer
                STA    TMPPTR
                LDA    DBUFHI
                STA    TMPPTR+1

                LDY    #$0B                        ; Use Y as index
RDRPB1
                DEY                                    ; Set byte to copy
                LDA    (RDTMPA),Y        ; Copy PERCOM block into buffer
                STA    (TMPPTR),Y
                CPY    #$00
                BNE    RDRPB1
            
                LDY    #SUCCES            ; Exit
                STY    DSTATS
                RTS

RDPRCM
                ; NOTE:  HARD CODED TO $800 128 BYTE SECTORS FOR TESTING
                ; tracks, step rate, H#sec,L#sec,#sides,density,H#BPS,L#BPS,drive present,0,0,0
                DB    $01,$00,$08,$00,$00,$00,$00,$80,$FF,$00,$00,$00


; RAM Disk Status
RDST = *
                LDA    DBUFLO
                STA    TMPPTR
                LDA    DBUFHI
                STA    TMPPTR+1
                LDY    #$00
                
                LDA    #$80
                STA    (TMPPTR),Y
                INY
                LDA    #$FF
                STA    (TMPPTR),Y
                INY
                LDA    #$E0
                STA    (TMPPTR),Y
                INY
                LDA    #$00
                STA    (TMPPTR),Y
                
                LDY    #SUCCES
                STY    DSTATS
                RTS

; RAM Disk Write PERCOM block
RDWPB = *
                LDY    #SUCCES
                STY    DSTATS            ; Return status code of #$01

                RTS

; RAM Disk Write Sector
RDWT = *
                JSR     RDCMA                ; Calculate the Memory Address

                LDA    PORTB                ; Store PORTB
                PHA

                JSR    RDBKO                ; Set the bank

                LDA    DBUFLO            ; Set data buffer address in page zero for indexing
                STA    RDTMPA
                LDA    DBUFHI
                STA    RDTMPB

                LDY    #$80
RDWT1                                            ; Copy sector from RAM Disk to buffer.
                DEY
                LDA    (RDTMPA),Y
                STA    (RDSLB),Y
                CPY    #$00
                BNE    RDWT1

                PLA                                ; Restore PORTB and turn off banking.
                STA    PORTB

                LDY    #SUCCES
                STY    DSTATS            ; Return status code of #$01

                RTS

 

 

Edited by reifsnyderb
  • Like 1
Link to comment
Share on other sites

Edit to add:

 

CONFIG.SYS used with SDX:

 

USE OSRAM

DEVICE SPARTA OSRAM

DEVICE SIO

DEVICE ATARIDOS

DEVICE RTIME8

DEVICE JIFFY

 

While the RAMDISK is attempting to use PORTB, SDX is configured such that SDX is not using PORTB.  Keep in mind, using RAMBO extended memory is only temporary and for development purposes.

 

After comparing attempts to select a drive via the format program and using the performance analyzer I found the following SIO activity:

 

When attempting to select D2:, which is an emulated floppy disk:

  Send: 32 53 06 00 8B

  Receive: 41 43 00 DF E0 00 C0

 

  Send: 32 4E 06 00 86

  Receive: 41 43 28 01 00 12 00 00 00 80 FF 00 00 00 BB

 

  So, an emulated floppy disk is responding to both status and percom.

 

When attempting the D4: RAM Disk:

  Send: 34 53 06 00 8D

  Send repeats 4 times with no response.

 

ping @trub and/or @drac030

 

 

 

Link to comment
Share on other sites

Try 'DEVICE SIO /A'. SDX has its own SIO driver, but it property defers to PBI drivers (for example, the U1MB PBI HSIO driver) should they happen to action the IO request. But if you're just patching the OS, SDX needs to be told to defer to the OS SIO handler (using the '/A' switch).

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

35 minutes ago, flashjazzcat said:

Try 'DEVICE SIO /A'. SDX has its own SIO driver, but it property defers to PBI drivers (for example, the U1MB PBI HSIO driver) should they happen to action the IO request. But if you're just patching the OS, SDX needs to be told to defer to the OS SIO handler (using the '/A' switch).

That was it!  Thank you!  I've now got a 256k RAM Disk working in SDX.   :-D

  • Like 1
Link to comment
Share on other sites

7 hours ago, phaeron said:

SpartaDOS X is also special with regard to PBI access, as it directly accesses PBI devices instead of going through the OS.

Necessarily so. I can't see any alternative way of doing it if you're not actually calling SIO to begin with, which takes care of PBI access transparently.

Link to comment
Share on other sites

1 hour ago, ClausB said:

Yes, so users know they may have malfunctioning RAM, or some other sort of corruption, and perhaps can take action before losing data. I had checksums in my original RAMdisk driver, for peace of mind.

 

 

 

Did you have a checksum for every sector?  I am now pondering over this because I am currently using 128 sectors per 16k bank and the math works perfectly. 

Link to comment
Share on other sites

Doesn't DOS already perform a check when handling the files sectors etc.

Would a standalone RAM tester also test the RAM.

Would a test or checksum at very first start up suffice? or a calculated checksum at shut down / startup to verify integrity of battery backed up ram?

Maybe a firmware hardware sort of thing transparent to the Atari itself?

Link to comment
Share on other sites

27 minutes ago, _The Doctor__ said:

Doesn't DOS already perform a check when handling the files sectors etc.

Would a standalone RAM tester also test the RAM.

Would a test or checksum at very first start up suffice? or a calculated checksum at shut down / startup to verify integrity of battery backed up ram?

Maybe a firmware hardware sort of thing transparent to the Atari itself?

I was thinking it would be nice to add a non-destructive RAM test to the firmware.  (That would also help testing when assembling them.   🙂  )  A non-destructive test at boot time is also possible.

 

I think raw sectors have checksum information, but it's handled by the drive and transparent to DOS unless an error is thrown.

 

Adding some sort of check information would really screw up the math.  Maybe a quick "spot check", at boot, would work?

Link to comment
Share on other sites

5 hours ago, ClausB said:

The sums are in a table separate from the sector data. My RAMdisk has 720 sectors so there's room for a table. Yours has $800 sectors, exactly 256K, so there's no room without losing 16 sectors. 

Are you just summing up the 128 bytes of each sector and dropping the carry?  The $800 sectors are only available with the right OS.  With Atari's DOS 2.5 there is extra space, of course.

I too am wondering about how much the checksums slow down the operations.

 

I've added the capability of partitioning the memory into multiple RAM Disks.  So, there is some waste.  I am still pondering how to add checksum information.

Link to comment
Share on other sites

2 hours ago, ClausB said:

Don't your CF drivers use error checking of some sort?

No, a) because that would slow down IO to an unacceptable degree, and b) because the controller should detect transmission errors and react accordingly. Back in the MYIDE I days, checksums were implemented because the hardware was so janky and unstable that it was difficult to even be sure that sector data read from the HDD hadn't become corrupted between the controller, data register and CPU. Performance was as a consequence miserably poor. Once SIDE2, MYIDE II, IDE Plus, etc, came along, there was no need for costly checksums and software error correction, because the hardware basically 'worked'. IDE Plus and my own SIDE drivers implemented some perfunctory tests for undesirable conditions at the end of a sector transfer (DRQ being disasserted early or late, indicating 'missed' or 'double' reads by the CPU), and this was implemented because it was almost completely 'free'. But in restrospect, if the hardware doesn't work well enough that the data cannot pass uncorrupted between the controller and the data register, and the data register and the CPU, the hardware is unstable, and no amount of extra error checking is going to compensate for that.

 

Likewise, if an internal RAM upgrade cannot guarantee that memory reflects what the CPU wrote to it, or that the CPU accurately reads what's in memory, it's a mess, and a PBI or bus-attached memory upgrade (which might conceivably also provide or supplant the main RAM in the machine, as per the external U1MB or Incognito) that can't provide error-free CPU reads and writes is unlikely to be a pleasant experience. Nevertheless, if an argument for checksumming every single sector in real-time can be presented, it's important to remember that if the external banking window appears anywhere other than a PBI window in the $D6xx area (say, at $4000-$7FFF), there is already a hefty buffering overhead (burst IO being impossible if the target buffer occipies the same memory space as the banking window) on top of any additional software error checking.

2 hours ago, ClausB said:

I never timed it but from the code it appears to slow by 20%, still lightning fast compared to floppy disk.

Doubtless, but it may not be so impressive when compared to an SIO device running at 126Kb/s, or a hard disk transferring 70-80KB/s.

Edited by flashjazzcat
  • Like 2
  • Thanks 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...