/*
 * floppy.h
 *
 * Copyright (C) 2016 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _FLOPPY_H_
#define _FLOPPY_H_

#include <common.h>
#include <device.h>

#define FLOPPY_SRA  0x3F0
#define FLOPPY_SRB  0x3F1
#define FLOPPY_DOR  0x3F2
#define FLOPPY_TDR  0x3F3
#define FLOPPY_MSR  0x3F4
#define FLOPPY_DSR  0x3F4
#define FLOPPY_FIFO 0x3F5
#define FLOPPY_DIR  0x3F7
#define FLOPPY_CCR  0x3F7

#define FLOPPY_CMD_SPECIFY     0x03
#define FLOPPY_CMD_WRITE       0x05
#define FLOPPY_CMD_READ        0x06
#define FLOPPY_CMD_RECALIBRATE 0x07
#define FLOPPY_CMD_SENSE_INT   0x08
#define FLOPPY_CMD_SEEK        0x0F
#define FLOPPY_CMD_VERSION     0x10
#define FLOPPY_CMD_CONFIGURE   0x13

#define FLOPPY_FLAG_MFM        0x40
#define FLOPPY_FLAG_MULTITRACK 0x80

#define FLOPPY_RW_INPUTS  9
#define FLOPPY_RW_OUTPUTS 7

#define CMOS_FLOPPY_REG 0x10

#define FLOPPY_IRQ 6
#define FLOPPY_DMA_CHANNEL 2
#define FLOPPY_ST0_SEEK_END (1 << 5)
#define FLOPPY_IO_TIMEOUT 1000
#define FLOPPY_SEEK_TIMEOUT 1000
#define FLOPPY_READ_TIMEOUT 10000
#define FLOPPY_FIRST_NAME "Floppy0"
#define FLOPPY_SECOND_NAME "Floppy1"
#define FLOPPY_TYPE_144MB 0x04

#define FLOPPY_DRIVES 2
#define FLOPPY_SECTOR_SIZE 512
#define FLOPPY_HEADS 2
#define FLOPPY_TRACKS 80
#define FLOPPY_SPT 18
#define FLOPPY_SECTORS (FLOPPY_HEADS * FLOPPY_TRACKS * FLOPPY_SPT)

#define FLOPPY_SRT 10
#define FLOPPY_HLT 5
#define FLOPPY_HUT 15

#define FLOPPY_LBA_TO_CHS(block) { .cylinder = (block) / (FLOPPY_SPT * FLOPPY_HEADS), \
                                   .head = ((block) / FLOPPY_SPT) % FLOPPY_HEADS, \
                                   .sector = 1 + ((block) % FLOPPY_SPT) }

enum
{
    FLOPPY_MOTOR_STOPPED,
    FLOPPY_MOTOR_STOPPING,
    FLOPPY_MOTOR_IDLE,
    FLOPPY_MOTOR_RUNNING
};

typedef struct
{
    byte_t cylinder;
    byte_t head;
    byte_t sector;
} floppy_chs_t;

dword_t floppy_driver_load(void);

#endif
