PAGE 63,132 ; printer format name _800 ; 800 Rel II Ver 1.80 ; WARNING: this program must be assembled, linked ; and converted to .COM . code segment assume cs:code org 0h new_base db 11 dup (?) ; room for base table org 80h prmlen db ? ; Length of command line parameters prm db 7fh dup (?) ; Command line org 100h ; .COM format res_sh_par equ 10 ; resident shift in paragraphs res_sh_byt equ res_sh_par*16 ; resident shift in bytes start_resident: begin: jmp init ; jmp to initialization oldint13 dd ? ; old int 13 (disk) dosver dw ? pspseg dw ? ; table of format-gap and media-state. ; sectors, ; format-gap and media-state for double_den, ; high_den, micro, micro144. ; 0=format not supported. low80 equ 54h ; media_state for 80 track low density low80co equ 57h ; media_state compatibility mode sct_cyl dw 2a0ah ; 360K drive: 43 Tracks, 10 sectors dw 5411h ; 1200K drive: 85 Tracks, 17 sectors dw 540ah ; 720K drive: 85 Tracks, 10 sectors dw 5414h ; 1440K drive: 85 Tracks, 20 sectors state_gap db 09h,50h,93h,50h,74h,50h,97h,50h,97h ; 360K db 0ah,2ah,93h,2ah,74h,2ah,97h,2ah,97h ; 400K db 0fh,00h,00h,54h,15h,00h,00h,6ch,17h ;1200K db 11h,00h,00h,1eh,15h,00h,00h,6ch,17h ;1360K db 12h,00h,00h,00h,00h,00h,00h,6ch,17h ;1440K db 14h,00h,00h,00h,00h,00h,00h,29h,17h ;1600K db 00h ; end of table base_tbl db 0dfh,002h,025h,002h,009h,01bh,0ffh,050h,0f6h,00fh,008h ; 720K base table base_length equ size new_base my_boot label byte ; 800KB 5¬" boot sector changes jmp $+3 ; system ID overwritten. nop ; reset double step bit and byte ptr cs:[490h],11011111b db 0ebh ; jmp (to boot program). my_boot_len equ $-offset my_boot drive db 0,0 ; drive types chgav db 0,0 ; change line available flag nodrive equ 0 ; no drive double_den equ 1 ; 360K drive high_den equ 2 ; 1.2M drive micro equ 3 ; 3« inch 720K drive micro144 equ 4 ; 3« inch 1.44M drive drive_sel equ byte ptr ds:[43Fh] ; Drive Select Status media_ctl equ byte ptr ds:[48Bh]; Last Data & Step Rate media_state equ byte ptr ds:[490h+si] ; (data rate, double step, etc) DRS_port equ 3f7h ; Data Rate Select bps_300 equ 01000000b ; 300bps data rate (only 5¬ low-density) ST2 equ byte ptr ds:[444h] ; ST2: controller status wrongcyl equ 00010000b ; Wrong cylinder bit media_known equ 00010000b ; media type already established base_point equ ds:[1eh*4] ; pointer to base table. lastsct equ es:[bx+4] ;last sector in base_table double_step equ 00100000b ; double step bit on equ 1 off equ 0 inv_cmd equ 2 ; invalid prm on command line. cmd db 1 ; 1 when 800 is active. PAGE oldint13p proc ; call old int 13 handler pushf cli call oldint13 ret oldint13p endp reset proc pushf push ax mov ah,0 ; reset disk call oldint13p pop ax popf ret reset endp test300 proc push ax ; test 300Kbs (360KB in 1.2MB) mov al,media_state ; (720KB in 1.2MB) and al,11000000b ; (800KB in 1.2MB) cmp al,bps_300 pop ax ret test300 endp setCTR proc push ax push bx push dx mov bl,media_ctl mov al,media_state ; media_state.tr_rate=>media_ctl.LASTRATE rol al,1 rcl bl,1 rol al,1 rcl bl,1 ror bl,1 ror bl,1 mov media_ctl,bl and al,11b mov dx,DRS_port ; set Controller Transfer Rate out dx,al pop dx pop bx pop ax ret setCTR endp setESDI proc ; input CH=Cylinders CL=sectors push ax ; output ES:DI base table push bx push dx mov al,drive[si] cbw cmp al,double_den jb exitCY cmp al,micro144 ja exitCY cmp ch,84 ; max 85 tracks. ja exitCY xor bx,bx foloop: mov dl,state_gap[bx] ; look for format in table or dl,dl jz exitCY cmp dl,cl ; format found jae fofound add bx,09h ; loop. jmp foloop fofound: push di mov di,ax shl di,1 mov dx,word ptr state_gap[bx+di-1] ; load dl=gap pop di or dx,dx ; dh=media state je exitCY set_st_gap: cmp ch,42 ; if tracks>43 ... jbe fook cmp al,high_den ja fook jb exitCY ; ... and drive=360K then not supported. cmp dh,74h ; ... and drive=1.2M and low-density then jne fook core2: mov dh,low80 ; set single step. fook: mov media_state,dh ; set media state ; set BASE TABLE mov base_tbl[4],cl ; set EOT mov base_tbl[7],dl ; set format gap push cs ; move 1.6M,1.44M,1.36M,800K,400K,720K base table pop es ; on new_base push cx push si mov di,offset new_base+res_sh_byt mov si,offset base_tbl mov cx,base_length push ds push cs pop ds cld rep movsb pop ds pop si pop cx mov di,offset new_base+res_sh_byt ;ES:DI points to base table. exitNC: clc jmp short exitESDI exitCY: stc ; format not supported. exitESDI: pop dx pop bx pop ax ret setESDI endp PAGE newint13 proc sti ; new int 13h handler cmp ah,18h jne chkon cmp cx,0fedch ; answer to installation request jne chkon push cs pop es ; ES:=CS mov ax,0ba98h stc retf 2 chkon: cmp cmd,off je oldi cmp ah,1 jbe oldi cmp dl,1 ; do oldint if Hard-disk request jbe continue oldi: cli jmp oldint13 continue: push ds push si xor si,si ; set DS to seg 0000h mov ds,si mov si,dx ; save drive number and si,00000001b cmp ah,5 jae chkbootwr push es ; read/write/verify push bx push dx les bx,base_point mov dl,cl add dl,al dec dl cmp dl,lastsct jbe donoth mov dh,1bh mov lastsct,dx ; allows 1.6MB read/write/verify donoth: pop dx pop bx pop es cmp drive[si],high_den ; 1.2MB drive jne chkbootwr test media_state,media_known ; media unknown jnz chkbootwr ; establish media call test300 ; low density in 1.2MB jne establ mov media_state,61h ; 360/1.2 not established establ: push ax push cx mov ax,0401h ; verify command on trk 0 to make mov cx,0001h ; disk type established. call oldint13p jnc twc pop cx ; can't establish media. pop si jmp short intexit twc: call test300 ; low density in 1.2MB drive jne popchkboot mov ax,0401h ; verify track 1 to know mov ch,01h ; if double step needed. call oldint13p test ST2,wrongcyl ; if wrong cyl then single step needed call reset je popchkboot core1: mov media_state,low80 popchkboot: pop cx pop ax chkbootwr: cmp ah,3 jne chk08 cmp cx,0001h ; writing boot sector ? jne oldint cmp dh,0 jne oldint call test300 ; double density in 1.2M drive jne oldint test media_state,double_step ; 80 track jnz oldint cmp byte ptr es:[bx+1],01h ; is boot OK for 5¬ 800K ? je oldint push di ; change boot sector before writing push si push cx mov cl,es:[bx+1] sub cl,9 mov es:[bx+my_boot_len],cl mov di,bx mov si,offset my_boot mov cx,my_boot_len push ds push cs pop ds cld rep movsb pop ds pop cx pop si pop di oldint: call oldint13p ; call old int 13h handler intexit : pop si pop ds retf 2 chk08: cmp ah,08h ; get drive parameters jne chk18 mov bl,drive[si] ; drive type mov dh,01 ; 2 heads push bx xor bh,bh dec bl shl bl,1 mov cx,sct_cyl[bx] ; CL=sectors CH=tracks pop bx call setESDI jc oldint mov dl,2 ; 2 drives cmp drive[1],0 jne ok2 dec dl ok2: clc xor ah,ah jmp intexit chk18: cmp ah,18h ; set media type for format ? jne oldint push ax cmp chgav[si],1 ; change line available ? jne exitcl mov ah,16h call oldint13p ; change line active ? jnc exitcl push cx push dx mov ax,0401h mov cx,0001h ; reset change line mov dh,0 call oldint13p cmp ah,80h ; exit on drive not ready error pop dx pop cx call reset jne exitcl stc pop si ; to compensate PUSH AX jmp short intexit exitcl: pop ax call setESDI jc oldint cmp word ptr chgav,0 je noCTR call setCTR noCTR: clc jmp intexit newint13 endp oldint21 dd ? ID_1 dw 02d0h ; 360K drive dw 0960h ; 1.2M drive dw 05a0h ; 720K drive ID_4 dw 0b40h ; 1.44M drive Searchlen equ (offset ID_4 - offset ID_1 + 2) / 2 f44_chgs db 00h ; device type db 2bh ; 43 tracks (360K drive) db 01h ; sectors/cluster dw 0070h ; root entries dw 035ch ; total sectors db 0f0h ; media type db 03h ; sectors/FAT db 0ah ; sectors/track entrylen equ $-offset f44_chgs db 01h db 55h ; 85 tracks (1.2M drive) db 01h dw 00e0h dw 0b4ah db 0f0h db 09h db 11h db 07h db 55h ; (720K drive) db 01h dw 00e0h dw 06a4h db 0f0h db 05h db 0ah db 07h db 55h ; (1.44M drive) db 01h dw 00e0h dw 0d48h db 0f0h db 0ah db 14h ; Alternate tables: for prgs<>diskcopy IDA_1 dw 035ch ; 360K drive dw 0b4ah ; 1.2M drive dw 06a4h ; 720K drive IDA_4 dw 0d48h ; 1.44M drive f44_achgs db 00h db 28h ; 40 tracks (360K drive) dos4_1: db 02h dw 0070h dw 02d0h ; total sectors db 0fdh ; media type dos4_2: db 02h ; sectors/FAT db 09h ; sectors/track db 01h db 50h ; 80 tracks (1.2M drive) db 01h dw 00e0h dw 0960h db 0f9h db 07h db 0fh db 02h db 50h ; (720K drive) dos4_3: db 02h dw 0070h dw 05a0h db 0f9h dos4_4: db 03h db 09h db 07h db 50h ; (1.44M drive) db 01h dw 00e0h dw 0b40h db 0f0h db 09h db 12h fname1 db 'DISKCOPY' fname1len equ $-offset fname1 fname2 db 'DISKCOMP' fname2len equ $-offset fname2 fname3 db 'FORMAT' fname3len equ $-offset fname3 newint21 proc sti cmp ax,440dh ; IOctl get default device parameters jne jmpoldint21 cmp cx,0860h jne jmpoldint21 xchg bx,dx test byte ptr ds:[bx],1 ; BPB from disk or default ? xchg dx,bx jz dochgs jmpoldint21:cli jmp oldint21 ; from disk dochgs: pushf ; from default cli call oldint21 pushf push es push ax push bx push cx push si push di push dx push ds cmp cmd,on je donew21 jmp exitsrc donew21: mov ah,62h ; get PSP address of current process pushf cli call oldint21 mov ds,bx mov pspseg,bx mov ds,ds:[2ch] ; get environment address mov si,0ffffh loopen: inc si cmp word ptr ds:[si],0000h ; find end of environment jne loopen add si,3 loopname: inc si cmp byte ptr ds:[si],00h ; find end of full filename. jne loopname loopfname: dec si and byte ptr ds:[si],11011111b ; lower to uppercase cmp byte ptr ds:[si],'\' ; find begin of filename. jne loopfname inc si push cs pop es mov dx,si mov di,offset fname1 ; Is Diskcopy running ? mov cx,fname1len cld repe cmpsb je exitsrc mov si,dx mov di,offset fname2 ; Is Diskcomp running ? mov cx,fname2len repe cmpsb je exitsrc cmp dosver, 0500h ; DOS 5+ ? jb exitsrc mov si,dx mov di,offset fname3 ; Is Format running ? mov cx,fname3len repe cmpsb jne exitsrc mov ds,pspseg ; look for /T on cmd-line mov di,0 ; look for '/' mov si,0 mov cl,ds:[80h] ; prmlen slhlopp: mov bl,ds:[81h+si] cmp bl,'/' jne proxcf inc si dec cl mov bx,word ptr ds:[81h+si] or bx,2020h ; upper_case to lower_case cmp bx,':t' je exitsrc proxcf: inc si dec cl jg slhlopp cmp cl, 1 ; reset Z flag exitsrc: pop ds pop bx push dx mov ax,word ptr ds:[bx][0fh] ; look for media type ; (total sectors). mov cx,searchlen push cs pop es mov dx,offset f44_achgs jne contchgs mov dx,offset f44_chgs contchgs: mov si,offset ID_1 mov di,si cld repne scasw je chgs mov cx,searchlen mov si,offset IDA_1 mov di,si repne scasw jne exit21 chgs: sub di,si dec di dec di shr di,1 mov ax,di mov cl,entrylen mul cl mov di,ax add di,dx mov al,es:[di] ; device type. mov ds:[bx][01h],al mov al,es:[di][1] ; change device parameter mov ds:[bx][04h],al ; table: tracks, mov al,es:[di][2] mov ds:[bx][09h],al mov ax,es:[di][3] mov ds:[bx][0dh],ax mov ax,es:[di][5] mov ds:[bx][0fh],ax ; total sectors, mov ax,es:[di][7] mov ds:[bx][11h],ax ; media type & sectors/FAT, mov al,es:[di][9] mov ds:[bx][14h],al ; sectors/track. exit21: pop dx pop di pop si pop cx pop bx pop ax pop es popf retf 2 newint21 endp end_resident: resident_length equ end_resident - start_resident resident_par equ (resident_length+100h-res_sh_byt-1)/16+1 PAGE assume ds:code,ss:code ; initialized by DOS (.COM) inst_msg db 10 db ' ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿',13,10 db ' ³ 800 II Diskette BIOS Enhancer Version 1.80 July 14th 1991 ³',13,10 db ' ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´',13,10 db ' ³ Copyright (c) 1991 Alberto Pasquale All rights reserved ³',13,10 db ' ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´',13,10 refmsg: db ' ³ Drive A: 800 now O ³',13,10 db ' ³ Drive B: 800h for help. ³',13,10 db ' ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ',13,10,'$' inv_cmd_msg db 10 db ' ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿',13,10 refmsg2: db ' ³ WARNING: ³',13,10 db ' ³ ³',13,10 db ' ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ',13,10,7,7,'$' invcmdmsg db 'Invalid command^' invcmdmsglen equ $-offset invcmdmsg linelongmsg db 'Command line too long !' linelongmsglen equ $-offset linelongmsg inv_dos_msg db 10 db ' ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿',13,10 db ' ³ WARNING: 800 II requires DOS 3.30 or later for full performance !!! ³',13,10 db ' ³ Some DOS commands may malfunction. ³',13,10 db ' ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ',13,10,7,7,'$' drivetypemsg dw offset notinstmsg dw offset doubdenmsg dw offset highdenmsg dw offset micro72msg dw offset micro14msg dw offset invdrivmsg notinstmsg db ' Not Installed. ' doubdenmsg db ' 360KB (5¬"). ' highdenmsg db ' 1.2MB (5¬"). ' micro72msg db ' 720KB (3«"). ' micro14msg db ' 1.44MB (3«"). ' invdrivmsg db ' Unknown type. ' drivemsglen equ $-offset invdrivmsg compmsg db '(Compatibility mode)' compmsglen equ $-offset compmsg compat1 equ byte ptr offset core1+4 ; locations to be changed compat2 equ byte ptr offset core2+1 ; in compatibility mode. inst_flag db 0 ; 1 if 800 already installed ke_flag db 0 ; 1 if /ke switch used set21 db on ocmd db ? wrdos proc mov ah,9 ; writes string by DOS int 21h ret wrdos endp readcmd proc ; read parameter on command line cmp prmlen,0 ja contrd ret contrd: mov di,0 ; look for '/' mov si,0 mov cl,prmlen slhloop: mov bl,prm[si] cmp bl,'/' je chkcmd cmp bl,' ' je proxch invalid: mov al,es:cmd mov cs:ocmd,al mov es:cmd,inv_cmd ; show invalid command line parameter push es push cs pop es cmp prmlen,59 ja linelong lea di,offset refmsg2+18+81+1-invcmdmsglen[si] mov si,offset invcmdmsg mov cx,invcmdmsglen cld rep movsb mov si,offset prm mov di,offset refmsg2+18 xor ch,ch mov cl,prmlen cld rep movsb jmp short exitinv linelong: mov si,offset linelongmsg ; show line too long msg mov di,offset refmsg2+19 mov cx,linelongmsglen cld rep movsb exitinv: pop es mov dx,offset inv_cmd_msg call wrdos ret proxch: inc si dec cl jnz slhloop ret chkcmd: cmp cl,2 jb invalid inc si dec cl mov bx,word ptr prm[si] or bx,2020h ; upper_case to lower_case cmp bl,'0' ;/0 jne chk36 cmp di,1 ja invalid mov es:drive[di],nodrive inc di cmp cl,2 jb proxch cmp bx,'00' jne proxch jmp indec chk36: cmp cl,2 jb jinvalid cmp bx,'63' ;/36 jne chk12 cmp di,1 ja jinvalid mov es:drive[di],double_den inc di jmp indec chk12: cmp bx,'21' ;/12 jne chk72 cmp di,1 ja jinvalid mov es:drive[di],high_den inc di jmp indec chk72: cmp bx,'27' ;/72 jne chk14 cmp di,1 ja jinvalid mov es:drive[di],micro inc di jmp indec chk14: cmp bx,'41' ;/14 jne chkco cmp di,1 jbe set14 jinvalid: jmp invalid set14: mov es:drive[di],micro144 inc di jmp short indec chkco: cmp bx,'oc' ;/CO jne chkke mov bl,low80 cmp es:compat1,low80co je set_co mov bl,low80co set_co: mov es:compat1,bl mov es:compat2,bl jmp short indec chkke: cmp bx,'ek' ;/KE jne chkcmdon cmp inst_flag,1 jne setkeflag jmp invalid setkeflag: mov ke_flag,1 jmp short indec chkcmdon: cmp bx,'no' ;/ON jne chkcmdof mov es:cmd,on jmp short indec chkcmdof: cmp bx,'fo' ;/OFF je setoff jmp invalid setoff: cmp cl,3 jae chkf jmp invalid chkf: cmp prm[si+2],'F' je cmof cmp prm[si+2],'f' je cmof jmp invalid cmof: inc si dec cl mov es:cmd,off indec: inc si dec cl jmp proxch readcmd endp show_ins proc mov si,0 showtype: mov dl,es:drive[si] ; show drive types xor dh,dh mov di,dx cmp di,4 jbe typeok mov di,5 typeok: shl di,1 lea di,drivetypemsg[di] push si push es cmp si,1 mov si,[di] push cs pop es mov di,offset refmsg+13 jne typecont add di,81 typecont: mov cx,drivemsglen cld rep movsb pop es pop si inc si cmp si,1 jbe showtype cmp es:cmd,off je prgoff ; show 800 state mov word ptr refmsg+50,' n' mov byte ptr refmsg+52,'!' jmp showco prgoff: mov word ptr refmsg+50,'ff' mov word ptr refmsg+52,'! ' showco: cmp es:compat1,low80 je showin push es push cs ; copy compatibility msg pop es mov si,offset compmsg mov di,offset refmsg+56 mov cx,compmsglen cld rep movsb pop es showin: mov dx,offset inst_msg ; show name msg call wrdos ret show_ins endp estmedia proc push ds ; make 360K in 1.2M unestablished xor ax,ax mov ds,ax mov si,1 setmedia: mov al,media_state and al,11000000b cmp al,bps_300 jne try_next mov media_state,61h try_next: dec si jz setmedia pop ds ret estmedia endp get_drive proc cmp bl,0 ja enddr ; valid drive type from service #8 mov bl,4 cmp cx,4f12h ; type 4: 1.44M drive je enddr dec bl cmp cx,4f09h ; type 3: 720K drive je enddr dec bl cmp cx,4f0fh ; type 2: 1.2M drive je enddr dec bl cmp cx,2709h ; type 1: 360K drive je enddr dec bl ; type 0: not installed enddr: ret get_drive endp use1st proc push es mov ah,08h mov dl,00h int 13h mov ah,08h mov dl,01h int 13h pop es ret use1st endp init: mov ah,18h ; initialization mov dl,8Fh mov cx,0fedch int 13h ; installation check cmp ax,0ba98h ; if installed then ES=resident segment jne notinsted mov inst_flag,1 jmp short rdcmd notinsted: mov ah,15h ; read DASD type for drive 0 mov dl,0 int 13h jc eseqcs push ax push si push ds mov ax,0 ; Set Last Transfer Rate mov ds,ax mov al, drive_sel shr al,1 shr al,1 shr al,1 shr al,1 and ax, 11b mov si, ax call setCTR pop ds pop si pop ax cmp ah,2 ; change line available ? jne chkd1 mov chgav[0],1 ; set change line available flag chkd1: mov ah,15h ; read DASD type for drive 1 mov dl,1 int 13h cmp ah,2 ; change line available ? jne eseqcs mov chgav[1],1 ; set change line available flag eseqcs: push cs pop es rdcmd: call readcmd ; read command line parameters cmp es:cmd,inv_cmd jne cmpins mov al,cs:ocmd mov es:cmd,al mov al,1 ; return code if error on cmd line jmp exit cmpins: cmp inst_flag,1 je showins cmp word ptr es:drive,0 jne showins mov ah,8 ; set number of tracks of both drives xor dl,dl push es int 13h pop es jc cmosread call get_drive mov es:drive[0],bl mov ah,8 mov dl,1 push es int 13h pop es call get_drive mov es:drive[1],bl jmp short showins cmosread: push ds mov ax,0f000h mov ds,ax mov al,ds:[0fffeh] ; System ID pop ds cmp al,0fdh ; do not read CMOS-RAM if PC or XT jae read_sw cmp al,0fbh jne readcmos read_sw: int 11h ; get configuration test al,1 ; are there drives ? jz showins mov es:drive[0],1 ; at least 1 drive. mov cl,6 shr al,cl cmp al,1 ; are there 2 drives ? jb showins mov es:drive[1],1 jmp short showins readcmos: mov al,10h ; read drive type from CMOS-RAM out 70h,al jmp $+2 jmp $+2 jmp $+2 in al,71h xor ah,ah mov cx,4 divdr: shr al,1 rcl ah,1 loop divdr mov word ptr es:drive,ax showins: call show_ins call estmedia cmp inst_flag,1 jne install call use1st mov al,00h ; return code exit: mov ah,4ch ; exit int 21h install: mov ah,30h ; check dos version int 21h xchg ah,al mov dosver, ax cmp ax,0400h ; 4.0 jb dos3 cmp ax,0500h ; 5.0 jae dos3 mov byte ptr dos4_1,1 ; set 360KB/720KB drive defaults mov byte ptr dos4_2,3 ; to 1sct/clust mov byte ptr dos4_3,1 mov byte ptr dos4_4,5 dos3: cmp ax,031Eh ; 3.30 or later jae cont_ins cmp ax,0314h ; 3.20 jae wrinvmsg mov cs:set21,off ; disable new INT21 wrinvmsg: mov dx,offset inv_dos_msg call wrdos cont_ins: cmp ke_flag,1 je saveold13 mov es,cs:[2ch] ; release environment mov ah,49h int 21h saveold13: mov ax,3513h ; save old INT 13h vector int 21h mov word ptr oldint13,bx mov word ptr oldint13+2,es mov ax,3521h ; save old INT 21h vector int 21h mov word ptr oldint21,bx mov word ptr oldint21+2,es mov ax,cs ; move resident on PSP sub ax,res_sh_par mov es,ax push es mov si,offset start_resident mov di,si mov cx,resident_length cld rep movsb pop ds mov dx,offset newint13 mov ax,2513h ; steal INT13 vector int 21h cmp cs:set21,on jne TSR mov dx,offset newint21 mov ax,2521h ; steal INT21 vector int 21h TSR: mov dx,resident_par ; Terminate but Stay Resident mov ax,3100h int 21h code ends end begin