ORG BDOS %include "hdr/bios.asm" %include "hdr/fcb.asm" %include "hdr/bpb.asm" DISKBUF: EQU (BDOS-0x200) ; deblocking DISKBPB: EQU (DISKBUF-21) ; BPB of the current driv DISKDRV: EQU (DISKBPB-1) ; BYTE denoting drive of current fcb (1=A, ...) PROGBX: EQU (DISKDRV-2) STACK: EQU (PROGBX & 0xFFFE) ; even address, grows down DEFDRV: EQU 4 ; default drive when opening a FCB (1=A, ...) SYSCALL: MOV [PROGBX], BX XOR BH, BH MOV BL, CL ADD BX, BX ADD BX, FUNCS MOV BX, [BX] PUSH BX MOV BX, [PROGBX] SYSRET: RET FUNCS: DW SETUP,GETC,PUTC,SYSRET DW SYSRET,SYSRET,SYSRET,SYSRET DW SYSRET,PUTS,GETS,STATUS DW SYSRET,DISKRST,SETDEFDSK,FCBOPEN DW SYSRET,SYSRET,SYSRET,SYSRET DW SYSRET,SYSRET,SYSRET,SYSRET SETUP: MOV SP, STACK MOV BYTE [DEFDRV], 0x01 MOV CX, DISKBUF CALL SETDMA SUB SP, 0x20 MOV BX, SP CALL FCBOPEN CLI HALT: HLT JMP HALT GETC: CALL CONIN TEST AL, AL JZ GETC PUSH DX MOV DL, AL CALL CONOUT POP DX ret PUTC: JMP CONOUT PUTS: PUSH SI MOV SI, DX PUTS_L: MOV DL, BYTE [SI] CMP DL, '$' JZ PUTS_E CALL CONOUT INC SI JMP PUTS_L PUTS_E: POP SI RET ; BX base ptr to buffer ; CH maximum BL ; CL minimum BL GETS: PUSH AX PUSH CX PUSH DX PUSH BX ; BX is base pointer MOV BX, DX ; CL is maximum, CH is current position MOV CX, [BX] XOR CH, CH ; BX starts at actual character area ADD BX, 2 GETS_L: ; Read and maybe handle control chars CALL GETC CMP AL, 0x0D JE GETS_E CMP AL, 8 JE GETS_BS ; Store character PUSH BX ADD BL, CH ADC BH, 0 MOV [BX], AL POP BX ; Loop if we arent full yet INC CH CMP CH, CL JC GETS_L GETS_E: ; Append LF to CR MOV DL, 0x0A CALL PUTC ; Write back length data SUB BX, 2 MOV [BX], CX ; Restore registers POP BX POP DX POP CX POP AX ret GETS_BS: TEST CH, CH JZ GETS_L MOV DL, 0x20 CALL PUTC MOV DL, 8 CALL PUTC DEC CL JMP GETS_L STATUS: JMP CONST DISKRST: MOV BYTE [DISKDRV], 0xFF RET SETDEFDSK: MOV BYTE [DEFDRV], DL RET FCBOPEN: MOV CL, BYTE [BX] TEST CL, CL JNZ NODEFDRV MOV CL, BYTE [DEFDRV] MOV BYTE [BX], CL NODEFDRV: CALL LOADBPB MOV CX, [DISKBPB+BPB_RDE] CALL FATSIZE ADD DX, WORD [DISKBPB+BPB_RSC] CALL SETLSEC CALL READ MOV AX, [DISKBUF] INT3 ; TODO: search for file in rootdir ; TODO: init cluster number RET ; Set logical sector number ; IN DX sector number SETLSEC: PUSH AX PUSH CX PUSH DX XOR AX, AX XCHG AX, DX DIV WORD [DISKBPB+BPB_SPT] MOV CX, AX CALL SETTRK MOV CX, DX INC CX CALL SETSEC POP DX POP CX POP AX RET ; OUT DX number of sectors by all FATs FATSIZE: PUSH AX MOV DL, BYTE [DISKBPB+BPB_FN] MOV AL, BYTE [DISKBPB+BPB_SF] MUL DL XCHG AX, DX POP AX RET: RET ; IN CL drive num, 1=A, 2=B, 3=C LOADBPB: CMP BYTE [DISKDRV], CL JE RET PUSH CX DEC CL CALL SELDSK ; first track MOV CX, 0 CALL SETTRK ; first sector MOV CX, 1 CALL SETSEC ; into default diskbuf MOV CX, DISKBUF CALL SETDMA POP CX CALL READ JC DISKRST ; copy BPB PUSH CX PUSH SI PUSH DI MOV CX, 21 MOV SI, DISKBUF+0x0B MOV DI, DISKBPB REP MOVSB POP DI POP SI POP CX ; store drive number MOV BYTE [DISKDRV], CL RET