reifsnyderb Posted September 4, 2023 Share Posted September 4, 2023 (edited) 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 September 4, 2023 by reifsnyderb 1 Quote Link to comment Share on other sites More sharing options...
reifsnyderb Posted September 4, 2023 Author Share Posted September 4, 2023 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 Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted September 4, 2023 Share Posted September 4, 2023 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). 1 1 Quote Link to comment Share on other sites More sharing options...
reifsnyderb Posted September 4, 2023 Author Share Posted September 4, 2023 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. 1 Quote Link to comment Share on other sites More sharing options...
phaeron Posted September 4, 2023 Share Posted September 4, 2023 SpartaDOS X is also special with regard to PBI access, as it directly accesses PBI devices instead of going through the OS. IIRC the original versions of SDX had a bug with polling PBI devices in opposite priority order from the OS ($80 first instead of $01 first). 2 Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted September 5, 2023 Share Posted September 5, 2023 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. Quote Link to comment Share on other sites More sharing options...
+Larry Posted September 5, 2023 Share Posted September 5, 2023 Can you share a little more info about the board? And how does your ramdisk differ from other available ramdisks? Quote Link to comment Share on other sites More sharing options...
reifsnyderb Posted September 5, 2023 Author Share Posted September 5, 2023 1 hour ago, Larry said: Can you share a little more info about the board? And how does your ramdisk differ from other available ramdisks? I'd rather not get into too many details until it's ready to go. 🙂 Quote Link to comment Share on other sites More sharing options...
ClausB Posted September 6, 2023 Share Posted September 6, 2023 Consider adding a checksum table with a sum for each sector. Quote Link to comment Share on other sites More sharing options...
reifsnyderb Posted September 6, 2023 Author Share Posted September 6, 2023 (edited) 4 minutes ago, ClausB said: Consider adding a checksum table with a sum for each sector. Are you thinking this should be done to replace some sort of bad sector checking? Edited September 6, 2023 by reifsnyderb Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted September 6, 2023 Share Posted September 6, 2023 For users with malfunctioning RAM? Quote Link to comment Share on other sites More sharing options...
ClausB Posted September 6, 2023 Share Posted September 6, 2023 (edited) 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. Edited September 6, 2023 by ClausB Quote Link to comment Share on other sites More sharing options...
reifsnyderb Posted September 7, 2023 Author Share Posted September 7, 2023 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. Quote Link to comment Share on other sites More sharing options...
_The Doctor__ Posted September 7, 2023 Share Posted September 7, 2023 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? Quote Link to comment Share on other sites More sharing options...
reifsnyderb Posted September 7, 2023 Author Share Posted September 7, 2023 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? Quote Link to comment Share on other sites More sharing options...
ClausB Posted September 7, 2023 Share Posted September 7, 2023 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. Quote Link to comment Share on other sites More sharing options...
+Larry Posted September 7, 2023 Share Posted September 7, 2023 @ClausB, just curious -- did the checksums slow down the the ramdisk operation much? Quote Link to comment Share on other sites More sharing options...
reifsnyderb Posted September 7, 2023 Author Share Posted September 7, 2023 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. Quote Link to comment Share on other sites More sharing options...
ClausB Posted September 7, 2023 Share Posted September 7, 2023 My sums were unsophisticated ADCs without carry. There are better algorithms. I don't recall ever getting an error, and that increased confidence in the RAMdisk. 1 Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted September 7, 2023 Share Posted September 7, 2023 19 minutes ago, ClausB said: I don't recall ever getting an error, and that increased confidence in the RAMdisk. Which should already be quite high, providing you don't already suspect the computer has faulty RAM. I find this peculiar. 1 Quote Link to comment Share on other sites More sharing options...
ClausB Posted September 7, 2023 Share Posted September 7, 2023 Consider the context. 1984, first 256K expansion, original driver code, no existing RAM testers, etc. Still peculiar? 1 Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted September 8, 2023 Share Posted September 8, 2023 Yes, but it's 2023 and you're advocating that a new RAMdisk driver has checksum code added now. Quote Link to comment Share on other sites More sharing options...
ClausB Posted September 8, 2023 Share Posted September 8, 2023 It's a new hardware design, right? Also, it can reveal other forms of corruption than just bad RAM, such as collision with other software that uses extended RAM. Don't your CF drivers use error checking of some sort? Quote Link to comment Share on other sites More sharing options...
ClausB Posted September 8, 2023 Share Posted September 8, 2023 20 hours ago, Larry said: @ClausB, just curious -- did the checksums slow down the the ramdisk operation much? I never timed it but from the code it appears to slow by 20%, still lightning fast compared to floppy disk. Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted September 8, 2023 Share Posted September 8, 2023 (edited) 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 September 8, 2023 by flashjazzcat 2 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.