* INITIALIZE A DISK FOR CP/68 OPERATING SYSTEM
* BASED ON ICOM 8 INCH FLOPPY DISK PROGRAM BY J. HEMENWAY 1979
* 
* MODIFIED BY ROBERTO SANCHO TO SUPPORT MF68 DISKS ON SWTPC SIMH EMULATION
* APR/2022 (FROM LISTING IN PDF P166)
*
* UPDATED BY MIKE DOUGLAS TO RUN ON REAL HARDWARE, JUL/2022
*
* SAVE AS TRANSIENT COMMAND AFTER LOADING INIT.S19 AND BOOT.S19 INTO
* RAM AS FOLLOWS:
*    SAVE INIT.CMD,$2100,$2578,$21C3
*
* DISK GEOMETRY: 35 TRACKS X 18 SECTORS X 128 BYTES
* TRACK 0 HAS SECTORS NUMBERED 0,1,2,4..18 (NO SECTOR 3, FIRST SECTOR IS ZERO)
* TRACK 1..34 HAS SECTORS NUMBERED 1,2..18 
*
* TRACK 0: SECTOR 0,1,2: HOLDS BOOT PROGRAM
* TRACK 0: SECTOR 4..18: DIRECTORY
* TRACK 1..34: DATA SECTORS FOR FILES
*
* DISK ATTRIBUTES
*
SECSIZ EQU 128    128 BYTES PER SECTOR
TRKSIZ EQU 18     18 SECTORS PER TRACK
DSKSIZ EQU 34     34 DATA TRACKS ON DISK (LESS TRACK 0) 
*
* FCB DEFINITIONS:
*
FCBSTA EQU 5  ERROR STATUS FLAG
FCBDBA EQU 7  DATA BUFFER ADDRESS
FCBDRV EQU 9  DRIVE NUMBER
FCBTRK EQU 10 TRACK NUMBER
FCBSCT EQU 11 SECTOR NUMBER
FCBTlK EQU 12 TRACK LINK POINTER
FCBSLK EQU 13 SECTOR LINK POINTER
*
* COMMAND-LINE INTERPRETER BASE-PAGE LOCATIONS
*
DESCRA EQU $20   ADDRESS OF TOKEN
VALUE  EQU $27   VALUE OF NUMERIC TOKEN
*
* LOCATION OF BOOT CODE IN MEMORY TO WRITE TO DISK
*
BOOT   EQU $2400

       ORG $2100

FCBSPC FCB 0,0
       FCC 'DSK'
       FCB 0
       FCB $FF
       RMB 35
       
BUFFER RMB SECSIZ

PROMPT FCC 'INIT. DISK IN DRIVE '
DRVNO  FCB 0
       FCC ' ? '
       FCB $04

* INIT ENTRY POINT 

INITR  LDAA VALUE+1      GET DRIVE TO INIT 
       ANDA #$03         MAX 4 DRIVES
       LDX   #FCBSPC      POINT T0 FCB
       STAA FCBDRV,X     STORE DRIVE NUM
       ADDA #$30         MAKE DRV NUM ASCII
       STAA DRVNO        PUT IN PROMPT LINE
       LDX   #PROMPT      
       SWI PRTMSG         OUTPUT PROMPT 
        FCB 49
       SWI GTCMD          GET USER RESPONSE
        FCB 48
       LDX   DESCRA       
       LDAA 0,X          GET FIRST CHAR OF RESPONSE
       CMPA #'Y'         WAS IT 'YES'?
       BEQ   INITR2       BR IF YES
       RTS                QUIT
                          
INITR2 LDX   #FCBSPC                           
       CLR   FCBTRK,X     TRACK=0
       CLR   FCBSCT,X     SECTOR=0
       SWI TXAB  
        FCB 2        
       LDX   #BOOT        POINT TO BOOT CODE
       SWI XABX          
        FCB 4
       STAA FCBDBA,X
       STAB FCBDBA+1,X
       JSR   WRTBLK       WRITE FIRST SECTOR -> FIRST 128 BYTES OF BOOT PROG
       TST   FCBSTA,X     DISK ERROR?
       BEQ   INIT2B       BR IF NO ERROR
       BRA   INITQ0       FATAL ERROR, QUIT
INIT2B INC   FCBSCT,X     SECTOR=1
       SWI TXAB
        FCB 2        
       LDX   #BOOT+$80
       SWI XABX
        FCB 4
       STAA FCBDBA,X
       STAB FCBDBA+1,X
       JSR   WRTBLK       WRITE SECOND SECTOR -> SECOND 128 BYTES OF BOOT PROG
       TST   FCBSTA,X     DISK ERROR?
       BEQ   INIT2C       BR IF NO ERROR
       BRA   INITQ0       FATAL ERROR, QUIT
INIT2C INC   FCBSCT,X     SECTOR=2
       SWI TXAB
        FCB 2        
       LDX   #BOOT+$100   WRITE THIRD BLOCK -> THIRD 128 BYTES OF BOOT PROG
       SWI XABX           BOOT PROG CAN HAVE UP TO 128x3-6 BYTES
        FCB 4
       STAA FCBDBA,X
       STAB FCBDBA+1,X
       LDAA #$01         SET 01/01 AS TWO LAST BYTES OF SECTOR 2
       STAA BOOT+$17E           
       STAA BOOT+$17F           
       JSR   WRTBLK       WRITE SECTOR 2 - LAST 128 BYTES OF BOOT SECTOR      
       TST   FCBSTA,X     ERROR?      
       BEQ   INIT2D       BR IF NOT      
INITQ0 BRA   INITQ        ERROR     
INIT2D SWI   TXAB         RESTORE BACK EMPTY BUFFER      
        FCB 2        
       LDX   #BUFFER      AS SECTOR DATA ORIGIN              
       SWI XABX                 
        FCB 4
       STAA FCBDBA,X                 
       STAB FCBDBA+1,X                 
*
* WRITE DIRECTORY SECTORS (ALL ZERO)
*         
INITR3 LDX   #BUFFER      ZERO THE BUFFER
       LDAB  #SECSIZ
       CLRA
INIR31 STAA  0,X
       INX
       DECB
       BNE   INIR31

       LDX   #FCBSPC      X->FCB
       LDAA  #4           DIRECTORY START ON SECCTOR 4
       STAA  FCBSCT,X

INITR4 BSR   WRTBLK       INIT DIR TO ZERO: WRT SECTOR
       TST   FCBSTA,X     ERROR? 
       BEQ   INIT4B       BR IF OK
       BRA   INITQ        ERROR
INIT4B LDAA FCBSCT,X     GET CURRENT SECT
       INCA              NEXT SECT
       CMPA #TRKSIZ      END OF TRACK?
       BEQ   INITR5       BR IF YES
       STAA FCBSCT,X
       BRA   INITR4       CONT WRITING
           
INITR5 LDAA #$01         INIT REST OF DISK 
       STAA FCBSCT,X     SECTOR=1
       STAA FCBTRK,X     TRACK=1
       TAB  
INITR6 INCB              MAKE SECTOR LINKAGE
       CMPB #TRKSIZ+1    END OF TRACK?
       BNE   INITR7       NO
       LDAB #$01
       INCA
       CMPA #DSKSIZ+1    END OF DISK?
       BNE   INITR7       NO
       CLRA              LAST SECTOR POINTS TO 0,0
       CLRB
INITR7 STAA BUFFER       TRACK LINK
       PSHB              SAVE LSEC
       BSR   GETSC        GET PSEC 
       STAB BUFFER+1     SECTOR LINK
       PULB              RESTORE LSEC
       BSR   WRTBLK       WRITE SECTOR
       TSTA              DONE?
       BNE   INITR8       NO
       TSTB              DONE?
       BNE   INITR8       NO
       RTS                YES! DONE
INITR8 STAA FCBTRK,X     
       PSHB              SAVE LSEC
       BSR   GETSC        GET PSEC
       STAB FCBSCT,X     
       PULB              GET LSEC
       BRA   INITR6       KEEP WRITING

INITQ  LDX   #QMSG        MSG INITIALIZATION FAILED
       SWI PRTMSG
        FCB 49
       RTS 
QMSG   FCC 'INITIALIZATION FAILED' 
       FCB $0D              

GETSC  SWI PSHX           CONVERT LSEC (LOGICAL SECT) TO PSEC (PHYSICAL SECT)
        FCB 5
       LDX   #TBL         X=PHYSICAL TO LOGICAL TABLE
       SWI ADDBX
        FCB 10
       DEX                SECTOR STARTS AT 1
       LDAB 0,X          GET PSEC
       SWI PULX           RESTORE X-REG
        FCB 6 
       RTS  
           
WRTBLK PSHA              WRITE A SECTOR WITH ERROR CHECKING
       CLRA
       CLR   FCBSTA,X     CLEAR ERROR FLAG
       SWI IOHDR             
        FCB 19
       STAA FCBSTA,X       
       TSTA              ERROR?
       BNE   WRTERR       YES
       PULA
       RTS  
           
WRTERR TAB             
       BSR   OUTHL        CONVERT LEFT DIGIT
       STAA ERTYPE
       TBA  
       BSR   OUTHR        CONVERT RIGHT DIGIT
       STAA ERTYPE+1
       SWI PSHX           SAVE X
        FCB 5
       LDAA FCBSCT,X
       BSR   OUTHL        MAKE SECT NUM HEX
       STAA SECT
       LDAA FCBSCT,X
       BSR   OUTHR
       STAA SECT+1
       LDAA FCBTRK,X
       BSR   OUTHL
       STAA TRACK
       LDAA FCBTRK,X
       BSR   OUTHR
       STAA TRACK+1
       LDX   #DERROR
       SWI PRTMSG
        FCB 49
       SWI WARMSTART
        FCB 31
       RTS  
       
DERROR FCC 'DISK ERROR:'
ERTYPE FCB 0,0
       FCC ' AT SECTOR '
SECT   FCB 0,0
       FCC ' TRACK '
TRACK  FCB 0,0                
       FCB $0D              
           
OUTHL  LSRA           CONVERT BINARY TO HEX-ASCII
       LSRA
       LSRA
       LSRA
OUTHR  ANDA #$0F      GET NIBBLE
       ADDA #$30      MAKE ASCII
       CMPA #$39      IS >9?
       BLS   OUTH1     NO
       ADDA #$07      YES
OUTH1  RTS  

* PHYSICAL TO LOGICAL TABLE

       FCB 0

* THIS TABLE FROM THE BOOK FOR THE SWTPC RESULTS RESULTS IN MORE THAN A
* A FULL REVOLUTION PER SECTOR LOADED (NOT ENOUGH SPACE BETWEEN SECTORS).
* PROCESSING TIME FOR A SECTOR IS ABOUT 130MS-150MS WHICH REQUIRES A SKEW
* OF 14 OR 15 SECTORS. 14 WORKS IF THE "E" BIT IS TURNED OFF FOR READS
* WHICH DO NOT REQUIRE HEAD SETTLE TIME, HOWEVER, THE PUBLISHED CODE DOES
* NOT DO THIS. THEREFORE, A SKEW OF 15 OR 16 IS REQUIRED.

TBL    FCB 1,6,11,16,3,8,13,18,5,10,15,2,7,12,17,4,9,14

INITE  EQU *
       END
