📄 second.s
字号:
push dx push ax#endif#else movzx edx,ax ! zero extend segment part to EDX movzx edi,di ! zero extend offset shl edx,4 ! make segment into address add edx,edi ! form long absolute address seg es mov CL_POINTER,edx ! and pass the address#if DEBUG_NEW push edx #endif#endif /* LCF_M386 */#if DEBUG_NEW call dout jmp cl_wait#else jmp start_setup#endif! the old command line passing protocolprotocol201: seg es mov CL_MAGIC_ADDR,#CL_MAGIC ! set magic number seg es mov word ptr CL_OFFSET,di#if DEBUG_NEW mov ax,es call wout mov al,#0x3A ! issue colon call display mov ax,di call woutcl_wait: call crlf call crlf jmp start_setup#endifstart_setup: ! kernel boot comes here#if DEBUG_NEW && defined(LCF_VIRTUAL) mov bx,#msg_real call vmtest jnc boot_real_msg mov bx,#msg_virtualboot_real_msg: call say#endif#ifdef LCF_BDATA mov bx,#msg_bc call say BEG_FS SEG_FS ! suppress BIOS data collection? test byte ptr par1_prompt+SSDIFF,#FLAG_NOBD ; suppress? END_FS jz start_setup3 mov bx,#msg_by call say jmp start_setup2start_setup3:#ifndef LCF_READONLY or byte ptr [KEYTABLE+256+mt_flag],#FLAG_NOBD ; suppress call kt_write#endif#if 0#if DEBUG_NEW call ss3 .ascii "BIOS check\ns" .byte 0ss3: pop bx call say#else mov al,#0x73 ! display an 's' call display#endif#endif /* if 0 */#if DEBUG_NEW call pause mov ah,#2 ! get keyboard flags int 0x16 and al,#0x70 ! Caps, Num, Scroll Lock flags cmp al,#0x70 je near zzz ! fail with all 3 on#endif call io_biosdata mov bx,#msg_s call say#ifndef LCF_READONLY; if the BIOS data collection was successful, do not suppress it on future boots and byte ptr [KEYTABLE+256+mt_flag],#~FLAG_NOBD ; no suppress call kt_write#endif#endifstart_setup2: ! chain loader boot comes here#if DEBUG_NEW call pause ! last chance to use the timer#endif call remto ! free timer interrupt push es pop ds#if 0 push es pop fs push es pop gs#endif#ifdef VAR_LOAD add sp,#SETUP_STACK_DYN ! increase stack size over this code seg cs push [setupseg] push #0 retf ! start the kernel setup code#else mov ax,cs shl ax,4 add ax,#SETUP_STACK_DYN mov sp,ax jmpi 0,SETUPSEG ! start the setup#endif! Load one sector (called from load)doload: pop bx ! restore ES:BX pop es! Load a sequence of sectors, possibly moving into "high memory" (> 1 MB)! afterwards.xread: push ax ! ES == 0 ? mov ax,es or ax,ax pop ax jz rdhigh ! yes -> read into high memory#ifdef DEBUG br sread#else jmp sread#endifrdhigh: push bx ! okay - DS:BX points to GDT in this case mov bx,#LOADSEG ! adjust ES:BX mov es,bx xor bx,bx 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:#if 0 /* we now have 5 tries down in cread */ xor ax,ax ! reset the disk mov dl,al int 0x13 pop dx ! try again pop cx pop bx push bx mov al,tempal call cread jnc rokay ! okay -> go on#endif 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 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_NEWpause: push ax mov ax,#3000/55 ! delay 3 seconds call settodelay1: test byte ptr timeout,#-1 jz delay1 pop ax 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 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 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,par1_timeout+SSDIFF ;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 mov word ptr par1_timeout+SSDIFF,#0xffffnoosht: 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#ifdef LCF_M386 mov eax,[0x1c*4] ! get the old vector seg cs mov [int1c_l],eax ! save H & L parts#else mov ax,[0x1c*4] ! get the old vector seg cs mov int1c_l,ax mov ax,[0x1c*4+2] seg cs mov int1c_h,ax#endif 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#ifdef LCF_M386 mov eax,[int1c_l] ! restore the old vector seg es mov [0x1c*4],eax ! **#else cli mov ax,int1c_l ! restore the old vector seg es mov [0x1c*4],ax mov ax,int1c_h seg es mov [0x1c*4+2],ax sti ! done#endif 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:#if 0 popf ! done seg cs jmpi (int1c_l) ! continue with old interrupt#else#ifdef LCF_M386 seg cs push dword [int1c_l]#else seg cs push word [int1c_h] seg cs push word [int1c_l]#endif iret ! continue with old interrupt#endifkt_set: BEG_FS SEG_FS ! load the keyboard translation table mov cx,par1_keytab+SSDIFF ;MSG_OFF+SSDIFF+7 SEG_FS mov dx,par1_keytab+2+SSDIFF ;MSG_OFF+SSDIFF+9 SEG_FS mov al,par1_keytab+4+SSDIFF ;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 call cwrite pop es ret! Sector write; used for the stored command line onlycmd_write: BEG_FS SEG_FS mov cx,par1_dflcmd+SSDIFF SEG_FS mov dx,par1_dflcmd+2+SSDIFF SEG_FS mov al,par1_dflcmd+4+SSDIFF END_FS; fall into cwrite;; General sector write;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -