Permalink
Cannot retrieve contributors at this time
| ; Copyright (C) 2007 - 2011 by David Schmidt | |
| ; 1110325+david-schmidt@users.noreply.github.com | |
| ; | |
| ; This program is free software; you can redistribute it and/or modify it | |
| ; under the terms of the GNU General Public License as published by the | |
| ; Free Software Foundation; either version 2 of the License, or (at your | |
| ; option) any later version. | |
| ; | |
| ; This program is distributed in the hope that it will be useful, but | |
| ; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
| ; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| ; for more details. | |
| ; | |
| ; You should have received a copy of the GNU General Public License along | |
| ; with this program; if not, write to the Free Software Foundation, Inc., | |
| ; 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| ; | |
| ;********************************************************************* | |
| ;* * Movie: * | |
| ;* ProDOS Hyper-FORMAT * ProDOS Hyper-FORMAT II * | |
| ;* * The Return * | |
| ;* created by Jerry Hewett * Modified by Gary Desrochers * | |
| ;* copyright 1985 * * | |
| ;* Living Legends Software * Tryll Software * | |
| ;* * * | |
| ;* A Public Domain disk formatting * A Puplic Domain Disk Formatting * | |
| ;* routine for the ProDOS Disk Op- * You know the same as -------| * | |
| ;* erating System. These routines *<----------------------------| * | |
| ;* can be included within your own * Except it now includes code for * | |
| ;* software as long as you give us * the 3.5 Disk and the Ram3 Disk. * | |
| ;* credit for developing them. * (Please don't use this for any * | |
| ;* * SmartPort volumes bigger than * | |
| ;* Updated on: 23Aug85 * 2.1 Meg.) - fixed to a certain * | |
| ;* * extent in ADTPro integration * | |
| ;*********************************** * | |
| ; * Updated on: 22Dec89 * | |
| ; * * | |
| ; *********************************** | |
| FormatDone: | |
| rts | |
| AgainCloser: | |
| jmp Again | |
| FormatEntry: | |
| ldy #PMFORMAT ; Format title line | |
| jsr PICKVOL ; A now has index into DEVICES table; UNITNBR holds chosen unit | |
| bmi FormatDone | |
| sta DevIndex ; Hang on to that DEVICES index | |
| ldy #PMNULL | |
| jsr WRITEMSG | |
| lda UNITNBR | |
| sta Slot | |
| tax | |
| lda NUMBLKS | |
| sta VolBlks | |
| lda NUMBLKS+1 | |
| sta VolBlks+1 | |
| lda #$00 | |
| sta VolBlks+2 | |
| HypForm: | |
| LSlot: | |
| ldy DevCnt ; Load how many devices | |
| FLoop: | |
| lda DevList,y ; since this isn't a sequential | |
| sta ListSlot ; list then must go through each one | |
| and #$F0 ; must also store what is there for later | |
| cmp Slot | |
| beq ItIsNum | |
| dey | |
| bpl FLoop | |
| jmp NoUnit ; Used to be bmi | |
| ItIsNum: | |
| txa ; Make the slot the indexed register | |
| lsr a ; for getting device drive controller | |
| lsr a | |
| lsr a | |
| tay | |
| lda DevAdr,y ; Get it | |
| sta Addr ; and save it | |
| lda DevAdr+1,y | |
| sta Addr+1 | |
| tay | |
| and #$F0 ; Next see if it begins with a C0 | |
| cmp #$C0 | |
| beq YesSmart ; and if it does is a very smart device | |
| txa | |
| cmp #$B0 ; If it isn't smart test for /Ram | |
| beq YesRam3 | |
| clc | |
| ror a | |
| ror a | |
| ror a | |
| ror a | |
| and #$07 | |
| ora #$C0 | |
| sta Addr+1 ; if it isn't either then treat it as | |
| jmp YesSmart1 ; smart and save what bank it is in. | |
| YesRam3: | |
| lda Addr+1 ; If you think it is a /Ram then check | |
| cmp #$FF ; the bits that tell you so. | |
| beq Loop7 ; Does the Address pointer start with FF | |
| jmp NoUnit | |
| Loop7: | |
| lda Addr ; And end with 00 | |
| cmp #$00 | |
| beq Loop8 | |
| jmp NoUnit | |
| Loop8: | |
| lda ListSlot | |
| and #$F3 | |
| cmp #$B3 | |
| beq Loop9 | |
| jmp NoUnit | |
| Loop9: | |
| lda #$13 | |
| jsr TABV | |
| ldy #PMNULL | |
| jsr WRITEMSGLEFT | |
| jsr OldName | |
| jsr Ram3Form | |
| Jump2: | |
| jmp Again | |
| YesSmart: | |
| tya | |
| and #$0F | |
| rol a ; Move lower 4 bits to upper 4 bits | |
| rol a | |
| rol a | |
| rol a | |
| sta Slot ; Store result in FORMAT slot | |
| YesSmart1: | |
| lda Addr+1 ; Check signiture bytes in the Cn page | |
| sta Buffer+1 ; for a smart device. | |
| lda #$00 | |
| sta Buffer | |
| ldy #$01 | |
| lda (Buffer),y | |
| cmp #$20 | |
| bne NoUnit | |
| ldy #$03 | |
| lda (Buffer),y | |
| bne NoUnit | |
| ldy #$05 | |
| lda (Buffer),y | |
| cmp #$03 | |
| bne NoUnit | |
| ldy #$FF | |
| lda (Buffer),y | |
| cmp #$00 ; Apples DiskII | |
| beq DiskII | |
| cmp #$FF ; Wrong DiskII | |
| beq NoUnit ; must be a smart device. | |
| ldy #$07 ; Test last signiture byte for the | |
| lda (Buffer),y ; Protocol Converter. | |
| cmp #$3C | |
| beq YesSmart2 ; Found a hard drive, CFFA, etc. | |
| cmp #$55 | |
| beq YesSmart2 ; Found a ProFile | |
| cmp #$00 | |
| bne NoUnit ; It isn't so it's no device I know. | |
| YesSmart2: | |
| jsr LName ; Get New name | |
| jsr OldName ; Ask if ready | |
| ldy #$FE | |
| lda (Buffer),y | |
| and #$08 | |
| sta ShouldLLFormat ; Skip the test for low level format capability | |
| jsr SmartForm ; Jump to routine to format Smart Drive | |
| lda ListSlot | |
| and #$F0 | |
| sta Slot | |
| jsr CodeWr ; Jump to routine to produce Bit map | |
| jmp Catalog ; Write Directory information to the disk | |
| Jump3: jmp Again | |
| NoUnit: | |
| ldy #PMUnitNone ; Prompt to continue or not Because | |
| jsr WRITEMSGAREA ; There is no unit number like that | |
| jmp Again | |
| DiskII: | |
| jsr LName ; Get new name | |
| jsr OldName ; Ask if ready | |
| jmp DIIForm ; Format DiskII | |
| ;******************************* | |
| ;* * | |
| ;* LName: Prompt for unit name * | |
| ;* * | |
| ;******************************* | |
| LName: | |
| lda #$14 | |
| jsr TABV | |
| ldy #PMVolName | |
| jsr WRITEMSGLEFT | |
| LRdname: | |
| lda #$0E ; Reset CH to 14 | |
| sta CH | |
| ldx #$00 | |
| beq LInput ; Always taken | |
| LBackup: | |
| cpx #0 ; Handle backspaces | |
| beq LRdname | |
| dex | |
| lda #$88 ; <-- | |
| jsr COUT | |
| LInput: | |
| jsr RDKEY ; Get a keypress | |
| cmp #$88 ; Backspace? | |
| beq LBackup | |
| cmp #$FF ; Delete? | |
| beq LBackup | |
| cmp #$8D ; C/R is end of input | |
| beq LFormat | |
| cmp #CHR_ESC ; Escape bails out | |
| beq LAbort | |
| cmp #$AE ; (periods are ok...) | |
| beq LStore | |
| cmp #$B0 ; Less than '0'? | |
| bcc LInput ; Then it's invalid | |
| cmp #$BA ; Less than '9'+1? | |
| bcc LStore ; Then it's a number - store it | |
| and #$DF ; Force any lower case to upper case | |
| cmp #$C1 ; Less than 'A'? | |
| bcc LInput ; Then it's invalid | |
| cmp #$DB ; Less than 'Z'+1? | |
| bcc LStore ; Then it's a letter - store it | |
| jmp LInput ; So sorry, try again | |
| LStore: | |
| jsr COUT ; Print keypress on the screen | |
| and #$7F ; Clear MSB | |
| sta VOLnam,x ; Store character in VOLnam | |
| inx | |
| cpx #$0F ; Have 15 characters been entered? | |
| bcc LInput | |
| LFormat: | |
| txa ; See if default VOLUME_NAME was taken | |
| bne LSetLEN | |
| WLoop: | |
| lda MBlank,x ; Transfer 'BLANK' to VOLnam | |
| and #$7F ; Clear MSB | |
| sta VOLnam,x | |
| inx | |
| cpx #$05 ; End of transfer? | |
| bcc WLoop | |
| lda #$13 ; Reset CH to 19 | |
| sta CH | |
| LSetLEN: | |
| jsr CLRLN ; Erase the rest of the line | |
| clc | |
| txa ; Add $F0 to Volume Name length | |
| adc #$F0 ; Create STORAGE_TYPE, NAME_LENGTH byte | |
| sta VolLen | |
| rts | |
| LAbort: | |
| pla ; Pop return address off the stack | |
| pla | |
| jmp Again | |
| DIIForm: | |
| jsr REPLACEVOLNAME ; Replace the volume name | |
| jsr Format ; Format the disk | |
| jsr CodeWr ; Form Bitmap | |
| jmp Catalog ; Write Directory information to the disk | |
| ;********************************** | |
| ;* * | |
| ;* Write Block0, Block1 to disk * | |
| ;* * | |
| ;********************************** | |
| CodeWr: lda #$81 ; Set Opcode to WRITE | |
| sta CallMLI+OS_CALL_OFFSET | |
| lda #$00 ; Set MLIBlk to 0 | |
| sta MLIBlk | |
| sta MLIBlk+1 | |
| lda #<BootCode ; Set MLIbuf to BootCode | |
| ldy #>BootCode | |
| sta MLIbuf | |
| sty MLIbuf+1 | |
| jsr CallMLI ; Write block #0 to target disk | |
| jsr ZeroFill6800 | |
| lda #$01 ; Set MLIBlk to 1 | |
| sta MLIBlk | |
| jsr CallMLI ; Write block #1 to target disk | |
| ;************************************** | |
| ;* * | |
| ;* Prepare BitMap and Link blocks * | |
| ;* for writing to disk * | |
| ;* * | |
| ;************************************** | |
| Fill: | |
| lda #$05 ; Block 5 on Disk | |
| sta MLIBlk | |
| jsr ZeroFill6800 | |
| lda #$05 ; Length of DirTbl | |
| sta Count | |
| LLink: | |
| ldx Count | |
| lda DirTbl,x ; Move Directory Link values into Buffer | |
| sta $6802 ; Store next Directory block # | |
| dex | |
| lda DirTbl,x ; Fetch another # from DirTbl | |
| sta $6800 ; Store previous Directory block # | |
| dex | |
| stx Count | |
| jsr CallMLI ; Write Directory Link values to disk | |
| LDec: | |
| dec MLIBlk ; Decrement MLI block number | |
| lda MLIBlk ; See if MLIBlk = 2 | |
| cmp #$02 | |
| bne LLink ; Process another Link block | |
| ;********************************** | |
| ;* * | |
| ;* Calculate BitMap Size and cndo * | |
| ;* * | |
| ;********************************** | |
| BlkCount: | |
| ; Fill full pages first, then do remainder page | |
| lda #$06 ; First block to deal with: $06 | |
| sta MLIBlk | |
| clc | |
| lda VolBlks+1 | |
| sta FullPages | |
| lda VolBlks+2 | |
| beq :+ | |
| sec | |
| : ror FullPages ; VolBlks is now divided by 512 (we've already dropped byte 0) | |
| lsr FullPages ; ... by 1024 | |
| lsr FullPages ; ... by 2048 | |
| lsr FullPages ; ... by 4096 | |
| beq LastBlock ; No full blocks? Skip to remainder part. | |
| jsr FFFill6800 ; Set up to fill pages | |
| lda #$81 ; Change Opcode to $81 (WRITE) | |
| sta CallMLI+OS_CALL_OFFSET | |
| lda #$00 ; Reset MLIbuf to $6800 | |
| ldx #$68 | |
| sta MLIbuf | |
| stx MLIbuf+1 | |
| sta MLIBlk+1 | |
| lda #$00 ; Mark first blocks as used | |
| sta $6800 | |
| sta $6801 | |
| lda #$03 | |
| sta $6802 | |
| lda #$00 | |
| sta Curblk | |
| : jsr Call2MLI ; Write Buffer (BitMap) to block on the disk | |
| lda #$ff ; Mark first blocks as unused again | |
| sta $6800 | |
| sta $6801 | |
| sta $6802 | |
| inc MLIBlk | |
| inc Curblk | |
| lda Curblk | |
| cmp FullPages | |
| bne :- | |
| LastBlock: | |
| jsr BlkRemainder | |
| jsr Call2MLI | |
| rts | |
| BlkRemainder: | |
| jsr ZeroFill6800 | |
| lda VolBlks+1 ; Where # of blocks are stored | |
| ldx VolBlks | |
| ldy VolBlks+2 ; Can't deal with block devices this big | |
| stx Count+1 ; Divide the # of blocks by 8 for bitmap | |
| lsr a ; calculation | |
| ror Count+1 | |
| lsr a | |
| ror Count+1 | |
| lsr a | |
| ror Count+1 | |
| sta Count+2 | |
| BitMapCode: | |
| lda FullPages ; Only tick off 7 blks if this is the only page in the BAM | |
| bne BitMapNotFirst | |
| lda #%00000001 ; Clear first 7 blocks | |
| sta (Buffer),y | |
| jmp BitMapGo | |
| BitMapNotFirst: | |
| lda #$ff | |
| sta (Buffer),y | |
| BitMapGo: | |
| ldy Count+1 ; Original low block count value | |
| bne Jump11 ; if it is 0 then make FF | |
| dey ; Make FF | |
| dec Count+2 ; Make 256 blocks less one | |
| sty Count+1 ; Make FF new low block value | |
| Jump11: | |
| ldx Count+2 ; High Block Value | |
| bne Jump15 ; If it isn't equal to 0 then branch | |
| ldy Count+1 | |
| jmp Jump19 | |
| Jump15: | |
| lda #$69 ; Set the adress of the upper part of | |
| sta Buffer+1 ; Block in bitmap being created | |
| lda #%11111111 | |
| ldy Count+1 ; Using the low byte count | |
| Jump20: | |
| dey | |
| sta (Buffer),y ; Store them | |
| beq Jump17 | |
| jmp Jump20 | |
| Jump17: | |
| dey ; Fill in first part of block | |
| lda #$68 | |
| sta Buffer+1 | |
| Jump19: | |
| lda #%11111111 | |
| dey | |
| sta (Buffer),y | |
| cpy #$01 ; Except the first byte. | |
| beq Jump18 | |
| jmp Jump19 | |
| Jump18: | |
| rts | |
| Curblk: .res 1 | |
| ;************************************* | |
| ;* * | |
| ;* Catalog - Build a Directory Track * | |
| ;* * | |
| ;************************************* | |
| Catalog: | |
| lda #$81 ; Change Opcode to $81 (WRITE) | |
| sta CallMLI+OS_CALL_OFFSET | |
| clc | |
| lda #$06 | |
| adc FullPages | |
| sta MLIBlk | |
| lda #$00 ; Reset MLIbuf to $6800 | |
| ldx #$68 | |
| sta MLIbuf | |
| stx MLIbuf+1 | |
| sta MLIBlk+1 | |
| jsr Call2MLI ; Write Buffer (BitMap) to block #6 on the disk | |
| CALLOS OS_GET_TIME, 0 ; Call for time and date | |
| lda $BF90 ; Get them and save them into the | |
| sta Datime ; Directory to be written. | |
| lda $BF91 | |
| sta Datime+1 | |
| lda $BF92 | |
| sta Datime+2 | |
| lda $BF93 | |
| sta Datime+3 | |
| jsr ZeroFill6800 | |
| ldy #$2A ; Move Block2 information to $6800 | |
| CLoop: | |
| lda Block2,y | |
| sta (Buffer),y | |
| dey | |
| bpl CLoop | |
| lda #$02 ; Write block #2 to the disk | |
| sta MLIBlk | |
| jsr Call2MLI | |
| Again: | |
| lda #$17 | |
| jsr TABV | |
| ldy #PMNuther | |
| jsr WRITEMSGLEFT | |
| jsr YNLOOP ; Get a Yes or No answer | |
| beq MExit ; Answer was No... | |
| jmp FormatEntry ; Format another disk | |
| MExit: | |
| rts | |
| Call2MLI: | |
| jsr CallMLI | |
| rts | |
| ;************************************* | |
| ;* * | |
| ;* CallMLI - Call the MLI Read/Write * | |
| ;* routines to transfer blocks to or * | |
| ;* from memory * | |
| ;* * | |
| ;************************************* | |
| CallMLI: | |
| CALLOS OS_WRITEBLOCK, Parms | |
| bcs MLIError | |
| rts | |
| MLIError: | |
| sta ZP | |
| pla | |
| pla | |
| pla | |
| pla | |
| lda ZP | |
| jmp Died | |
| ;*********************************** | |
| ;* * | |
| ;* FORMAT - Format the target disk * | |
| ;* * | |
| ;*********************************** | |
| Format: | |
| lda Slot ; Fetch target drive SLOTNUM value | |
| pha ; Store it on the stack | |
| and #$70 ; Mask off bit 7 and the lower 4 bits | |
| sta SlotF ; Store result in FORMAT slot storage | |
| tax ; Assume value of $60 (drive #1) | |
| pla ; Retrieve value from the stack | |
| bpl LDrive1 ; If < $80 the disk is in drive #1 | |
| inx ; Set X offset to $61 (drive #2) | |
| LDrive1: | |
| lda Select,x ; Set softswitch for proper drive | |
| ldx SlotF ; Set X offset to FORMAT slot/drive | |
| lda DiskON,x ; Turn the drive on | |
| lda ModeRD,x ; Set Mode softswitch to READ | |
| lda DiskRD,x ; Read a byte | |
| lda #$23 ; Assume head is on track 35 | |
| sta TRKcur | |
| lda #$00 ; Destination is track 0 | |
| sta TRKdes | |
| jsr Seek ; Move head to track 0 | |
| ldx SlotF ; Turn off all drive phases | |
| lda Step0,x | |
| lda Step2,x | |
| lda Step4,x | |
| lda Step6,x | |
| lda TRKbeg ; Move TRKbeg value (0) to Track | |
| sta Track | |
| jsr Build ; Build a track in memory at $6700 | |
| ;******************************* | |
| ;* * | |
| ;* WRITE - Write track to disk * | |
| ;* * | |
| ;******************************* | |
| Write: | |
| jsr Calc ; Calculate new track/sector/checksum values | |
| jsr Trans ; Transfer track in memory to disk | |
| bcs DiedII ; If carry set, something died | |
| MInc: | |
| inc Track ; Add 1 to Track value | |
| lda Track ; Is Track > ending track # (TRKend)? | |
| cmp TRKend | |
| beq LNext ; More tracks to FORMAT | |
| bcs Done ; Finished. Exit FORMAT routine | |
| LNext: | |
| sta TRKdes ; Move next track to FORMAT to TRKdes | |
| jsr Seek ; Move head to that track | |
| jmp Write ; Write another track | |
| Done: | |
| ldx SlotF ; Turn the drive off | |
| lda DiskOFF,x | |
| rts ; FORMAT is finished. Return to calling routine | |
| DiedII: | |
| pha ; Save MLI error code on the stack | |
| jsr Done | |
| pla ; Retrieve error code from the stack | |
| jmp Died ; Prompt for another FORMAT... | |
| ; | |
| ; Note - the routine named Trans: and entrypoint named Trans2: | |
| ; have moved to the main.asm in order to keep it within a | |
| ; page boundary. | |
| ; | |
| ;************************************** | |
| ;* * | |
| ;* Died - Something awful happened to * | |
| ;* the disk or drive. Die a miserable * | |
| ;* death... * | |
| ;* * | |
| ;************************************** | |
| Died: | |
| cmp #$27 | |
| beq DriveOpen | |
| cmp #$28 | |
| beq DriveOpen | |
| cmp #$2F | |
| beq DiskError | |
| cmp #$2B | |
| beq Protected | |
| jmp NoDied | |
| DiskError: | |
| ldy #PMNoDisk | |
| jmp DiedOut | |
| DriveOpen: | |
| ldy #PMDead | |
| jmp DiedOut | |
| Protected: | |
| ldy #PMProtect | |
| jmp DiedOut | |
| NoDied: | |
| pha ; Save MLI error code on the stack | |
| ldy #PMUnRecog | |
| jsr WRITEMSGAREA | |
| pla ; Retrieve error code from the stack | |
| jsr PRBYTE ; Print the MLI error code | |
| jmp Again | |
| DiedOut: | |
| jsr WRITEMSGAREA | |
| jmp Again ; Prompt for another FORMAT... | |
| ;************************************ | |
| ;* * | |
| ;* BUILD - Build GAP1 and 16 sector * | |
| ;* images between $6700 and $8000 * | |
| ;* * | |
| ;************************************ | |
| Build: | |
| lda #$10 ; Set Buffer to $6710 | |
| ldx #$67 | |
| sta Buffer | |
| stx Buffer+1 | |
| ldy #$00 ; (Y offset always zero) | |
| ldx #$F0 ; Build GAP1 using $7F (sync byte) | |
| lda #$7F | |
| sta LByte | |
| jsr LFill ; Store sync bytes from $6710 to $6800 | |
| lda #$10 ; Set Count for 16 loops | |
| sta Count | |
| LImage: | |
| ldx #$00 ; Build a sector image in the Buffer area | |
| ELoop: | |
| lda LAddr,x ; Store Address header, info & sync bytes | |
| beq LInfo | |
| sta (Buffer),y | |
| jsr LInc ; Add 1 to Buffer offset address | |
| inx | |
| bne ELoop | |
| LInfo: | |
| ldx #$AB ; Move 343 bytes into data area | |
| lda #$96 ; (4&4 encoded version of hex $00) | |
| sta LByte | |
| jsr LFill | |
| ldx #$AC | |
| jsr LFill | |
| ldx #$00 | |
| YLoop: | |
| lda LData,x ; Store Data Trailer and GAP3 sync bytes | |
| beq LDecCnt | |
| sta (Buffer),y | |
| jsr LInc | |
| inx | |
| bne YLoop | |
| LDecCnt: | |
| clc | |
| dec Count | |
| bne LImage | |
| rts ; Return to write track to disk (WRITE) | |
| LFill: | |
| lda LByte | |
| sta (Buffer),y ; Move A register to Buffer area | |
| jsr LInc ; Add 1 to Buffer offset address | |
| dex | |
| bne LFill | |
| rts | |
| LInc: | |
| clc | |
| inc Buffer ; Add 1 to Buffer address vector | |
| bne LDone | |
| inc Buffer+1 | |
| LDone: rts | |
| ;*********************************** | |
| ;* * | |
| ;* CALC - Calculate Track, Sector, * | |
| ;* and Checksum values of the next * | |
| ;* track using 4&4 encoding * | |
| ;* * | |
| ;*********************************** | |
| Calc: | |
| lda #$03 ; Set Buffer to $6803 | |
| ldx #$68 | |
| sta Buffer | |
| stx Buffer+1 | |
| lda #$00 ; Set Sector to 0 | |
| sta Sector | |
| ZLoop: | |
| ldy #$00 ; Reset Y offset to 0 | |
| lda #$FE ; Set Volume # to 254 in 4&4 encoding | |
| jsr LEncode | |
| lda Track ; Set Track, Sector to 4&4 encoding | |
| jsr LEncode | |
| lda Sector | |
| jsr LEncode | |
| lda #$FE ; Calculate the Checksum using 254 | |
| eor Track | |
| eor Sector | |
| jsr LEncode | |
| clc ; Add 385 ($181) to Buffer address | |
| lda Buffer | |
| adc #$81 | |
| sta Buffer | |
| lda Buffer+1 | |
| adc #$01 | |
| sta Buffer+1 | |
| inc Sector ; Add 1 to Sector value | |
| lda Sector ; If Sector > 16 then quit | |
| cmp #$10 | |
| bcc ZLoop | |
| rts ; Return to write track to disk (WRITE) | |
| LEncode: | |
| pha ; Put value on the stack | |
| lsr a ; Shift everything right one bit | |
| ora #$AA ; OR it with $AA | |
| sta (Buffer),y ; Store 4&4 result in Buffer area | |
| iny | |
| pla ; Retrieve value from the stack | |
| ora #$AA ; OR it with $AA | |
| sta(Buffer),y ; Store 4&4 result in Buffer area | |
| iny | |
| rts | |
| ;************************************* | |
| ;* * | |
| ;* Seek - Move head to desired track * | |
| ;* * | |
| ;************************************* | |
| Seek: | |
| lda #$00 ; Set InOut flag to 0 | |
| sta LInOut | |
| lda TRKcur ; Fetch current track value | |
| SEC | |
| SBC TRKdes ; Subtract destination track value | |
| beq LExit ; If = 0 we're done | |
| bcs LMove | |
| eor #$FF ; Convert resulting value to a positive number | |
| adc #$01 | |
| LMove: | |
| sta Count ; Store track value in Count | |
| rol LInOut ; Condition InOut flag | |
| lsr TRKcur ; Is track # odd or even? | |
| rol LInOut ; Store result in InOut | |
| asl LInOut ; Shift left for .Table offset | |
| ldy LInOut | |
| ALoop: | |
| lda LTable,y ; Fetch motor phase to turn on | |
| jsr Phase ; Turn on stepper motor | |
| lda LTable+1,y ; Fetch next phase | |
| jsr Phase ; Turn on stepper motor | |
| tya | |
| eor #$02 ; Adjust Y offset into LTable | |
| tay | |
| dec Count ; Subtract 1 from track count | |
| bne ALoop | |
| lda TRKdes ; Move current track location to TRKcur | |
| sta TRKcur | |
| LExit: | |
| rts ; Return to calling routine | |
| ;********************************** | |
| ;* * | |
| ;* PHASE - Turn the stepper motor * | |
| ;* on and off to move the head * | |
| ;* * | |
| ;********************************** | |
| Phase: | |
| ora SlotF ; OR Slot value to PHASE | |
| tax | |
| lda Step1,x ; PHASE on... | |
| lda #$56 ; 20 ms. delay | |
| jsr DELAY | |
| lda Step0,x ; PHASE off... | |
| rts | |
| ;********************************** | |
| ;* * | |
| ;* Format a Ram3 device. * | |
| ;* * | |
| ;********************************** | |
| Ram3Form: | |
| lda #3 ; Format Request number | |
| sta $42 | |
| lda Slot ; Slot of /Ram | |
| sta $43 | |
| lda #$00 ; Buffer space if needed Low byte | |
| sta $44 | |
| lda #$67 ; and high byte | |
| sta $45 | |
| lda $C08B ; Read and write Ram, using Bank 1 | |
| lda $C08B | |
| jsr Ram3Dri | |
| bit $C082 ; Read ROM, use Bank 2(Put back on line) | |
| bcs Ram3Err | |
| rts | |
| Ram3Dri: | |
| jmp (Addr) | |
| Ram3Err: | |
| tax | |
| pla | |
| pla | |
| txa | |
| jmp Died | |
| ;********************************** | |
| ;* * | |
| ;* Format a SmartPort Device * | |
| ;* * | |
| ;********************************** | |
| SmartForm: | |
| lda ShouldLLFormat ; Will be $08 if so | |
| beq SmartFormDone | |
| lda #3 ; Give Protocol Converter a Format Request | |
| sta $42 ; Give it Slot number | |
| lda ListSlot | |
| and #$F0 | |
| sta $43 | |
| lda #$00 ; Give a buffer which probably won't be | |
| sta $44 ; used. | |
| lda #$68 | |
| sta $45 | |
| jsr SmartDri | |
| bcs SmartErr ; Skip the test for successful low level formatting | |
| clc | |
| SmartFormDone: | |
| jsr REPLACEVOLNAME ; Replace the volume name | |
| rts | |
| SmartDri: | |
| jmp (Addr) | |
| SmartErr: | |
| tax | |
| pla | |
| pla | |
| txa | |
| jmp Died | |
| ShouldLLFormat: | |
| .res 1 | |
| ;********************************** | |
| ;* * | |
| ;* Is there an old name? * | |
| ;* * | |
| ;********************************** | |
| OldName: | |
| lda #$15 | |
| jsr TABV | |
| ldy #PMTheOld | |
| jsr WRITEMSGLEFT | |
| jsr YNLOOP | |
| bne OldDone | |
| pla | |
| pla | |
| jmp Again | |
| OldDone: | |
| rts | |
| ;*********************************** | |
| ;* * | |
| ;* Fill6800: clear buffer at $6800 * | |
| ;* * | |
| ;*********************************** | |
| FFFill6800: | |
| lda #$FF | |
| pha | |
| jmp Fill6800Go | |
| ZeroFill6800: | |
| lda #$00 | |
| pha | |
| Fill6800Go: | |
| lda #$00 ; Set Buffer, MLIbuf to $6800 | |
| ldx #$68 | |
| sta MLIbuf | |
| sta Buffer | |
| stx MLIbuf+1 | |
| stx Buffer+1 | |
| tay ; Fill $6800-$69FF with zeros | |
| ldx #$01 ; Fill 2 pages of 256 bytes | |
| pla | |
| LZero: | |
| sta (Buffer),y | |
| iny | |
| bne LZero | |
| inc Buffer+1 | |
| dex | |
| bpl LZero | |
| lda #$00 | |
| sta Buffer | |
| lda #$68 ; Reset Buffer to $6800 | |
| sta Buffer+1 | |
| rts | |
| REPLACEVOLNAME: | |
| lda DevIndex | |
| asl | |
| asl | |
| asl | |
| asl | |
| tax | |
| ;jsr Mult16 ; Set x to the start of the DEVICES table | |
| lda #>DEVICES | |
| sta UTILPTR+1 | |
| lda #<DEVICES | |
| sta UTILPTR | |
| txa | |
| clc | |
| adc UTILPTR | |
| sta UTILPTR | |
| bcc :+ | |
| inc UTILPTR+1 | |
| : | |
| lda VolLen | |
| and #$0f | |
| sta Util | |
| tay ; Set y to the number of digits to transfer | |
| : | |
| lda VOLnam-1,y | |
| sta (UTILPTR),y | |
| dey | |
| bne :- | |
| ldy #$00 | |
| lda (UTILPTR),y ; Load the length of the dev name in DEVICES | |
| and #$f0 | |
| sta (UTILPTR),y | |
| clc | |
| adc Util | |
| sta (UTILPTR),y | |
| rts | |
| ;************************* | |
| ;* * | |
| ;* Variable Storage Area * | |
| ;* * | |
| ;************************* | |
| Info: | |
| .byte $02 | |
| .res 1 | |
| .addr VolLen | |
| Parms: .byte $03 ; Parameter count = 3 | |
| Slot: .byte $60 ; Default to S6,D1 | |
| MLIbuf: .addr BootCode ; Default buffer address | |
| MLIBlk: .byte $00,$00 ; Default block number of 0 | |
| QSlot: .res 1 ; Quit Slot number | |
| ListSlot: | |
| .res 1 ; Saving the slot total from the list | |
| Addr: .res 2 ; Address for indirect jump | |
| LByte: .res 1 ; Storage for byte value used in Fill | |
| LAddr: | |
| .byte $D5,$AA,$96 ; Address header | |
| .byte $AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA ; Volume #, Track, Sector, Checksum | |
| .byte $DE,$AA,$EB ; Address trailer | |
| .byte $7f,$7f,$7f,$7f,$7f,$7f ; GAP2 sync bytes | |
| .byte $D5,$AA,$AD ; Buffer header | |
| .byte $00 ; End of Address information | |
| LData: | |
| .byte $DE,$AA,$EB ; Data trailer | |
| .byte $7f,$7f,$7f,$7f,$7f,$7f,$7f,$7f,$7f,$7f,$7f,$7f,$7f,$7f,$7f,$7f ;GAP3 sync bytes | |
| .byte $00 ; End of Data information | |
| LInOut: .res 1 ; Inward/Outward phase for stepper motor | |
| LTable: | |
| .byte $02,$04,$06,$00 ; Phases for moving head inward | |
| .byte $06,$04,$02,$00 ; | | | | outward | |
| Block2: .byte $00,$00,$03,$00 | |
| VolLen: .res 1 ; $F0 + length of Volume Name | |
| VOLnam: .res 15 ; Volume Name | |
| Reserved: | |
| .res 6 | |
| UpLowCase: | |
| .byte $00,$00 | |
| Datime: | |
| .res 4 | |
| Version: | |
| .byte 01 | |
| .byte $00,$C3,$27,$0D | |
| .byte $00,$00,$06,$00 | |
| VolBlks: | |
| .res 3 ; Number of blocks available | |
| DirTbl: | |
| .byte $02,$04,$03 ; Linked list for directory blocks | |
| .byte $05,$04,$00 | |
| BitTbl: | |
| .byte $7f ; dc B'01111111' ; BitMap mask for bad blocks | |
| .byte $bf ; dc B'10111111' | |
| .byte $df ; dc B'11011111' | |
| .byte $ef ; dc B'11101111' | |
| .byte $f7 ; dc B'11110111' | |
| .byte $fb ; dc B'11111011' | |
| .byte $fd ; dc B'11111101' | |
| .byte $fe ; dc B'11111110' | |
| Count: .res 3 ; General purpose counter/storage byte | |
| Pointer: | |
| .res 2 ; Storage for track count (8 blocks/track) | |
| Track: .res 2 ; Track number being FORMATted | |
| Sector: .res 2 ; Current sector number (max=16) | |
| SlotF: .res 2 ; Slot/Drive of device to FORMAT | |
| TRKcur: .res 2 ; Current track position | |
| TRKdes: .res 2 ; Destination track position | |
| TRKbeg: .byte 00 ; Starting track number | |
| TRKend: .byte 35 ; Ending track number | |
| FullPages: | |
| .byte 00 ; Number of BAM pages to fill | |
| DevIndex: | |
| .byte 00 ; Storage for index into DEVICES table | |
| Util: .byte 00 | |
| BootCode: | |
| ; Floppy boot code at block 0; block 1 is zeroed out | |
| .byte $01,$38,$B0,$03,$4C,$32,$A1,$86,$43,$C9,$03,$08,$8A,$29,$70,$4A,$4A,$4A,$4A,$09,$C0,$85,$49,$A0 | |
| .byte $FF,$84,$48,$28,$C8,$B1,$48,$D0,$3A,$B0,$0E,$A9,$03,$8D,$00,$08,$E6,$3D,$A5,$49,$48,$A9,$5B,$48 | |
| .byte $60,$85,$40,$85,$48,$A0,$63,$B1,$48,$99,$94,$09,$C8,$C0,$EB,$D0,$F6,$A2,$06,$BC,$1D,$09,$BD,$24 | |
| .byte $09,$99,$F2,$09,$BD,$2B,$09,$9D,$7F,$0A,$CA,$10,$EE,$A9,$09,$85,$49,$A9,$86,$A0,$00,$C9,$F9,$B0 | |
| .byte $2F,$85,$48,$84,$60,$84,$4A,$84,$4C,$84,$4E,$84,$47,$C8,$84,$42,$C8,$84,$46,$A9,$0C,$85,$61,$85 | |
| .byte $4B,$20,$12,$09,$B0,$68,$E6,$61,$E6,$61,$E6,$46,$A5,$46,$C9,$06,$90,$EF,$AD,$00,$0C,$0D,$01,$0C | |
| .byte $D0,$6D,$A9,$04,$D0,$02,$A5,$4A,$18,$6D,$23,$0C,$A8,$90,$0D,$E6,$4B,$A5,$4B,$4A,$B0,$06,$C9,$0A | |
| .byte $F0,$55,$A0,$04,$84,$4A,$AD,$02,$09,$29,$0F,$A8,$B1,$4A,$D9,$02,$09,$D0,$DB,$88,$10,$F6,$29,$F0 | |
| .byte $C9,$20,$D0,$3B,$A0,$10,$B1,$4A,$C9,$FF,$D0,$33,$C8,$B1,$4A,$85,$46,$C8,$B1,$4A,$85,$47,$A9,$00 | |
| .byte $85,$4A,$A0,$1E,$84,$4B,$84,$61,$C8,$84,$4D,$20,$12,$09,$B0,$17,$E6,$61,$E6,$61,$A4,$4E,$E6,$4E | |
| .byte $B1,$4A,$85,$46,$B1,$4C,$85,$47,$11,$4A,$D0,$E7,$4C,$00,$20,$4C,$3F,$09,$26,$50,$52,$4F,$44,$4F | |
| .byte $53,$20,$20,$20,$20,$20,$20,$20,$20,$20,$A5,$60,$85,$44,$A5,$61,$85,$45,$6C,$48,$00,$08,$1E,$24 | |
| .byte $3F,$45,$47,$76,$F4,$D7,$D1,$B6,$4B,$B4,$AC,$A6,$2B,$18,$60,$4C,$BC,$09,$A9,$9F,$48,$A9,$FF,$48 | |
| .byte $A9,$01,$A2,$00,$4C,$79,$F4,$20,$58,$FC,$A0,$1C,$B9,$50,$09,$99,$AE,$05,$88,$10,$F7,$4C,$4D,$09 | |
| .byte $AA,$AA,$AA,$A0,$D5,$CE,$C1,$C2,$CC,$C5,$A0,$D4,$CF,$A0,$CC,$CF,$C1,$C4,$A0,$D0,$D2,$CF,$C4,$CF | |
| .byte $D3,$A0,$AA,$AA,$AA,$A5,$53,$29,$03,$2A,$05,$2B,$AA,$BD,$80,$C0,$A9,$2C,$A2,$11,$CA,$D0,$FD,$E9 | |
| .byte $01,$D0,$F7,$A6,$2B,$60,$A5,$46,$29,$07,$C9,$04,$29,$03,$08,$0A,$28,$2A,$85,$3D,$A5,$47,$4A,$A5 | |
| .byte $46,$6A,$4A,$4A,$85,$41,$0A,$85,$51,$A5,$45,$85,$27,$A6,$2B,$BD,$89,$C0,$20,$BC,$09,$E6,$27,$E6 | |
| .byte $3D,$E6,$3D,$B0,$03,$20,$BC,$09,$BC,$88,$C0,$60,$A5,$40,$0A,$85,$53,$A9,$00,$85,$54,$A5,$53,$85 | |
| .byte $50,$38,$E5,$51,$F0,$14,$B0,$04,$E6,$53,$90,$02,$C6,$53,$38,$20,$6D,$09,$A5,$50,$18,$20,$6F,$09 | |
| .byte $D0,$E3,$A0,$7F,$84,$52,$08,$28,$38,$C6,$52,$F0,$CE,$18,$08,$88,$F0,$F5,$BD,$8C,$C0,$10,$FB,$00 | |
| .byte $00,$00,$00,$00,$00,$00,$00,$00 |