📄 pcs.asm
字号:
;Ver 0.0.9 By Toby & Jrf;Ver 0.0.3;Created By Mike[bits 32][org 0x10000][segment .text]start: mov eax, cr0 and eax, 0x7FFFFFFF mov cr0, eax mov ax,datasel mov ss,ax mov eax, 0x7C00 mov esp, eax call .empty_8042 ;Enable A20 & Init Mem mov al,0xD1 out 0x64,al call .empty_8042 mov al,0xDF out 0x60,al call .empty_8042 mov eax,CodeA mov word [code_gdtA+2],ax mov eax,CodeB mov word [code_gdtB+2],ax mov eax,tmpputc mov word [putc_gdt],ax mov eax,changetr mov word [changetr_idt],ax mov ecx,gdt_end mov esi,gdt sub ecx,esi mov edi,0x2000 rep movsb xor edi,edi xor eax,eax mov ecx,0x400 ;Prepare Page Tables cld rep stosd mov dword [0],1007h mov dword [0xC00],1007h mov ecx,0x3FF mov edi,0x1FFC std .NextItem: mov eax,ecx shl eax,12 or eax,111b stosd loop .NextItem mov dword [0x1000],111b xor eax,eax mov cr3,eax mov eax,cr0 or eax,80000000h mov cr0,eax lgdt [gdtr] jmp codesel:gdt_end.empty_8042: wait in al,0x64 test al,2 jnz .empty_8042 retinit8259: mov al, 0xff out 0xa1, al cli lidt [idtr] mov al,0x11 ; initialization sequence out 0x20,al ; send it to 8259A-1 wait out 0xA0,al ; and to 8259A-2 wait mov al,0x20 ; start of hardware int's (0x20) out 0x21,al wait mov al,0x28 ; start of hardware int's 2 (0x28) out 0xA1,al wait mov al,0x04 ; 8259-1 is master out 0x21,al wait mov al,0x02 ; 8259-2 is slave out 0xA1,al wait mov al,0x01 ; 8086 mode for both out 0x21,al wait out 0xA1,al wait mov al,0x20 out 0x20,al wait mov al,00110110b ; bit 7,6 = (00) timer counter 0 ; bit 5,4 = (11) write LSB then MSB ; bit 3-1 = (011) generate square wave ; bit 0 = (0) binary counter out 43h,al ; prep PIT, counter 0, square wave&init count wait mov cx,0x0 ; default is 0x0000 (65536) (18.2 per sec) ; Now Set to 256 mov al,cl ; send LSB of timer count out 40h,al wait mov al,ch ; send MSB of timer count out 40h,al wait sti ret gdtr: dw 0xfff dd 0xc0002000 gdt: nullsel equ $-gdt ; $->current location,so nullsel = 0h gdt0: ; Null descriptor,as per convention gdt0 is 0 dd 0 ; Each gdt entry is 8 bytes, so at 08h it is CS dd 0 ; In all the segment descriptor is 64 bits codesel equ $-gdt ; This is 8h,ie 2nd descriptor in gdt code_gdt: ; Code descriptor 4Gb flat segment at 0000:0000h dw 0x0ffff ; Limit 4Gb bits 0-15 of segment descriptor dw 0x0000 ; Base 0h bits 16-31 of segment descriptor (sd) db 0x00 ; Base addr of seg 16-23 of 32bit addr,32-39 of sd db 0x09a ; P,DPL(2),S,TYPE(3),A->Present bit 1,Descriptor ; ; privilege level 0-3,Segment descriptor 1 ie code ; ; or data seg descriptor,Type of seg,Accessed bit db 0x0cf ; Upper 4 bits G,D,0,AVL ->1 segment len is page ; ; granula, 1 default operation size is 32bit seg ; ; AVL : Available field for user or OS ; ; Lower nibble bits 16-19 of segment limit db 0xc0 ; Base addr of seg 24-31 of 32bit addr,56-63 of sd datasel equ $-gdt ; ie 10h, beginning of next 8 bytes or data sd data_gdt: ; Data descriptor 4Gb flat seg at 0000:0000h dw 0x0ffff ; Limit 4Gb dw 0x0000 ; Base 0000:0000h db 0x00 ; Descriptor format same as above db 0x092 db 0x0cf db 0xc0 codeselA equ $-gdt+3 ; This is 8h,ie 2nd descriptor in gdt code_gdtA: ; Code descriptor 4Gb flat segment at 0000:0000h dw 0x0ffff ; Limit 4Gb bits 0-15 of segment descriptor dw 0x0000 ; Base 0h bits 16-31 of segment descriptor (sd) db 0x01 ; Base addr of seg 16-23 of 32bit addr,32-39 of sd db 0x0fa ; P,DPL(2),S,TYPE(3),A->Present bit 1,Descriptor ; ; privilege level 0-3,Segment descriptor 1 ie code ; ; or data seg descriptor,Type of seg,Accessed bit db 0x040 ; Upper 4 bits G,D,0,AVL ->1 segment len is page ; ; granula, 1 default operation size is 32bit seg ; ; AVL : Available field for user or OS ; ; Lower nibble bits 16-19 of segment limit db 0xc0 ; Base addr of seg 24-31 of 32bit addr,56-63 of sd codeselB equ $-gdt+3 ; This is 8h,ie 2nd descriptor in gdt code_gdtB: ; Code descriptor 4Gb flat segment at 0000:0000h dw 0x0ffff ; Limit 4Gb bits 0-15 of segment descriptor dw 0x0000 ; Base 0h bits 16-31 of segment descriptor (sd) db 0x01 ; Base addr of seg 16-23 of 32bit addr,32-39 of sd db 0x0fa ; P,DPL(2),S,TYPE(3),A->Present bit 1,Descriptor ; ; privilege level 0-3,Segment descriptor 1 ie code ; ; or data seg descriptor,Type of seg,Accessed bit db 0x040 ; Upper 4 bits G,D,0,AVL ->1 segment len is page ; ; granula, 1 default operation size is 32bit seg ; ; AVL : Available field for user or OS ; ; Lower nibble bits 16-19 of segment limit db 0xc0 ; Base addr of seg 24-31 of 32bit addr,56-63 of sd dataselA equ $-gdt+3 ; ie 10h, beginning of next 8 bytes or data sd data_gdtA: ; Data descriptor 4Gb flat seg at 0000:0000h dw 0x0ffff ; Limit 4Gb dw 0x0000 ; Base 0000:0000h db 0x00 ; Descriptor format same as above db 0x0f2 db 0x0cf db 0xc0 videosel equ $-gdt ; ie 18h,next gdt entry dw 640*480/8-1 ; Limit 640*480/8-1 dw 0x0000 ; Base 0xc00a0000 db 0x0a db 0x92 ; present,ring 0,data,expand-up,writable db 0x00 ; byte granularity 16 bit db 0xc0 sysstacksel equ $-gdt ; ie 20h, beginning of next 8 bytes or data sd sysstack_gdt: ; Stack descriptor 4Kb flat seg at C000:3000h dw 0x0ffff ; Limit 4Kb dw 0x0000 ; Base C000:3000h db 0x00 ; Descriptor format same as above db 0x092 db 0x040 db 0xc0 sysstackselA equ $-gdt+3; ie 20h, beginning of next 8 bytes or data sd sysstack_gdtA: ; Stack descriptor 4Kb flat seg at C000:3000h dw 0x0ffff ; Limit 4Kb dw 0x0000 ; Base C000:0000h db 0x00 ; Descriptor format same as above db 0x0f2 db 0x040 db 0xc0 tsssel equ $-gdt ; This is 8h,ie 2nd descriptor in gdt tss_gdt: ; Code descriptor 4Gb flat segment at 0000:0000h dw 0x067 ; Limit 4Gb bits 0-15 of segment descriptor dw 0x4000 ; Base 0h bits 16-31 of segment descriptor (sd) db 0x00 ; Descriptor format same as above db 0x089 db 0x0 db 0xc0 tssselA equ $-gdt ; This is 8h,ie 2nd descriptor in gdt tss_gdtA: ; Code descriptor 4Gb flat segment at 0000:0000h dw 0x067 ; Limit 4Gb bits 0-15 of segment descriptor dw 0x5000 ; Base 0h bits 16-31 of segment descriptor (sd) db 0x00 ; Descriptor format same as above db 0x0E9 db 0x0 db 0xc0 tssselB equ $-gdt ; This is 8h,ie 2nd descriptor in gdt tss_gdtB: ; Code descriptor 4Gb flat segment at 0000:0000h dw 0x067 ; Limit 4Gb bits 0-15 of segment descriptor dw 0x6000 ; Base 0h bits 16-31 of segment descriptor (sd) db 0x00 ; Descriptor format same as above db 0x0E9 db 0x0 db 0xc0 putcgate equ $-gdt+3; putc_gdt: dw 0 ;OffsetLow dw 1000b ;Selector db 1 ;Dcount db 11101100b ;GateType dw 1 ;OffsetHighgdt_end:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mov ax,datasel mov ds,ax mov es,ax mov ax,sysstacksel mov ss,ax mov sp,0x4000 mov ax,tsssel ltr ax mov dword [TRESP0],0x4000 mov word [TRSS0],sysstacksel mov dword [TRESP],0x8000 mov dword [TREIP],0 mov dword [TREFlag],0x200 mov word [TRES],dataselA mov word [TRCS],codeselA mov word [TRSS],sysstackselA mov word [TRDS],dataselA mov word [TRFS],dataselA mov word [TRGS],dataselA mov edi,0x5000 mov ecx,104 mov esi,TRLink cld rep movsb mov dword [TRESP0],0xC000 mov dword [TRESP],0x9000 mov word [TRCS],codeselB mov dword [0],0 mov edi,0x6000 mov ecx,104 mov esi,TRLink rep movsb call init8259 sti jmp tssselA:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CodeA: mov ecx,0xA.NextChar: push ecx mov ebx,0xA sub ebx,ecx lea eax,[ebx+0x730] shl ebx,1 mov [0xB8000+ebx],ax mov ecx,0xFFFFF.Redo: loop .Redo pop ecx loop .NextChar mov ecx,0xA mov edi,0xB8000 mov ax,0 rep stosw jmp CodeA retCodeB: mov ecx,0xA.NextChar: push ecx mov ebx,0xA sub ebx,ecx lea eax,[ebx+0x741] shl ebx,1 mov [0xB80A0+ebx],ax mov ecx,0xFFFFF.Redo: loop .Redo pop ecx loop .NextChar mov ecx,0xA mov edi,0xB80A0 mov ax,0 rep stosw jmp CodeB retchangetr: pusha push ds mov al, 0x60 out 0x20, al mov cx,datasel mov ds,cx inc byte [Count] cmp byte [Count],50 jb .Return mov byte [Count],0 mov ebx,[NowTr] mov ecx,1 sub ecx,[NowTr] mov [NowTr],ecx jecxz .Zero jmp tssselB:0 jmp .Return.Zero: jmp tssselA:0.Return: pop ds popa iretCount db 0NowTr dd 0tmpputc: mov ax,datasel mov ds,ax mov es,ax mov fs,ax mov gs,ax mov ecx,[esp+8] mov ch,7 mov [0xB8000],cx retf 4 idtr dw 0x21*0x8 dd idt+0xC0000000idt times 0x20*0x8 db 0changetr_idt: dw 0 ;OffsetLow dw 1000b ;Selector db 0 ;Dcount db 10001110b ;GateType dw 1 ;OffsetHighTRLink DW 0 ;链接字段 DW 0 ;不使用,置为0TRESP0 DD 0 ;0级堆栈指针TRSS0 DW 0 ;0级堆栈段寄存器 DW 0 ;不使用,置为0TRESP1 DD 0 ;1级堆栈指针TRSS1 DW 0 ;1级堆栈段寄存器 DW 0 ;不使用,置为0TRESP2 DD 0 ;2级堆栈指针TRSS2 DW 0 ;2级堆栈段寄存器 DW 0 ;不使用,置为0TRCR3 DD 0 ;CR3TREIP DD 0 ;EIPTREFlag DD 0 ;EFLAGSTREAX DD 0 ;EAXTRECX DD 0 ;ECXTREDX DD 0 ;EDXTREBX DD 0 ;EBXTRESP DD 0 ;ESPTREBP DD 0 ;EBPTRESI DD 0 ;ESITREDI DD 0 ;EDITRES DW 0 ;ES DW 0 ;不使用,置为0TRCS DW 0 ;CS DW 0 ;不使用,置为0TRSS DW 0 ;SS DW 0 ;不使用,置为0TRDS DW 0 ;DS DW 0 ;不使用,置为0TRFS DW 0 ;FS DW 0 ;不使用,置为0TRGS DW 0 ;GS DW 0 ;不使用,置为0TRLDTR DW 0 ;LDTR DW 0 ;不使用,置为0TRTrip DW 0 ;调试陷阱标志(只用位0)TRIOMap DW 0 ;指向I/O许可位图区的段内偏移
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -