;*********************************************************************
;*      MDFORMAT.PRG  (short for "Musical Disk Formatter v1.0")      *
;*                    and TUTORIAL SOURCE CODE                       *
;*           was written by Clark A. Hay on July 17, 1991.           *
;*               - for Color Monitor Only - Med Rez. -               *
;* Plays some music while you format your disk with 10 sectors/track!*
;* Does NOT use sector skewing as with "TWISTER" and others like it. *
;*                                                                   *
;* If you are a programmer, this source code should be fairly easy to*
;* modify so that it could be used in any resolution by adjusting the*
;* the cols and rows, the fill colors, and fonts based on user res.  *
;*                                                                   *
;*   For the less ambitious programmer, this code contains several   *
;*              routines which you may find of interest:             *
;*                                                                   *
;* 1. You can learn how a disk is formatted in 5 easy steps:         *
;*    a. format all tracks on sides 1 and 2 using XBIOS #10          *
;*    b. 0 out the 1st 2 tracks on each side for the FAT and DIR's   *
;*    c. use XBIOS #18 to create a protoboot sector                  *
;*    d. modify the buffer if using more than 9 sectors per track.   *
;*    e. write boot sector buffer to disk at sector 1 track 0 side 0.*
;*                                                                   *
;* 2. Learn how to use a few key Line_A calls such as:               *
;*    a. DrawLine - to make a line anywhere on the screen.           *
;*    b. BoxFill  - to make different types of filled boxes          *
;*    c. TextBlit - to put strings of various sizes/styles anywhere  *
;*    d. Change Mouse - modify the mouse shape and color as desired  *
;*                                                                   *
;* 3. Discover how ongoing music can be produced and controlled.     *
;*    (admittedly, the music here is no big treat - add your own!)   *
;*                                                                   *
;*                             EXPERIMENT                            *
;*  Feel free to modify the code, steal it, use it, or play with it. *
;*                          - Clark A. Hay -                         *
;*********************************************************************

; Offsets into data tables of variables used by my Line_A routines
BOX_X1       EQU 0              ;box fill upper left col
BOX_Y1       EQU 2              ;box fill upper left row
BOX_X2       EQU 4              ;box fill lower right col
BOX_Y2       EQU 6              ;box fill lower right row
BOXFCOLR     EQU 8              ;color to fill the box with
BOXFFILL     EQU 10             ;addr of the fill pattern
BOXFMODE     EQU 14             ;writing mode for the fill pattern

BOXLCOLR     EQU 16             ;colour of the line surrounding box
BOXLPTRN     EQU 18             ;pattern of the line     "       "
BOXLMODE     EQU 20             ;writing mode for the line

; the four Line_A writing modes:
REPLACE      EQU 0              ;does what it says - overwrites
JUST_OR      EQU 1              ;adds color bits to the screen color
MAKE_EOR     EQU 2              ;reverses screen color
INVRT_OR     EQU 3              ;similar to above and then OR's line

;---------------------------------------------------------------------
CALCPROG: ;set the stack we use and calculate the size of our program
    MOVE.L   A7,A1              ; get current addr
    PEA      PRGSTACK           ; put in our program stack
    MOVE.L   4(A1),A1           ; get addr of basepage info
    MOVE.L   $C(A1),D0          ; get program text length
    ADD.L    $14(A1),D0         ; add program data length
    ADD.L    $1C(A1),D0         ; add program bss  length
    ADD.L    #$100,D0           ; add room for 256 byte basepage

SET_BLOCK: ;reserve only the space needed for our program:
    MOVE.L   D0,-(SP)           ;reserve this number of bytes
    MOVE.L   A1,-(SP)           ;starting at this address
    CLR.W    -(SP)
    MOVE.W   #$4A,-(SP)
    TRAP     #1
    LEA      12(SP),SP
    TST.L    D0                 ;did setblock fail?
    BMI      BYE_BYE            ;if so, we bail out quick

    BSR      GET_REZ
    CMP.W    #1,D0              ;are we in medium rez?
    BNE      BYE_BYE            ;if not, get out

    BSR      INITLN_A           ;gets addresses we'll need for Line_A
    BSR      MOUS_OFF           ;hide the mouse cursor

    LEA      MOUSE_1,A0         ;select the shape we'll use for it
    BSR      CHNGMOUS           ;make the mouse that shape and color

    BSR      DO_BOXES           ;draw all boxes & set our write modes
    BSR      DO_TEXT            ;put the text in the boxes

    BSR      DEFAULTS           ;set the default boxes and variables
    BSR      MOUS_ON            ;and show the mouse again

    CLR.W    EXITFLAG           ;make sure our exit flag is false (0)

MAINLOOP: ;here we go...
    TST.W    EXITFLAG           ;does the user want to quit?
    BNE      BYE_BYE            ;if not 0, then yes - so leave
    BSR      E_MULT             ;get a keyboard or mouse response
    TST.L    D0                 ;did user press a key?
    BEQ      NO_KEY             ;if not, then user pressed mouse
    CMP.B    #13,D0             ;did user press the return key?
    BNE      NOT_RTN            ;if not then skip the format
    BSR      DOFORMAT           ;else format the disk
    BSR      CLR_KBD            ;get rid of key-presses during format
    BRA      MAINLOOP           ;and go back for more
NOT_RTN:
    CMP.B    #27,D0             ;did user press the escape key?
    BEQ      BYE_BYE            ;if so, we leave
    BRA      MAINLOOP           ;else go back and try again
NO_KEY:  ;user pressed a mouse button
    CMP.W    #1,D1              ;did user press the left mouse button?
    BNE      MAINLOOP           ;if not,then ignore it.
    BSR      CHKBOXES           ;else check the boxes and do routine
    BRA      MAINLOOP           ;and go back for more

BYE_BYE: ;we prepare to leave:
    BSR      MOUS_OFF           ;hide the mouse
    BSR      CLR_SCRN           ;clear the screen
    BSR      CLR_KBD            ;clear the keyboard buffer
    BSR      CLR_MOUS           ;clear the mouse buttons
    BSR      MOUS_ON            ;turn mouse back on
    CLR.W    -(SP)              ;and leave this program
    TRAP     #1
;*********************************************************************
;*     here are all the sub-routines I employ in this program:       *
;*********************************************************************
INITLN_A:
    MOVEM.L  D0-D3/A0-A3,-(SP)
    DC.W     $A000              ;gets us some important Line_A addrs
    MOVE.L   A0,LN_AVARS        ;save addr of all Line_A variables
    MOVE.L   A1,LN_AFONT        ;save addr of font table pointer
    MOVEM.L  (SP)+,D0-D3/A0-A3
    RTS
;---------------------------------------------------------------------
CHNGMOUS: ;addr of new mouse data & shape should be in A0
    MOVEM.L  D0-D7/A0-A6,-(SP)
    MOVE.L   LN_AVARS,A1
    MOVE.L   8(A1),A1           ;get Line_A IntIn array
    MOVE.L   (A0)+,(A1)+        ;set col and row of new mouse hot spot
    ADDQ.L   #2,A1
    MOVE.L   (A0)+,(A1)+        ;set the mask and mouse colors
    MOVE.W   #15,D0             ;16 long words of mouse shape data
CHGMOUS:
    MOVE.L   (A0)+,(A1)+        ;transfer mouse data
    DBRA     D0,CHGMOUS         ;till done
    DC.W     $A00B              ;change to our new mouse shape!
    MOVEM.L  (SP)+,D0-D7/A0-A6
    RTS
;---------------------------------------------------------------------
DRAWLINE: ;A0 = addr of box info, line X1Y1 in D4.L and X2Y2 in D5.L
    MOVEM.L  D0-D5/A0-A5,-(SP)
    MOVE.L   A0,A3              ;save addr of box info in A3
    MOVE.L   LN_AVARS,A0        ;get addr of Line_A variables
    ADDA.L   #24,A0             ;add 24 for offset to those we use
    MOVE.W   BOXLCOLR(A3),D0    ;get color of our box's line
    MOVE.W   #3,D1              ;4 color planes are used (-1 for dbra)
    MOVEQ.L  #0,D2              ;0 out holder
DLLOOP:
    MOVE.W   D0,D2              ;get color bits in d2
    AND.W    #1,D2              ;eliminate all but bit 1 of color
    MOVE.W   D2,(A0)+           ;store colour bit in Line_A plane info
    ROR.W    #1,D0              ;shift colour bits one bit right
    DBRA     D1,DLLOOP          ;and continue for all 4 color planes
    MOVE.W   #-1,(A0)+          ;LstLine should always be -1
    MOVE.W   BOXLPTRN(A3),(A0)+ ;put in our line pattern
    MOVE.W   BOXLMODE(A3),(A0)+ ;put in our writing mode
    MOVE.L   D4,(A0)+           ;put in our upper left col/row
    MOVE.L   D5,(A0)+           ;put in our lower right col/row
    DC.W     $A003              ;draw the line - "Make it so!"
    MOVEM.L  (SP)+,D0-D5/A0-A5
    RTS
;---------------------------------------------------------------------
FILL_BOX: ;A0= addr of box variables
    MOVEM.L  D0-D5/A0-A5,-(SP)
    MOVE.L   A0,A3              ;save addr of or box info
    MOVE.L   LN_AVARS,A0        ;get addr of LIne_a variables
    MOVE.L   A0,A2              ;save a copy of this addr
    ADDA.L   #24,A0             ;move to the variables we'll use here
    MOVE.W   BOXFCOLR(A3),D0    ;get box color
    MOVE.W   #3,D1              ;assume we have up to 4 planes (-1)
    MOVEQ.L  #0,D2              ;clear out our holder
FLLOOP:
    MOVE.W   D0,D2              ;copy bit pattern of colour
    AND.W    #1,D2              ;keep the first bit only
    MOVE.W   D2,(A0)+           ;store it in Line_A bit plane info
    ROR.W    #1,D0              ;shift color 1 bit to right
    DBRA     D1,FLLOOP          ;and repeat for all four planes
    ADDQ.L   #4,A0              ;move past unwanted Line_A info
    MOVE.W   BOXFMODE(A3),(A0)+ ;set the box writing mode
    MOVE.L   BOX_X1(A3),D0      ;get the upper left corner col/row
    ADD.L    #$00010001,D0      ;add 1 so that box is inside lines
    MOVE.L   D0,(A0)+           ;set the upper left corner
    MOVE.L   BOX_X2(A3),D0      ;do the same for lower right corner
    SUB.L    #$00010001,D0      ;except we sub 1 from col and row
    MOVE.L   D0,(A0)+
    MOVE.L   BOXFFILL(A3),(A0)+ ;set addr of fill pattern to use
    MOVE.W   #3,(A0)+           ;num of lines in fill pattern (- 1)
    ADDQ.L   #2,A0              ;skip a portion of Line_A info
    MOVE.W   #1,(A0)+           ;we want "clipping" to be in effect
    MOVE.L   #0,(A0)+           ;use the upper left corner of screen
    MOVE.W   -12(A2),(A0)+      ;and the lower right corner of screen
    MOVE.W   -4(A2),(A0)        ; "
    DC.W     $A005              ;draw the filled box on the screen
    MOVEM.L  (SP)+,D0-D5/A0-A5
    RTS
;---------------------------------------------------------------------
TEXTBLIT: ;A0 = addr of null terminated string info
; Format: X,Y,Font_Number,Enlarge?,Style,Color_Of_Text,Background_Color
;         Write_Mode,String+0
    MOVEM.L  D0-D3/A0-A3,-(SP)
    MOVE.L   A0,A3              ;save copy of string info addr
    MOVE.L   LN_AVARS,A0        ;get addr of Line_A variables
    MOVE.L   LN_AFONT,A2        ;get addr of font table
    MOVE.L   (A3)+,76(A0)       ;set col and row of string
    MOVE.W   (A3)+,D1           ;get the font number we wish to use
; 0 = low rez font, 1 = medium rez font, 2 = high rez font
    MOVE.W   (A3)+,66(A0)       ;set enlargement (0 = none, -1 = yes)
    MOVE.W   #1,68(A0)          ;set boolean "use enlargment" to true
    MOVE.W   #1,70(A0)          ;set "monospaced font data" to true
    MOVE.W   (A3)+,90(A0)       ;set style of text to use
;0= normalstyle, bits:  0= bold, 1=lightened, 2= italics, 4= outlined
    MOVE.W   #$5555,92(A0)      ;mask for lightened/shaded text
    MOVE.W   64(A2),94(A0)      ;use systems own skewing mask
    MOVE.W   #1,96(A0)          ;"weight" for bold/thicken (works best)
    MOVE.W   56(A2),98(A0)      ;use systems own info for right offset
    MOVE.W   56(A2),100(A0)     ; ditto for left offset in italics
    MOVE.W   #1,102(A0)         ;set "scaling" flag to true
    MOVE.W   #0,104(A0)         ;set angle of rotation to 0 (none)
;$384 = 90 degrees, $708 = 180, $A8C = 270 degrees of rotation
    MOVE.W   (A3)+,106(A0)      ;set text color
    MOVE.L   #TBLTBUFF,108(A0)  ;set addr of special effect buffer
    MOVE.W   #$80,112(A0)       ;set offset to enlargement buffer
    MOVE.W   (A3)+,114(A0)      ;set text background color
    MOVE.W   (A3)+,36(A0)       ;set the writing mode for our text
    MOVE.W   #1,54(A0)          ;set "clipping" to true
    MOVE.L   #0,56(A0)          ;set upper left xy of screen
    MOVE.W   -12(A0),D0         ;get lower right corner of screen:
    SUBQ.W   #1,D0              ;-1
    MOVE.W   D0,60(A0)          ;set it
    MOVE.W   -4(A0),D0          ;  ditto
    SUBQ.W   #1,D0
    MOVE.W   D0,62(A0)
    LSL.W    #2,D1              ;multiply font requested by 4
    MOVE.L   (A2,D1),A2         ;get addr of that font
    MOVE.L   76(A2),84(A0)      ;set addr of the font
    MOVE.W   80(A2),88(A0)      ;set the width of the font
    MOVE.W   82(A2),82(A0)      ;set the char height of the font
    MOVE.L   72(A2),A1          ;get addr of font data for use below
TBT_LOOP: ;here is the loop that outputs the zero terminated string:
    MOVEQ.L  #0,D0              ;clear our char holder
    MOVE.B   (A3)+,D0           ;get a char from string
    BEQ      END_TBLT           ;if zero then we end
    SUB.W    36(A2),D0          ;subtract char offset from char
    LSL.W    #1,D0              ;multiply this by 2
    MOVE.W   (A1,D0.W),72(A0)   ;set source of chars top
    MOVE.W   #0,74(A0)          ;set source of chars 1st line
    ADDQ.W   #2,D0              ;add 2 bytes to D0 for next char
    MOVE.W   (A1,D0.W),D0       ;get next char offset
    SUB.W    72(A0),D0          ;sub the last char from it
    MOVE.W   D0,80(A0)          ;set this as the char's width
    MOVE.W   #$8000,64(A0)      ;always set this before each $A008 call
    MOVEM.L  D0-D3/A0-A3,-(SP)  ;save registers destoyed by call
    DC.W     $A008              ;call the textblit routine - make it so
    MOVEM.L  (SP)+,D0-D3/A0-A3  ;restore registers
    BRA      TBT_LOOP           ;and go back to top of text output loop
END_TBLT:
    MOVEM.L  (SP)+,D0-D3/A0-A3
    RTS
;---------------------------------------------------------------------
MAKE_BOX: ;A0 = addr of box - creates a filled box & outlines it.
    MOVEM.L  D4/D5,-(SP)
    BSR      FILL_BOX           ;first fill the box, then
    MOVE.L   BOX_X1(A0),D4      ;put upper left col/row in D4
    MOVE.L   BOX_X2(A0),D5      ;put lower right col/row in D5
    MOVE.W   D4,D5              ;put upper left row in D5
    BSR      DRAWLINE           ;DO TOP LINE
    MOVE.W   BOX_X1(A0),D5      ;put upper left col in D5
    SWAP     D5                 ;move it to high word
    MOVE.W   BOX_Y2(A0),D5      ;get lower right row in low word
    BSR      DRAWLINE           ;DO LEFT SIDE
    MOVE.W   D5,D4              ;put lower right row in D4
    MOVE.L   BOX_X2(A0),D5      ;put lower right col/row in D5
    BSR      DRAWLINE           ;DO BOTTOM LINE
    MOVE.L   BOX_X2(A0),D4      ;put lower right col/row in D4
    MOVE.W   BOX_Y1(A0),D4      ;put upper left row in D4
    BSR      DRAWLINE           ;DO RIGHT SIDE
    MOVEM.L  (SP)+,D4/D5
    RTS
;---------------------------------------------------------------------
DO_BOXES: ;uses Make_Box to draw all boxes in our data table listing
    MOVEM.L  D0-D3/A0-A3,-(SP)
    LEA      THEBOXES,A1        ;get addr of the boxes
    MOVE.W   (A1)+,D1           ;get number of boxes to do
SHOWBOXS:
    MOVE.L   (A1)+,A0           ;get addr of box
    BSR      MAKE_BOX           ;make it so
    CMP.W    #2,D1              ;we don't want to fool with status box
    BEQ      NOTTHIS1
    MOVE.W   #MAKE_EOR,BOXFMODE(A0) ;set BOX FILL write mode to E_OR
NOTTHIS1:
    ADDQ.L   #4,A1              ;move past routine associted with box
    DBRA     D1,SHOWBOXS        ;and do (show) all boxes
    MOVEM.L  (SP)+,D0-D3/A0-A3
    RTS
;---------------------------------------------------------------------
DO_TEXT: ;writes all the text we need using our data table info.
    MOVEM.L  D0-D3/A0-A3,-(SP)
    LEA      THE_TEXT,A1        ;get addr of text table
    MOVE.W   (A1)+,D1           ;get number of text items to show
SHOWTEXT:
    MOVE.L   (A1)+,A0           ;get addr of text
    BSR      TEXTBLIT           ;show it
    DBRA     D1,SHOWTEXT        ;and do all others
    MOVEM.L  (SP)+,D0-D3/A0-A3
    RTS
;---------------------------------------------------------------------
CLR_SCRN: ;VT-52 routine to clear the screen
    MOVEM.L  D0-D2/A0-A2,-(SP)
    MOVE.W   #27,-(SP)         ; output ESC
    MOVE.W   #2,-(SP)
    MOVE.W   #3,-(SP)
    TRAP     #13
    ADDQ.L   #6,SP
    MOVE.W   #69,-(SP)         ; output "E"
    MOVE.W   #2,-(SP)
    MOVE.W   #3,-(SP)
    TRAP     #13
    ADDQ.L   #6,SP
    MOVEM.L  (SP)+,D0-D2/A0-A2
    RTS
;---------------------------------------------------------------------
CURS_ON: ;VT-52 routine to turn on the text cursor
    MOVEM.L  D0-D4/A0-A4,-(SP)
    MOVE.W   #27,-(SP)         ; output ESC
    MOVE.W   #2,-(SP)
    MOVE.W   #3,-(SP)
    TRAP     #13
    ADDQ.L   #6,SP
    MOVE.W   #101,-(SP)         ; output "e"
    MOVE.W   #2,-(SP)
    MOVE.W   #3,-(SP)
    TRAP     #13
    ADDQ.L   #6,SP
    MOVEM.L  (SP)+,D0-D4/A0-A4
    RTS
;---------------------------------------------------------------------
CURS_OFF: ;VT-52 routine to turn off the text cursor
    MOVEM.L  D0-D4/A0-A4,-(SP)
    MOVE.W   #27,-(SP)         ; output ESC
    MOVE.W   #2,-(SP)
    MOVE.W   #3,-(SP)
    TRAP     #13
    ADDQ.L   #6,SP
    MOVE.W   #102,-(SP)         ; output "f"
    MOVE.W   #2,-(SP)
    MOVE.W   #3,-(SP)
    TRAP     #13
    ADDQ.L   #6,SP
    MOVEM.L  (SP)+,D0-D4/A0-A4
    RTS
;---------------------------------------------------------------------
CHK_KBD: ; BConStat #1, D0 = 0 if no keys are in keyboard buffer
    MOVEM.L  D1/D2/A0-A2,-(SP)
    MOVE.W   #2,-(SP)
    MOVE.W   #1,-(SP)
    TRAP     #13
    ADDQ.L   #4,SP
    MOVEM.L  (SP)+,D1/D2/A0-A2
    RTS
;---------------------------------------------------------------------
GET_KEY: ; BConStat #2, D0 = key pressed
    MOVEM.L  D1/D2/A0-A2,-(SP)
    MOVE.W   #2,-(SP)
    MOVE.W   #2,-(SP)
    TRAP     #13
    ADDQ.L   #4,SP
    MOVEM.L  (SP)+,D1/D2/A0-A2
    RTS
;---------------------------------------------------------------------
MOUSBUTN: ;puts mouse button status in D0.W
;Thanks to STARFALL [Alan] (on GENIE, Wed Jul 24,1991) for offsets
    MOVE.L   A0,-(SP)           ;(CAUTION!  This seems to work now...)
    MOVE.L   LN_AVARS,A0        ;(...but it may not work with all TOS)
    MOVE.W   -$254(A0),D0       ;(..versions.  VDI must then be used.)
    MOVE.L   (SP)+,A0           ;(...... yuch! -C.H.)
    RTS
;---------------------------------------------------------------------
MOUS_XY: ; puts mouse cursor xy in D0.L
;Thanks to STARFALL [Alan] (on GENIE, Wed Jul 24,1991) for offsets
    MOVE.L   A0,-(SP)           ;(CAUTION!  This seems to work now...)
    MOVE.L   LN_AVARS,A0        ;(...but it may not work with all TOS)
    MOVE.L   -$25A(A0),D0       ;(..versions.  VDI must then be used.)
    MOVE.L   (SP)+,A0           ;(...... yuch! -C.H.)
    RTS
;---------------------------------------------------------------------
MOUS_ON: ;shows the mouse cursor - regardless of # of hide calls!
    MOVEM.L  D0-D7/A0-A6,-(SP)
    MOVE.L   LN_AVARS,A0        ;get addr of Line_A variables
    MOVE.L   8(A0),A0           ;get addr of the IntIn array
    CLR.W    (A0)               ;clear the number of "hide" calls
    DC.W     $A009              ;show our mouse cursor
    MOVEM.L  (SP)+,D0-D7/A0-A6
    RTS
;---------------------------------------------------------------------
MOUS_OFF: ;hides the mouse cursor
    MOVEM.L  D0-D7/A0-A6,-(SP)
    DC.W     $A00A              ;each call to this increments "hide"
    MOVEM.L  (SP)+,D0-D7/A0-A6  ;          (see above)
    RTS
;---------------------------------------------------------------------
E_MULT: ; Puts char in D0.L, Mouse button in D1.W, Mouse XY in D2.L
; This is my "poor man's" version of GEM's Event_Multi - I hate Gem!
    MOVEQ.L  #0,D0              ;clear char holder
    MOVE.L   D0,D1              ; and mouse button holder
    MOVE.L   D0,D2              ; and mouse XY holder
EMULT1:
    BSR      CHK_KBD            ;did user press a key?
    TST.W    D0                 ;well?
    BEQ      EMULT2             ;if not, then check mouse
    BSR      GET_KEY            ;else get the key the user pressed
    BRA      END_MULT           ;and leave
EMULT2:
    BSR      MOUSBUTN           ;did user press a mouse button?
    TST.W    D0                 ;well?
    BEQ      EMULT1             ;if not then go back to top of loop
    EXG.L    D1,D0              ;else swap d0 and d1
    BSR      MOUS_XY            ;and get the mouse XY
    EXG.L    D0,D2              ;and put it in D2
END_MULT:
    RTS
;---------------------------------------------------------------------
CLR_KBD: ;clears keyboard buffer of all key presses.
    MOVEQ.L  #0,D0              ;clear our keypressed value
    BSR      CHK_KBD            ;is there a key value in the buffer?
    TST.W    D0
    BEQ      KBD_CLR            ;if not, then we're OK
    BSR      GET_KEY            ;else get the key from the buffer
    BRA      CLR_KBD            ;and repeat till all chars are gone
KBD_CLR:
    RTS
;---------------------------------------------------------------------
CLR_MOUS: ;waits till you release the mouse buttons
    BSR      MOUSBUTN           ;get the mouse button value
    TST.W    D0                 ;was a mouse button pressed?
    BNE      CLR_MOUS           ;if so, then repeat till not
    RTS
;---------------------------------------------------------------------
F_FORMAT: ;formats one track - non-skewed
    MOVEM.L  D1-D4/A0-A4,-(SP)
    MOVE.W   #$E5E5,-(SP)       ;virgin data
    MOVE.L   #$87654321,-(SP)   ;magic "valid atari disk" value
    MOVE.W   #1,-(SP)           ;interleave value - normal value
    MOVE.W   SIDE2DO,-(SP)      ;side
    MOVE.W   TRAK2DO,-(SP)      ;track
    MOVE.W   #10,-(SP)          ;sectors per track
    MOVE.W   DRIVE,-(SP)        ;0 = drive A (1 would = drive B)
    CLR.L    -(SP)
    PEA      BUFFER             ;must be @ 1024 bytes long per track
    MOVE.W   #10,-(SP)          ;XBIOS Floppy Format
    TRAP     #14
    LEA      26(SP),SP
    MOVEM.L  (SP)+,D1-D4/A0-A4
    RTS
;---------------------------------------------------------------------
FLOPWRIT: ;writes data from a buffer to designated sectors.
    MOVEM.L  D1-D4/A0-A4,-(SP)
    MOVE.W   SEC2WRIT,-(SP)     ;sectors to write
    MOVE.W   SIDE2DO,-(SP)      ;side to write
    MOVE.W   TRAK2DO,-(SP)      ;track to write
    MOVE.W   #1,-(SP)           ;starting sector should always be 1
    MOVE.W   DRIVE,-(SP)        ;use designated drive
    CLR.L    -(SP)              ;filler
    PEA      BUFFER             ;use info in the buffer
    MOVE.W   #9,-(SP)           ;XBIOS Floppy Write
    TRAP     #14
    LEA      20(SP),SP
    MOVEM.L  (SP)+,D1-D4/A0-A4
    RTS
;---------------------------------------------------------------------
PROTO: ;puts Atari format disk boot sector data in our buffer.
    MOVEM.L  D1-D4/A0-A4,-(SP)
    MOVE.W   #0,-(SP)           ;boot sector should NOT be executable
    MOVE.W   SIDES,D1           ;get # of sides user wants to format
    ADDQ.W   #2,D1              ;add 2 to get proper value
    MOVE.W   D1,-(SP)           ;80 tracks: 2=single sided, 3 = double
    MOVE.L   #$01234567,-(SP)   ;create a random serial number
    PEA      BUFFER             ;512 byte buffer is all we need
    MOVE.W   #18,-(SP)          ;XBIOS protoboot
    TRAP     #14
    LEA      14(SP),SP
    MOVEM.L  (SP)+,D1-D4/A0-A4
    RTS
;---------------------------------------------------------------------
FORMAT:  ;this carries out all the neccessary tasks to format a disk:
    MOVEM.L  D1-D4/A0-A4,-(SP)
    LEA      WORKING,A0         ;show that we're busy
    BSR      TEXTBLIT

    BSR      CLIK_OFF           ;turn off the key click

    MOVE.W   #0,ERROR           ;assume all is ok - no errors

; 1. format all tracks on sides 1 (and 2 ?) using XBIOS #10
    MOVE.W   #0,SIDE2DO         ;start with side 0
    MOVE.W   #0,TRAK2DO         ;and start with track 0

FRMTLOOP:
    BSR      DOMUSIC            ;keep our music playing
    BSR      F_FORMAT           ;do side 0
    TST.L    D0                 ;did an error occur?
    BMI      LEAVE              ;if so, get out

    TST.W    SIDES              ;see how many sides user has (wants)
    BEQ      JUST_1             ;if 0 then user has just 1 side
    MOVE.W   #1,SIDE2DO         ;else change to side 1
    BSR      F_FORMAT           ;do side 1
    TST.L    D0                 ;see if error occurred
    BMI      LEAVE              ;and leave if it did
    MOVE.W   #0,SIDE2DO         ;change back to side 0

JUST_1:

    LEA      STATLINE,A0        ;let's set up our status line info:
    MOVE.L   BOX_X1(A0),D4      ;col
    MOVE.L   BOX_X2(A0),D5      ;row
    BSR      DRAWLINE           ;now draw our format status line
    ADD.W    #1,BOX_X1(A0)      ;increment our status line columns:
    ADD.W    #1,BOX_X2(A0)

    ADDQ.W   #1,TRAK2DO         ;move to next track
    MOVE.W   TRAK2DO,D6         ;get the tracks we've done
    MOVE.W   TRACKS,D7          ;and the total number we want to do
    CMP.W    D6,D7              ;have we done all our tracks?
    BNE      FRMTLOOP           ;if not then continue to format

; 2. zero out the first two tracks on each side for FAT and DIR
CLR_TRAK:
    LEA      BUFFER,A0          ;get addr of our track buffer
    MOVEQ.L  #0,D0              ;we'll write 4 zero bytes at a time
    MOVE.W   #2559,D1           ;and fill the track buffer with 0's
CLR_LOOP:
    MOVE.L   D0,(A0)+
    DBRA     D1,CLR_LOOP

; (Now we must write these zeros to tracks 0 and 1 [on both sides])
; (This will zero out the File Allocation Tables and ...)
; (... the DIRectory listings for us.)
    MOVE.W   #10,SEC2WRIT       ;sectors to write
    MOVE.W   #0,SIDE2DO         ;start with side 0
    MOVE.W   #0,TRAK2DO         ;and track 0
WRITZERO:
    BSR      FLOPWRIT           ;write zeros to one whole track
    TST.L    D0                 ;did an error occur?
    BMI      LEAVE              ;if so, bail out quick
    TST.W    SIDES              ;see if user has more than 1 side
    BEQ      ONLY_1             ;if 0 then user has just 1 side
    MOVE.W   #1,SIDE2DO         ;do the other side
    BSR      FLOPWRIT
    TST.L    D0
    BMI      LEAVE
    MOVE.W   #0,SIDE2DO         ;go back to side 0
ONLY_1:
    ADDQ.W   #1,TRAK2DO         ;and move to the next track
    CMP.W    #2,TRAK2DO
    BNE      WRITZERO           ;make sure we ony do this to 2 tracks

; 3. use XBIOS #18 to create a protoboot sector
    BSR      PROTO              ;create the protoboot sector in buffer
    TST.L    D0                 ;did we have an error?
    BMI      LEAVE              ;if so, leave
    LEA      BUFFER,A0          ;get addr of the protoboot sector

; 4. we must alter the boot sector in the buffer if we are to use
;   anything over 9 sectors per track or 80 tracks per disk:
;   Here is how the info in the boot sector block is set up:
;
;    Offset in Bytes:                Description of info:
;
;            0                  Branch to boot code (if any)
;            2                  reserved for Operating Environment
;            8                  24 bit volume serial number
;            11                 Number of bytes per sector
;            13                 number of sectors per cluster
;            14                 number of reserved sectors
;            16                 # of File Allocation Tables
;            17                 number of directory entries
; Modified:  19                 total number of sectors on disk
;    "                          !low byte of word 1st then high byte!
;            21                 media descriptor - unused -
;            22                 number of sectors per FAT
; Modified:  24                 number of sectors per track
;            26                 number of sides to disk
;            28                 number of hidden sectors
;            30                 start of boot code (if any)
;                               !room for 480 bytes of code!
;            511                2 bytes used for checksum value

    MOVE.W   TRACKS,D0          ;get the number of tracks user wanted
    MULU     #10,D0             ;times 10 sectors per track
    MOVE.W   SIDES,D1           ;get # of sides the user has (0 or 1)
    LSL.W    D1,D0              ;multiply it x 0 (or 2)

    MOVE.B   D0,19(A0)          ;use MS-DOS format to put in the info
    LSR.W    #8,D0              ;shift high byte down to low byte
    MOVE.B   D0,20(A0)          ;using MS-DOS format to put in info
    MOVE.B   #10,24(A0)         ;and change to 10 sectors per track

; 5. write this boot sector to disk at sector 1 track 0 side 0.
    MOVE.W   #1,SEC2WRIT        ;sectors to write
    MOVE.W   #0,SIDE2DO         ;side to write
    MOVE.W   #0,TRAK2DO         ;track to write
    BSR      FLOPWRIT           ;write the boot sector to disk
    TST.L    D0                 ;did we have an error?
    BMI      LEAVE              ;if so, leave
    BRA      FMT_OK             ;else we get out successfully
LEAVE:
    MOVE.W   #1,ERROR
FMT_OK:
    LEA      SILENCE,A0         ;get addr of silence data
    BSR      DO_SOUND           ;turn off the music

    LEA      STATCNST,A0        ;put StatLine data back as it was:
    LEA      STATLINE,A1
    MOVE.L   (A0)+,(A1)+
    MOVE.L   (A0),(A1)

    LEA      THE_STAT,A0        ;remake the stat line box
    BSR      MAKE_BOX
    LEA      WAITING,A0         ;get addr of "Waiting" stat line text
    TST.W    ERROR              ;did we have an error?
    BEQ      NOERROR            ;if not then we're OK

    LEA      BOMBFALL,A0        ;else get addr of falling bomb sound
    BSR      DO_SOUND           ;and play it
    LEA      ANERROR,A0         ;and then get addr of "ERROR" text
NOERROR:
    BSR      TEXTBLIT           ;show the text
    BSR      CLIK_ON            ;restore orig key click value
    MOVEM.L  (SP)+,D1-D4/A0-A4
    RTS
;---------------------------------------------------------------------
RINGBELL:
    MOVEM.L  D0-D3/A0-A3,-(SP)
    MOVE.W   #7,-(SP)           ;sound bell note using ConOut
    MOVE.W   #2,-(SP)
    TRAP     #1
    ADDQ.L   #4,SP
    MOVEM.L  (SP)+,D0-D3/A0-A3
    RTS
;---------------------------------------------------------------------
;-     The next 9 routines are what we use when selecting a box:     -
;---------------------------------------------------------------------
SET_A:
    BSR      MOUS_OFF           ;hide mouse
    TST.W    DRIVE              ;see which drive we're using
    BEQ      A_OK               ;if 0 then we need do nothing
    LEA      THE_B,A0           ;else get addr of B drive box info
    BSR      MAKE_BOX           ;and unhighlight the B drive
    MOVE.W   #0,DRIVE           ;make Drive variable = to A drive
    LEA      THE_A,A0           ;get addr of A drive box info
    BSR      MAKE_BOX           ;and highlight it
A_OK:
    BSR      MOUS_ON            ;show the mouse again
    BSR      CLR_MOUS           ;wait till user releases mouse button
    RTS
;---------------------------------------------------------------------
SET_B:
    BSR      MOUS_OFF           ;see Set_A for what this does.
    TST.W    DRIVE
    BNE      B_OK
    LEA      THE_A,A0
    BSR      MAKE_BOX
    MOVE.W   #1,DRIVE
    LEA      THE_B,A0
    BSR      MAKE_BOX
B_OK:
    BSR      MOUS_ON
    BSR      CLR_MOUS           ;wait till user releases mouse button
    RTS
;---------------------------------------------------------------------
SET_1:
    BSR      MOUS_OFF           ;see Set_A for how this works.
    TST.W    SIDES
    BEQ      S1_OK
    LEA      THE_2,A0
    BSR      MAKE_BOX
    MOVE.W   #0,SIDES
    LEA      THE_1,A0
    BSR      MAKE_BOX
S1_OK:
    BSR      MOUS_ON
    BSR      CLR_MOUS           ;wait till user releases mouse button
    RTS
;---------------------------------------------------------------------
SET_2:
    BSR      MOUS_OFF           ;see Set_A
    TST.W    SIDES
    BNE      S2_OK
    LEA      THE_1,A0
    BSR      MAKE_BOX
    MOVE.W   #1,SIDES
    LEA      THE_2,A0
    BSR      MAKE_BOX
S2_OK:
    BSR      MOUS_ON
    BSR      CLR_MOUS           ;wait till user releases mouse button
    RTS
;---------------------------------------------------------------------
SET_80:
    BSR      MOUS_OFF           ;see Set_A
    CMP.W    #80,TRACKS
    BEQ      T80_OK
    LEA      THE_82,A0
    BSR      MAKE_BOX
    MOVE.W   #80,TRACKS
    LEA      THE_80,A0
    BSR      MAKE_BOX
T80_OK:
    BSR      MOUS_ON
    BSR      CLR_MOUS           ;wait till user releases mouse button
    RTS
;---------------------------------------------------------------------
SET_82:
    BSR      MOUS_OFF           ;see Set_A
    CMP.W    #82,TRACKS
    BEQ      T82_OK
    LEA      THE_80,A0
    BSR      MAKE_BOX
    MOVE.W   #82,TRACKS
    LEA      THE_82,A0
    BSR      MAKE_BOX
T82_OK:
    BSR      MOUS_ON
    BSR      CLR_MOUS           ;wait till user releases mouse button
    RTS
;---------------------------------------------------------------------
DOFORMAT:
    BSR      MOUS_OFF           ;hide mouse
    LEA      THE_FMT,A0         ;highlight format box
    BSR      MAKE_BOX
    BSR      FORMAT             ;format the disk
    LEA      THE_FMT,A0
    BSR      MAKE_BOX           ;unhighlight format box
    BSR      MOUS_ON            ;show mouse again
    BSR      CLR_MOUS           ;wait till user releases mouse button
    RTS
;---------------------------------------------------------------------
SET_EXIT:
    BSR      MOUS_OFF           ;hide mouse
    LEA      THE_EXIT,A0        ;highlight exit box
    BSR      MAKE_BOX           ;(really not much point in this)
    MOVE.W   #1,EXITFLAG        ;set ExitFlag to true (1)
    BSR      MOUS_ON            ;and show mouse again
    BSR      CLR_MOUS           ;wait till user releases mouse button
    RTS
;---------------------------------------------------------------------
NOTHING:                        ;a do_nothing filler routine
    RTS
;---------------------------------------------------------------------
DEFAULTS: ;sets default boxes and variables
    MOVE.W   #0,EXITFLAG        ;set ExitFlag to false (0)
    MOVE.W   #0,ERROR           ;start with 0 errors
    MOVE.W   #0,DRIVE           ;and make the A the default drive
    LEA      THE_A,A0           ;highlight the A drive box
    BSR      MAKE_BOX
    MOVE.W   #1,SIDES           ;make 2 sides the default
    LEA      THE_2,A0           ;highlight the default sides box
    BSR      MAKE_BOX
    MOVE.W   #82,TRACKS         ;set default tracks to 82
    LEA      THE_82,A0          ;and highlight that box
    BSR      MAKE_BOX
    RTS
;---------------------------------------------------------------------
CHKBOXES: ;this runs through our list of boxes after mouse button is
;   pressed to see if it's in a box - if it is, we jump to the address
;   of the routine for that box.
    LEA      THEBOXES,A1        ;get addr of our table of boxes
    MOVE.W   (A1)+,D7           ;get number of boxes (-1 for dbra)
    MOVE.L   (A1),A0            ;get the big box addr from our table
    CMP.W    BOX_Y1(A0),D2      ;is mouse left of the left side?
    BCS      OUTOFBOX           ;if so, we're out of the box
    CMP.W    BOX_Y2(A0),D2      ;is mouse right of the right side?
    BHI      OUTOFBOX           ;if so, we're out of the box
    SWAP     D2                 ;put col value in low word of D2
    CMP.W    BOX_X1(A0),D2      ;is mouse to left of the left side?
    BCS      OUTOFBOX           ;if so, we're out of the box
    CMP.W    BOX_X2(A0),D2      ;is mouse to right of the right side?
    BLS      CHKNEXTS           ;if NOT then we're ok so far
OUTOFBOX:
    BSR      RINGBELL           ;else we're outside main box - ring bell
    RTS                         ;and return
CHKLOOP:
    MOVE.L   (A1),A0            ;get the box addr from our table
    CMP.W    BOX_Y1(A0),D2      ;is mouse at or right of the left side
    BCS      CHKNEXT            ;if not then check next box
    CMP.W    BOX_Y2(A0),D2      ;is mouse at or left of the right side
    BHI      CHKNEXT            ;if not then check next box
    SWAP     D2
    CMP.W    BOX_X1(A0),D2      ;is mouse at or right of the left side
    BCS      CHKNEXTS           ;if not then check next box
    CMP.W    BOX_X2(A0),D2      ;is mouse at or left of the right side
    BHI      CHKNEXTS           ;if not then check next box
    ADDQ.L   #4,A1              ;we're IN the box, so move to routine
    MOVE.L   (A1),A0            ;get addr of routine in A0
    JMP      (A0)               ;and jump to that addr
CHKNEXTS:
    SWAP     D2                 ;put col back in highword of D2
CHKNEXT:
    ADDQ.L   #8,A1              ;move to next box in table
    DBRA     D7,CHKLOOP         ;until all are checked
    RTS
;---------------------------------------------------------------------
CLIK_OFF: ;a key click will kill our music - so we will turn it off:
    MOVEM.L  D0-D4/A0-A4,-(SP)
    PEA      CLKOFF             ;use super_exec to execute this
    MOVE.W   #38,-(SP)
    TRAP     #14
    ADDQ.L   #6,SP
    MOVEM.L  (SP)+,D0-D4/A0-A4
    RTS
CLKOFF:
    MOVE.W   D0,-(SP)
    MOVE.B   $484,D0            ;get system conterm byte
    MOVE.B   D0,CONTERM         ;save it so we can restore it later
    AND.B    #8,D0              ;erase bits 0 to 2 to kill key clicks
    MOVE.B   D0,$484            ;and put it back - make it so, # 1
    MOVE.W   (SP)+,D0
    RTS
;---------------------------------------------------------------------
CLIK_ON: ;enable the key click sound after music is done:
    MOVEM.L  D0-D4/A0-A4,-(SP)
    PEA      CLKON              ;use super_exec to execute this
    MOVE.W   #38,-(SP)
    TRAP     #14
    ADDQ.L   #6,SP
    MOVEM.L  (SP)+,D0-D4/A0-A4
    RTS
CLKON:
    MOVE.W   D0,-(SP)
    MOVE.B   CONTERM,D0         ;get the conterm value we saved
    MOVE.B   D0,$484            ;put it back as it was originally
    MOVE.W   (SP)+,D0
    RTS
;---------------------------------------------------------------------
DOMUSIC: ;for continuous play of a song (USE IN A LOOP)
    MOVEM.L  D0-D4/A0-A4,-(SP)
    MOVE.L   #-1,-(SP)          ;let's see if there is any music
    MOVE.W   #32,-(SP)          ;  or sound being processed:
    TRAP     #14                ;D0 = 0 if there is no sound
    ADDQ.L   #6,SP              ;otherwise the addr of sound table
    TST.L    D0                 ;well?
    BNE      SOUND_ON           ;if not 0 then sound is playing
    PEA      MUSIC              ;put addr of our sound table on stack
    MOVE.W   #32,-(SP)
    TRAP     #14                ;play it again
    ADDQ.L   #6,SP
SOUND_ON:
    MOVEM.L  (SP)+,D0-D4/A0-A4
    RTS
;---------------------------------------------------------------------
DO_SOUND: ;addr of sound/music in A0
    MOVEM.L  D0-D4/A0-A4,-(SP)
    MOVE.L   A0,-(SP)           ;put addr of our sound table on stack
    MOVE.W   #32,-(SP)
    TRAP     #14                ;kill all sounds
    ADDQ.L   #6,SP
    MOVEM.L  (SP)+,D0-D4/A0-A4
    RTS
;---------------------------------------------------------------------
GET_REZ: ;D0 will = 0 (low), or 1 (medium), or 2 (high rez)
    MOVEM.L  D1-D4/A0-A4,-(SP)
    MOVE.W   #4,-(SP)
    TRAP     #14
    ADDQ.L   #2,SP
    MOVEM.L  (SP)+,D1-D4/A0-A4
    RTS
;-------------------------------------------------------------------
    DATA
; Unfortunately I will not take time to discuss the sound commands
; used below - maybe at another time and in another program. - C.H.
BOMBFALL:
 DC.B 0,0,1,1,2,0,3,0,4,0,5,0,6,0,7,254,8,7,9,0,10,0,11,0,12,0,13,0
 DC.B 128,0,129,0,2,220,130,14
 DC.B 1,0,6,10,7,199,8,16,9,16,10,16,11,0,12,80,13,0,130,120
 DC.B 6,0,7,255,0,0,1,0,8,0,9,0,10,0,12,0,255,0

MUSIC: ;my simple rendition of the "Midnight Express" theme song:
; my apology to music buffs and the original authors of the tune/song.
; If you can find some public domain song data, you can put it here:
  DC.B 0,$7B,1,$1,2,0,3,0,4,0,5,0,6,0,7,$F8,8,10,9,0,10,0,11,0,12,0,13,0
  DC.B 130,16
  DC.B 0,$A9,1,$1,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$38,1,$2,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$CB,1,$2,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$F6,1,$2,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$53,1,$3,7,$F8,8,10
  DC.B 130,40

  DC.B 0,$7B,1,$1,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$A9,1,$1,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$38,1,$2,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$CB,1,$2,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$F6,1,$2,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$53,1,$3,7,$F8,8,10
  DC.B 130,16

  DC.B 0,$F6,1,$2,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$CB,1,$2,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$7D,1,$2,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$38,1,$2,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$F6,1,$2,7,$F8,8,10
  DC.B 130,130

  DC.B 0,$7B,1,$1,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$A9,1,$1,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$38,1,$2,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$CB,1,$2,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$F6,1,$2,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$53,1,$3,7,$F8,8,10
  DC.B 130,40

  DC.B 0,$7B,1,$1,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$A9,1,$1,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$38,1,$2,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$CB,1,$2,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$F6,1,$2,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$53,1,$3,7,$F8,8,10
  DC.B 130,16

  DC.B 0,$F6,1,$2,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$CB,1,$2,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$7D,1,$2,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$38,1,$2,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$F6,1,$2,7,$F8,8,10
  DC.B 130,130
;
  DC.B 0,$A9,1,$1,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$DD,1,$1,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$18,1,$2,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$CB,1,$2,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$7D,1,$2,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$38,1,$2,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$18,1,$2,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$DD,1,$1,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$A9,1,$1,7,$F8,8,10
  DC.B 130,50

  DC.B 0,$18,1,$2,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$DD,1,$1,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$A9,1,$1,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$7B,1,$1,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$65,1,$1,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$3E,1,$1,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$1C,1,$1,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$A9,1,$1,7,$F8,8,10
  DC.B 130,130

  DC.B 0,$1C,1,$1,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$1C,1,$1,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$3E,1,$1,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$3E,1,$1,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$65,1,$1,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$1C,1,$1,7,$F8,8,10
  DC.B 130,32

  DC.B 0,$3E,1,$1,7,$F8,8,10
  DC.B 130,8
  DC.B 0,$3E,1,$1,7,$F8,8,10
  DC.B 130,130

  DC.B 0,$91,1,$1,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$65,1,$1,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$3E,1,$1,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$1C,1,$1,7,$F8,8,10
  DC.B 130,16
  DC.B 0,$0C,1,$1,7,$F8,8,10
  DC.B 130,16

  DC.B 0,$1C,1,$1,2,$D4,3,0,7,$F8,8,10,9,10
  DC.B 130,8
  DC.B 0,$1C,1,$1,2,$C8,3,0,7,$F8,8,10,9,10
  DC.B 130,8
  DC.B 0,$1C,1,$1,2,$D4,3,0,7,$F8,8,10,9,10
  DC.B 130,8
  DC.B 0,$1C,1,$1,2,$EE,3,0,7,$F8,8,10,9,10
  DC.B 130,4
  DC.B 0,$1C,1,$1,2,$EE,3,0,7,$F8,8,10,9,10
  DC.B 130,4
  DC.B 0,$1C,1,$1,2,$D4,3,0,7,$F8,8,10,9,10
  DC.B 130,8
  DC.B 0,$1C,1,$1,2,$EE,3,0,7,$F8,8,10,9,10
  DC.B 130,10
  DC.B 0,$1C,1,$1,2,$D4,3,0,7,$F8,8,10,9,10
  DC.B 130,16

  DC.B 0,$1C,1,$1,7,$F8,8,10,9,10
  DC.B 130,8
  DC.B 0,$1C,1,$1,2,$D4,3,0,7,$F8,8,10,9,10
  DC.B 130,8
  DC.B 0,$1C,1,$1,2,$C8,3,0,7,$F8,8,10,9,10
  DC.B 130,8
  DC.B 0,$1C,1,$1,2,$D4,3,0,7,$F8,8,10,9,10
  DC.B 130,8
  DC.B 0,$1C,1,$1,2,$EE,3,0,7,$F8,8,10,9,10
  DC.B 130,4
  DC.B 0,$1C,1,$1,2,$EE,3,0,7,$F8,8,10,9,10
  DC.B 130,4
  DC.B 0,$1C,1,$1,2,$D4,3,0,7,$F8,8,10,9,10
  DC.B 130,80

SILENCE:
  DC.B 0,0,1,0,2,0,3,0,4,0,5,0,6,0,7,$FF,8,0,9,0,10,0,11,0,12,0,13,0
  DC.B 255,0 ;end all sounds

MOUSE_1: ;our new mouse shape/color data:
;mouse's column and row for the hot_spot:
    DC.W     8,8
;mouse mask color and shape color
    DC.W     2,15
;mouse mask:
    DC.W     %1110000000000111
    DC.W     %1110000000000111
    DC.W     %0111000000001110
    DC.W     %0011100000011100
    DC.W     %0001110000111000
    DC.W     %0000111001110000
    DC.W     %0000011111100000
    DC.W     %0000001111000000
    DC.W     %0000001111000000
    DC.W     %0000011111100000
    DC.W     %0000111001110000
    DC.W     %0001110000111000
    DC.W     %0011100000011100
    DC.W     %0111000000001110
    DC.W     %1110000000000111
    DC.W     %1110000000000111
;mouse shape
    DC.W     %0000000000000000
    DC.W     %0100000000000010
    DC.W     %0010000000000100
    DC.W     %0001000000001000
    DC.W     %0000100000010000
    DC.W     %0000010000100000
    DC.W     %0000001001000000
    DC.W     %0000000110000000
    DC.W     %0000000110000000
    DC.W     %0000001001000000
    DC.W     %0000010000100000
    DC.W     %0000100000010000
    DC.W     %0001000000001000
    DC.W     %0010000000000100
    DC.W     %0100000000000010
    DC.W     %0000000000000000

;a few of the different types of fills you can use - create your own.
FILL_1:      DC.W $FFFF,$FFFF,$FFFF,$FFFF
FILL_2:      DC.W $5555,$5555,$5555,$5555
FILL_3:      DC.W $8888,$8888,$8888,$8888
FILL_4:      DC.W $FFFF,$5555,$FFFF,$5555
FILL_5:      DC.W $FFFF,$8888,$FFFF,$8888
FILL_6:      DC.W $FFFF,$0000,$FFFF,$0000
FILL_7:      DC.W $5555,$8888,$5555,$8888
FILL_8:      DC.W $5555,$0000,$5555,$0000
FILL_9:      DC.W $AAAA,$5555,$AAAA,$5555
FILL_10:     DC.W $8888,$4444,$2222,$1111

BOXFILLS:    DC.L FILL_1,FILL_2,FILL_3,FILL_4,FILL_5
             DC.L FILL_6,FILL_7,FILL_8,FILL_9,FILL_10

TITLE:
; Format: X,Y,Font_Number,Enlarge?,Style,Color_Of_Text,Background_Color
;         Write_Mode,String+0
    DC.W     260,32,1,0,0,15,0,JUST_OR
    DC.B     "Disk Formatter",0
    ALIGN
CREDIT:
    DC.W     273,40,0,0,0,15,0,JUST_OR
    DC.B     "By Clark A. Hay",0
    ALIGN
SHOW_A:
    DC.W     272,48,1,0,0,15,0,JUST_OR
    DC.B     "A",0
    ALIGN
SHOW_DRV:
    DC.W     296,48,1,0,0,15,0,JUST_OR
    DC.B     "Drive",0
    ALIGN
SHOW_B:
    DC.W     352,48,1,0,0,15,0,JUST_OR
    DC.B     "B",0
    ALIGN
SHOW_1:
    DC.W     272,62,1,0,0,15,0,JUST_OR
    DC.B     "1",0
    ALIGN
SHOW_SID:
    DC.W     296,62,1,0,0,15,0,JUST_OR
    DC.B     "Sides",0
    ALIGN
SHOW_2:
    DC.W     352,62,1,0,0,15,0,JUST_OR
    DC.B     "2",0
    ALIGN
HOW_MANY:
    DC.W     256,73,1,0,0,15,0,JUST_OR
    DC.B     "How Many Tracks",0
    ALIGN
SHOW_80:
    DC.W     280,85,1,0,0,15,0,JUST_OR
    DC.B     "80",0
    ALIGN
SHOW_82:
    DC.W     336,85,1,0,0,15,0,JUST_OR
    DC.B     "82",0
    ALIGN
STATUS:
    DC.W     264,97,1,0,0,15,0,JUST_OR
    DC.B     "Format Status",0
    ALIGN
WAITING:
    DC.W     289,108,1,0,0,15,0,JUST_OR
    DC.B     "Waiting",0
    ALIGN
SHOW_FMT:
    DC.W     264,121,1,0,0,15,0,JUST_OR
    DC.B     "Format",0
    ALIGN
SHOW_EXT:
    DC.W     336,121,1,0,0,15,0,JUST_OR
    DC.B     "Exit",0
    ALIGN

WORKING:
    DC.W     289,108,1,0,0,15,0,REPLACE
    DC.B     "Working",0
    ALIGN
ANERROR:
    DC.W     297,108,1,0,0,15,0,JUST_OR
    DC.B     "ERROR",0
    ALIGN

THE_TEXT:
    DC.W     14 ;number of text items (- 1) to display
    DC.L     TITLE,CREDIT,SHOW_A,SHOW_DRV,SHOW_B,SHOW_1,SHOW_SID,SHOW_2
    DC.L     HOW_MANY,SHOW_80,SHOW_82,STATUS,WAITING,SHOW_FMT,SHOW_EXT


;Box Format: X1,Y1,X2,Y2,Fill_Color,Fill_Addr,Fill_Mode,Line_Color,
;            Line_Pattern,Line_Draw_Mode
BIG_BOX:
    DC.W     252,30,379,132,2
    DC.L     FILL_3
    DC.W     REPLACE,15,$FFFF,REPLACE
THE_A:
    DC.W     268,46,283,56,0
    DC.L     FILL_1
    DC.W     REPLACE,15,$FFFF,REPLACE
THE_B:
    DC.W     348,46,363,56,0
    DC.L     FILL_1
    DC.W     REPLACE,15,$FFFF,REPLACE
THE_1:
    DC.W     268,60,283,70,0
    DC.L     FILL_1
    DC.W     REPLACE,15,$FFFF,REPLACE
THE_2:
    DC.W     348,60,363,70,0
    DC.L     FILL_1
    DC.W     REPLACE,15,$FFFF,REPLACE
THE_80:
    DC.W     276,83,299,93,0
    DC.L     FILL_1
    DC.W     REPLACE,15,$FFFF,REPLACE
THE_82:
    DC.W     332,83,355,93,0
    DC.L     FILL_1
    DC.W     REPLACE,15,$FFFF,REPLACE
THE_STAT:
    DC.W     274,106,358,116,0
    DC.L     FILL_1
    DC.W     REPLACE,15,$FFFF,REPLACE
THE_FMT:
    DC.W     260,119,316,129,0
    DC.L     FILL_1
    DC.W     REPLACE,15,$FFFF,REPLACE
THE_EXIT:
    DC.W     332,119,372,129,0
    DC.L     FILL_1
    DC.W     REPLACE,15,$FFFF,REPLACE

STATCNST:
    DC.W     275,107,275,115
STATLINE:
    DC.W     275,107,275,115,0
    DC.L     FILL_1
    DC.W     REPLACE,1,$FFFF,MAKE_EOR

THEBOXES:
    DC.W     9  ;number of boxes/routines -1 for dbra
; addr of box_data & addr of routine to execute if mouse is in box
    DC.L     BIG_BOX,NOTHING
    DC.L     THE_A,SET_A
    DC.L     THE_B,SET_B
    DC.L     THE_1,SET_1
    DC.L     THE_2,SET_2
    DC.L     THE_80,SET_80
    DC.L     THE_82,SET_82
    DC.L     THE_STAT,NOTHING
    DC.L     THE_FMT,DOFORMAT
    DC.L     THE_EXIT,SET_EXIT
;---------------------------------------------------------------------
    BSS
             DS.L 300           ;big enough stack for most programs
PRGSTACK:    DS.L 1             ;our stack starts here and goes up
             DS.L 10            ;just in case we undershoot the stack

DRIVE:       DS.W 1             ;the designated drive to format
TRACKS:      DS.W 1             ;number of tracks user wants to do
SIDES:       DS.W 1             ;number of sides the user has
TRAK2DO:     DS.W 1             ;track number to format
SIDE2DO:     DS.W 1             ;side of disk to format
SEC2WRIT:    DS.W 1             ;number of sectors to write
EXITFLAG:    DS.W 1             ;no exit if exit = 0
ERROR:       DS.W 1             ;no errors if error = 0
CONTERM:     DS.W 1             ;holder for original conterm vlue

LN_AVARS:    DS.L 1             ;holder for Line_A variables addr
LN_AFONT:    DS.L 1             ;holder for system Font Addr table
TBLTBUFF:    DS.B $1200         ;buffer used by TextBlit special effects

BUFFER:      DS.B 10*1024       ;disk formatting buffer
    END

;that's all... Enjoy! - C.H.

