diff options
| -rw-r--r-- | DskImg.HC | 67 | ||||
| -rw-r--r-- | Floppy.HH | 98 | ||||
| -rw-r--r-- | KStart32.HC | 118 | ||||
| -rw-r--r-- | Kernel.PRJ | 63 | ||||
| -rw-r--r-- | KernelC.HH | 787 | ||||
| -rw-r--r-- | NewFloppy.HC | 477 | ||||
| -rw-r--r-- | ReadMe.TXT | 27 |
7 files changed, 1637 insertions, 0 deletions
diff --git a/DskImg.HC b/DskImg.HC new file mode 100644 index 0000000..077a986 --- /dev/null +++ b/DskImg.HC @@ -0,0 +1,67 @@ +#define CYLINDERS 80 +#define SECTORS 18 +#define BASE 0x03F0 +#define IMG_SIZE 1474560 + +/* + + Make sure IRQ6 is on and + pointed to the correct handler! + +*/ + +U8 DskImg() +{ + U64 i; + + // Open image file for writing + CFile *img = FOpen("Floppy.IMG","w",IMG_SIZE/BLK_SIZE); + + // Initialize the controller + FDCReset(BASE); + Sleep(100); + + /* + + Loop through each sector, + reading each into the buffer, + then writing it into the file + + */ + + for (i = 0; i < CYLINDERS; i++) { + "Track %d\n", i; + if (FDCSeek(BASE, i, 0)) { + FDCReset(BASE); + FClose(img); + return 1; + } + if (FDCSeek(BASE, i, 1)) { + FDCReset(BASE); + FClose(img); + return 1; + } + FDCReadMulti(BASE, i, 0, 1, 18); + FBlkWrite(img, &FDC_DMA, 36 * i, 36); + } + + // Return to track 0 + "Returning to track 0...\n"; + if (FDCSeek(BASE, 0, 0)) { + FDCReset(BASE); + FClose(img); + return 1; + } + if (FDCSeek(BASE, 0, 1)) { + FDCReset(BASE); + FClose(img); + return 1; + } + + // Close the image file + FClose(img); + + return 0; +} + +DskImg;
\ No newline at end of file diff --git a/Floppy.HH b/Floppy.HH new file mode 100644 index 0000000..4e5cfdb --- /dev/null +++ b/Floppy.HH @@ -0,0 +1,98 @@ +// FDC uses IRQ6 = int 26h +#define I_FDC 0x26 +#define IRQ_FDC 6 + +// FDC regs (primary ctrlr) +#define FDC_STAT_A 0x0 +#define FDC_STAT_B 0x1 +#define FDC_DOR 0x2 +#define FDC_TAPE 0x3 +#define FDC_MSR_DSR 0x4 +#define FDC_DATA 0x5 +#define FDC_CCR_DIR 0x7 + +// FDC cmds +#define FDC_READ_TRACK 0x02 +#define FDC_SPECIFY 0x03 +#define FDC_SENSE_STAT 0x04 +#define FDC_WRITE_DATA 0x05 +#define FDC_READ_DATA 0x06 +#define FDC_RECALIBRATE 0x07 +#define FDC_SENSE_INTR 0x08 +#define FDC_WRITE_DEL 0x09 +#define FDC_READ_ID 0x0A +#define FDC_READ_DEL 0x0C +#define FDC_FMT_TRACK 0x0D +#define FDC_DUMP_REG 0x0E +#define FDC_SEEK 0x0F +#define FDC_VERSION 0x10 +#define FDC_SCAN_EQL 0x11 +#define FDC_PERP_MODE 0x12 +#define FDC_CONFIGURE 0x13 +#define FDC_LOCK 0x14 +#define FDC_VERIFY 0x16 +#define FDC_SCAN_LO_EQL 0x19 +#define FDC_SCAN_HI_EQL 0x1D + +// Motor stuff +#define FDC_MOTOR_OFF 0 +#define FDC_MOTOR_ON 1 +#define FDC_MOTOR_WAIT 2 + +// Read/write directions +#define FDC_DIR_READ 0 +#define FDC_DIR_WRITE 1 + +// Digital Output Register (DOR) flags + +// DOR motor control flags: 1 = on, 0 = off +#define FDC_DOR_MOTD 0x80 // Drive D +#define FDC_DOR_MOTC 0x40 // Drive C +#define FDC_DOR_MOTB 0x20 // Drive B +#define FDC_DOR_MOTA 0x10 // Drive A + +// other DOR flags +#define FDC_DOR_DMA 0x08 // DMA2/IRQ6 On/Off +#define FDC_DOR_REST 0x04 // Controller Reset: this is active low; 1 = normal, 0 = reset + +// DOR drive select (DOR & 0x03): selects drive 0-3 + +// Main Status Register (MSR) flags +#define FDC_MSR_RQM 0x80 // Main Request: 1 = ready, 0 = not ready +#define FDC_MSR_DIO 0x40 // Data In/Out: 1 = FDC -> PC, 0 = PC -> FDC +#define FDC_MSR_NDMA 0x20 // Non-DMA: 1 = DMA off, 0 = DMA on +#define FDC_MSR_BUSY 0x10 // Device busy: self-explanatory + +// MSR drive seek flags: 1 = seeking, 0 = idle +#define FDC_MSR_ACTD 0x08 // Drive D +#define FDC_MSR_ACTC 0x04 // Drive C +#define FDC_MSR_ACTB 0x02 // Drive B +#define FDC_MSR_ACTA 0x01 // Drive A + +// Status Register 0 (ST0) flags + +/* ST0 interrupt code (ST0 & 0xC0): + 00 = normal termination + 01 = abnormal termination + 10 = invalid cmd + 11 = abnormal termination by poilling (drive became not ready) +*/ + +#define FDC_ST0_SEEK_END 0x20 // Seek End: seek/calibration completed +#define FDC_ST0_UNIT_CHK 0x10 // Unit Check: drive encountered a fault or recalibration failed +#define FDC_ST0_NOT_RDY 0x08 // Not Ready: self-explanatory +#define FDC_ST0_HEAD 0x04 // Active Head + +// ST0 unit select (ST0 & 0x03): same fmt as DOR drive select + +// Status Register 1 (ST1) flags +#define FDC_ST1_END_CYL 0x80 // End of Cylinder: set when sector count > sectors on track +// 0x40 is unused +#define FDC_ST1_DATA_ERR 0x20 // Data Error: set when an error is detected in a sector's data or ID fields +#define FDC_ST1_TIMEOUT 0x10 // Timeout: set when a data overrun occurs (i.e. the system is not reading data fast enough) +// 0x08 is unused +#define FDC_ST1_NO_DATA 0x04 // No Data: set when either a sector cannot be read, or an ID cannot be successfully read, or if the sector sequence cannot be determined +#define FDC_ST1_NO_WRITE 0x02 // Not Writable: set when attempting to write to a write-protected disk +#define FDC_ST1_NO_ID 0x01 // No Addr. Mark: set when an ID/(deleted) data address mark cannot be found. + +// Status Register 2 (ST2) flags
\ No newline at end of file diff --git a/KStart32.HC b/KStart32.HC new file mode 100644 index 0000000..ec8f67b --- /dev/null +++ b/KStart32.HC @@ -0,0 +1,118 @@ +asm { +USE32 +//************************************ +// ASM Global vars not required for 16-bit start-up + ALIGN 8,OC_NOP +MEM_HEAP_BASE:: DU64 0; +MEM_HEAP_LIMIT:: DU64 0; +MEM_PAGE_SIZE:: DU64 0; +MEM_MAPPED_SPACE:: DU64 0; +MEM_2MEG_NUM:: DU64 0; +MEM_1GIG_NUM:: DU64 0; +MEM_512GIG_NUM:: DU64 0; +MEM_PML2:: DU64 0; +MEM_PML3:: DU64 0; +MEM_PML4:: DU64 0; + +#exe { + StreamPrint( +"SYS_MEM_INIT_FLAG:: DU8 %d;" +"SYS_MEM_INIT_VAL:: DU8 %d;" +"SYS_HEAP_INIT_FLAG:: DU8 %d;" +"SYS_HEAP_INIT_VAL:: DU8 %d;" +"SYS_VAR_INIT_FLAG:: DU8 %d;" +"SYS_VAR_INIT_VAL:: DU8 %d;" +"SYS_STAFF_MODE_FLAG:: DU8 %d;", +kernel_cfg->opts[CFG_MEM_INIT], kernel_cfg->mem_init_val, +kernel_cfg->opts[CFG_HEAP_INIT],kernel_cfg->heap_init_val, +kernel_cfg->opts[CFG_VAR_INIT], kernel_cfg->var_init_val, +kernel_cfg->opts[CFG_STAFF_MODE]); +}; +SYS_HEAP_DBG_FLAG:: DU8 _CFG_HEAP_DBG; + + ALIGN 8,0 +SYS_CTRL_ALT_FLAGS:: DU64 0; +SYS_EXTERN_TABLE:: DU64 0; + +SYS_CODE_BP:: DU64 0; +SYS_DATA_BP:: DU64 0; + +SYS_PROGRESSES:: +SYS_PROGRESS1:: DU64 0; +SYS_PROGRESS1_MAX:: DU64 0; +SYS_PROGRESS1_T0:: DU64 0; +SYS_PROGRESS1_TF:: DU64 0; +SYS_PROGRESS1_DESC:: DU8 PROGRESS_DESC_LEN DUP(0); +SYS_PROGRESS2:: DU64 0; +SYS_PROGRESS2_MAX:: DU64 0; +SYS_PROGRESS2_T0:: DU64 0; +SYS_PROGRESS2_TF:: DU64 0; +SYS_PROGRESS2_DESC:: DU8 PROGRESS_DESC_LEN DUP(0); +SYS_PROGRESS3:: DU64 0; +SYS_PROGRESS3_MAX:: DU64 0; +SYS_PROGRESS3_T0:: DU64 0; +SYS_PROGRESS3_TF:: DU64 0; +SYS_PROGRESS3_DESC:: DU8 PROGRESS_DESC_LEN DUP(0); +SYS_PROGRESS4:: DU64 0; +SYS_PROGRESS4_MAX:: DU64 0; +SYS_PROGRESS4_T0:: DU64 0; +SYS_PROGRESS4_TF:: DU64 0; +SYS_PROGRESS4_DESC:: DU8 PROGRESS_DESC_LEN DUP(0); +#assert $$-SYS_PROGRESSES==sizeof(CProgress)*4 + +SYS_FOCUS_TASK:: DU64 0; +SYS_CPU_STRUCTS:: DU64 0; +SYS_MP_CNT:: DU64 1; +SYS_MP_CNT_INITIAL:: DU64 1; +SYS_MP_CNT_LOCK:: DU64 1; + + ALIGN DFT_CACHE_LINE_WIDTH,OC_NOP +SYS_CACHE_LINE_WIDTH:: DU64 DFT_CACHE_LINE_WIDTH; + DU8 DFT_CACHE_LINE_WIDTH-sizeof(CBinFile)-8 DUP(0); +SYS_SEMAS:: DU8 SEMA_SEMAS_NUM*DFT_CACHE_LINE_WIDTH DUP(0); +//************************************ + ALIGN 16,OC_NOP +CORE0_32BIT_INIT:: //Entry point for $LK,"BootRAM",A="MN:BootRAM"$. + PUSH U32 RFLAGG_START + POPFD + MOV EAX,SYS_START_CR0 + MOV_CR0_EAX + + MOV AX,CGDT.boot_ds //LOAD DS SELECTOR + MOV DS,AX + BTS U32 [SYS_RUN_LEVEL],RLf_32BIT + MOV ESI,U32 [SYS_BOOT_PATCH_TABLE_BASE] + MOV EDI,U32 [MEM_BOOT_BASE] + + MOV AX,CGDT.ds + MOV DS,AX + MOV ES,AX + MOV FS,AX + MOV GS,AX + MOV SS,AX + MOV ESP,BOOT_RAM_LIMIT //Tmp Stk + +//Patch abs addresses + MOV ECX,U32 CPatchTableAbsAddr.abs_addres_cnt[ESI] + LEA ESI,U32 CPatchTableAbsAddr.abs_addres[ESI] +@@05: LODSD + ADD EAX,EDI + ADD U32 [EAX],EDI + LOOP @@05 + + DU8 0xEA; //JMP CGDT.cs32:@@10 + DU32 @@10; + DU16 CGDT.cs32; + +@@10: BTS U32 [SYS_RUN_LEVEL],RLf_PATCHED + + CALL SYS_FIND_PCIBIOS_SERVICE_DIR + CALL SYS_FIND_PCI_SERVICES + CALL SYS_INIT_PAGE_TABLES + CALL SYS_INIT_16MEG_SYS_CODE_BP + PUSH U32 0 //Return from next call will be 64-bit + CALL SYS_ENTER_LONG_MODE + + //We fall-thou to $LK,"KStart64",A="FL:::/Kernel/KStart64.HC,1"$, next. +} +U8 FDC_DMA[0x4800]; // Floppy DMA buffer
\ No newline at end of file diff --git a/Kernel.PRJ b/Kernel.PRJ new file mode 100644 index 0000000..158b096 --- /dev/null +++ b/Kernel.PRJ @@ -0,0 +1,63 @@ +//Compile this by calling $LK,"BootHDIns",A="MN:BootHDIns"$(). +//Don't do it directly. See $LK,"Cmp(\"/Kernel/Kernel\")",A="FF:::/Adam/Opt/Boot/BootHDIns.HC,Cmp(\"/Kernel/Kernel\""$. + +#exe { + Cd(__DIR__);; + Option(OPTf_WARN_PAREN,ON); + Option(OPTf_WARN_DUP_TYPES,ON); + #include "KCfg" + CKCfg *kernel_cfg; + kernel_cfg=KCfgNew; +}; + +#include "KernelA.HH" +#include "KStart16" +#include "KStart32" +#include "KStart64" +#include "KMathA" +#include "KUtils" +#exe {Option(OPTf_KEEP_PRIVATE,ON);}; +#include "/Compiler/CompilerA.HH" +#exe {Option(OPTf_EXTERNS_TO_IMPORTS,ON);}; +#include "/Compiler/CompilerB.HH" +#exe {Option(OPTf_EXTERNS_TO_IMPORTS,OFF);}; +#exe {Option(OPTf_KEEP_PRIVATE,OFF);}; +#include "KernelB.HH" +#include "KExts" +#include "StrA" +#include "KGlbls" +#include "KMathB" +#include "Sched" +#include "Mem/MakeMem" +#include "FontStd" +#include "FontCyrillic" +#include "StrB" +#include "KHashA" +#include "KInts" +#include "KDataTypes" +#include "Compress" +#include "KHashB" +#include "KLoad" +#include "KDate" +#include "StrPrint" +#include "StrScan" +#include "KDefine" +#include "Display" +#include "KMisc" +#include "KDbg" +#include "KeyDev" +#include "KExcept" +#include "SerialDev/MakeSerialDev" +#include "QSort" +#include "KTask" +#include "Job" +#include "PCIBIOS" +#include "MultiProc" +#include "EdLite" +#include "BlkDev/MakeBlkDev" +#include "FunSeg" +#include "KMain" +#include "Floppy.HH" +#include "NewFloppy" + +#exe {KCfgDel(kernel_cfg);}; diff --git a/KernelC.HH b/KernelC.HH new file mode 100644 index 0000000..ffa7c8b --- /dev/null +++ b/KernelC.HH @@ -0,0 +1,787 @@ +#help_index "AutoComplete" +#help_file "::/Doc/AutoComplete" +public extern CAutoCompleteGlbls ac; + +#help_index "AutoComplete/Dictionary" +public extern CAutoCompleteDictGlbls acd; + +#help_index "Bit" +public extern I64 BCnt(I64 d); +public extern U8 *rev_bits_table,*set_bits_table; + +#help_index "Boot" +#help_file "::/Doc/Boot" +public extern U0 Reboot(); + +#help_index "Call" +public argpop extern I64 CallStkGrow(I64 stk_size_threshold,I64 stk_size, + /*argpop*/I64 (*fp_addr)(...),...); +//fp_addr can have any fixed number of arguments. + +#help_index "Call/FarCall32" +public _extern _FAR_CALL32 Bool FarCall32(U0 (*fp_addr)());//Not reentrant +public _extern C32_EAX U32 c32_eax; +public _extern C32_EBX U32 c32_ebx; +public _extern C32_ECX U32 c32_ecx; +public _extern C32_EDI U32 c32_edi; +public _extern C32_EDX U32 c32_edx; +public _extern C32_EFLAGS U32 c32_eflags; +public _extern C32_ESI U32 c32_esi; + +#help_index "Char/BitMaps" +public extern U32 char_bmp_alpha[16],char_bmp_alpha_numeric[16], +char_bmp_alpha_numeric_no_at[16], char_bmp_word[16], +char_bmp_dec_numeric[16], char_bmp_hex_numeric[16], +char_bmp_white_space[16], char_bmp_non_eol_white_space[16], +char_bmp_zero_cr_nl_cursor[16], char_bmp_zero_tab_cr_nl_cursor[16], +char_bmp_zero_tab_cr_nl_cursor_dollar[16], +char_bmp_macro[16], char_bmp_printable[16], +char_bmp_displayable[16], char_bmp_safe_dollar[16], +char_bmp_filename[16], char_bmp_non_eol[16]; + +#help_index "Char/Conversion" +public extern U8 *Char2KeyName(I64 ch,Bool include_ctrl=TRUE); +public extern I64 Char2ScanCode(I64 ch,I64 sc_flags=0); +public extern U8 ScanCode2Char(I64 sc); +public extern U8 *ScanCode2KeyName(I64 sc); +public extern F64 Str2F64(U8 *src,U8 **_end_ptr=NULL); +public extern I64 Str2I64(U8 *st,I64 radix=10,U8 **_end_ptr=NULL); +public extern U8 *StrScan(U8 *src,U8 *fmt,...); + +#help_index "Char/Conversion;Time/Date/CDate;Date/CDate" +public extern CDate Str2Date(U8 *src); + +#help_index "Char/Flags" +public extern U0 ScanFlags(U8 *_dst_flags,U8 *lst,U8 *src); +public extern U8 *StrPrintFlags(U8 *dst,U8 *lst,I64 flags); + +#help_index "Char/Lists" +public extern I64 LstMatch(U8 *needle, U8 *haystack_lst,I64 flags=0); +public extern U8 *LstSub(I64 sub, U8 *lst); + +#help_index "Char/Operations" +public extern U8 *MStrPrint(U8 *fmt,...); +public extern U8 *MStrUtil(U8 *src,I64 flags,F64 indent_scale_factor=0); +public extern U8 *ScaleIndent(U8 *src,F64 indent_scale_factor); +public extern I64 Spaces2Tabs(U8 *dst,U8 *src); +public _extern _STRCMP I64 StrCmp(U8 *st1,U8 *st2); +public _extern _STRCPY U0 StrCpy(U8 *dst,U8 *src); +public extern U8 *StrFind(U8 *needle,U8 *haystack_str,I64 flags=0); +public extern U8 *StrFirstOcc(U8 *src,U8 *marker); +public extern U8 *StrFirstRem(U8 *src,U8 *marker,U8 *dst=NULL); +public _extern _STRICMP I64 StrICmp(U8 *st1,U8 *st2); +public _extern _STRIMATCH U8 *StrIMatch(U8 *needle,U8 *haystack_str); +public extern U8 *StrLastOcc(U8 *src,U8 *marker); +public extern U8 *StrLastRem(U8 *src,U8 *marker,U8 *dst=NULL); +public _extern _STRMATCH U8 *StrMatch(U8 *needle,U8 *haystack_str); +public _extern _STRNCMP I64 StrNCmp(U8 *st1,U8 *st2,I64 n); +public _extern _STRNICMP I64 StrNICmp(U8 *st1,U8 *st2,I64 n); +public extern I64 StrOcc(U8 *src, U8 ch); +public extern U8 *StrPrint(U8 *dst,U8 *fmt,...); +public extern U8 *StrPrintJoin(U8 *dst,U8 *fmt,I64 argc,I64 *argv); +public extern U8 *StrUtil(U8 *_src,I64 flags); +public extern U8 *Tabs2Spaces(U8 *src); +public extern Bool WildMatch(U8 *test_str,U8 *wild_str); + +#help_index "Char/Operations;Memory" +public extern U8 *CatPrint(U8 *dst,U8 *fmt,...); + +#help_index "Char/Operations;Memory/Adam Heap" +public extern U8 *AStrNew(U8 *buf); + +#help_index "Char/Operations;Memory/Heap" +public extern U8 *StrNew(U8 *buf,CTask *mem_task=NULL); + +#help_index "Char/Output;StdOut" +public extern U0 GetOutOfDollar(); +public extern Bool IsSilent(); +public extern U0 Print(U8 *fmt,...); +public extern U0 PrintErr(U8 *fmt,...); +public extern U0 PrintWarn(U8 *fmt,...); +public extern U0 PutChars(U64 ch); +extern U0 PutHex(I64 num,I64 width); +public extern U0 PutKey(I64 ch=0,I64 sc=0); +extern U0 PutS(U8 *st); //Use $LK,"Print",A="MN:Print"$() +public extern Bool Silent(Bool val=ON); +extern U8 *StrPrintHex(U8 *dst,I64 num;I64 width); + +#help_index "Char;Debugging/Raw Output;TextBase Layer/Char" +public extern CTextGlbls text; + +#help_index "Compiler/Lex" +public extern U0 HashSrcFileSet(CCmpCtrl *cc, + CHashSrcSym *h,I64 line_num_offset=0); + +#help_index "Compiler;Cmd Line (Typically)" +extern U8 *Load(U8 *filename,I64 ld_flags=0, + CBinFile *bfh_addr=INVALID_PTR); //INVALID_PTR=don't care what load addr + +#help_index "Compression" +public extern CArcCompress *CompressBuf(U8 *src,I64 size,CTask *mem_task=NULL); +public extern U8 *ExpandBuf(CArcCompress *arc,CTask *mem_task=NULL); + +#help_index "Compression/Piece by Piece" +public extern U0 ArcCompressBuf(CArcCtrl *c); +public extern U0 ArcCtrlDel(CArcCtrl *c); +public extern CArcCtrl *ArcCtrlNew(Bool expand,I64 compression_type=CT_8_BIT); +public extern U0 ArcExpandBuf(CArcCtrl *c); +public extern Bool ArcFinishCompression(CArcCtrl *c); + +#help_index "Data Types/Circular Queue" +public extern I64 QueCnt(CQue *head); +public extern CQue *QueCopy(CQue *head,CTask *mem_task=NULL); +public extern U0 QueDel(CQue *head,Bool querem=FALSE); +public extern I64 QueSize(CQue *head); + +#help_index "Data Types/Fifo" +public extern I64 FifoI64Cnt(CFifoI64 *f); +public extern U0 FifoI64Del(CFifoI64 *f); +public extern U0 FifoI64Flush(CFifoI64 *f); +public extern Bool FifoI64Ins(CFifoI64 *f,I64 q); +public extern CFifoI64 *FifoI64New(I64 size,CTask *mem_task=NULL); +public extern Bool FifoI64Peek(CFifoI64 *f,I64 *_q); +public extern Bool FifoI64Rem(CFifoI64 *f,I64 *_q); +public extern I64 FifoU8Cnt(CFifoU8 *f); +public extern U0 FifoU8Del(CFifoU8 *f); +public extern U0 FifoU8Flush(CFifoU8 *f); +public extern Bool FifoU8Ins(CFifoU8 *f,U8 b); +public extern CFifoU8 *FifoU8New(I64 size,CTask *mem_task=NULL); +public extern Bool FifoU8Peek(CFifoU8 *f,U8 *_b); +public extern Bool FifoU8Rem(CFifoU8 *f,U8 *_b); + +#help_index "Data Types/Linked List" +public extern I64 LinkedLstCnt(U8 **_lst); +public extern U8 *LinkedLstCopy(U8 **_lst,CTask *mem_task=NULL); +public extern U0 LinkedLstDel(U8 **_lst); +public extern I64 LinkedLstSize(U8 **_lst); + +#help_index "Data Types/Queue Vector" +public extern U0 QueVectU8Del(CQueVectU8 *v); +public extern I64 QueVectU8Get(CQueVectU8 *v,I64 idx); +public extern CQueVectU8 *QueVectU8New(I64 min_idx=0); +public extern U0 QueVectU8Put(CQueVectU8 *v,I64 idx,U8 ch); + +#help_index "Debugging" +public extern U8 *Caller(I64 num=1); +public extern Bool ChkCodePtr(U8 *ptr); +public extern Bool ChkOnStk(U8 *ptr,CTask *task=NULL); +public extern Bool ChkPtr(U8 *ptr); +public extern Bool IsSingleUser(); +public extern Bool IsSysDbg(); +public extern Bool SingleUser(Bool val); +public extern Bool SysDbg(Bool val); +public extern U8 *TaskCaller(CTask *task=NULL, + I64 num=0,Bool saved_context=FALSE); +public extern I64 UnusedStk(CTask *task=NULL); +public extern CDbgGlbls dbg; + +#help_index "Debugging/Debugger" +public extern Bool B(U8 *addr,CTask *task=NULL,Bool live=TRUE) //Toggle bpt. +public extern I64 B2(CTask *task=NULL,Bool live=TRUE); +extern CBpt *BptFind(U8 *needle_addr,CTask *haystack_task=NULL,Bool rem=FALSE); +public extern Bool BptR(U8 *addr,CTask *task=NULL,Bool live=TRUE,Bool rem=TRUE); +public extern Bool BptS(U8 *addr,CTask *task=NULL,Bool live=TRUE); +public extern Bool DbgMode(Bool val); +public extern Bool E(U8 *addr,I64 cnt=512,I64 edf_dof_flags=0); +public extern Bool EdLite(U8 *filename,I64 num=1,I64 edf_dof_flags=0); +extern Bool EdLiteFileLine(U8 *fl_file_line,I64 edf_dof_flags=0); +public extern Bool Fix(I64 edf_dof_flags=0); +public extern U0 FixSet(U8 *filename,I64 line); +public extern U0 G(U8 *ms=INVALID_PTR,CTask *task=NULL); +public extern U0 G2(U8 *ms=INVALID_PTR,CTask *task=NULL); +public extern Bool IsDbgMode(); +public extern U0 S(U8 *ms=INVALID_PTR,CTask *task=NULL); + +#help_index "Debugging/Debugger;DolDoc/Cmd Line (Typically);"\ + "Cmd Line (Typically);Help System" +public extern Bool Man(U8 *st,I64 edf_dof_flags=0); + +#help_index "Debugging/Dump" +public extern U0 CallerRep(U8 **rbp=NULL,CTask *task=NULL); +public extern U0 D(U8 *addr,I64 cnt=0x80,Bool show_offset=TRUE); +public extern U0 Da(U8 **addr,I64 cnt=0x10); +public extern U0 Dm(U8 *addr,I64 cnt=0x80); +public extern U0 Dr(CTask *task=NULL); +public extern U0 StkRep(CTask *task=NULL); +extern I64 *TaskRegAddr(CTask *task,I64 reg_num); + +#help_index "Debugging/FunSeg" +#help_file "::/Doc/DbgFunSeg" +public extern Bool PutSrcLink(U8 *addr,I64 cnt=1,U8 *buf=NULL); +public extern U8 *SrcEdLink(U8 *addr,I64 cnt=1,CTask *mem_task=NULL); +public extern U8 *SrcFileName(U8 *addr,I64 cnt=1,CTask *mem_task=NULL); +public extern I64 SrcLineNum(U8 *addr,I64 cnt=1); + +#help_index "Debugging/FunSeg;Hash/System" +public extern CHash *FunSegFind(U8 *addr,I64 *_offset); + +#help_index "Debugging/Raw Output" +public extern Bool IsRaw(); +public extern Bool Raw(Bool val); +public extern U0 RawD(I64 mS=100,U8 *addr,I64 cnt=0x80); +public extern U0 RawDm(I64 mS=100,U8 *addr,I64 cnt=0x80); +extern U0 RawDr(CTask *task=NULL); +public extern U0 RawPrint(I64 mS=100,U8 *fmt,...); +public extern U0 RawPutChar(I64 ch); +public extern U0 VGAFlush(); + +#help_index "Debugging;Debugging/Debugger" +public extern U0 Dbg(U8 *msg=NULL,I64 msg_num=0); +public extern U0 Panic(U8 *msg=NULL,I64 msg_num=0,Bool panic=TRUE); + +#help_index "Define;Char/Define" +#help_file "::/Doc/Define" +public extern U8 *Define(U8 *dname); +public extern CHashDefineStr *DefineLoad(U8 *dname,U8 *st); +public extern U0 DefinePrint(U8 *dname,U8 *src,...); + +#help_index "Define;Char/Define;Char/Lists" +public extern I64 DefineCnt(U8 *dname); +public extern CHashDefineStr *DefineLstLoad(U8 *dname,U8 *lst); +public extern I64 DefineMatch(U8 *needle,U8 *haystack_lst_dname,I64 flags=0); +public extern U8 *DefineSub(I64 sub,U8 *dname); + +#help_index "Devices;Memory/Page Tables" +public extern U8 *Mem32DevAlloc(I64 size,I64 alignment); +public extern U0 Mem32DevFree(U8 *base); +public extern U8 *Mem64DevAlloc(I64 *_pages1Gig); +public extern U0 Mem64DevFree(U8 *base,I64 pages1Gig); +public extern CDevGlbls dev; + +#help_index "DolDoc/Clip" +public extern CDoc *sys_clip_doc; + +#help_index "DolDoc/Task;StdOut/Task" +#help_file "::/Doc/StdOutTask" +extern CDoc *(*fp_doc_put)(CTask *task=NULL); + +#help_index "Exceptions" +public extern U0 Break(); +public extern Bool BreakLock(CTask *task=NULL); +public extern Bool BreakUnlock(CTask *task=NULL); +public extern U0 PutExcept(Bool catch_it=TRUE); +extern U0 SysTry(U8 *start_label,U8 *skip_label); +extern U0 SysUntry(); +public extern U0 throw(I64 ch=0,Bool no_log=FALSE); + +#help_index "File/CD DVD" +public extern U0 DVDImageRead(U8 dvd_drv_let,U8 *out_name); +public extern U0 DVDImageWrite(U8 dvd_drv_let, + U8 *in_name=NULL,I64 media_type=MT_DVD); + +#help_index "File/CFile" +public extern Bool FBlkRead(CFile *f,U8 *buf,I64 blk=FFB_NEXT_BLK,I64 cnt=1); +public extern Bool FBlkWrite(CFile *f,U8 *buf,I64 blk=FFB_NEXT_BLK,I64 cnt=1); +public extern U0 FClose(CFile *f); +public extern CFile *FOpen(U8 *filename,U8 *flags,I64 cnt=0); +public extern I64 FSize(CFile *f); + +#help_index "File/Cmd Line (Typically);Cmd Line (Typically)" +public extern Bool Cd(U8 *dirname=NULL,Bool make_dirs=FALSE); +public extern I64 Del(U8 *files_find_mask,Bool make_mask=FALSE, + Bool del_dir=FALSE,Bool print_msg=TRUE); +public extern I64 Dir(U8 *files_find_mask="*",Bool full=FALSE); +public extern Bool DirMk(U8 *filename,I64 entry_cnt=0); +public extern Bool Drv(U8 drv_let); +public extern U0 DskChg(U8 drv_let=0); +public extern U0 HomeSet(U8 *dirname); + +#help_index "File/Cmd Line (Typically);Cmd Line (Typically);Install" +public extern Bool DrvMap(U8 drv_let,CDrv *dv); + +#help_index "File/FileNames" +extern CDirEntry *Cd2DirEntry(CDirEntry *tmpde,U8 *abs_name); +public extern U8 *DirCur(CTask *task=NULL,CTask *mem_task=NULL); +public extern U8 *DirFile(U8 *dirname,U8 *name=NULL,U8 *_extension=NULL); +public extern U8 *DirNameAbs(U8 *dirname); +public extern CBlkDev *DrvIsWritable(U8 drv_let=0,Bool except=FALSE); +public extern U8 *ExtChg(U8 *filename,U8 *extension); +public extern U8 *ExtDft(U8 *filename,U8 *extension); +public extern U8 *FileExtDot(U8 *src); +public extern U8 *FileExtRem(U8 *src,U8 *dst=NULL); +public extern U8 *FileNameAbs(U8 *filename,I64 fuf_flags=0); +public extern Bool FileNameChk(U8 *filename); +public extern Bool FilesFindMatch(U8 *_test_name, + U8 *files_find_mask,I64 fuf_flags=0); +public extern Bool IsDir(U8 *dir_name); +public extern Bool IsDotC(U8 *filename); +public extern Bool IsDotZ(U8 *filename); +public extern U0 PutDirLink(U8 *dirname,U8 *full_name=NULL); +public extern U0 PutFileLink(U8 *filename,U8 *full_name=NULL, + I64 line=0,Bool plain_text=FALSE); +public extern U0 ToFileLine(U8 *_fl_file_line,U8 **_filename,I64 *_linenum); +public extern U8 *ToggleZorNotZ(U8 *name); + +#help_index "File/FileNames;Misc" +public extern U8 *FileNameTmpTxt(); + +#help_index "File/Internal" +public extern U0 DirContextDel(CDirContext *dirc,Bool restore=TRUE); +public extern CDirContext *DirContextNew(U8 *mask, + Bool make_mask=FALSE,Bool make_dirs=FALSE,Bool no_mask=FALSE); +public extern Bool DirNew(CDrv *dv,U8 *cur_dir, + CDirEntry *tmpde,Bool free_old_chain=TRUE); +extern I64 FileAttr(U8 *name,I64 old_attr=0); + +#help_index "File/Low Level" +#help_file "::/Doc/FileLowLevel" +public extern CBlkDev *BlkDevChk(CBlkDev *bd,Bool except=TRUE); +public extern U0 BlkDevDel(CBlkDev *bd); +public extern Bool BlkDevLock(CBlkDev *bd); +public extern CBlkDev *BlkDevNextFreeSlot(U8 first_drv_let,I64 type); +public extern Bool BlkDevUnlock(CBlkDev *bd,Bool rst=FALSE); +public extern U0 BlkDevsRelease(); +public extern Bool BlkRead(CDrv *dv,U8 *buf, I64 blk, I64 cnt); +public extern Bool BlkWrite(CDrv *dv,U8 *buf, I64 blk, I64 cnt); +public extern U0 BlkWriteZero(CDrv *dv,I64 blk,I64 cnt); +public extern I64 Clus2Blk(CDrv *dv,I64 c); +public extern I64 ClusAlloc(CDrv *dv,I64 c=0, + I64 cnt=1,Bool contiguous=FALSE); +public extern I64 ClusBlkRead(CDrv *dv,U8 *buf,I64 c,I64 blks); +public extern I64 ClusBlkWrite(CDrv *dv,U8 *buf,I64 c,I64 blks); +public extern I64 ClusNumNext(CDrv *dv,I64 c,I64 cnt=1); +public extern I64 ClusRead(CDrv *dv,U8 *buf,I64 c,I64 cnt); +public extern I64 ClusWrite(CDrv *dv,U8 *buf,I64 c,I64 cnt); +extern Bool CopySingle(U8 *f1,U8 *f2); //Just one file +public extern U8 Drv2Let(CDrv *dv=NULL); +public extern CDrv *DrvChk(CDrv *dv,Bool except=TRUE); +public extern U0 DrvDel(CDrv *dv); +public extern Bool DrvLock(CDrv *dv); +public extern CDrv *DrvMakeFreeSlot(U8 drv_let); +public extern U8 *DrvModelNum(U8 drv_let=0); +public extern U8 DrvNextFreeLet(U8 first_drv_let='C'); +public extern U8 *DrvSerialNum(U8 drv_let=0); +public extern U8 DrvTextAttrGet(U8 drv_let=0); +public extern Bool DrvUnlock(CDrv *dv,Bool rst=FALSE); +public extern U0 DrvsRelease(); +extern U0 FAT32FreeClus(CDrv *dv,I64 c); +public extern CBlkDev *Let2BlkDev(U8 drv_let=0,Bool except=TRUE); +public extern I64 Let2BlkDevType(U8 drv_let); +public extern CDrv *Let2Drv(U8 drv_let=0,Bool except=TRUE); +public extern U8 Let2Let(U8 drv_let=0); +extern I64 Name2DirClus(CDrv *dv,U8 *dirname); +extern I64 Name2ParentDirClus(CDrv *dv,U8 *dirname); +extern U0 RedSeaFreeClus(CDrv *dv,I64 c,I64 cnt); + +#help_index "File/Program Routines" +public extern U0 DirEntryDel(CDirEntry *tmpde); +public extern U0 DirEntryDel2(CDirEntry *tmpde); +public extern U0 DirTreeDel(CDirEntry *tmpde); +public extern U0 DirTreeDel2(CDirEntry *tmpde); +public extern Bool FileFind(U8 *filename,CDirEntry *_de=NULL,I64 fuf_flags=0); +public extern U8 *FileRead(U8 *filename,I64 *_size=NULL,I64 *_attr=NULL); +public extern I64 FileWrite(U8 *filename, + U8 *fbuf,I64 size,CDate cdt=0,I64 attr=0); + +#help_index "File/Program Routines;File/FileNames" +public extern CDirEntry *FilesFind(U8 *files_find_mask,I64 fuf_flags=0); + +#help_index "File/System" +public extern CATARep *ATAIDDrvs(CATARep *head,CATARep **_ata_drv, + CATARep **_atapi_drv); +extern CBlkDev *ATAMount(U8 first_drv_let, + I64 type,I64 base0,I64 base1,I64 unit); +extern Bool ATAPIStartStop(CBlkDev *bd,F64 timeout,Bool start); +extern I64 ATAProbe(I64 base0,I64 base1,I64 unit); +extern U0 ATAReadBlks(CBlkDev *bd,U8 *buf, I64 blk, I64 cnt); +extern U0 ATAWriteBlks(CBlkDev *bd,U8 *buf, I64 blk, I64 cnt); +extern I64 BlkDevAdd(CBlkDev *bd,I64 prt_num=I64_MIN, + Bool whole_drv,Bool make_free); +extern U0 DskCacheInit(I64 size_in_U8s); +public extern U0 DskCacheInvalidate(CDrv *dv); +public extern I64 MountIDEAuto(); +public extern CBlkDevGlbls blkdev; + +#help_index "Graphics/Color" +extern U0 (*fp_set_std_palette)(); +public extern U8 *Color2Str(U8 *buf,CColorROPU32 c); +public extern CColorROPU16 Str2ColorU16(U8 *st); +public extern CColorROPU32 Str2ColorU32(U8 *st); + +#help_index "Hash" +#help_file "::/Doc/Hash" +public _extern _HASH_ADD U0 HashAdd(CHash *tmph,CHashTable *table); +public _extern _HASH_ADD_AFTER U0 HashAddAfter(CHash *tmph, + CHash *pred,CHashTable *table); //Add hash entry after entry. +public _extern _HASH_BUCKET_FIND CHash **HashBucketFind( + U8 *needle_str,CHashTable *haystack_table); +public _extern _HASH_FIND CHash *HashFind(U8 *needle_str, + CHashTable *haystack_table,I64 mask,I64 instance=1); +public _extern _HASH_SINGLE_TABLE_FIND CHash *HashSingleTableFind( + U8 *needle_str,CHashTable *haystack_table,I64 mask,I64 instance=1); +public _extern _HASH_STR I64 HashStr(U8 *st); +public extern CHashTable *HashTableNew(I64 size,CTask *mem_task=NULL); + +#help_index "Hash/Frame" +#help_file "::/Doc/Frame" +public extern I64 FramePtr(U8 *name,CTask *task=NULL); +public extern CHashGeneric *FramePtrAdd(U8 *name,I64 val=0,CTask *task=NULL); +public extern I64 FramePtrDel(U8 *name,CTask *task=NULL); +public extern I64 FramePtrSet(U8 *name,I64 val,CTask *task=NULL); + +#help_index "Hash/System" +public extern U0 HashDel(CHashSrcSym *tmph); +public extern CHashGeneric *HashGenericAdd(U8 *name, + I64 type,I64 val=0,I64 u8=0,I64 u16=0,CTask *task=NULL); +public extern CHashGeneric *HashPublic(U8 *st,I64 mask,Bool val=TRUE); +public _extern _HASH_REM_DEL Bool HashRemDel(CHash *tmph,CHashTable *table, + I64 instance=1);//instance must match tmph's +public extern U0 HashTableDel(CHashTable *table); +public extern I64 HashTablePurge(CHashTable *table); +public extern I64 HashTypeNum(CHash *tmph); +public extern I64 HashVal(CHash *tmph); +extern U0 SysSymImportsResolve(U8 *sptr,I64 ld_flags=0); + +#help_index "Hash/System;Char/Lists" +public extern I64 HashLstAdd(U8 *lst,I64 type,CHashTable *table); + +#help_index "Hash/System;Define;Char/Define;Char/Lists" +public extern I64 HashDefineLstAdd(U8 *dname,I64 type,CHashTable *table); + +#help_index "Help System;Debugging/Debugger" +public extern U0 Help(); + +#help_index "Info;File/Cmd Line (Typically);Cmd Line (Typically);Install" +public extern U0 DrvRep(); + +#help_index "Install" +#help_file "::/Doc/Install" +extern CATARep *ATARepFind(CATARep *haystack_head,I64 needle_num); +public extern Bool DrvEnable(U8 drv_let,Bool val); + +#help_index "Install;File/Cmd Line (Typically);Cmd Line (Typically);" +public extern U0 Fmt(U8 drv_let,Bool quick=TRUE, + Bool confirm=TRUE,I64 type=FSt_FAT32); + +#help_index "Install;Memory/BlkPool" +public extern I64 Scale2Mem(I64 min,I64 max,I64 limit=2*1024*1024*1024); + +#help_index "Job/Exe;Task/Job/Exe" +public extern U0 AdamErr(U8 *fmt,...); +public extern U0 AdamLog(U8 *fmt,...); +public extern I64 ExeCmdLine(CCmpCtrl *cc); +public extern U0 JobDel(CJob *tmpc); +public extern I64 JobsHndlr(I64 run_flags,CTask *task=NULL); +extern U0 SrvCmdLine(); +public extern U0 SrvTaskCont(); +public extern CJob *TaskExe(CTask *srv,CTask *master,U8 *data,I64 flags); +public extern U0 TaskRstAwaitingMsg(CTask *task=NULL); +public extern U0 UserTaskCont(); + +#help_index "Job/Exe;Task/Job/Exe;Compiler" +public extern I64 Adam(U8 *fmt,...); +public extern I64 PopUp(U8 *buf,CTask *parent=NULL,CTask **_pu_task=NULL); +public extern I64 PopUpPrint(U8 *fmt,...); + +#help_index "Job/Exe;Task/Job/Exe;MultiCore" +public extern I64 JobResGet(CJob *rqst=NULL); +public extern Bool JobResScan(CJob *rqst=NULL,I64 *_res=NULL); + +#help_index "Job/Text & Msgs;Task/Job/Text & Msgs" +public extern CJob *TaskText(CTask *srv,CTask *master,U8 *data,I64 flags); + +#help_index "Job/Text & Msgs;Task/Job/Text & Msgs;InFile;StdIn/InFile" +public extern U0 In(U8 *fmt,...); +public extern U0 InFile(U8 *filename); +public extern U0 InStr(U8 *fmt,...); +public extern U0 XTalk(CTask *task,U8 *fmt,...); +public extern U0 XTalkStr(CTask *task,U8 *fmt,...); +public extern U0 XTalkStrWait(CTask *task,U8 *fmt,...); +public extern U0 XTalkWait(CTask *task,U8 *fmt,...); + +#help_index "Job/Text & Msgs;Task/Job/Text & Msgs;Messages" +public extern U0 Msg(I64 msg_code,I64 arg1,I64 arg2,I64 flags=0); +public extern U0 PostMsg(CTask *task, + I64 msg_code,I64 arg1,I64 arg2,I64 flags=0); +public extern U0 PostMsgWait(CTask *task,I64 msg_code, + I64 arg1,I64 arg2,I64 flags=0); +public extern CJob *TaskMsg(CTask *srv,CTask *master, + I64 msg_code,I64 arg1,I64 arg2,I64 flags); + +#help_index "Job;Task/Job" +#help_file "::/Doc/Job" + +#help_index "Keyboard Devices/System;Char/System" +#help_file "::/Doc/KeyDev" +public extern U0 CtrlAltCBSet(U8 ch,U0 (*fp_hndlr)(I64 sc), + U8 *no_shift_desc=NULL,U8 *shift_desc=NULL,Bool in_irq=FALSE); +public extern U0 KeyDescSet(U8 *fmt,...); +public extern CKeyDevEntry *KeyDevAdd(Bool (*fp_put_key)(I64 ch,I64 sc), + Bool (*fp_puts)(U8 *st),I64 priority,Bool key_descs=FALSE); +public extern U0 KeyDevRem(CKeyDevEntry *tmpk); +extern CKeyDevGlbls keydev; +extern CJob sys_macro_head; +extern CTask *sys_macro_task; + +#help_index "Keyboard Devices;Char/Input;StdIn" +extern U8 *(*fp_getstr2)(I64 flags=0); //GetStr $LK,"Flags",A="MN:GSF_SHIFT_ESC_EXIT"$ +public extern Bool AreYouSure(); +public extern I64 GetChar(I64 *_scan_code=NULL,Bool echo=TRUE, + Bool raw_cursor=FALSE); +public extern I64 GetKey(I64 *_scan_code=NULL,Bool echo=FALSE, + Bool raw_cursor=FALSE); +public extern I64 GetS(U8 *buf,I64 size,Bool allow_ext=TRUE); +public extern U8 *GetStr(U8 *msg=NULL,U8 *dft=NULL,I64 flags=0); +extern U0 KbdInit(); +public extern I64 KbdMsEvtTime(); +extern U0 KbdMsHndlr(Bool poll_kbd,Bool poll_ms); +extern U0 KbdMsInit(); +extern I64 KbdMsgsQue(); +public extern U0 KbdTypeMatic(U8 delay); +extern Bool MsHardDrvrInstall(); +public extern I64 PressAKey(); +public extern I64 ScanChar(); +public extern Bool ScanKey(I64 *_ch=NULL,I64 *_scan_code=NULL,Bool echo=FALSE); +public extern Bool YorN(); +public extern CKbdStateGlbls kbd; + +#help_index "Math" +public extern I64 CeilI64(I64 num,I64 to); +public extern U64 CeilU64(U64 num,U64 to); +public extern F64 Clamp(F64 d,F64 lo,F64 hi); +public extern I64 FloorI64(I64 num,I64 to); +public extern U64 FloorU64(U64 num,U64 to); +public extern F64 Max(F64 n1,F64 n2); +public extern F64 Min(F64 n1,F64 n2); +public extern F64 Pow10I64(I64 i); +public extern F64 Rand(); //With timestamp +public extern I16 RandI16(); +public extern I32 RandI32(); +public extern I64 RandI64(); +public extern U16 RandU16(); +public extern U32 RandU32(); +public extern U64 RandU64(); +public extern I64 RoundI64(I64 num,I64 to); +public extern I64 Seed(I64 seed=0,CTask *task=NULL); + +#help_index "Memory/Adam Heap" +public extern U8 *ACAlloc(I64 size); +public extern U8 *AMAlloc(I64 size); +public extern U8 *AMAllocIdent(U8 *src); + +#help_index "Memory/BlkPool" +public extern U0 BlkPoolAdd(CBlkPool *bp,CMemBlk *m,I64 pags); +public extern U0 BlkPoolInit(CBlkPool *bp,I64 pags); +public extern U8 *MemPagAlloc(I64 pags,CBlkPool *bp=NULL); +public extern U0 MemPagFree(CMemBlk *m,CBlkPool *bp=NULL); + +#help_index "Memory/Heap" +public extern U8 *CAlloc(I64 size,CTask *mem_task=NULL); +public extern U8 *CAllocAligned(I64 size,I64 alignment, + CTask *mem_task=NULL,I64 misalignment=0); +public _extern _FREE U0 Free(U8 *addr); +public _extern _MALLOC U8 *MAlloc(I64 size,CTask *mem_task=NULL); +public extern U8 *MAllocAligned(I64 size,I64 alignment, + CTask *mem_task=NULL,I64 misalignment=0); +public extern U8 *MAllocIdent(U8 *src,CTask *mem_task=NULL); +public _extern _MHEAP_CTRL CHeapCtrl *MHeapCtrl(U8 *src); +public _extern _MSIZE I64 MSize(U8 *src); //size of heap object +public _extern _MSIZE2 I64 MSize2(U8 *src); //Internal size + +#help_index "Memory/HeapCtrl" +public extern U0 HeapCtrlDel(CHeapCtrl *hc); +public extern CHeapCtrl *HeapCtrlInit(CHeapCtrl *hc=NULL, + CTask *task=NULL,CBlkPool *bp); + +#help_index "Memory/Page Tables" +public extern I64 *MemPageTable(U8 *a); + +#help_index "Messages" +#help_file "::/Doc/Msgs" +public extern I64 FlushMsgs(CTask *task=NULL); +public extern I64 GetMsg(I64 *_arg1=NULL,I64 *_arg2=NULL, + I64 mask=~1,CTask *task=NULL); +extern U0 InputFilterTask(); +public extern I64 ScanMsg(I64 *_arg1=NULL,I64 *_arg2=NULL, + I64 mask=~1,CTask *task=NULL); + +#help_index "Misc" +public extern I64 EndianI64(I64 d); +public extern U16 EndianU16(U16 d); +public extern U32 EndianU32(U32 d); +public extern U0 QSort(U8 *base,I64 num, I64 width, + I64 (*fp_compare)(U8 *e1,U8 *e2)); +public extern U0 QSortI64(I64 *base,I64 num, + I64 (*fp_compare)(I64 e1,I64 e2)); +public extern F64 sys_os_version; + +#help_index "Misc/Progress Bars" +public extern U0 ProgressBarsRst(U8 *path=NULL); + +#help_index "Mouse" +#help_file "::/Doc/Mouse" +public extern U0 GridInit(); +public extern U0 MsSet(I64 x=I64_MAX,I64 y=I64_MAX,I64 z=I64_MAX, + I64 l=I64_MAX,I64 r=I64_MAX); +public extern CMsStateGlbls ms; +public extern CGridGlbls ms_grid; +public extern CMsHardStateGlbls ms_hard; +extern CMsHardStateGlbls ms_hard_last; +extern CMsStateGlbls ms_last; + +#help_index "Mouse/Ptr" +extern U0 MsInit(); +extern U0 MsUpdate(I64 x,I64 y,I64 z,Bool l,Bool r); + +#help_index "MultiCore" +extern U0 Core0StartMP(); +extern U0 CoreAPSethTask(); +public extern U0 MPInt(U8 num,I64 cpu_num=1); +public extern U0 MPIntAll(U8 num); +public extern U0 MPNMInt(); +extern CTask *SpawnQue(U0 (*fp_addr)(U8 *data),U8 *data=NULL, + U8 *task_name=NULL,I64 target_cpu, + CTask *parent=NULL, //NULL means adam + I64 stk_size=0,I64 flags=1<<JOBf_ADD_TO_QUE); + +#help_index "MultiCore;Boot" +public extern U0 MPHalt(); + +#help_index "MultiCore;Job/Exe;Task/Job/Exe" +public extern CJob *JobQue(I64 (*fp_addr)(U8 *data),U8 *data=NULL, + I64 target_cpu=1,I64 flags=1<<JOBf_FREE_ON_COMPLETE, + I64 job_code=JOBT_CALL,U8 *aux_str=NULL,I64 aux1=0,I64 aux2=0); + +#help_index "PCI" +public extern I64 PCIClassFind(I64 class_code,I64 n); +public extern U16 PCIReadU16(I64 bus,I64 dev,I64 fun,I64 rg); +public extern U32 PCIReadU32(I64 bus,I64 dev,I64 fun,I64 rg); +public extern U8 PCIReadU8(I64 bus,I64 dev,I64 fun,I64 rg); +public extern U0 PCIWriteU16(I64 bus,I64 dev,I64 fun,I64 rg,I64 val); +public extern U0 PCIWriteU32(I64 bus,I64 dev,I64 fun,I64 rg,I64 val); +public extern U0 PCIWriteU8(I64 bus,I64 dev,I64 fun,I64 rg,I64 val); +public _extern SYS_PCIBIOS_SERVICE_DIR + U32 sys_PCIBIOS_service_dir;//Far call routine in the BIOS +public _extern SYS_PCI_SERVICES + U32 sys_pci_services;//Far call routine in the BIOS + +#help_index "PCI;Info;File/System;Devices" +public extern I64 ATARep(Bool pmt=TRUE, + Bool just_ide=FALSE,CATARep **_head=NULL); + +#help_index "Processor" +public extern U8 *IntEntryGet(I64 irq); +public extern U8 *IntEntrySet(I64 irq, + U0 (*fp_new_hndlr)(),I64 type=IDTET_IRQ,I64 dpl=0); + +#help_index "ScrnCast;Cmd Line (Typically)" +public extern Bool ScrnCast(Bool val=ON,Bool just_audio=FALSE, + U8 *print_fmt="B:/Tmp/%X.GR") +public extern CScrnCastGlbls scrncast; + +#help_index "Snd" +#help_file "::/Doc/Snd" +public extern U0 Beep(I8 ona=62,Bool busy=FALSE); +public extern I8 Freq2Ona(F64 freq); +public extern Bool IsMute(); +public extern Bool Mute(Bool val); +public extern F64 Ona2Freq(I64 ona); +public extern U0 Snd(I8 ona=0); +public extern U0 SndRst(); + +#help_index "StdIn" +#help_file "::/Doc/Streams" + +#help_index "StdOut" +#help_file "::/Doc/Streams" + +#help_index "Task" +public extern I64 BirthWait(CTask **_task,I64 task_num=-1); +public extern U0 DeathWait(CTask **_task,Bool send_exit=FALSE); +public extern U0 Exit(); +public extern Bool IsSuspended(CTask *task=NULL); +public extern Bool Kill(CTask *task,Bool wait=TRUE,Bool just_break=FALSE); +public extern Bool Suspend(CTask *task=NULL,Bool state=TRUE); +_extern _TASK_CONTEXT_RESTORE U0 TaskContextRestore(); +_extern _TASK_END_NOW U0 TaskEndNow(); +extern U0 TaskKillDying(); +public extern U0 TaskQueIns(CTask *task,CTask *pred=NULL); +public extern U0 TaskQueRem(CTask *task); +public extern Bool TaskValidate(CTask *task); +public extern U0 TaskWait(CTask *task=NULL,Bool cmd_line_pmt=FALSE); +public extern CTask *User(U8 *fmt=NULL,...); +public extern U0 UserCmdLine(); +public _extern _YIELD U0 Yield(); +public extern CTask *adam_task; +public extern I64 sys_num_spawned_tasks; +extern CTask *sys_winmgr_task,*sys_task_being_scrn_updated; + +#help_index "Task/Delay;Time/CPU Cycles" +public extern U0 Busy(I64 ęS); //Loosely timed +public extern U0 PortNop(); //On the order of 1uS +extern I64 TimeCal(); + +#help_index "Task/Delay;Time/Jiffies" +public extern U0 Sleep(I64 mS); +public extern U0 SleepUntil(I64 wake_jiffy); + +#help_index "Task/Misc" +extern U0 (*fp_update_ctrls)(CTask *task); +public extern U0 TSSBusy(I64 tr,Bool val=OFF); +public extern U0 TaskDerivedValsUpdate(CTask *task=NULL,Bool update_z_buf=TRUE); +public extern U0 WinDerivedValsUpdate(CTask *task); + +#help_index "Task;Job/Exe;Task/Job/Exe;MultiCore" +public extern CTask *Spawn(U0 (*fp_addr)(U8 *data),U8 *data=NULL, + U8 *task_name=NULL,I64 target_cpu=-1, //-1 means current CPU + CTask *parent=NULL, //NULL means adam + I64 stk_size=0,I64 flags=1<<JOBf_ADD_TO_QUE); + +#help_index "Time/CPU Cycles;Time/HPET;Time/Jiffies" +public extern CCntsGlbls cnts; + +#help_index "Time/Date/CDate;Date/CDate" +#help_file "::/Doc/TimeDate" +public extern U0 Date2Struct(CDateStruct *_ds,CDate cdt); +extern U8 *MPrintDate(CDate cdt); +extern U8 *MPrintTime(CDate cdt); +public extern CDate Now(); +public extern CDate Struct2Date(CDateStruct *_ds); +public extern CDate local_time_offset; + +#help_index "Time/Date;Date" +#help_file "::/Doc/Date" +public extern I64 DayOfWeek(I64 i); +public extern I64 FirstDayOfMon(I64 i); +public extern I64 FirstDayOfYear(I64 i); +public extern I64 LastDayOfMon(I64 i); +public extern I64 LastDayOfYear(I64 i); +public extern I64 YearStartDate(I64 year); +public extern U16 mon_start_days1[12]; +public extern U16 mon_start_days2[12]; + +#help_index "Time/HPET" +#help_file "::/Doc/TimeHPET" +public extern I64 HPET(); + +#help_index "Time/Jiffies" +#help_file "::/Doc/TimeJiffy" +public extern I64 SysTimerRead();//18.33333*65536Hz (SYS_TIMER_FREQ) + +#help_index "Time/Seconds" +public extern Bool Blink(F64 Hz=2.5); +public extern F64 tS(); //From SysTimerFreq. + +#help_index "Windows" +public extern Bool WinInside(I64 x,I64 y,CTask *task=NULL,I64 border=0); + +#help_index "" +// headers for floppy driver +public extern Bool FDCIrq; +public extern U16 fdc_base; +public extern U0 CMOSGetFloppyDrives(); +public extern U0 FDCSendCmd(U16 base, U8 cmd); +public extern U8 FDCReadData(U16 base); +public extern U0 FDCCheckInt(U16 base, U8 *st0, U8 *cyl); +public extern I16 fdc_mtr_ticks; +public extern U8 fdc_mtr_state; +public extern U0 FDCMotorOff(U16 base); +public extern U0 FDCMotorPwrOffTimer(); +public extern U0 FDCMotorCtrl(U16 base, Bool onoff); +public extern I8 FDCRecalibrate(U16 base); +public extern I8 FDCReset(U16 base); +public extern I8 FDCSeek(U16 base, U8 cyli, U8 head); +public extern U0 FDCRead(U16 base, U8 cyl, U8 head, U8 sect, U8 trklen); +public extern U0 FDCReadMulti(U16 base, U8 cyl, U8 head, U8 sect, U8 trklen); +public extern U0 FDCWrite(U16 base, U8 cyl, U8 head, U8 sect, U8 trklen); +public extern U0 FDCWriteMulti(U16 base, U8 cyl, U8 head, U8 sect, U8 trklen);
\ No newline at end of file diff --git a/NewFloppy.HC b/NewFloppy.HC new file mode 100644 index 0000000..9e67467 --- /dev/null +++ b/NewFloppy.HC @@ -0,0 +1,477 @@ +/* + New, (hopefully) Less Messy Floppy Driver + Copyright (C) 2025 Yoshi128k. + Licensed under version 2 of the Do What The Fuck You Want To Public License + See COPYING for details. +*/ + +Bool FDCIrq = FALSE; + +U0 FDCDMAInit(U16 len) +{ + U64 /*buf_lo, buf_hi, page,*/ cnt_lo, cnt_hi; + +// buf_lo = &FDC_DMA & 0xFF; +// buf_hi = &FDC_DMA >> 8; +// page = &FDC_DMA >> 16; + cnt_lo = (len - 1) & 0xFF; + cnt_hi = (len - 1) >> 8; + + OutU8(0x0A, 6); // mask ch 0 and 2 + Sleep(1); + OutU8(0x0C, -1); // reset flip flop + Sleep(1); + OutU8(0x04, 0x75); // buf low byte + Sleep(1); + OutU8(0x04, 0x9F); // buf high byte + Sleep(1); + OutU8(0x0C, -1); // reset flip flop again + Sleep(1); + OutU8(0x05, cnt_lo); // cntr low byte + Sleep(1); + OutU8(0x05, cnt_hi); // cntr high byte + Sleep(1); + OutU8(0x81, 0); // page + Sleep(1); + OutU8(0x0A, 2); // unmask ch 0 and 2 + Sleep(1); +} + +U0 FDCDMAPrepWrite() +{ + OutU8(0x0A, 6); // mask ch 0 and 2 + Sleep(1); + OutU8(0x0B, 0x5A); // single xfer, addr inc, auto init, write, ch 2 + Sleep(1); + OutU8(0x0A, 2); // unmask ch 0 and 2 + Sleep(1); +} + +U0 FDCDMAPrepRead() +{ + OutU8(0x0A, 6); // mask ch 0 and 2 + Sleep(1); + OutU8(0x0B, 0x56); // single xfer, addr inc, auto init, read, ch 2 + Sleep(1); + OutU8(0x0A, 2); // unmask ch 0 and 2 + Sleep(1); +} + +interrupt U0 FDCIrqHandler() { + OutU8(0x20, 0x20); // EOI + FDCIrq = TRUE; +} + +U16 fdc_base = 0x03F0; + +static U8 *fd_types[8] = { + "none", + "360kB 5.25\"", + "1.2MB 5.25\"", + "720kB 3.5\"", + + "1.44MB 3.5\"", + "2.88MB 3.5\"", + "unknown type", + "unknown type" +}; + +U0 CMOSGetFloppyDrives() +{ + OutU8(0x70, 0x10); + Sleep(1); + + U64 drives = InU8(0x71); + + AdamLog("Floppy Drive 0: %s\n", fd_types[drives >> 4]); + AdamLog("Floppy Drive 1: %s\n", fd_types[drives & 0xF]); +} + +U0 FDCSendCmd(U16 base, U8 cmd) +{ + // Send a command to the floppy controller + + // 60 sec timeout + U64 i; + for (i = 0; i < 600; i++) { + Sleep(10); + if (0x80 & InU8(base + FDC_MSR_DSR)) { + OutU8(base + FDC_DATA, cmd); + Sleep(1); + return; + } + } + AdamErr("FDC Command TimeOut"); +} + +U8 FDCReadData(U16 base) +{ + // Read data from the floppy controller + + // 60 sec timeout + U64 i; + for (i=0;i<600;i++) { + Sleep(10); + if (0x80 & InU8(base + FDC_MSR_DSR)) { + return InU8(base + FDC_DATA); + } + } + AdamErr("FDC Read TimeOut"); +} + +U0 FDCCheckInt(U16 base, U8 *st0, U8 *cyl) +{ + FDCSendCmd(base, FDC_SENSE_INTR); + + *st0 = FDCReadData(base); + *cyl = FDCReadData(base); +} + +I16 fdc_mtr_ticks = 0; +U8 fdc_mtr_state = FDC_MOTOR_OFF; + +U0 FDCMotorOff(U16 base) +{ + OutU8(base + FDC_DOR, 0x0C); + fdc_mtr_state = FDC_MOTOR_OFF; +} + +U0 FDCMotorPwrOffTimer() +{ + // You're supposed to run this function as a separate CTask. It will exit when the motor + // exits the "wait" state (either because it has turned off or because something needs it to be on). + // The driver only spawns this when the motor is moved from "on" to "wait". + while (fdc_mtr_state == FDC_MOTOR_WAIT) { + // Sanity check for if something wants the motor on at the last second + if (fdc_mtr_state == FDC_MOTOR_ON) break; + + Sleep(500); + + fdc_mtr_ticks -= 50; + if (fdc_mtr_ticks <= 0) { + FDCMotorOff(fdc_base); + } + Yield; // Give control back to the scheduler + } +} + +U0 FDCMotorCtrl(U16 base, Bool onoff) +{ + U64 prev_mtr_state; + if (onoff) { + if (!fdc_mtr_state) { + // Turn on motor + OutU8(base + FDC_DOR, 0x1C); + Sleep(500); // Wait 500 ms to allow drive to spin up + } + fdc_mtr_state = FDC_MOTOR_ON; + } else { + prev_mtr_state = fdc_mtr_state; + if (fdc_mtr_state == FDC_MOTOR_WAIT) { + AdamLog("FDC: Motor PowerOff Already Pending\n"); + } + fdc_mtr_ticks = 300; // 3 sec timeout before motor turns off + fdc_mtr_state = FDC_MOTOR_WAIT; + // Only spawn the timer task of the motor is currently on; infinitely-looping tasks peg the CPU + if (prev_mtr_state != FDC_MOTOR_WAIT) Spawn(&FDCMotorPwrOffTimer,,"FDCMotorPwrOffTimer"); + } +} + +I8 FDCRecalibrate(U16 base) +{ + FDCIrq = FALSE; + + U64 i; + U8 st0, cyl; + + FDCMotorCtrl(base, FDC_MOTOR_ON); + + for (i=0;i<10;i++) { + FDCSendCmd(base, FDC_RECALIBRATE); + FDCSendCmd(base, 0); + + // Wait for an interrupt, then get the status + while (!FDCIrq) Yield; + FDCCheckInt(base, &st0, &cyl); + AdamLog("ST0: %d Cyl: %d\n",st0,cyl); + + if (st0 & 0xC0) { + static U8 * status[4] = {0, "error", "invalid", "drive"}; + AdamLog("Calibration Status: %s\n", status[st0 >> 6]); + } + + if (!cyl) { + FDCMotorCtrl(base, FDC_MOTOR_OFF); + return 0; + } + } + + AdamErr("FDC ReCalibrate TimeOut"); + FDCMotorCtrl(base, FDC_MOTOR_OFF); + return -1; +} + +I8 FDCReset(U16 base) +{ + FDCIrq = FALSE; + + OutU8(base + FDC_DOR, 0x00); + Sleep(1); + OutU8(base + FDC_DOR, 0x0C); + Sleep(1); + + while (!FDCIrq) Yield; + + // Ignore this + U64 i, lck; + U8 st0, cyl; + for (i=0;i<4;i++) { + FDCCheckInt(base, &st0, &cyl); + } + + // Set xfer rate to 500kbps + OutU8(base + FDC_CCR_DIR, 0x00); + Sleep(1); + + // Set the mechanical params and disable DMA (Terry didn't use it) + FDCSendCmd(base, FDC_SPECIFY); + FDCSendCmd(base, 0b10000000); // SRT = 8 (8 ms), HUT = 0 (256 ms) + FDCSendCmd(base, 0b00011110); // HLT = 15 (30 ms), NDMA = 0 (DMA enabled) + + // Configure the FIFO + FDCSendCmd(base, FDC_CONFIGURE); + FDCSendCmd(base, 0x00); // 1st param is a 0 + FDCSendCmd(base, 0b01011011); // 2nd param: Implied seek on, FIFO on, Drive polling disabled, threshold = 12 + FDCSendCmd(base, 0x00); // 3rd param: write precomp = 0 + + // Lock the configuration + FDCSendCmd(base, 0x94); + lck = FDCReadData(base); // Result: lock status + + // contingency + if (FDCRecalibrate(base)) return -1; + + return 0; +} + +I8 FDCSeek(U16 base, U8 cyli, U8 head) +{ + U64 i; + U8 st0, cyl; + FDCIrq = FALSE; + + FDCMotorCtrl(base, FDC_MOTOR_ON); + + for (i=0;i<10;i++) { + // Attempt to move to given cyl + // 1: X X X X X HD D1 D0 + // 2: Cyl No + FDCSendCmd(base, FDC_SEEK); + FDCSendCmd(base, head<<2); + FDCSendCmd(base, cyli); + + while (!FDCIrq) Yield; + FDCCheckInt(base, &st0, &cyl); + AdamLog("ST0: %d Cyl: %d\n",st0,cyl); + + if (st0 & 0xC0) { + static U8 * status[4] = {0, "error", "invalid", "drive"}; + AdamLog("Seek Status: %s\n", status[st0 >> 6]); + } + + if (cyl == cyli) { + FDCMotorCtrl(base, FDC_MOTOR_OFF); + return 0; + } + } + + AdamErr("FDC Seek TimeOut"); + FDCMotorCtrl(base, FDC_MOTOR_OFF); + return -1; +} + +U0 FDCRead(U16 base, U8 cyl, U8 head, U8 sect, U8 trklen) +{ + // Read data from disk (single-track) + static U8 flags; + flags = 0x40; // Multi-track off, MFM modulation + static U64 cmd; + cmd = FDC_READ_DATA | flags; + FDCIrq = FALSE; + + U64 st0, st1, st2, rcyl, rhd, rsect, rsectsize; + + FDCMotorCtrl(base, FDC_MOTOR_ON); + + AdamLog("Cmd: %d\nParams: %d %d %d %d %d %d %d %d\n",cmd,head<<2,cyl,head,sect,2,trklen,0x1B,0xFF); + + // Prepare the DMA controller + AdamLog("Preparing DMA\n"); + FDCDMAInit(512*(trklen - sect + 1)); + FDCDMAPrepRead(); + + FDCSendCmd(base, cmd); + FDCSendCmd(base, head << 2); // Drive 0, specified head + FDCSendCmd(base, cyl); + FDCSendCmd(base, head); + FDCSendCmd(base, sect); + FDCSendCmd(base, 2); // Sector size = 2 = 512 bytes + FDCSendCmd(base, trklen); // Track Length/Max Sector No. + FDCSendCmd(base, 0x1B); // GAP3 Length = 27 (3.5") + FDCSendCmd(base, 0xFF); // Data Length (irrelevant) + + // Wait for xfer to complete + while (!FDCIrq) Yield; + + st0 = FDCReadData(base); + st1 = FDCReadData(base); + st2 = FDCReadData(base); + rcyl = FDCReadData(base); + rhd = FDCReadData(base); + rsect = FDCReadData(base); + rsectsize = FDCReadData(base); + + AdamLog("Read Results:\nST0: %d\nST1: %d\nST2: %d\nCyl: %d\nHead: %d\nSect: %d\nSect Size: %d\n",st0,st1,st2,rcyl,rhd,rsect,rsectsize); + + FDCMotorCtrl(base, FDC_MOTOR_OFF); +} + + +U0 FDCReadMulti(U16 base, U8 cyl, U8 head, U8 sect, U8 trklen) +{ + // Read data from disk (multi-track) + static U8 flags; + flags = 0xC0; // Multi-track on, MFM modulation + static U64 cmd; + cmd = FDC_READ_DATA | flags; + FDCIrq = FALSE; + + U64 st0, st1, st2, rcyl, rhd, rsect, rsectsize; + + FDCMotorCtrl(base, FDC_MOTOR_ON); + + AdamLog("Cmd: %d\nParams: %d %d %d %d %d %d %d %d\n",cmd,head<<2,cyl,head,sect,2,trklen,0x1B,0xFF); + + // Prepare the DMA controller + AdamLog("Preparing DMA\n"); + FDCDMAInit(512*(trklen - sect + 1)*2); + FDCDMAPrepRead(); + + FDCSendCmd(base, cmd); + FDCSendCmd(base, head << 2); // Drive 0, specified head + FDCSendCmd(base, cyl); + FDCSendCmd(base, head); + FDCSendCmd(base, sect); + FDCSendCmd(base, 2); // Sector size = 2 = 512 bytes + FDCSendCmd(base, trklen); // Track Length/Max Sector No. + FDCSendCmd(base, 0x1B); // GAP3 Length = 27 (3.5") + FDCSendCmd(base, 0xFF); // Data Length (irrelevant) + + // Wait for the xfer to complete + while (!FDCIrq) Yield; + + st0 = FDCReadData(base); + st1 = FDCReadData(base); + st2 = FDCReadData(base); + rcyl = FDCReadData(base); + rhd = FDCReadData(base); + rsect = FDCReadData(base); + rsectsize = FDCReadData(base); + + AdamLog("Read Results:\nST0: %d\nST1: %d\nST2: %d\nCyl: %d\nHead: %d\nSect: %d\nSect Size: %d\n",st0,st1,st2,rcyl,rhd,rsect,rsectsize); + + FDCMotorCtrl(base, FDC_MOTOR_OFF); +} + +U0 FDCWrite(U16 base, U8 cyl, U8 head, U8 sect, U8 trklen) +{ + // Write data to disk (single-track) + static U8 flags; + flags = 0x40; // Multi-track off, MFM modulation + static U64 cmd; + cmd = FDC_WRITE_DATA | flags; + FDCIrq = FALSE; + + U64 st0, st1, st2, rcyl, rhd, rsect, rsectsize; + + FDCMotorCtrl(base, FDC_MOTOR_ON); + + AdamLog("Cmd: %d\nParams: %d %d %d %d %d %d %d %d\n",cmd,head<<2,cyl,head,sect,2,trklen,0x1B,0xFF); + + // Prepare the DMA controller + AdamLog("Preparing DMA\n"); + FDCDMAInit(512*(trklen - sect + 1)); + FDCDMAPrepWrite(); + + FDCSendCmd(base, cmd); + FDCSendCmd(base, head << 2); // Drive 0, specified head + FDCSendCmd(base, cyl); + FDCSendCmd(base, head); + FDCSendCmd(base, sect); + FDCSendCmd(base, 2); // Sector size = 2 = 512 bytes + FDCSendCmd(base, trklen); // Track Length/Max Sector No. + FDCSendCmd(base, 0x1B); // GAP3 Length = 27 (3.5") + FDCSendCmd(base, 0xFF); // Data Length (irrelevant) + + // Wait for xfer to complete + while (!FDCIrq) Yield; + + st0 = FDCReadData(base); + st1 = FDCReadData(base); + st2 = FDCReadData(base); + rcyl = FDCReadData(base); + rhd = FDCReadData(base); + rsect = FDCReadData(base); + rsectsize = FDCReadData(base); + + AdamLog("Read Results:\nST0: %d\nST1: %d\nST2: %d\nCyl: %d\nHead: %d\nSect: %d\nSect Size: %d\n",st0,st1,st2,rcyl,rhd,rsect,rsectsize); + + FDCMotorCtrl(base, FDC_MOTOR_OFF); +} + + +U0 FDCWriteMulti(U16 base, U8 cyl, U8 head, U8 sect, U8 trklen) +{ + // Write data to disk (multi-track) + static U8 flags; + flags = 0xC0; // Multi-track on, MFM modulation + static U64 cmd; + cmd = FDC_WRITE_DATA | flags; + FDCIrq = FALSE; + + U64 st0, st1, st2, rcyl, rhd, rsect, rsectsize; + + FDCMotorCtrl(base, FDC_MOTOR_ON); + + AdamLog("Cmd: %d\nParams: %d %d %d %d %d %d %d %d\n",cmd,head<<2,cyl,head,sect,2,trklen,0x1B,0xFF); + + // Prepare the DMA controller + AdamLog("Preparing DMA\n"); + FDCDMAInit(512*(trklen - sect + 1)*2); + FDCDMAPrepRead(); + + FDCSendCmd(base, cmd); + FDCSendCmd(base, head << 2); // Drive 0, specified head + FDCSendCmd(base, cyl); + FDCSendCmd(base, head); + FDCSendCmd(base, sect); + FDCSendCmd(base, 2); // Sector size = 2 = 512 bytes + FDCSendCmd(base, trklen); // Track Length/Max Sector No. + FDCSendCmd(base, 0x1B); // GAP3 Length = 27 (3.5") + FDCSendCmd(base, 0xFF); // Data Length (irrelevant) + + // Wait for the xfer to complete + while (!FDCIrq) Yield; + + st0 = FDCReadData(base); + st1 = FDCReadData(base); + st2 = FDCReadData(base); + rcyl = FDCReadData(base); + rhd = FDCReadData(base); + rsect = FDCReadData(base); + rsectsize = FDCReadData(base); + + AdamLog("Read Results:\nST0: %d\nST1: %d\nST2: %d\nCyl: %d\nHead: %d\nSect: %d\nSect Size: %d\n",st0,st1,st2,rcyl,rhd,rsect,rsectsize); + + FDCMotorCtrl(base, FDC_MOTOR_OFF); +}
\ No newline at end of file diff --git a/ReadMe.TXT b/ReadMe.TXT new file mode 100644 index 0000000..9e2970a --- /dev/null +++ b/ReadMe.TXT @@ -0,0 +1,27 @@ +These files contain the code required for the low-level floppy disk driver. +Currently, there is no block device code that implements this driver. + +System source files from my system are included as a reference. + +To install the driver: +1. Copy Floppy.HC and Floppy.HH to the Kernel directory +2. Copy the headers at the bottom of the provided KernelC.HC into *your* KernelC. +3. Add "U8 FDC_DMA[0x4800];" to the bottom of KStart32.HC; This is the DMA buffer for the floppy disk (yeah, I know, DMA = blasphemy, but it's more reliable than PIO while being just as simple). +4. Add Floppy.HC and Floppy.HH to Kernel.PRJ so that they will be compiled into the kernel. + +On startup, you will have to unmask IRQ6 and point its int to the IRQ handler, FDCIrqHandler. +To do this, write 0xB8 to port 0x21, then use IntEntrySet to set the vector for the aforementioned int. +In HolyC, that would be: +OutU8(0x21,0xB8); +IntEntrySet(0x26,&FDCIrqHandler,IDTET_IRQ); + +Use FDCReset to initialize the drive (make sure a disk is inserted; it does not test for one before doing things) + +FDCSeek does what it says. + +FDCRead/FDCReadMulti will read data from the disk. +FDCWrite/FDCWriteMulti will write data to the disk. +Data that has been read or is to be written goes in FDC_DMA. +(The FDC*Multi funs use multi-track mode; data will be read from both heads) + +The result of seeks, recalibrations, and data xfers will be displayed in the Adam Task. |
