;P.C. Debug Monitor Revision 6/23/2005 by Don Stoner ; ORG 100H ;DOS file.COM execution begins here ; ;========================================================== ; ; Code Begins Here: ; JMP SHORT START ; ;------------------------------------------------ ; ; USER REGISTER CONTENTS: ; RAX: DW 1111H RBX: DW 8000H RCX: DW 3333H RDX: DW 4444H RSI: DW 5555H RDI: DW 6666H RBP: DW 7777H RSP: DW 0FF80H RCS: DW 0 RDS: DW 0 RES: DW 0 RSS: DW 0 RIP: DW 100H RFG: DW 0 ; LGSEC: DW 0 ;LOGICAL SECTOR ; ; BOOT RECORD IMAGE ; BOOTRC: DB 0,0,0 ;(JUMP) NAME: DB " " ;NAME OF FORMATTING DOS BPS: DW 0 ;BYTES/SECTOR SPC: DB 0 ;SECTORS/CLUSTER SBR: DW 0 ;SECTORS IN BOOT RECORD CFT: DB 0 ;COPIES OF FAT RDE: DW 0 ;ROOT DIRECTORY ENTRIES SPD: DW 0 ;SECTORS/DISK DTP: DB 0 ;DISK TYPE: F8H HDD, F9 3.5" SPF: DW 0 ;SECTORS/FAT SPT: DW 1 ;SECTORS/TRACK HPD: DW 1 ;HEADS/DISK NRS: DW 0 ;# OF RESERVED SECTORS ; ; CALCULATED FROM BOOT RECORD ; HXS: DW 0 ;HEADS TIMES SECTORS / TRACK ; RFPU: DB 0,0,0,0,0,0,0,0,0,0 C10K: DW 10000 ; ;========================================================== ; ; SETUP ; ; TAKE OVER INTERRUPT VECTORS 1 (STEP) AND 3 (BREAK) ; START: MOV AX,0 MOV DS,AX ; MOV AX,[4] ;SAVE EXISTING VECTORS MOV [CS:OFF],AX MOV AX,[6] MOV [CS:SEGSAV],AX ; MOV AX,VECTOR ;SET NEW VECTORS MOV [4],AX MOV [12],AX MOV AX,CS MOV [6],AX MOV [14],AX ; ; MISC. SETUP ; CLD ;NORMAL FORWARD MOVES DB 90H,0DBH,0E3H ;FINIT (INIT FPU) ; ; Set up segment registers: ; MOV AX,CS MOV DS,AX MOV [RCS],AX MOV [RDS],AX MOV [RES],AX MOV [RSS],AX RESTART: MOV AX,CS MOV DS,AX MOV ES,AX CLI ;NO INTERRUPTS MOV SS,AX ;WHILE SETTING MOV SP,0FFFEH ;STACK POINTER STI ; ;================================================ ; ; Main Code Loop ; MLOOP: CALL CLS ;Clear Screen CALL HOME ;DISPLAY THE DATA CALL FIX CALL BLKOUT MOV AL,">" CALL OUTPUT CALL INPUT ;GET INPUT MOV [KEY],AX ; ;---------------------------------------- ; ; Quit to DOS (only for debug under DOS) ; CMP AL,"Q" ;KEY IS Q? JNZ NTQ ; MOV AX,0 ;RESTORE INTERRUPT VECTORS MOV DS,AX MOV AX,[CS:OFF] MOV [4],AX MOV [12],AX MOV AX,[CS:SEGSAV] MOV [6],AX MOV [14],AX ; MOV AH,0 ;"EXIT DOS" FUNCTION CALL INT 21H NTQ: ; ;======================================== ; DISK FUNCTIONS ; ; CONVERT LOGICAL TO PHYSICAL SECTOR ; CMP AL,"R" ;KEY IS "R"? JNZ NTR ; RLG: ;MOV DL,[PRWD+1] ;MOV BX,[RBX] ;NEW SHORTER FORM ;MOV AX,[RAX] ;CALL READLG ; CALL LOG2PH ;old sets track/sector info CALL RDLGC JMP SHORT MLOOP NTR: ; ; INC/DEC LOGICAL SECTORS ; CMP AX,4A2DH ;- ON KEYPAD JNZ NMKP DEC WORD [LGSEC] JMP RLG NMKP: ; CMP AX,4E2BH ;+ ON KEYPAD JNZ NPKP INC WORD [LGSEC] JMP RLG NPKP: ; ;---------------------------------------- ; ; SELECT Floppy ; CMP AX,4F31H ;KEY IS NUM.LOCK 1 (END) JNZ NTFD MOV AL,0 ;SELECT FLOPPY JMP SHORT FHDMG NTFD: ; ;---------------------------------------- ; ; SELECT HARD DISK ; CMP AX,4737H ;KEY IS NUM.LOCK 7 (HOME) JNZ NTHD MOV AL,80H ;SELECT HARD DISK FHDMG: MOV [PRWD+1],AL ;SAVE DISK CODE CALL AINIT ;GET BOOT RECORD JMP MLOOP NTHD: ; ;---------------------------------------- ; ; INC SECTOR ; CMP AX,4D36H ;KEY IS NUM.LOCK 6 -> JNZ NTINS INC BYTE [PRWC+1] JMP SHORT READ NTINS: ; ;---------------------------------------- ; ; DEC SECTOR ; CMP AX,4B34H ;KEY IS NUM.LOCK 4 <- JNZ NTDCS DEC BYTE [PRWC+1] JMP SHORT READ NTDCS: ; ;---------------------------------------- ; ; Read Sector ; CMP AX,4C35H ;KEY IS NUM.LOCK 5 JNZ NTRS READ: MOV AX,201H ;AH=2 AL=SECTOR COUNT (1-9) JMP SHORT RWMG NTRS: ; ;---------------------------------------- ; ; Write Sector ; CMP AL,17h ;KEY IS ^W? JNZ NTW MOV AX,301H ;AH=3 AL=SECTOR COUNT (1-9) RWMG: ; MOV BX,[RBX] ;MEMORY BUFFER OFFSET PRWC: MOV CX,0001H ;TRACK (0-39), SECTOR (1-9) PRWD: MOV DX,0 ;HEAD (0-1), DRIVE (0-3) INT 13H JMP MLOOP NTW: ; ;---------------------------------------- ; ; INC TRACK ; CMP AX,4838H ;KEY IS NUM.LOCK 8 (UP) JNZ NTINT INC BYTE [PRWC+2] JMP SHORT READ NTINT: ; ;---------------------------------------- ; ; DEC TRACK ; CMP AX,5032H ;KEY IS NUM.LOCK 2 (DN) JNZ NTDCT DEC BYTE [PRWC+2] JMP SHORT READ NTDCT: ; ;---------------------------------------- ; ; INC HEAD ; CMP AX,4939H ;KEY IS NUM.LOCK 9 (PGUP) JNZ NTINH INC BYTE [PRWD+2] JMP SHORT READ NTINH: ; ;---------------------------------------- ; ; DEC HEAD ; CMP AX,5133H ;KEY IS NUM.LOCK 3 (PGDN) JNZ NTDCH DEC BYTE [PRWD+2] JMP SHORT READ NTDCH: ; ;======================================== ; ; GO (RUN) ; CMP AL,"G" ;KEY IS G? JNZ NTG JMP RUN NTG: ; ;---------------------------------------- ; ; SINGLE STEP ; CMP AL,"S" ;KEY IS S? JNZ NTS JMP STEP NTS: ; ;---------------------------------------- ; ; HOME ; CMP AX,4700H ;HOME extended code JNZ NTHM MOV AX,100h MOV [RIP],AX JMP MLOOP NTHM: ; ;---------------------------------------- ; ; END ; CMP AX,4F00H ;END extended code JNZ NTEND MOV AX,8000H MOV [RIP],AX MOV [PAGE],AX JMP MLOOP NTEND: ; ;---------------------------------------- ; ; ASCII EDIT ; CMP AL,"'" ;KEY IS '? JNZ NTSQ CALL INPUT ;GET CHARACTER MOV SI,[RIP] MOV [SI],AL ;PUT IT INTO THE CODE JMP MLOOP NTSQ: ; ;---------------------------------------- ; ; HEX EDIT ; CMP AL,30H ;KEY IS 0-9? JC NTH CMP AL,3AH ;("9"+1) JNC NTH AND AL,0FH JMP SHORT HMG NTH: CMP AL,41H ;KEY IS A-F? JC NTH2 CMP AL,47H ;("F"+1) JNC NTH2 SUB AL,55 ;TURNS A->10 HMG: MOV SI,[RIP] MOV AH,[SI] ;PUT IT INTO THE CODE ADD AH,AH ADD AH,AH ADD AH,AH ADD AH,AH OR AH,AL MOV [SI],AH JMP MLOOP NTH2: ; ;---------------------------------------- ; ; Right Arrow Function ; CMP AL,20H ;SPACE OR JZ RTA CMP AX,4D00H ;Right ARROW extended code JNZ NTRTA RTA: MOV AX,1 JMP SHORT MOVE NTRTA: ; ;---------------------------------------- ; ; Left Arrow Function ; CMP AX,4B00H ;Left ARROW extended code JNZ NTLFA MOV AX,-1 JMP SHORT MOVE NTLFA: ; ;---------------------------------------- ; ; Down Arrow Function ; CMP AX,5000H ;DOWN ARROW extended code JNZ NTDNA MOV AX,16 JMP SHORT MOVE NTDNA: ; ;---------------------------------------- ; ; Up Arrow Function ; CMP AX,4800H ;UP ARROW extended code JNZ NTUPA MOV AX,-16 JMP SHORT MOVE NTUPA: ; ;---------------------------------------- ; ; Page Down Function ; CMP AX,5100H ;Page DOWN extended code JNZ NTPDN MOV AX,100h JMP SHORT MOVE NTPDN: ; ;---------------------------------------- ; ; Page Up Function ; CMP AX,4900H ;Page UP extended code JNZ NTPUP MOV AX,-100h MOVE: ADD AX,[RIP] ;ADD OFFSET TO IP POINTER MOV [RIP],AX NTPUP: ; JMP MLOOP ; ;========================================================== ; ; SUBROUTINES: ; ;---------------------------------------- ; ; CLEAR SCREEN, HOME CURSOR ; CLS: MOV AX,600h ;ah=6, al=lines to scroll up MOV BH,17h ;BG,FG WINDOW COLOR ATTRIBUTE MOV CX,0 ;UPPER-LEFT CORNER ROW,COL MOV DX,24*256+79 ;LOWER-RIGHT ROW,COL INT 10H ; HOME: MOV AH,2 ;SET CURSOR MOV BH,0 ;PAGE 0 MOV DX,0 ;X=0,Y=0 INT 10h RET ; ;---------------------------------------- ; ; INPUT ASCII KEY CODE INTO AL ; (EXTENDED KEY CODE INTO AX) ; uses BIOS interrupt ; INPUT: MOV AH,0 INT 16H RET ; ;---------------------------------------- ; ; HEX OUTPUT (FROM AX OR AL) ; AXOUT: ;PUSH AX ;4 NIBBLES FROM AX ;MOV AL,AH xchg al,ah CALL ALOUT xchg ah,al ;POP AX ; ALOUT: PUSH AX ;2 NIBBLES FROM AQL PUSH CX MOV CL,4 ROR AL,CL POP CX CALL LSNOUT POP AX ; LSNOUT: AND AL,0FH ;LSN ONLY OR AL,30H CMP AL,3AH ;HEX ALPHA JC OUTPUT ADD AL,41H-3AH ;*** drops through *** ; ; OUTPUT ASCII CHARACTER (FROM AL) ; (uses BIOS interrupt) ; OUTPUT: PUSH AX ;SAVE AX MOV AH,0EH ;TTY OUT MOV BX,0 ;FOREGROUND PAGE,COLOR INT 10H POP AX ;RESTORE AX RET ; ;---------------------------------------- ; ; OUTPUT HIGHLIGHT CONTROL ; (outputs 2 spaces using BIOS interrupt) ; HIGH: MOV BX,5FH ;bh=PAGE, bl=ATTRIBUTE CMP SI,[RIP] JZ HIGH2 LOW: MOV BX,17H ;bh=PAGE, bl=ATTRIBUTE HIGH2: PUSH AX PUSH CX MOV CX,2 ;TWO (count) MOV AX,920H ;BLANKS (al=20h) INT 10H POP CX POP AX RET ; ;---------------------------------------- ; ; SPACE OUTPUT ; SPACE: PUSH AX MOV AL," " CALL OUTPUT POP AX RET ; ;---------------------------------------- ; ; C.R. AND L.F. ; CRLF: MOV AL,0DH CALL OUTPUT LF: MOV AL,0AH JMP SHORT OUTPUT ; ;---------------------------------------- ; ; OUTPUT AN ASCIIZ CHARACTER STRING (POINTED BY SI) ; PRINTS: ;MOV AL,[SI] ;GET character ;INC SI ;next character LODSB ;(LODS - SAME AS MOV AL,[SI] INC SI) ; AND AL,AL ;END/NULL STRING? JZ ENDSTR CALL OUTPUT ;OUTPUT IT JMP SHORT PRINTS ENDSTR: RET ; ;---------------------------------------- ; ; FPU REGISTER OUTPUT ; - OUTPUTS & POPS ST(0) ; FPUOUT: MOV SI,C10K DB 0DEH,0CH ;FIMULT *10,000 DB 0DEH,0CH ;FIMULT DB 0DEH,0CH ;FIMULT (*10^12) ; DB 0DFH,36H ;DECIMAL STORE & POP DW RFPU ;->RFPU ; MOV AX,[RFPU+8] CALL AXOUT MOV AX,[RFPU+6] CALL AXOUT MOV AL,"." CALL OUTPUT MOV AX,[RFPU+4] CALL AXOUT MOV AX,[RFPU+2] CALL AXOUT ;MOV AX,[RFPU] ;CALL AXOUT JMP SPACE ; ;---------------------------------------- ; ; BLOCK OUTPUT ; BLKOUT: MOV AL,[DTP] AND AL,AL ;BOOT RECORD? JZ SKIPBR ; MOV SI,MTYPE ;OUTPUT BOOT INFO CALL PRINTS MOV AL,[DTP] CALL ALOUT ; MOV SI,MHEADS CALL PRINTS MOV AX,[HPD] CALL AXOUT ; MOV SI,MTRCKS CALL PRINTS MOV AX,[SPD] XOR DX,DX IDIV WORD [HXS] CALL AXOUT ; MOV SI,MSECTS CALL PRINTS MOV AX,[SPT] CALL AXOUT ; CALL CRLF SKIPBR: ; MOV SI,MDISK ;OUTPUT DISK POINTERS CALL PRINTS MOV AL,[PRWD+1] CALL ALOUT ; MOV SI,MHEAD CALL PRINTS MOV AL,[PRWD+2] CALL ALOUT ; MOV SI,MTRCK CALL PRINTS MOV AL,[PRWC+2] CALL ALOUT ; MOV SI,MSECT CALL PRINTS MOV AL,[PRWC+1] CALL ALOUT ; MOV SI,MLOG CALL PRINTS MOV AX,[LGSEC] CALL AXOUT ; MOV SI,MAX ;AX OUT CALL PRINTS MOV AX,[RAX] CALL AXOUT ; MOV SI,MBX ;BX OUT CALL PRINTS MOV AX,[RBX] CALL AXOUT ; MOV SI,MCX ;CX OUT CALL PRINTS MOV AX,[RCX] CALL AXOUT ; MOV SI,MDX ;DX OUT CALL PRINTS MOV AX,[RDX] CALL AXOUT ; MOV SI,MSI ;SI OUT CALL PRINTS MOV AX,[RSI] CALL AXOUT ; MOV SI,MDI ;DI OUT CALL PRINTS MOV AX,[RDI] CALL AXOUT ; MOV SI,MBP ;BP OUT CALL PRINTS MOV AX,[RBP] CALL AXOUT ; MOV SI,MSP ;SP OUT CALL PRINTS MOV AX,[RSP] CALL AXOUT ; MOV SI,MCS ;CS OUT CALL PRINTS MOV AX,[RCS] CALL AXOUT ; MOV SI,MDS ;DS OUT CALL PRINTS MOV AX,[RDS] CALL AXOUT ; MOV SI,MES ;ES OUT CALL PRINTS MOV AX,[RES] CALL AXOUT ; MOV SI,MSS ;SS OUT CALL PRINTS MOV AX,[RSS] CALL AXOUT ; MOV SI,MIP ;IP OUT CALL PRINTS MOV AX,[RIP] MOV DI,AX CALL AXOUT ; MOV SI,MFG ;FLAGS OUT CALL PRINTS MOV AX,[RFG] CALL AXOUT ; MOV SI,MKEY ;PRINT "KEY: " CALL PRINTS MOV AX,[KEY] CALL OUTPUT ;ECHO THE INPUT CALL SPACE CALL AXOUT ;show its hex code ; MOV SI,MFPU ;F.P.U. CALL PRINTS DB 0D9H,0C0H ;FLD ST0 (DUPE) CALL FPUOUT DB 0D9H,0C1H ;FLD ST1 (DUPE) CALL FPUOUT DB 0D9H,0C2H ;FLD ST2 (DUPE) CALL FPUOUT ; MOV SI,MEND CALL PRINTS ; MOV SI,[PAGE] ;memory block MOV CH,16 ;16 lines BLKLP1: CALL LINOUT DEC CH JNZ BLKLP1 JMP CRLF ; ; LINE OUT ; LINOUT: MOV AX,SI ;ADDRESS CALL AXOUT MOV AL,":" CALL OUTPUT CALL SPACE ; MOV CL,16 LINLP1: ;HEX CALL HIGH ;highlight on? LODSB ;LODS (BYTE) COMMAND CALL ALOUT CALL SPACE DEC CL JNZ LINLP1 CALL SPACE ; SUB SI,16 MOV CL,16 LINLP2: CALL HIGH ;ASCII LODSB ;LODS (BYTE) COMMAND CMP AL,0H JZ CHRFIX CMP AL,07H JZ CHRFIX ;(EXCEPTIONS) CMP AL,0AH JZ CHRFIX CMP AL,0DH JNZ CHROK CHRFIX: MOV AL,"." CHROK: CALL OUTPUT CALL LOW DEC CL JNZ LINLP2 JMP CRLF ; ;---------------------------------------- ; ; PAGE CENTERING FIX ; FIX: MOV AX,[RIP] SUB AX,[PAGE] JNC TOPOK ;OFF TOP OF DISPLAY PAGE? MOV AX,[RIP] AND AX,0FFF0H MOV [PAGE],AX TOPOK: ; MOV AX,[PAGE] ADD AX,0FFH ;OFF BOTTOM OF DISPLAY PAGE? SUB AX,[RIP] JNC BOTOK MOV AX,[RIP] AND AX,0FFF0H SUB AX,0F0H MOV [PAGE],AX BOTOK: RET ; ;========================================================== ; ; SINGLE STEP OR RUN (INSIDE OUT INTERRUPT) ; STEP: MOV AX,[RFG] OR AX,100H ;SINGLE STEP FLAG BIT ON MOV [RFG],AX ; RUN: MOV AX,[RSS] ;"RESTORE" USER STACK CLI MOV SS,AX MOV SP,[RSP] STI ; ;PUSH [RFG] DW 36FFH,RFG ;SETUP IRET STUFF ;PUSH [RCS] ;(ON USER'S STACK) DW 36FFH,RCS ;PUSH [RIP] DW 36FFH,RIP ;(ASSEMBLER WORKAROUND) ; MOV AX,[RES] ;"RESTORE" ALL REGISTERS MOV ES,AX MOV BP,[RBP] MOV DI,[RDI] MOV SI,[RSI] MOV DX,[RDX] MOV CX,[RCX] MOV BX,[RBX] ; ;PUSH [RAX] DW 36FFH,RAX ;THESE ARE TRICKY MOV AX,[RDS] ;BECAUSE WE LOSE THE MOV DS,AX ;D-SEGMENT REGISTER POP AX ; IRET ;GO DO IT USING A INTERRUPT RETURN ;---------------------------------------------------------- ; ;THEN "RETURN" USING AN INTERRUPT ; ; INTERRUPT 1 (STEP) OR 3 (BREAK) RETURNS ; (FLAGS,CS,IP ARE ON STACK) ; VECTOR: PUSH DS ;SAVE THESE (ON THE USER STACK) PUSH AX ;BECAUSE WE NEED THE REGISTERS MOV AX,CS MOV DS,AX ;TO GET ACCESS TO MEMORY ; POP AX MOV [RAX],AX ;RECOVER AX MOV [RBX],BX MOV [RCX],CX ;SAVE ALL REGISTERS MOV [RDX],DX MOV [RSI],SI MOV [RDI],DI MOV [RBP],BP ; ;POP [RDS] ;SEGMENT REGISTERS ;DWL 368FH,RDS ;(WORKAROUND) POP AX MOV [RDS],AX MOV AX,ES MOV [RES],AX ; ;POP [RIP] ;RECOVER IRET STUFF FROM STACK ;DWL 368FH,RIP ;(WORKAROUND) POP AX MOV [RIP],AX ;POP [RCS] ;DWL 368FH,RCS POP AX MOV [RCS],AX ;POP [RFG] ;DWL 368FH,RFG POP AX MOV [RFG],AX ; MOV AX,SS ;RECOVER USER STACK POINTERS MOV [RSS],AX MOV [RSP],SP ; MOV AX,[RFG] AND AX,0FEFFH ;SINGLE STEP FLAG BIT OFF MOV [RFG],AX ; JMP RESTART ;RESTART PROGRAM LOOP ; ;========================================================== ; ; MONITOR VARIABLES ; PAGE: DW 100H ;BEGINNING OF DISPLAY PAGE SEGSAV: DW 0 OFF: DW 0 ;SEG:OFF OF OLD INTERRUPT VECTORS KEY: DW 20H ;IMAGE OF LAST TYPED KEY ; ; Messages: ; MTYPE: DB "TYPE:",0 MHEADS: DB " HEADS:",0 MTRCKS: DB " TRACKS:",0 MSECTS: DB " SECTORS:",0 MDISK: DB "DISK:",0 MHEAD: DB " HEAD:",0 MTRCK: DB " TRACK:",0 MSECT: DB " SECTOR:",0 MLOG: DB " LOGICAL:",0 MAX: DB 13,10,"AX:",0 MBX: DB " BX:",0 MCX: DB " CX:",0 MDX: DB " DX:",0 MSI: DB " SI:",0 MDI: DB " DI:",0 MBP: DB " BP:",0 MSP: DB " SP:",0 MCS: DB 13,10,"CS:",0 MDS: DB " DS:",0 MES: DB " ES:",0 MSS: DB " SS:",0 MIP: DB " IP:",0 MFG: DB " FLAGS:",0 MINST: DB " INST:",0 MKEY: DB " KEY: ",0 MFPU: DB 13,10,"FPU:",0 MEND: DB 13,10,10,0 ;================================================ ; ; R/W LOGICAL SECTOR ; ;---------------------------------------- ; ; READ BOOT RCORD (AND CALCULATE TRACK SIZE) ; USE THIS THE FIRST TIME ; AINIT: ;ALWAYS INITIATE MOV AL,0 MOV [DTP],AL ;DISABLE ; MOV SI,2 ;RETRY COUNT IRTRY: MOV AX,201H ;READ (AH=2) ONE SECTOR (AL=1) MOV BX,[RBX] ;(BOOT SECTOR TO BX BUFFER) MOV CX,1 ;TRACK=0 SECTOR=1 MOV DH,0 ;HEAD=0 MOV DL,[PRWD+1] ;GET DRIVE NUMBER INT 13H ; JNC RDOK DEC SI ;RETRY? JNZ IRTRY JMP SHORT ERROR ;READ ERROR ; ; Xfer Info ; RDOK: MOV SI,[RBX] ;XFER BOOT RECORD MOV DI,BOOTRC MOV CX,15 ;MOVE 30 BYTES (15 WORDS) REPNZ MOVSW ;DFB 0A5H ;(MOVS WORD PTR) ; MOV AX,[HPD] IMUL WORD [SPT] MOV [HXS],AX ;CALCULATE SIZE OF TRACK RET ; ;---------------------------------------- ; ; CONVERT LOGICAL TO PHYSICAL SECTORS ; LOG2PH: MOV AX,[LGSEC] XOR DX,DX ;GET LOGICAL (RAX) IDIV WORD [HXS] ;/(HEADS*SECTORS) MOV [PRWC+2],AL ;SAVE TRACK MOV AX,DX XOR DX,DX ;GET REMAINDER IDIV WORD [SPT] ;/SECTORS MOV [PRWD+2],AL ;SAVE HEAD INC DX ;STARTS AT 1 MOV [PRWC+1],DL ;REMAINDER IS SECTOR RET ; ;---------------------------------------- ; ; LOGICAL SECTOR READ (ADVANCES BX) RDLGC: ; MOV SI,2 ;RETRY COUNT LRWLP: MOV AX,201H ;READ AH=2 AL=SECTOR COUNT (1-9) MOV BX,[RBX] ;MEMORY BUFFER OFFSET MOV CX,[PRWC+1] ;TRACK (0-39), SECTOR (1-9) MOV DX,[PRWD+1] ;HEAD (0-1), DRIVE (0-3) INT 13H ; JNC LRWND DEC SI ;RETRY? JNZ LRWLP ; LRWND: MOV [RBX],BX ERROR: RET ;(RET FAR PTR) ; ;------------------------------------------------ ; ; READ OR WRITE LOGICAL SECTORS (IN AX) ; DRIVE IN DL (0=A:, 1=B:) ; MEMORY BUFFER: [BX] ; WRITLG: MOV CX,301H ;WRITE AH=3 AL=SECTOR COUNT (1-9) JMP SHORT MERGLG ; READLG: MOV CX,201H ;READ AH=2 AL=SECTOR COUNT (1-9) MERGLG: PUSH CX ;SAVE READ OR WRITE COMMAND PUSH DX ;SAVE DRIVE ; XOR DX,DX ;LOGICAL SECTOR IN AX IDIV WORD [HXS] ;/(HEADS*SECTORS) MOV CH,AL ;CH=TRACK ;MOV CL,AH ;CL=MS2BITS ;ROR CL ;ROR CL ; MOV AX,DX XOR DX,DX ;GET REMAINDER IDIV WORD [SPT] ;/SECTORS MOV DH,AL ;DH=HEAD ; INC DL ;SECTOR=REMAINDER+1 MOV CL,DL ;CL=SECTOR ;OR CL,DL ; POP AX ;POP DRIVE MOV DL,AL ;DL=DRIVE ; MOV SI,2 ;RETRY COUNT POP AX ;READ/WRITE COMMAND ; RTYLG: PUSH AX INT 13H JNC ENDLG POP AX DEC SI ;RETRY? JNZ RTYLG PUSH AX ENDLG: POP CX RET ;(RET FAR PTR) ; ;================================================ ; END ;end of code