From 09f2c66bad3f597b82d672de900dd465af991bc7 Mon Sep 17 00:00:00 2001 From: kieranhj Date: Sun, 13 Jan 2019 14:20:23 +0000 Subject: [PATCH] Removed DFS dependency in disksys Just uses OSFILE to load whole files to &3C00 and then copy entire block up to &8000. Should make it compatible with more FS (inc TAPE!) and remove need for DTRAP on DataCentre. --- .gitignore | 1 + beebstep.asm | 11 +- beebstep.ssd | Bin 72192 -> 71936 bytes lib/disksys.asm | 571 ++++++++---------------------------------------- 4 files changed, 102 insertions(+), 481 deletions(-) diff --git a/.gitignore b/.gitignore index 07d9eae..47a2399 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ compile.txt makekc.bat runkc.bat b-emlog.txt +beeb-step.txt diff --git a/beebstep.asm b/beebstep.asm index 76ce873..f17f8d4 100644 --- a/beebstep.asm +++ b/beebstep.asm @@ -70,9 +70,6 @@ GUARD &3000 .start -; Master 128 PAGE is &0E00 since MOS uses other RAM buffers for DFS workspace -SCRATCH_RAM_ADDR = &0400 - INCLUDE "lib/exomiser.asm" INCLUDE "lib/vgmplayer.asm" INCLUDE "lib/disksys.asm" @@ -82,10 +79,10 @@ INCLUDE "lib/bresenham.asm" ; disk loader uses hacky filename format (same as catalogue) ; we use disk loader for SWR banks only -.bank_file0 EQUS "Bank0 $" -.bank_file1 EQUS "Bank1 $" -.bank_file2 EQUS "Bank2 $" -.bank_file3 EQUS "Bank3 $" +.bank_file0 EQUS "Bank0",13 +.bank_file1 EQUS "Bank1",13 +.bank_file2 EQUS "Bank2",13 +.bank_file3 EQUS "Bank3",13 .screen_file EQUS "LOAD Page", 13 diff --git a/beebstep.ssd b/beebstep.ssd index b0afa9a285cd6161810868bb7f7524679eef1bdd..949e122dc424ad6001dd9a3bf80f541815b84b02 100644 GIT binary patch delta 2199 zcmbVNe@s(H9KXH-g#y}^zW4gOhoeeWpdt)R+!Us!l5QjF787MW5HpZ~8%w7Dn0C54 zN4N@UNH7^m(^%p$>j)Y*|EM8bX4-BsFH4rVFn*W?ENnK_smx{R+r2^&aappxm)w2t z`~7@A_x;}8yXU%=;Tp{tSu5E>0~dLBf*+Uq{-yq{rJe@LD$RFFAO%1WlwgeNs~H=m zwo51(ef3por}U5@fK?CrLhZS%?g^^>mwjq1I3@%%sSZx66%^hMZ>s%*!gBdbb?~}6 zAqnH{=!x3%RP6^LAPfQ_#xKO5sN+x7=lD3+SHpPgvR`uM(NV=D7Lbfa*)+|(OtO#WL6Bwq}}#ENZ-Vu zW(FN${E9V=Oex0%o0tybYhr@UOb3ZHGr=QF#}N?{<$u1@I?Q$32kc~ZsT)mm{NJ;{t~S zA)d+d(l}XQQf^!++A5X{6uH+2Eba|wi$1o%ZO@On>OhgVO>T33!WQFLFNLG1j}2Je zo9f&f;rqs0n|KK~Ume&uQ#=wsYMpnSBCs%lokL$Q6TV^t#V-=9git*1xWd*pb++5` z#db@oEl;&u^Br&2?1J@8?;g#6<2dxfTs@Ubdtb?|avEt~i~8x*LdAS+u%Cvbv{)sv zxO5=7DnM3>9N#4t zQN@Da94a>qKGch5*k^)OCOn7k>9HQg^tcM$*OM9^=;1NQ&3Xc!NO?l)xTeRz?U_9v zI3JPo6@FQ0h1R|$E$m0fjo66ZGy0Q@s-KCfCZbCC5w(-wNQmp6C9zEWcA5A~iYUTO zeAV;lbjtYGG#Vcl_03||K+GDDtVL=uzivf_xL!mVQLJ%AaU!go*N~N1PGY45mc!cy zIAee(Ao&0$R0(}3u1_e@Px{cj9^KJ<#`RDT{D5306ROyBM(?6j2-s2p-#%_D{oGX&wOSN+L0nwE8N?TjG;a1pbB-c|Ue+M>!@`X!>Wd?&`Ti zdxb^em6LcIltomF$$Lgwt8FpyvLW`O#!+SBE*A1d7tI0Pke(Faom8^ad6RcRdEL-y z4)vQgZD-x~fa{HoHp$ zrKD>5Mj5n}CDsg;1WGmOq71X8d&>B!*^=;BHXr4d|2MY}L*9(@&|!F`0fydze6}BW zQkD-yqj1I?Z-87LsNH*DzkTnX1H1R_mjOKLwqfWE6jV^h;MMU03)NR!d72qwBpH7L DVV-UK delta 2400 zcmbVNeQZb&hxtu5{N^A5W+ChN($OmlUeIlDnP2Xy?(GJBB?g1 zZIVuvqpoH&%5~ztYJxukmWcy5;-R#BNY&;Ep{0Qnl#Op-Z}T2-|u(NJ@5K>=w0W~73cH@+fD%u!S^xryNdl;#U8F$0oC<3pnBv$ z$g=9tb$fFE^>^)Gwb?s_%ljNJI%0@_9ET8UMaDIsmbmO2x#H78N)4e`eF?)ia>8*)8pitAs{s7uJ) zqYv?LFU~k+&b;dxyKxH?(p`0oHt8Az0{8{ z4q#}5F^El<@hUcL8nZz?F6hVrv&b)mG|D2^II;@ngQG>4P#oZTIk#EO5C{}u<3Svr zv%%JDfj@^}_vlABxnI!bs!g%ILf-R7X3-9T?iT1*1iA+VQz*MvDAf#~?ht0KJ4Y$ z+NF_Ql9t#fjdV&E$fHsYnZ%~$noBOSO^V(Tc&OQ|EOOmuJ;d}|RXFyjL`Ou(QYw;^ z7#$QLk$c9hIz>+LRqk06^XzxZm?uTJ8I?r8`6f^FmJ@v`X;1BlxSfhdLhOTBLNrFjKFExU#+cYQ z#vyt0qYt{Lw94JFzn2h0C4MWUp0@F%Sm5go75}8?6NVsIE+p4xx(c%{^IjfaK~g-; zODoLmg~(?N!HVBNjT9}7T2`@LG95)|C>*!AkNcgHmT8J_&NRojoM?KZnfyS~x7O^B zU6EQ?Va(3*^p{d56yMqvZzYq#_qW1Tnh$4MZ?{YrkA>!=QvjO**h%`gWx{PK)AD6P z2na3n(VNnNXI?zsMo1I4J1e%mVt0X!KC%C6ME_IGCVN=WtKEBIU4q#_ZwTeS$f*Y7 zhCpr!{7~R&ONm{p63`jAofXzMS0xL72@B>ecsr50CCK4b5Qa!bU_MAG5+Vx9gFm}oc>?gOn^JVs`$fA(E=mXwves| z$^)x>c=$yRk-J{gTStTdxfWpch9k!F3&z!e*}!b{YQTup@hMOq0pw;qyosv; zU0e4^>>7W+M&2!c{3nBJ8lT=lnHRRLAt=X^1<6^KXvUBoi+ zi)ErzCUSVt-1DF4rIMkSu#E!SunDeDc-4qkji72yZ80~lsF1}uDoEw;uQ(iswVM)j zV!4Qw63k5;LE;aRiz?jpkG-Wpc9UGHqqTBYk?DFl;gN}Dr4h`DkG+Li=h)3?JgCpD zpRYYHm)zmoZ+h&IIxp*=)HZKCFY`e&m3>@J4kcfo$!-Cg-6L~%2X{MVy=6lOJ`V>N z|E_oD`qR@e-iO9M)uO)+>Ob1xkDUv`jLEH^UO!tkUGv)alqnViZ5|0i#P6n`1-q8R z!#(T5bMTkB1W^GZQ=gLXD$5vNxb)hw6+(LfwcAbiDfF(JV&y5BK4ezZ_fS!>`&rb3d5mJdXDgc`F7o5*K=z6xsKc8|tIaz~ zwUgU2+ok36=)^09ld7q(bu_77dP~jfs#%>ziL#eM`8@Hf#kW*#9XfFEsY8*2-+1cl ePaZ<-(|8+G^&fgW>}S=>lip_g>v$5|oc{tQg}_Px diff --git a/lib/disksys.asm b/lib/disksys.asm index 199f0e1..05a4737 100644 --- a/lib/disksys.asm +++ b/lib/disksys.asm @@ -3,502 +3,125 @@ ; http://chrisacorns.computinghistory.org.uk/docs/Acorn/Manuals/Acorn_DiscSystemUGI2.pdf ; Our SWR loader is 60% faster than *SRLOAD -DISKSYS_DEBUG = FALSE -DISKSYS_CATALOG_ADDR = SCRATCH_RAM_ADDR -DISKSYS_BUFFER_ADDR = DISKSYS_CATALOG_ADDR+512 ; &1000 ; must be page aligned -DISKSYS_BUFFER_SIZE = 1 ; SECTORS TO READ, MUST BE ONE (for now) +.beeb_disksys_start + +disksys_loadto_addr = $3C00 + +\*------------------------------- +\* DISKSYS OSFILE PARAMS +\*------------------------------- + +.osfile_params +.osfile_nameaddr +EQUW &FFFF +; file load address +.osfile_loadaddr +EQUD 0 +; file exec address +.osfile_execaddr +EQUD 0 +; start address or length +.osfile_length +EQUD 0 +; end address of attributes +.osfile_endaddr +EQUD 0 -.osword_params -.osword_params_drive -EQUB 0 ; drive -.osword_params_address -EQUD 0 ; address -EQUB &03 ; number params -EQUB &53 ; command = read data multi-sector -.osword_params_track -EQUB 0 ; logical track -.osword_params_sector -EQUB 0 ; logical sector -.osword_params_size_sectors -EQUB &2A ; sector size / number sectors = 256 / 10 -.osword_params_return -EQUB 0 ; returned error value - -; Returns last diskop error code in A -.disksys_get_error -{ - lda osword_params_return - rts -} - -;-------------------------------------------------------------- -; set disk head position for next read operation -;-------------------------------------------------------------- -; on entry -; X = track number (0-79) -; Y = sector number (0-9) -; max 80 tracks x 10 sectors = 800 sectors -.disksys_seek -{ - stx osword_params_track - sty osword_params_sector - rts -} - - - -;-------------------------------------------------------------- -; Load sectors from disk to memory ;-------------------------------------------------------------- -; on entry -; A = number of sectors to read (0-31) -; X = destination memory address LSB -; Y = destination memory address MSB -; if previous seek was to the first sector on a track, and A=10 then a complete track will be read. -.disksys_read_sectors -{ - \\ Store sector count in params block - and #&1f - ora #&20 - sta osword_params_size_sectors - - \\ Update load address in params block - stx osword_params_address+0 - sty osword_params_address+1 - - \\ Make DFS read multi-sector call - ldx #LO(osword_params) - ldy #HI(osword_params) - lda #&7F - jsr osword - - \\ Error value returned in osword_params_return - rts -} - -IF 0 -.disksys_catalogue_addr EQUW 0 - -;-------------------------------------------------------------- -; set the memory address where the disk catalogue will be stored +; Load a file from disk to memory (SWR supported) +; Loads in sector granularity so will always write to page aligned address ;-------------------------------------------------------------- -; on entry -; X = catalogue memory address LSB -; Y = catalogue memory address MSB -.disksys_set_catalogue_addr +; A=memory address MSB (page aligned) +; X=filename address LSB +; Y=filename address MSB +.disksys_load_direct { - stx disksys_catalogue_addr+0 - sty disksys_catalogue_addr+1 - rts -} -ENDIF + STA osfile_loadaddr+1 -;-------------------------------------------------------------- -; Fetch the 512 byte catalogue from the disk to memory -;-------------------------------------------------------------- -; on entry -; X = destination memory address LSB -; Y = destination memory address MSB -; on exit -; 512 bytes written to buffer in X/Y -.disksys_read_catalogue -{ - ; jsr disksys_set_catalogue_addr + \ Point to filename + STX osfile_nameaddr + STY osfile_nameaddr+1 - ldx #0 - ldy #0 - jsr disksys_seek - lda #2 - ldx #LO(DISKSYS_CATALOG_ADDR) ;disksys_catalogue_addr+0 - ldy #HI(DISKSYS_CATALOG_ADDR) ;disksys_catalogue_addr+1 - jsr disksys_read_sectors - rts + \ Ask OSFILE to load our file + LDX #LO(osfile_params) + LDY #HI(osfile_params) + LDA #&FF + JMP osfile } - -IF 0 -; on entry -; X is ID of the file -; Assumes disksys_read_catalogue has been called prior -; X, Y is preserved -; TEST FUNCTION -.disksys_get_filename +.disksys_load_file { - txa - pha + \ Final destination + STA write_to+1 - lda #LO(DISKSYS_CATALOG_ADDR) ;disksys_catalogue_addr+0 - sta addr+1 - lda #HI(DISKSYS_CATALOG_ADDR) ;disksys_catalogue_addr+1 - sta addr+2 + \ Where to? + LDA write_to+1 + BPL load_direct - txa - asl a - asl a - asl a - clc - adc #8 - tax + \ Load to screen if can't load direct + LDA #HI(disksys_loadto_addr) - ldy #8 -.addr - lda &ffff,x - jsr &ffee - inx - dey - bne addr + \ Load the file + .load_direct + JSR disksys_load_direct - pla - tax - rts -} -ENDIF + \ Do we need to copy it anywhere? + .write_to + LDX #&FF + BPL disksys_copy_block_return + \ Get filesize + LDY osfile_length+1 + LDA osfile_length+0 + BEQ no_extra_page + INY ; always copy a whole number of pages + .no_extra_page -;-------------------------------------------------------------- -; Returns number of files on the disk in A -;-------------------------------------------------------------- -; X/Y preserved -.disksys_get_numfiles -{ - lda #LO(DISKSYS_CATALOG_ADDR) ;disksys_catalogue_addr+0 - clc - adc #5 - sta addr+1 - lda #HI(DISKSYS_CATALOG_ADDR) ;disksys_catalogue_addr+1 - adc #1 - sta addr+2 -.addr - lda &ffff ; get numfiles (is *8) - ; divide numfiles by 8 - lsr a - lsr a - lsr a - rts + \ Read from + LDA #HI(disksys_loadto_addr) } +\\ Fall through! - -;-------------------------------------------------------------- -; Find a file on the disk by filename -;-------------------------------------------------------------- -; Returns id of a file on the disk (0-31) -; returns 255 if not found -; X = filename address LSB -; Y = filename address MSB -; filename must be an 8 byte format where D is directory "NNNNNNND" -; filename IS case sensitive. -.disksys_find_file +; A=read from PAGE, X=write to page, Y=#pages +.disksys_copy_block { - stx comp_addr2+1 - sty comp_addr2+2 - - lda #LO(DISKSYS_CATALOG_ADDR) ;disksys_catalogue_addr+0 - clc - adc #8 - sta comp_addr+1 - lda #HI(DISKSYS_CATALOG_ADDR) ;disksys_catalogue_addr+1 - adc #0 - sta comp_addr+2 - - ; get numfiles - jsr disksys_get_numfiles - sta counter+1 - -;loop through files looking for exact match - ldx #0 -.check_loop - ldy #7 -.comp_loop - -.comp_addr - lda &ffff,y ; modified - -.comp_addr2 - cmp &ffff,y ; modified - - bne failed - dey - bpl comp_loop - ; found it, return id - txa - rts - - -.failed - - lda comp_addr+1 - clc - adc #8 - sta comp_addr+1 - lda comp_addr+2 - adc #0 - sta comp_addr+2 - inx -.counter - cpx #123 ; modified - beq end - jmp check_loop -.end - ; not found - lda #255 - rts + STA read_from+2 + STX write_to+2 + + \ We always copy a complete number of pages + + LDX #0 + .read_from + LDA &FF00, X + .write_to + STA &FF00, X + INX + BNE read_from + INC read_from+2 + INC write_to+2 + DEY + BNE read_from } +.disksys_copy_block_return + RTS - -;-------------------------------------------------------------- -; Fetch file attributes -;-------------------------------------------------------------- -; returns file attributes for given file id -; on entry -; A=file id (0-31) -; on exit -; X=attributes LSB -; Y=attributes MSB -.disksys_file_info +IF 0 \\ enable when we have PuCrunch +.disksys_decrunch_file { - asl a - asl a - asl a - clc - adc #8 - adc #LO(DISKSYS_CATALOG_ADDR) ;disksys_catalogue_addr+0 - tax - lda #HI(DISKSYS_CATALOG_ADDR) ;disksys_catalogue_addr+1 - adc #1 - tay - rts + \ Final destination is baked into pu file + STA unpack_addr+1 + + \ Load to screen as can't load direct + LDA #HI(disksys_loadto_addr) + JSR disksys_load_direct + + .unpack_addr + LDA #&00 + LDX #LO(disksys_loadto_addr) + LDY #HI(disksys_loadto_addr) + JMP PUCRUNCH_UNPACK } - -;-------------------------------------------------------------- -; Load a file from disk to memory (SWR supported) -; Loads in sector granularity so will always write to page aligned address -;-------------------------------------------------------------- -; A=memory address MSB (page aligned) -; X=filename address LSB -; Y=filename address MSB -; clobbers memory DISKSYS_BUFFER_ADDR to DISKSYS_BUFFER_ADDR+768 -.disksys_load_file -{ - sta transfer_addr+2 - - ; get the currently selected ROM/RAM bank - ; BEFORE we do any DFS related work since that will page the DFS ROM in - lda &f4 - sta swr_select+1 - - txa:pha:tya:pha - - ; load 512 byte disk catalogue to DISKSYS_CATALOG_ADDR to DISKSYS_CATALOG_ADDR+512 - ldx #LO(DISKSYS_CATALOG_ADDR) - ldy #HI(DISKSYS_CATALOG_ADDR) - jsr disksys_read_catalogue - - pla:tay:pla:tax - - jsr disksys_find_file - bpl continue - ; file not found - rts -.file_length EQUB 0,0,0 -.file_sector EQUB 0,0 -.file_sectors EQUW 0 - -IF DISKSYS_DEBUG -.txt_sector EQUS "sector %w", LO(file_sector), HI(file_sector), 13,10,0 -.txt_length EQUS "length %w", LO(file_length), HI(file_length), 13,10,0 -.txt_sectors EQUS "sectors %w", LO(file_sectors), HI(file_sectors), 13,10,0 -.txt_t1 EQUS "Track %a", 13,10,0 -.txt_s1 EQUS "Sector %a", 13,10,0 -.txt_l1 EQUS "Loading to %a", 13,10,0 -ENDIF - - -.continue - ; get attributes - jsr disksys_file_info - ; we ignore load & exec address - ; just need length & start sector - stx &9e - sty &9f - - ; get file length in bytes - ldy #4 - lda (&9e),y - sta file_length+0 - iny - lda (&9e),y - sta file_length+1 - iny - lda (&9e),y - lsr a - lsr a - lsr a - lsr a - and #3 - sta file_length+2 - - ; get sector offset (10 bits) - lda (&9e),y - and #3 - sta file_sector+1 - iny - lda (&9e),y - sta file_sector+0 - - ; round up file length to total sector count - lda file_length+1 - sta file_sectors+0 - lda file_length+2 - sta file_sectors+1 - lda file_length+0 - beq pagea - inc file_sectors+0 - bcc pagea - inc file_sectors+1 -.pagea - -IF DISKSYS_DEBUG - MPRINT txt_sector - MPRINT txt_length - MPRINT txt_sectors -ENDIF - -; divide sector offset by 10 to get track & sector - lda file_sector+1 - ldx #8 - asl file_sector+0 -.l1 - rol a - bcs l2 - cmp #10 - bcc l3 -.l2 - sbc #10 - sec -.l3 - rol file_sector+0 - dex - bne l1 - - sta file_sector+1 ; now contains sector - -IF DISKSYS_DEBUG - lda file_sector+0 ; now contains track - MPRINT txt_t1 - lda file_sector+1 ; now contains sector - MPRINT txt_s1 -ENDIF - - - -.load_loop - - ; seek to sector - ldx file_sector+0 ; track - ldy file_sector+1 ; sector - jsr disksys_seek - - ; see if any sectors left to load - lda file_sectors+0 - bne fetch - lda file_sectors+1 - bne fetch - -IF DISKSYS_DEBUG - MPRINT txt_sectors -ENDIF - ; finished - rts -.fetch - -IF DISKSYS_DEBUG - lda transfer_addr+2 - MPRINT txt_l1 ENDIF - ; load a single sector to 256 byte memory buffer DISKSYS_BUFFER_ADDR - lda #DISKSYS_BUFFER_SIZE - ldx #LO(DISKSYS_BUFFER_ADDR) - ldy #HI(DISKSYS_BUFFER_ADDR) - jsr disksys_read_sectors - - sei -.swr_select - ; select the destination ROM/RAM bank that was selected on entry to the routine - lda #&FF ; MODIFIED - jsr swr_select_bank - - ; copy from the memory buffer to destination address - ldx #0 -.transfer - lda DISKSYS_BUFFER_ADDR,x -.transfer_addr - sta &ff00,x ; modified - inx - bne transfer - cli - - ; advance destination memory address by one page - inc transfer_addr+2 - - ; advance disk head to next sector - inc file_sector+1 - lda file_sector+1 - cmp #10 - bne same_track - ; move to next track - lda #0 - sta file_sector+1 - inc file_sector+0 -.same_track - - ; decrease the number of sectors remaining - lda file_sectors+0 - sec - sbc #1 - sta file_sectors+0 - lda file_sectors+1 - sbc #0 - sta file_sectors+1 - - jmp load_loop -} - -; DFS DISK FORMAT -; -; Sector 00 -; &00 to &07 First eight bytes of the 13-byte disc title -; &08 to &0E First file name -; &0F Directory of first file name -; &10 to &1E Second file name -; &1F Directory of second file name . . . . -; . . and so on -; Repeated up to 31 files - -; Sector 01 -; &00 to &03 Last four bytes of the disc title -; &04 Sequence number -; &05 The number of catalogue entries multiplied by 8 -; &06 (bits 0,1) Number of sectors on disc (two high order bits of 10 bit -; number) -; (bits 4,5) !BOOT start-up option -; &07 Number of sectors on disc (eight low order bits of 10 bit -; number) -; &08 First file's load address, low order bits -; &09 First file's load address, middle order bits -; &OA First file's exec address, low order bits -; &0B First file's exec address, middle order bits -; &0C First file's length in bytes, low order bits -; &0D First file's length in bytes, middle order bits -; &0E (bits 0,1) First file's start sector, two high order bits of 10 bit -; number -; (bits 2,3) First file's load address, high order bits -; (bits 4,5) First file's length in bytes, high order bits -; (bits 6,7) First file's exec address, high order bits -; &0F First file's start sector, eight low order bits of 10 bit -; number -; . . . and so on -; Repeated for up to 31 files - - +.beeb_disksys_end