📄 second.s
字号:
call sread ! load the sector(s) mov tempal,al pop bx ! get pointer to GDT push ax ! just in case ... push cx push si mov si,bx ! turn ES:SI into pointer to GDT push ds pop es xor cx,cx ! number of words to move mov ch,tempal#ifdef DEBUG push si push bx push cx mov al,(si+0x14) call bout mov ax,(si+0x12) call wout mov bx,#mov_ar call say mov ah,(si+0x1f) mov al,(si+0x1c) call wout mov ax,(si+0x1a) call wout mov bx,#mov_sz call say pop ax push ax call wout call crlf pop cx pop bx pop si#endif push [gdt+0x1e] push bx ! do the transfer. (save BX, CX and SI because push cx ! we are paranoid) push si mov ah,#0x87 ! Move Extended Memory Block int 0x15 pop si pop cx pop bx jc badmov ! failed ... pop ax ! check the GDT cmp ah,[gdt+0x1f] ! catch a BIOS that does not handle 386 ! addresses (>16Mb) jne badmov+1 ! AH error code will be hi byte of address shr cx,#8-1 ! convert words to bytes/256 sub ax,ax ! put ES back to 0 add (si+0x1b),cx adc (si+0x1f),al mov es,ax ! put ES back to 0 pop si pop cx pop ax ret ! donebadmov: pop bx ! discard GDT push ax ! save the error code mov bx,#msg_bm ! tell the user ... jmp reset ! (standard procedure calls say & bout)! Load a sequence of sectorssread: push bx ! save registers push cx push dx call cread mov di,ax ! save AL return count jc rerror ! error -> complain pop dx ! restore registers pop cxrokay: pop bx shl ax,8 ; convert sectors to bytes add ah,ah jc dowrap ! loaded an entire segment -> advance ES add bx,ax ! move BX jnc nowrap ! same segment -> go ondowrap: mov ax,es ! move ES add ax,#0x1000 mov es,axnowrap: mov ax,di ! restore the block count in ALaret: ret ! done! Read error - try a second time and give up if that fails toorerror: push ax mov bx,#msg_re ! say somethingreset: call say pop ax ! display the error code mov al,ah call bout call crlf ! a CR/LF mov moff,#0 ! restore initial state#if DEBUG_NEW pop ax call swout ! DX pop ax call swout ! CX pop ax call swout ! BX call crlf#endif br restrt! Convert character in AL to upper caseupcase: cmp al,#0x61 ! lower case character ? ('a') jb nolower ! no -> go on cmp al,#0x7a ! 'z' ja nolower sub al,#0x20 ! convert to upper casenolower:ret ! done#if DEBUG_NEW | 1pause:#if !DEBUG_NEW pusha mov ax,#5200/55 ! delay 5+ seconds call settodelay1: test byte ptr timeout,#-1 jz delay1 popa#else pusha mov ah,#0x86 ! delay in microseconds mov cx,#3<<4 ! 3 seconds; forget DX int 0x15 popa#endif ret#endif#if DEBUG_NEW! display a double word, pushed into the stackdout: push bp mov bp,sp push ax mov ax,(bp+6) ! get high order call wout mov ax,(bp+4) ! get low order call wout pop ax leave ret 4! display a space, followed by a word in AXswout: push ax mov al,#32 call display pop ax; and fall into wout! Display a hexadecimal word/byte/nibblewout: push ax xchg al,ah call bout pop ax; must fall into bout#endifbout: push ax ! save byte shr al,#4 ! display upper nibble call nout pop axnout: and al,#0x0F ! lower nible only daa ! smaller conversion routine add al,#0xF0 adc al,#0x40 ! AL is hex char [0..9A..F] jmp display ! display it! part of the 'say' routine! actual entry point is below at 'say:'say_loop: cmp al,#10 ! \n ? jne nonl ! no -> go on mov al,#13 ! display a CRLF call display mov al,#10nonl: cmp al,#12 ! ^L ? jne nocls ! no -> go on#ifdef MENU call menu_form_feed ! simulate a FF#else#ifdef BITMAP cmp BYTE [abs_cx+1],#0 ; graphic screen on? jne tosnext#endif push bx mov ah,#0xf ! clear the local screen int 0x10 xor ah,ah int 0x10 pop bx#endiftosnext: jmp snext ! next characternocls: call display ! display, tty-stylesnext: inc bx ! next one! fall into say ! process next character! Display a NUL-terminated string on the consolesay: mov al,(bx) ! get byte or al,al ! NUL ? jnz say_loop ! not the end ret! Display CR/LFcrlf: mov al,#13 ! CR call display mov al,#10 ! LF;;; jmp display; fall into display! Display one character on the consoledisplay: push bx ! save BX#ifndef LCF_NOSERIAL call serdisp#endif#if defined(MENU) || defined(BITMAP) seg cs cmp word [suppress],#0 jnz dispret#ifdef MENU push ds push cs pop ds push dx cmp byte [abs_cx+1],#0 ! is special scrolling in effect? je goshowit ! jump if no special handling call mn_getcursor ! get cursor pos. in DX cmp al,#8 ! is it BS jne scroll1 or dl,dl ! at col. 0? jne goshowit; must simulate a BS mov dl,[mn_max_row_col] ! move to EOL mov al,#0x0a ! change to LF dec dh ! back up first of two lines jmp scroll_set ! set new cursor pos. & ring BELscroll1: cmp al,#0x0a ! test for LF / NL jne scroll2 cmp dh,[mn_max_row_col+1] ! bottom row jae scrollitscroll2: cmp al,#0x20 ! printing char? jb goshowit cmp dx,[mn_max_row_col] ! bottom corner jne goshowitscrollit: pusha mov ax,#0x601 ! scroll up 1 line mov bh,[mn_at_mono] mov cx,[abs_cx] mov dx,[mn_max_row_col] int 0x10 ! do the scroll popascroll_set: dec dh call mn_setcursor ! set cursor up 1 rowgoshowit: pop dx pop ds#endif#endif;;; xor bh,bh ! display on screen mov bx,#7 ! set color for TEXT interface mov ah,#14 int 0x10dispret: pop bx ! restore BX ret#ifndef LCF_NOSERIALserdisp:push dx ! wait for space in the send buffer seg cs mov dx,slbase or dx,dx jz serret add dx,#5 push axserwait:in al,dx test al,#0x10 ! break -> set break flag jz nobrk seg cs mov byte ptr break,#1nobrk: test al,#0x20 ! ready to send ? jz serwait ! no -> wait sub dx,#5 ! send the character pop ax out dx,alserret: pop dx ! done ret#endif! Get a key (CX = timeout exit)getkey: ;; BEG_FS;; SEG_FS ! set the timeout mov ax,par2_timeout ;DSC_OFF-10+SSDIFF;; END_FS call settogwtkey: mov ah,#1 ! is a key pressed ? int 0x16 jnz gotkey ! yes -> get it#ifndef LCF_NOSERIAL mov dx,slbase ! using a serial port ? or dx,dx jz gnokey ! no -> wait add dx,#5 ! character ready ? in al,dx test al,#1 jz gnokey ! no -> wait sub dx,#5 ! get it in al,dx and al,#0x7f ! strip 8th bit jnz gotch ! ignore NULs#endifgnokey: #if defined(MENU) || defined(BITMAP)#ifdef BITMAP cmp byte [abs_cx+1],#0 je no_timer_display#endif call timer_displayno_timer_display:#endif test byte ptr timeout,#1 ! timed out ? jz gwtkey ! no -> wait pop ax ! discard return address jmp cx ! jump to timeout handlergotkey: xor ah,ah ! read a key int 0x16 push bx ! keyboard translation (preserve BX) mov bx,#KEYTABLE xlatb pop bxgotch:#ifdef LCF_ONE_SHOT BEG_FS SEG_FS ! always enter prompt ? test byte ptr par1_prompt+SSDIFF,#FLAG_PROMPT jz noosht ! yes -> do not disable timeout;; SEG_FS ! disable timeout test byte ptr par2_flag2,#FLAG2_UNATTENDED jnz nocancel mov word ptr par2_timeout,#0xffffnocancel:noosht: END_FS#endif ret ! done! Shift wait loop (AX = timeout, returns CY set if interrupred)waitsh: call setto ! set timeoutactlp: mov ah,#2 ! get shift keys int 0x16 and al,#0x5f ! anything set ? (except NumLock) jnz shpress ! yes -> return with CY set#ifndef LCF_NOSERIAL mov dx,slbase ! using a serial port ? or dx,dx jz acnosp ! no -> go on cmp byte ptr break,#0 ! break received ? jnz shpress ! yes -> return with CY set add dx,#5 ! check for pending break in al,dx test al,#0x10 jnz shpress ! break received -> return with CY set#endifacnosp: test byte ptr timeout,#1 ! timed out ? jz actlp ! no -> wait clc ! clear carry ret ! doneshpress:stc ! set carry ret ! done! Timeout handlinginstto: push ds ! install the timeout handler push #0 pop ds cli ! no interrupts mov eax,[0x1c*4] ! get the old vector seg cs mov [int1c_l],eax ! save H & L parts mov [0x1c*4],#tick ! install new vector mov [0x1c*4+2],cs sti ! done pop ds retremto: push es ! remove the interrupt handler push #0 pop es mov eax,[int1c_l] ! restore the old vector seg es mov [0x1c*4],eax ! ** pop es ret! AX = ticks, 0xffff = no timeoutsetto: or ax,ax ! time out immediately ? jz toimmed ! yes -> do it cli ! set timeout value mov cntdown,ax mov byte ptr timeout,#0 ! clear timed-out flag sti ! done rettoimmed:mov byte ptr timeout,#0xff ! set the timed-out flag ret ! donetick: pushf ! save flags seg cs ! no timeout ? cmp word ptr cntdown,#0xffff je notzro ! yes -> go on seg cs ! decrement counter dec word ptr cntdown jnz notzro ! not zero -> go on seg cs ! set timeout flag mov byte ptr timeout,#0xffnotzro: seg cs push dword [int1c_l] iret ! continue with old interruptkt_set:;; BEG_FS;; SEG_FS ! load the keyboard translation table mov cx,par2_keytab ;MSG_OFF+SSDIFF+7;; SEG_FS mov dx,par2_keytab+2 ;MSG_OFF+SSDIFF+9;; SEG_FS mov al,par2_keytab+4 ;MSG_OFF+SSDIFF+11;; END_FS mov bx,#KEYTABLE ret#ifndef LCF_READONLY! Sector write; used for the keytable onlykt_write: push es push ds pop es call kt_set ; set for KEYTABLE i/o BEG_FS SEG_FS ! BIOS data collection worked before? test byte ptr par1_prompt+SSDIFF,#FLAG_BD_OKAY END_FS jnz kt_nowrite test byte ptr [par2_flag2],#FLAG2_EL_TORITO ; a CD? jnz kt_nowrite call cwritekt_nowrite: pop es ret! Sector write; used for the stored command line onlycmd_write: ;BEG_FS;SEG_FS mov cx,mt_dflcmd+KEYTABLE+256;SEG_FS mov dx,mt_dflcmd+2+KEYTABLE+256;SEG_FS mov al,mt_dflcmd+4+KEYTABLE+256;END_FS; fall into cwrite;; General sector write;cwrite:#ifdef FLAG_RAID_NOWRITE BEG_FS SEG_FS test byte ptr par1_prompt+SSDIFF,#FLAG_RAID_NOWRITE ; no writes? END_FS jnz cwok ; jump if no writing allowed#endif BEG_FS SEG_FS test byte ptr par1_prompt+SSDIFF,#FLAG_RAID ; is it a RAID write END_FS jnz cmd_raid_wrt mov byte ptr (dsk_wrflag),#WR_ENABLE ! flag write operation call cread mov byte ptr (dsk_wrflag),#0 ! flag read operation jnc cwok ! no error - returncnok: pusha cmp ah,#3 ! write protect error je cnok3 push ax ! save error code in AH mov bx,#msg_wrerr call say pop ax mov al,ah ! error code call bout call crlf ! leave space jmp cnok5cnok3: mov bx,#msg_wrerr3 ! write protect call saycnok5: popa stc ! flag error JRCcwok:#if DEBUG_NEW pushf call pause popf#endif ret ! donecmd_raid_wrt: test dl,#RAID_REL_FLAG ; relocation called for? jnz crw1 mov ah,#0x99 ; flag error jmp cnokcrw1: push si mov si,[rmask] ; get raid physical device maskcwrm = LINEAR_FLAG|LBA32_FLAG|LBA32_NOCOUNT|RAID_REL_FLAG|0X80 and dl,#cwrm ; save flags, set device to 80cwr2: shr si,#1 jnc cwr3 pusha mov byte ptr (dsk_wrflag),#WR_ENABLE ! flag write operation call cread_physical ; read the PHYSICAL device # mov byte ptr (dsk_wrflag),#0 ! flag read operation popacwr3: inc dx or si,si ; clears the carry jnz cwr2 pop si;;; clc ; signal no error jmp cwokcwr_cnt: .byte 0 ; device code countcwr_flags: .byte 0 ; saved flags#endifkt_read: ; KEYTABLE read call kt_set ; set for KEYTABLE i/o call cread jc keyerr mov si,#KEYTABLE ! compute a checksum of the keytable mov di,#SECTOR_SIZE - 8 ! skip the last 4+4 bytes push dword #CRC_POLY1 call crc32 add di,si cmp eax,dword (di) jz nokeyerr! Checksum errorkeyerr: mov bx,#msg_chkkey br zz ! go waitnokeyerr: ret! Sector read! enter with AL, CX, DX, ES, BX set for read! trashes CX and DI!cread: ; entry point for mapped device r/w call map_device ; DL (logical) -> DL (physical)cread_physical: ; same entry, device is not mapped test dl,#LINEAR_FLAG|LBA32_FLAG jnz use_linear push ax ;save the count mov ah,#2 ;read command call dsk_do_rw ; int 0x13 with retries pop cx ;Carry Set means error on read mov al,cl ;count in AL, error code in AH retuse_linear: mov ah,hinib ;will be zero for LINEAR xchg al,dh ;AX is possible address test dl,#LBA32_FLAG ;test for LBA32/LINEAR ***** jz lnread ;pure LINEAR ***** test dl,#LBA32_NOCOUNT jz lnread mov ah,dh ;former count is really hi-nibble mov hinib,ah mov dh,#1 ;set count to 1lnread: xchg di,ax ;hi-address to DI mov al,dh ;count to AL test dl,#RAID_REL_FLAG ; ******
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -