Electron User


SEDFS

Author: Mark Smiddy
Publisher: Slogger
Machine: Acorn Electron

 
Published in Electron User 4.09

A DFS upgrade with BBC compatibility: Mark Smiddy puts Slogger's SEDFS through its paces

SEDFS

The official disc system for the Electron is Acorn's Plus 3, and although a powerful system, it uses up more than 3.7K of your memory.

Cumana soon solved the problem with its internal memory floppy disc system, and PAGE remains set at E00. This was reviewed in Electron User, July 1985. So where's the problem? I hear you cry.

It's down to that age-old computer hang up that we all suffer from at one time or another - compatibility. A disc system that cannot talk to other disc systems is at a disadvantage compared to one that can.

Cumana did offer some solutions on its utilities disc, which included software to read and write other formats such as Acorn's ADFS and DFS. Which is fine - just as long as you don't need to do it very often. But it also means that you, as a Cumana disc owner, cannot take advantage of all of the specially written software such as disc menus, disc editors and so on, that appear in magazines and on roms from time to time.

This is precisely the sort of problem that the new SEDFS from Slogger is designed to overcome - but does it?

Designing a DFS from scratch is not easy at the best of times, but trying to make it software compatible with someone else's format is another thing again. To the software, or the user, the DFS must appear to work in exactly the same way as the official Acorn DFS.

Putting the unit through its paces reveals that you can have the whole lot up and running in less than 15 minutes. Even for ham-fisted amateurs like me, changing the rom is not too difficult. And if you buy the complete thing, it's simply a matter of plug in and go.

Switch on and, if all's well, the message:

Acorn Electron
Slogger SEDFS
BASIC
>

appears, and looks very friendly too.

One quick *HELP later and the Slogger announces that it has DFS and UTILS built in and worth further inspection. Figure I shows the Help screen.

It is here that the SEDFS starts to flex its muscles, adding four new and useful commands to the original Acorn list: MAP, MCOPY, RUNPROT and STAT.

*MAP and *STAT are used to discover how much disc space is available and how it is being used.

*MCOPY is similar to *COPY but it copies as many files as memory will allow, not just individual ones, between disc swaps.

*RUNPROT is concerned with Slogger's Tape to Disc Utility and makes use of the internal ram of the DFS while it is loading a program.

Looking further, requesting HELP on the UTILS (figure II) shows four more utilities are available than on the Acorn: *DATE, *FORMAT, *FDCSTAT and *VERIFY. It's worth remembering here that because all of these utilities are built in, you don't have to do rummaging for that utilities disc that you lost months ago, just because you want to format one disc.

*FDCSTAT reveals the status of the floppy disc controller chip at the last error.

*DATE gives the current time and date held in the battery backed up ram inside the Cumana DFS.

Another nice feature is *OPT 8,255 which causes the SEDFS to automatically detect a 40 track disc in an 80 track drive and still be able to read it. In fact, SEDFS is so good that I can't easily find fault with it.

The manual is, quite simply, the best of the type I have seen, charged full of very useful information to suit everyone from the beginner to the professional. Early issues lacked an index but a new one is promised very soon.

Included is a section on overlays, how to fit a 20K plus program into memory at once. This text is a delight to read and other manufacturers would do well to follow Slogger's lead in this area.

There is nothing I hate more than buying a product only to find that I have to spend another 20 on manuals in order to learn how to use it.

Some readers familiar with BBC Micro history may have heard of the much maligned 8271 FDC. Software houses designed many disc loaders around the internal workings of the 8271, so any new DFS would benefit greatly from having that compatibility. Here too the SEDFS scores highly, with a virtual 100 per cent 8271 emulation to Acorn specifications.

So the SEDFS has all of the nice features that we have come to expect from Slogger. But how well does it perform as a filing system?

For the answer to that question we put it through some very tough trials. Result: Top marks right across the range, even to the extent that some of the bugs in the original Acorn DFS have been ironed out.

One of the most notable is where you have two drives, select the second drive and then try to !BOOT the disc. Acorn's DFS quite merrily returns back to the first drive and spins away waiting for a disc.

The SEDFS performed admirably throughout. Speedwise it is not very exciting, but it's no worse than any comparable DFS that I've seen and it would be unfair to benchmark test it against the Electron ADFS, except to say that it does perform very favourably.

To anyone used to the tape format, discs offer speed and reliability beyond compare. And to anyone considering upgrading to discs who needs thorough BBC compatibility, the SEDFS is the logical choice.

Though I must say that, given the choice and the money I think I'd tend to get the ADFS; since I haven't, the editor's going to have trouble getting this review copy back.

If you already have the old Cumana DFS, I can recommend the SEDFS upgrade unreservedly.

Figure I

>*HELP DFS
Expansion 1.00
  ADC/Printer/RS423
Slogger EDFS 1.01
  ACCESS     (L)
  BACKUP     
  COMPACT   ()
  COPY        
  DELETE    
  DESTROY   
  DIR       (

)
  DRIVE     ()
  ENABLE
  INFO      
  LIB       ()
  MAP       ()
  MCOPY      
  RENAME     
  RUNPROT   
  STAT      ()
  TITLE      <br />   WIPE      <afsp> <br />   <br /> OS 1.00 </p> </section> <section id = "Figure_II"> <header> <h3><a href = "/litem/Sedfs/1404/"> Figure II </a></h3> </header> <p id = "typed"> >*HELP UTILS <br /> Expansion 1.00 <br />   ADC/Printer/RS423 <br /> Slogger EDFS 1.01 <br />   BUILD     <fsp> <br />   DATE      <argument> <br />   DISC <br />   DUMP      <fsp> <br />   FORMAT    (<drv>) <br />   FDCSTAT <br />   LIST      <fsp> <br />   TYPE      <fsp> <br />   VERIFY    (<drv>) <br />   <br /> OS 1.00 </p> </section><p class = "text-right"><a onclick = "showSwirl()" href = "/lauthor/Mark-Smiddy/601/reviews/">Mark Smiddy</a></p> </div> </div> <!-- <div class="postcomment"> <div class="row"> <div class="col-md-2"> <img src="images/resources/bg-img4.png" alt=""> </div> <div class="col-md-8"> <form> <div class="form-group"> <input type="text" class="form-control" id="inputPassword" placeholder="Post a comment"> </div> </form> </div> <div class="col-md-2"> <a href="#">Send</a> </div> </div> </div> --> </div> <!--post-bar end--> </div> <!--posts-section end--> </div> <div class="main-ws-sec"> <div class = "item-info security plain-html"> <div class = "row"> <div class = "col-12" style = "margin-top: -12px;"> <h3> Other Acorn Electron Game Reviews By <a onclick = "showSwirl()" href = "/lauthor/Mark-Smiddy/601/reviews/">Mark Smiddy</a> </h3> <hr /> <div class = "jcarousel-wrapper"> <div class = "jcarousel"> <ul> <li> <a href = "/larticle/Survivors-000/18667/"> <div class = "flag_parent"> <img class = "flag_pos_1" src = "/covl_small/electron/atlantis/tapes/Survivors-000.jpg" alt = "Survivors Front Cover" title = "Survivors Review By Mark Smiddy"> </div> </a> Survivors</li> <li> <a href = "/larticle/Spy-Vs-Spy-1-000/13475/"> <div class = "flag_parent"> <img class = "flag_pos_1" src = "/covl_small/electron/tynesoft/tapes/Spy-Vs-Spy-1-000.jpg" alt = "Spy Vs. Spy Front Cover" title = "Spy Vs. Spy Review By Mark Smiddy"> </div> </a> Spy Vs. Spy</li> <li> <a href = "/larticle/Servicing-Personal-Computers-000/14528/"> <div class = "flag_parent"> <img class = "flag_pos_1" src = "/covl_small/electron/newnes/books/Servicing-Personal-Computers-3rd-Edition-000.jpg" alt = "Servicing Personal Computers Front Cover" title = "Servicing Personal Computers Review By Mark Smiddy"> </div> </a> Servicing Personal Computers</li> <li> <a href = "/larticle/Phantom-000/13337/"> <div class = "flag_parent"> <img class = "flag_pos_1" src = "/covl_small/electron/tynesoft/tapes/Phantom-000.jpg" alt = "Phantom Front Cover" title = "Phantom Review By Mark Smiddy"> </div> </a> Phantom</li> <li> <a href = "/larticle/Electron-Expansion-2-0-000/13328/"> <div class = "flag_parent"> <img class = "flag_pos_1" src = "/covl_small/electron/slogger/roms/Electron-Expansion-2-0-000.jpg" alt = "Electron Expansion 2.0 Front Cover" title = "Electron Expansion 2.0 Review By Mark Smiddy"> </div> </a> Electron Expansion 2.0</li> <li> <a href = "/larticle/Survivors-000/13341/"> <div class = "flag_parent"> <img class = "flag_pos_1" src = "/covl_small/electron/atlantis/tapes/Survivors-000.jpg" alt = "Survivors Front Cover" title = "Survivors Review By Mark Smiddy"> </div> </a> Survivors</li> <li> <a href = "/larticle/Phantom-000/18673/"> <div class = "flag_parent"> <img class = "flag_pos_1" src = "/covl_small/electron/tynesoft/tapes/Phantom-000.jpg" alt = "Phantom Front Cover" title = "Phantom Review By Mark Smiddy"> </div> </a> Phantom</li> </ul> </div> <a href="#" class="jcarousel-control-prev">‹</a> <a href="#" class="jcarousel-control-next">›</a> </div> </div> </div> </div> </div> <!--main-ws-sec end--> </div> <div class="col-xl-3 col-lg-3 col-md-12"> <div class="right-sidebar"> <!--widget-about end--> </div> <!--right-sidebar end--> </div> </div> <!-- freelancerbiding --> </div> </div> </div> </main> <div id = "image-modal" class = "modal fade bd-example-modal-lg"> <div class = "modal-dialog modal-lg"> <button type = "button" class = "close" data-dismiss = "modal" aria-label = "Close"> <span aria-hidden = "true">×</span> </button> <div class = "modal-content"> <div class="modal-body"> <div class="innerbody apply-jobbox"> <a id = "image-link-img" href = "" target = "_blank"> <img class = "img img-responsive" id = "image-ills-img" src = ""> </a> </div> </div> </div> </div> </div> <footer> <div class="footy-sec mn no-margin"> <div class="container"> <ul> <li><a href = "/site/page/view/egg-how-it-works">How It Works</a></li> <li><a href = "/site/page/view/egg-cookies">Cookies</a></li> <li><a href = "/site/page/view/egg-copyright">Copyright</a></li> <li><a href = "/site/page/view/egg-terms">Terms & Conditions</a></li> <li><a href = "/site/page/view/egg-history">History</a></li> <li><a href = "/landingMachineType/menu/">Machines Covered</a></li> <li><a href = "/site/page/view/egg-faqs">FAQs</a></li> <li><a href = "/site/page/view/egg-meet-the-team">Meet The Team</a></li> <li><a href = "/helpBuildIt/">Help Build It!</a></li> <li><a href = "/reportError/">Report Error</a></li> <li><a href = "/site/page/view/egg-api">API</a></li> <li><a href = "/contact/">Contact</a></li> <li><a href = "/links/">Links</a></li> </ul> <p><img src="/themeForest/images/copy-icon2.png" alt="">Copyright 2015-2024</p> <img class="fl-rgt" src="/eggman/everygamegoing.png" width = "219" height = "17" alt="everygamegoing logo"> </div> </div> </footer> </div><!--theme-layout end--> <div id = "modal-collection-items-modal" class = "modal fade" role = "dialog"> <div class = "modal-dialog"> <button type = "button" class = "close" data-dismiss = "modal" aria-label = "Close"> <span aria-hidden = "true">×</span> </button> <!-- Modal content--> <div class = "modal-content"> <div class = "modal-header" id = "modal-collection-items-modal-header"> </div> <div class = "modal-body" id = "modal-collection-items-modal-body"> </div> <div class = "modal-footer"> <div class = "row"> </div> </div> </div> </div> </div> <div id = "modal-logout-modal" class = "modal fade" role = "dialog"> <div class = "modal-dialog"> <button type = "button" class = "close" data-dismiss = "modal" aria-label = "Close"> <span aria-hidden = "true">×</span> </button> <!-- Modal content--> <div class = "modal-content"> <div class = "modal-header text-center"> Logout </div> <div class = "modal-body"> <div class = "row"> <div class = "col-12 text-center"> <p> Are you sure you want to logout? </p> <div style = "width: 100%"> <img style = "float: none !important; display: inline-block; height: 250px;" src = "/eggman/confused.png"> </div> <a href = "/site/logout"> <button type = "button" class = "btn btn-primary btn-block">Yes, Logout</button></a> </div> </div> </div> </div> </div> </div> <div class = "modal" id = "modal-shop-items-modal"> <div class = "modal-dialog"> <button type = "button" class = "close" data-dismiss = "modal" aria-label = "Close"> <span aria-hidden = "true">×</span> </button> <div class = "modal-content"> <div class = "modal-header" id = "modal-shop-items-modal-header"> </div> <div class = "modal-body" id = "modal-shop-items-modal-body"> </div> <div class = "modal-footer"> <div class = "row"> </div> </div> </div> </div> </div> <div id = "create-auction-modal" class = "modal fade" role = "dialog"> <div class = "modal-dialog"> <button type = "button" class = "close" data-dismiss = "modal" aria-label = "Close"> <span aria-hidden = "true">×</span> </button> <!-- Modal content--> <div class = "modal-content"> <div class = "modal-header text-center"> Create Auction </div> <div class = "modal-body"> <div class = "col-12"> <p> If you auction an item, it will no longer show in the regular shop section of the site. </p> </div> <div class = "row"> <input name = "auction_sales_item_id" id = "auction_sales_item_id" type = "hidden" readonly value = ""> <div class = "col-6"> <label for = "auction_start_price"> Enter Starting Price: </label> <div class="input-group mb-3"> <div class="input-group-prepend"> <span class="input-group-text">£</span> </div> <input maxlength = "10" class = "form-control" name = "auction_start_price" id = "auction_start_price" type = "text" value = "0.99" aria-label = "Price"> </div> </div> <div class = "col-6"> <label for = "postage_amount"> Enter Postage: </label> <div class="input-group mb-3"> <div class="input-group-prepend"> <span class="input-group-text">£</span> </div> <input maxlength = "10" class = "form-control" name = "postage_amount" id = "postage_amount" type = "text" value = "" aria-label = "Postage Amount"> </div> </div> </div> <div class = "row"> <div class = "col-12"> <label for = "duration_days"> How Long Should Your Auction Run: </label> <select name = "duration_days" id = "duration_days" class = "form-control"> <option value = "3s">3 seconds</option> <option value = "3">3 days</option> <option value = "7">7 days</option> <option selected value = "10">10 days</option> </select> <label for = "date_auction_start" style = "margin-top: 12px;"> Start Date: </label> <input type = "date" id = "date_auction_start" name = "date_auction_start" class = "form-control" value = "2024-11-21"> <label for = "time_auction_start" style = "margin-top: 12px;"> Start Time: </label> <input type = "time" id = "time_auction_start" name = "time_auction_start" class = "form-control" value = "15:21" </div> </div> <button type = "button" onclick = "ajaxCreateAuction()" class = "btn btn-primary btn-block" style = "margin: 12px 18px 24px 18px;">Create Auction</button> </div> </div> </div> </div> </div> <div class = "swirl"></div> </div> <script type="text/javascript" src="/themeForest/js/jquery.min.js"></script> <script type="text/javascript" src="/themeForest/js/popper.js"></script> <script type="text/javascript" src="/themeForest/js/bootstrap.min.js"></script> <script type="text/javascript" src="/themeForest/js/jquery.mCustomScrollbar.js"></script> <script type="text/javascript" src="/themeForest/lib/slick/slick.min.js"></script> <script type="text/javascript" src="/themeForest/js/script.js"></script> <script> // Reinitialize event listeners after a new carousel is loaded dynamically function reinitializeCarouselListeners() { // Loop through all carousels with the class "item-screenshot-carousel" document.querySelectorAll('.item-screenshot-carousel').forEach(function (carousel) { // Attach the event listener for the "previous" button carousel.querySelector('.carousel-control-prev').addEventListener('click', function (event) { event.preventDefault(); // Prevent default behavior // console.log('Previous button clicked on carousel:', carousel); // Manually move the carousel to the previous slide $(carousel).carousel('prev'); }); // Attach the event listener for the "next" button carousel.querySelector('.carousel-control-next').addEventListener('click', function (event) { event.preventDefault(); // Prevent default behavior // console.log('Next button clicked on carousel:', carousel); // Manually move the carousel to the next slide $(carousel).carousel('next'); }); }); } // Call this function after the API call that loads new carousels // For example: function loadCarouselsFromAPI() { // Simulate API call (this should be your actual API call logic) setTimeout(function () { // Let's assume carousels are added to the DOM here // Now reinitialize the listeners for the new carousels reinitializeCarouselListeners(); // Initialize Bootstrap carousel $('.carousel').carousel(); }, 1000); // Simulating a delay for the API call } // Initial setup when the page loads document.addEventListener('DOMContentLoaded', function () { console.log('DOM fully loaded and parsed.'); // Initialize carousels on page load $('.carousel').carousel(); // Initialize listeners for existing carousels reinitializeCarouselListeners(); }); function itemReleaseDateUpdate( item_id ) { base_url = '/'; // Get the value of that box var release_date = $( "#item_" + item_id + "_release_date_control" ).val(); jsonGet = base_url + 'api/setItemField/index/item_id/' + item_id + '/key/release_date/value/' + release_date + '/'; var json = fireJson( jsonGet ); if( json.report == 'Success' ) { var theHtml = ''; theHtml += '<a onclick = "itemFlagReleaseDateExactToggle( ' + item_id + ', \'' + release_date + '\')" maxlength = "10" ' + 'style = "text-align: right; width: 100px;" ' + 'name = "item_' + item_id + '_release_date_control" ' + 'id = "item_' + item_id + '_release_date_control">' + release_date + '</a>'; $( "#item" + item_id + "ReleaseDatePlaceholder" ).html( theHtml ); } } function itemFlagReleaseDateExactToggle( item_id, release_date ) { base_url = '/'; jsonGet = base_url + 'api/setItemField/index/item_id/' + item_id + '/key/flag_release_date_exact/value/0/'; var json = fireJson( jsonGet ); if( json.report == 'Success' ) { var theHtml = ''; theHtml += '<input onchange = "itemReleaseDateUpdate( ' + item_id + ');" maxlength = "10" ' + 'style = "text-align: right; width: 100px;" ' + 'name = "item_' + item_id + '_release_date_control" ' + 'id = "item_' + item_id + '_release_date_control" ' + 'value = "' + release_date + '">'; $( "#item" + item_id + "ReleaseDatePlaceholder" ).html( theHtml ); } } function changeItemMachineTypeGroup( item_id, flag_update_thing_machine_type_group ) { base_url = '/'; var machine_type_group_id = $( "#machine_type_group_id_" + item_id ).val(); var jsonGet = base_url + 'api/changeItemMachineTypeGroup/index/item_id/' + item_id + '/machine_type_group_id/' + machine_type_group_id + '/flag_update_thing_machine_type_group/' + flag_update_thing_machine_type_group + '/'; var json = fireJson( jsonGet ); if( json.report == 'Success' ) { if( $( '#machine_type_group_' + item_id + '_link' ).length ) { $( '#machine_type_group_' + item_id + '_link' ).val( json.machine_type_group_link ); } else { alert( 'Machine Type Group changed.' ); } } } function changeItemPublisherFolder( item_id, flag_update_thing_publisher ) { base_url = '/'; var publisher_folder = $( "#publisher_folder_" + item_id ).val(); var jsonGet = base_url + 'api/changeItemPublisherFolder/index/item_id/' + item_id + '/publisher_folder/' + publisher_folder + '/flag_update_thing_publisher/' + flag_update_thing_publisher + '/'; var json = fireJson( jsonGet ); if( json.report == 'Success' ) { alert( 'Publisher folder changed.' ); } } function modalCollectionItems( item_id ) { base_url = '/'; jsonGet = base_url + 'api/htmlSocialModalCollectionsItemsBody/index/item_id/' + item_id + '/'; // alert( jsonGet ); var json = fireJson( jsonGet ); if( json.report == 'Success' ) { $( '#modal-collection-items-modal-header' ).empty().html( json.html_modal_header ); $( '#modal-collection-items-modal-body' ).empty().html( json.html_modal_body ); $( '#modal-collection-items-modal' ).modal( 'show' ); loadCarouselsFromAPI(); } else { alert( json.alert_message ); } } function getAuctionPostageAmountEstimateBySalesItemId( sales_item_id ) { base_url = '/'; jsonGet = base_url + 'api/getAuctionPostageAmountEstimateBySalesItemId/index/sales_item_id/' + sales_item_id + '/'; var json = fireJson( jsonGet ); if( json.report == 'Success' ) { $( '#postage_amount' ).empty().val( json.postage_amount ); } } function showCreateAuctionModalFromSalesItem( sales_item_id ) { getAuctionPostageAmountEstimateBySalesItemId( sales_item_id ); $( '#modal-collection-items-modal' ).modal( 'hide' ); $( '#create-auction-modal' ).modal( 'show' ); $( '#auction_sales_item_id' ).val( sales_item_id ); $( '#create-auction-modal' ).on( 'shown.bs.modal', function () { $( '#auction_start_price' ).focus(); } ); } function popImage( filename ) { var base_url = '/'; $( '#image-ills-img' ).attr( 'src', base_url + filename ); $( '#image-link-img' ).attr( 'href', base_url + filename ); $( '#image-modal' ).modal( 'show' ); } function scrollToId( id ) { $('html, body').animate({ scrollTop: ($('#' + id ).offset().top) },200); } $( document ).ready(function() { updateKeywordSearchToMatchSelectedButton( '/', '', 'autofocus' ); }); function showSwirl() { // Show swirl $( 'body' ).addClass( 'loading' ); } function hideSwirl() { // Show swirl $( 'body' ).removeClass( 'loading' ); } function showLogoutModal() { $( '#modal-logout-modal' ).modal( 'show' ); } function ajaxCreateAuction() { // Show swirl $( 'body' ).addClass( 'loading' ); // Hide the auction modal $( '#create-auction-modal' ).modal( 'hide' ); var sales_item_id = $( '#auction_sales_item_id' ).val(); var postage_amount = $( '#postage_amount' ).val(); var auction_start_price = $( '#auction_start_price' ).val(); var date_auction_start = $( '#date_auction_start' ).val(); var time_auction_start = $( '#time_auction_start' ).val(); var duration_days = $( '#duration_days' ).val(); var auction_minimum_price = $( '#auction_minimum_price' ).val(); var auction_winner_username = $( '#auction_winner_username' ).val(); console.log( auction_minimum_price ); console.log( auction_winner_username ); request = $.ajax({ type: "POST", url: "/api/newAuction/", data: { sales_item_id: sales_item_id, postage_amount: postage_amount, auction_start_price: auction_start_price, date_auction_start: date_auction_start, time_auction_start: time_auction_start, duration_days: duration_days, auction_minimum_price: auction_minimum_price, auction_winner_username: auction_winner_username, }, }); request.done(function (json, textStatus, jqXHR){ // Remove swirl $( 'body' ).removeClass( 'loading' ); if( json.report == 'Success' ) { modalCollectionItems( $( '#viewing-item-id' ).val() ); } else { alert( 'Unexpected error!' ); } }); // Callback handler that will be called on failure request.fail(function (jqXHR, textStatus, errorThrown){ // Log the error to the console console.error( "The following error occurred: "+ textStatus, errorThrown ); }); } </script> </body> </html>