Advertisement
Guest User

Untitled

a guest
Apr 22nd, 2019
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ; testest
  2. ; practicum 4 computerarchitectuur
  3. ;
  4. ; dit programma bestaat uit een beperkt aantal sectoren die ingelezen
  5. ; worden na het uitvoeren van de BIOS. Dit zijn de eerste sectoren die
  6. ; bij het bootstrappen van de floppy of van de harde schijf gelezen
  7. ; worden
  8. ;
  9. ; de bios begint uit te voeren op adres 000ffff0h (startadres van de
  10. ; processor, en zal na verloop van tijd de eerste sector (512 bytes)
  11. ; van het bootstrap device (floppy, harddisk, CD) inlezen.
  12. ;
  13. ; deze sector wordt opgeslagen op adres 7c00h.
  14. ;
  15.  
  16. ; constantendefinities
  17.  
  18. Loaded      EQU 7C00h    ; adres waarop sector 0 geladen wordt
  19. SectorSize  EQU 512      ; grootte van 1 sector
  20. ;VIDEO_MODE     EQU     7        ; monochrome mode
  21. ;VGA_MEM        EQU     0xB0000  ; plaats van de videoram voor monochrome mode
  22. VIDEO_MODE      EQU     3        ; kleurmode
  23. VGA_MEM         EQU     0xB8000  ; plaats van de videoram voor kleurmode
  24. Wachtlus    EQU 100000
  25.  
  26.  
  27. ; de BIOS voert steeds uit in 16 bit mode. Een van de taken van het programma
  28. ; in sector 0 is het omschakelen naar 32 bit mode.
  29. ;
  30. ; de BITS directieve vraagt aan de assembler om 16-bit code te genereren.
  31. ;
  32. BITS 16         ; 16 bit real mode
  33.  
  34. ; de ORG-directieve vraagt aan de assembler ervan uit te gaan dat de volgende
  35. ; instructie uiteindelijk op adres 7C00h in het geheugen terecht zal komen
  36.  
  37. ORG     7C00h       ; adres waarop deze code geladen wordt
  38.  
  39. ; behalve het codesegment (deze instructies worden immers uitgevoerd), kunnen
  40. ; we er niet van uitgaan dat de andere segmentregisters geldige waarden hebben.
  41. ; we zorgen ervoor dat ds, es, en ss allemaal naar hetzelfde blok geheugen
  42. ; wijzen.
  43. ; Uit experimenten blijkt dat alle segmenten beginnen op adres 0. Let wel: dit
  44. ; zijn segmentregisters uit het IA16 model en hun interpretatie is verschillend van
  45. ; deze in het IA32 model.
  46.  
  47.     xor ax, ax
  48.     mov ds, ax
  49.     mov es, ax
  50.     mov ss, ax
  51.     mov sp, Loaded  ; sp wijst net voor de eerste instructie,
  52.                 ; en groeit ervan weg
  53.  
  54. ; Laad de rest van de sectoren na de eerste sector in het geheugen.
  55. ; Hiervoor wordt de BIOS oproep int 13h gebruikt. Daarvoor moeten wel alle
  56. ; parameters eerst goedgezet worden.
  57. ; aangezien niet elke BIOS multitrack reads ondersteunt dienen we de
  58. ; sectoren een voor een in te lezen (zou ook per track kunnen)
  59.  
  60.     mov si, 2           ; SI = huidige logische sector
  61.     mov ax, SecondStage
  62.     shr ax, 4
  63.     mov es, ax
  64.    
  65. load_next:
  66.     ; CL = sector = ((SI -1) % 18) + 1
  67.     ; CH = track = (SI - 1) / 36
  68.     ; DH = head = ((SI - 1) / 18) & 1
  69.     mov ax, si
  70.     dec ax
  71.     xor dx, dx
  72.     mov bx, 18
  73.     div bx
  74.     mov cl, dl
  75.     inc cl
  76.     mov ch, al
  77.     shr ch, 1
  78.     mov dh, al
  79.     and dh, 1
  80. .retry:
  81.     mov ah, 2   ; read sector
  82.     mov al, 1   ; 1 sector
  83.     mov bx, 0   ; buffer es:bx
  84.     mov dl, 0   ; diskette station A:
  85.     int 0x13
  86.     jc  .retry
  87.     mov ax, es
  88.     add ax, 0x20    ; 512 bytes / 16
  89.     mov es, ax
  90.     inc si      ; volgende sector
  91.     cmp si, SectorsToLoad + 2
  92.     jnz load_next
  93.  
  94. ; Met de BIOS-interrupt 10h zetten we de videomode goed.
  95. ; 25 lijnen van 80 witte tekens met zwarte achtergrond = VGA mode 03h
  96.  
  97.         mov ax, VIDEO_MODE
  98.         int 10h
  99.  
  100. ; Zet motor af
  101.     xor al, al      ; al = 0
  102.     mov dx, 0x3f2   ; FDD Digital Output Register
  103.     out dx, al
  104.  
  105. ; stop interrupts zodat we de onderbrekingsregelaar kunnen programmeren
  106.     cli
  107.  
  108. ; PIC initialization (8259A)
  109. ; PIC1: 0020-003F
  110. ; PIC2: 00A0-00BF          
  111. ; Maps IRQ 0 - IRQ 0xF to INT 8 - 23
  112.     mov al,11h  ; (init. command word 1) ICW1 to both controllers
  113.     out 20h,al      ; bit 0=1: ICW4 needed
  114.     out 0A0h,al     ; bit 1=0: cascaded mode
  115.                 ; bit 2=0: call address interval 8 bytes
  116.                 ; bit 3=0: edge triggered mode
  117.                 ; bit 4=1: ICW1 is being issued
  118.                 ; bit 5-7: not used
  119.     mov al, IRQBase ; ICW2 PIC1 - offset of vectors
  120.     out 21h,al      ; 20h -> right after the intel exceptions
  121.                 ; bit 0-2: 000 on 80x86 systems
  122.                 ; bit 3-7: A3-A7 of 80x86 interrupt vector
  123.  
  124.     mov al, IRQBase+8   ; ICW2 PIC2 - offset of vectors
  125.     out 0A1h,al     ; 28h -> after PIC1 vectors
  126.        
  127.     mov al,4h       ; ICW3 PIC1 (master)
  128.     out 21h,al      ; bit 2=1: irq2 has the slave
  129.        
  130.     mov al,2h       ; ICW3 PIC2 (slave)
  131.     out 0A1h,al     ; bit 1=1: slave id is 2
  132.        
  133.     mov al,1h       ; ICW4 to both controllers
  134.     out 21h,al      ; bit 0=1: 8086 mode
  135.                 ; bit 1=0: no auto EOI, so normal EOI
  136.     out 0A1h,al     ; bit 2-3=00: nonbuffered mode
  137.                 ; bit 4:0=sequential, bit 5-7: reserved
  138.        
  139.     mov al,0ffh     ; OCW1 interrupt mask to both
  140.     out 21h,al      ; no interrupts enabled
  141.     out 0A1h,al  
  142.  
  143. ; Zet de Global Descriptor Tabel (GDT) goed zodat we cs, ds, es, ss kunnen
  144. ; vullen met een segment selector die wijst naar het gehele adresbereik.
  145.  
  146.     lgdt    [GDTInfo]   ; laadt GDTR register
  147.  
  148. ; Laat het IDT register wijzen naar de Interrupt Descriptor Tabel (IDT)
  149. ; (die moeten we nog invullen)
  150.  
  151.     lidt    [IDTInfo]   ; laadt IDTR register
  152.    
  153. ; Het laagste bit in het controleregister cr0 bepaalt of we in 16 bit mode
  154. ; of in 32 bit mode werken.
  155.  
  156.     mov eax, cr0
  157.     or  eax, 1      ; 1 = protected mode (32 bit)
  158.     mov cr0, eax   
  159.  
  160. ; Spring naar het begin van de 32-bit code Main32. Door gebruik te maken
  161. ; van een intersegmentaire sprong worden zowel cs als eip meteen goed gezet.
  162. ; CodeSegmentSelector = selector naar de descriptor van het codesegment
  163. ; Main32 = 32-bit entry point
  164.  
  165.     jmp     CodeSegmentSelector:dword main
  166.  
  167. ; de assembler zal vanaf hier 32 bit code genereren
  168. BITS 32
  169.  
  170. ; Dit is het einde van de eerste sector. Deze wordt nu opgevuld met nullen
  171. ; totdat hij precies 512 bytes groot is. ($-$$)=grootte van de code
  172.  
  173. ; Laat NASM controleren of onze boot sector wel in 512 bytes past.
  174. %if ($-$$) > SectorSize - 2
  175. %error De bootsector is groter dan 512 bytes.
  176. %endif
  177.  
  178. TIMES   SectorSize-2-($-$$) DB 0 ; Zorg dat de boot sector 512 bytes lang is
  179.     DW  0xAA55  ; Verplichte signatuur van de bootsector
  180.             ; hieraan herkent de BIOS een bootsector
  181.  
  182. ;============================ SECOND STAGE SECTION ============================
  183. SecondStage:    ; de eerste bootsector zal op dit adres de volgende
  184.         ; sectoren inladen met onderstaande code en data
  185.         ; deze sectoren beginnen in principe op Loaded+SectorSize
  186.  
  187.  
  188. ;-----------------------------------------------------------------------------;
  189. ;                          GLOBAL DESCRIPTORS TABLE                           ;
  190. ;-----------------------------------------------------------------------------;
  191. ; Er worden hier drie segmenten gedefinieerd: codesegment, datasegment, en
  192. ; stapelsegment
  193. ; Al deze segmenten wijzen echter naar hetzelfde blok geheugen van 4 GiB
  194. ; (volledige 32-bit adresruimte).
  195.  
  196.  
  197. GDTStart:  
  198. NULLDesc    :
  199.     dd  0, 0        ; null descriptor  (wordt niet gebruikt)
  200. CodeDesc:
  201.     dw  0FFFFh      ; code limit 0 - 15
  202.     dw  0       ; code base 0 - 15
  203.     db  0       ; code base 16 - 23
  204.     db  10011010b   ; present, dpl=00, 1, code=1, cnf.=0, r=1, ac=0
  205.     db  11001111b   ; gran=1, use32=1, 0, 0, limit 16 - 19
  206.     db  0       ; code base 24 - 31
  207. DataDesc:  
  208.     dw  0FFFFh      ; data limit 0 - 15
  209.     dw  0       ; data base 0 - 15
  210.     db  0       ; data base 16 - 23
  211.     db  10010010b   ; present, dpl=00, 10, exp.d.=0, wrt=1, ac=0
  212.     db  11001111b   ; gran=1, big=1, 0, 0, limit 16 - 19
  213.     db  0       ; data base 24 - 31        
  214. StackDesc: 
  215.     dw  0       ; data limit 0 - 15
  216.     dw  0       ; data base 0 - 15
  217.     db  0       ; data base 16 - 23
  218.     db  10010110b   ; present, dpl=00, 10, exp.d.=1, wrt=1, ac=0
  219.     db  11000000b   ; gran=1, big=1, 0, 0, limit 16 - 19
  220.     db  0       ; data base 24 - 31        
  221. GDTEnd:
  222.  
  223. GDTInfo:                       ; inhoud van GDTR
  224. GDTLimit    dw  GDTEnd-GDTStart-1  ; GDT limit = offset hoogste byte   
  225. GDTBase     dd  GDTStart       ; GDT base  
  226.  
  227. ; constantendefinities om gemakkelijk naar de verschillende segmenten
  228. ; te kunnen refereren.
  229.  
  230. CodeSegmentSelector     EQU CodeDesc - GDTStart
  231. DataSegmentSelector     EQU DataDesc - GDTStart
  232. StackSegmentSelector    EQU StackDesc - GDTStart
  233.  
  234. ;-----------------------------------------------------------------------------;
  235. ;                          INTERRUPT DESCRIPTORS TABLE                        ;
  236. ;-----------------------------------------------------------------------------;
  237. ; De eerste 32 onderbrekingen worden door Intel gedefinieerd. De onderbrekingen
  238. ; afkomstig van de onderbrekingsregelaar starten bij onderbreking 32
  239.  
  240. IDTStart:
  241.     dd  0, 0    ; INT 0 : Divide error
  242.     dd  0, 0    ; INT 1 : Single Step
  243.     dd  0, 0    ; INT 2 : Nonmaskable interrupt
  244.     dd  0, 0    ; INT 3 : Breakpoint
  245.     dd  0, 0    ; INT 4 : Overflow
  246.     dd  0, 0    ; INT 5 : BOUND range exceeded
  247.     dd  0, 0    ; INT 6 : invalid opcode
  248.     dd  0, 0    ; INT 7 : device not available (no math co-cpu)
  249.     dd  0, 0    ; INT 8 : double fault  
  250.     dd  0, 0    ; INT 9 : co-cpu segment overrun
  251.     dd  0, 0    ; INT 10 : invalid TSS
  252.     dd  0, 0    ; INT 11 : segment not present
  253.     dd  0, 0    ; INT 12 : stack-segment fault
  254.     dd  0, 0    ; INT 13 : general protection
  255.     dd  0, 0    ; INT 14 : page fault
  256.     dd  0, 0    ; INT 15 : reserved
  257.     dd  0, 0    ; INT 16 : x87 FPU error
  258.     dd  0, 0    ; INT 17 : alignment check
  259.     dd  0, 0    ; INT 18 : machine check
  260.     dd  0, 0    ; INT 19 : SIMD floating-point exception
  261.     dd  0, 0    ; INT 20 : reserved
  262.     dd  0, 0    ; INT 21 : reserved
  263.     dd  0, 0    ; INT 22 : reserved
  264.     dd  0, 0    ; INT 23 : reserved
  265.     dd  0, 0    ; INT 24 : reserved
  266.     dd  0, 0    ; INT 25 : reserved
  267.     dd  0, 0    ; INT 26 : reserved
  268.     dd  0, 0    ; INT 27 : reserved
  269.     dd  0, 0    ; INT 28 : reserved
  270.     dd  0, 0    ; INT 29 : reserved
  271.     dd  0, 0    ; INT 30 : reserved
  272.     dd  0, 0    ; INT 31 : reserved
  273.     dd  0, 0    ; INT 32 : IRQ0 timer
  274.     dd  0, 0    ; INT 33 : IRQ1 keyboard, mouse, rtc
  275.     dd  0, 0    ; INT 34 : IRQ2 2de PIC
  276.     dd  0, 0    ; INT 35 : IRQ3 com1
  277.     dd  0, 0    ; INT 36 : IRQ4 serial port 2 (=com2)
  278.     dd  0, 0    ; INT 37 : IRQ5 hard disk
  279.     dd  0, 0    ; INT 38 : IRQ6 diskette controller
  280.     dd  0, 0    ; INT 39 : IRQ7 parallel printer
  281.     dd  0, 0    ; INT 40 : IRQ8 real-time clock
  282.     dd  0, 0    ; INT 41 : IRQ9 redirect cascade
  283.     dd  0, 0    ; INT 42 : IRQ10 reserved
  284.     dd  0, 0    ; INT 43 : IRQ11 reserved
  285.     dd  0, 0    ; INT 44 : IRQ12 mouse
  286.     dd  0, 0    ; INT 45 : IRQ13 coprocessor exeception interrupt
  287.     dd  0, 0    ; INT 46 : IRQ14 fixed disk
  288.     dd  0, 0    ; INT 47 : IRQ15 reserved
  289. IDTEnd:
  290.  
  291. IRQBase     EQU 32
  292.  
  293. IDTInfo:        ; Inhoud van IDTR
  294. IDTLimit    dw  IDTEnd-IDTStart-1 ; limit = offset hoogste byte
  295. IDTBase     dd      IDTStart
  296.  
  297. ;------------------------------------------------------------------------------
  298. ; Data voor de takenlijst
  299. ;------------------------------------------------------------------------------
  300.  
  301. MAX_TAKEN equ 5
  302.  
  303. STAPELGROOTTE equ 500
  304.  
  305. ; Takenlijst is een lijst van MAX_TAKEN groot. Deze lijst bevat de top van
  306. ; de stapel van de taak wanneer de taak niet aan het uitvoeren is. Indien
  307. ; het element 0 is, wijst dit op de afwezigheid van een taak. Bovendien
  308. ; bevat deze lijst informatie over wanneer in de tijd een taak mag uitgevoerd worden
  309.  
  310. takenlijst times 3*MAX_TAKEN dd (0)
  311. ; idle_taak_slot  times 2 dd (0) ; Niet nodig in 2019
  312.  
  313.  
  314. ; Hier worden enkele stapels gedefinieerd van elk STAPELGROOTTE grootte (bytes!).
  315. begin_stapels times 1 dd (0)
  316.  
  317. stapel1    times STAPELGROOTTE db (0)
  318. stapel2    times STAPELGROOTTE db (0)
  319. mainstapel times STAPELGROOTTE db (0)
  320. infostapel times STAPELGROOTTE db (0)
  321. idlestapel times STAPELGROOTTE db (0)
  322.  
  323. einde_stapels times 1 dd (0)
  324.  
  325. ; variabele die bijhoudt welke taak op elk ogenblik aan het uitvoeren is.
  326. ; De veranderlijk bevat het adres van het corresponderende element in takenlijst.
  327.  
  328. Huidige_Taak dd 0
  329.  
  330. ; variabele die kijkt hoeveel timer interrupts we al gehad hebben
  331. Huidige_Tick dd 0
  332.  
  333.  
  334. ;================================= MAIN ==============================
  335.  
  336. main:  
  337.  
  338. ;
  339. ; door de oproep met expliciet codesegment staat het codesegment-register
  340. ; hier meteen goed. De andere segmentregisters krijgen hier een waarde.
  341. ; alle segmentregisters (ook fs en gs) dienen met een geldige waarde te worden
  342. ; gevuld.
  343. ;
  344.     mov ax, DataSegmentSelector
  345.     mov ds, ax     
  346.     mov es, ax     
  347.     mov fs, ax 
  348.     mov gs, ax 
  349.  
  350.     mov ax, StackSegmentSelector
  351.     mov ss, ax
  352.     mov esp, Loaded     ; stapel wijst nog steeds naar dezelfde locatie
  353.  
  354. ;------------------------------------------------------------------------------
  355. ; Timer aanpassen (voor practicum 4)
  356. ;------------------------------------------------------------------------------
  357.  
  358.         ; Verhoog het aantal HZ van de PIT zijn standaardwaarde van 18.2Hz naar 100Hz:
  359.        ; Port 40h -> system time counter divisor
  360.        ; Port 43h -> control word register
  361.  
  362.         ; (00) counter 0 select (11) read/write counter bits 0-7 first, then 8-15 (x11) counter mode: square (0) binary counter
  363.         mov     al, 00110110b
  364.         out     43h, al
  365.  
  366.         ; bits 0-7
  367.         mov     al, 00h
  368.         out     40h, al
  369.        ; bits 8-15
  370.         mov     al, 00fh ; ~ 1000Hz? ### Check
  371.         out     40h, al
  372.        ; zet de onderbrekingen terug aan
  373.     sti
  374.  
  375. ;------------------------------------------------------------------------------
  376. ; Debug Excepties (voor practicum 4)
  377. ;------------------------------------------------------------------------------
  378.  
  379.  
  380.     ; Zorg er voor dat we debugexcepties genereren als een programma zijn stack lijkt te over/underflowen
  381.     ; (dit is geen garantie indien men sub/adds doet op esp, maar het is alvast ietsje betrouwbaarder)
  382.     lea  eax, [begin_stapels]
  383.     mov  dr0, eax
  384.     lea  eax, [einde_stapels]
  385.     mov  dr1, eax
  386.  
  387.     mov  eax, dr7
  388.     ; dr0
  389.     or   eax, 11b  ; L0|G0
  390.     or   eax, 00000000000000110000000000000000b ; R/W0
  391.     or   eax, 00000000000011000000000000000000b ; LEN0 == 4
  392.  
  393.     ; dr1
  394.     or   eax, 1100b ; L1|G1
  395.     or   eax, 00000000001100000000000000000000b ; R/W1
  396.     or   eax, 00000000110000000000000000000000b ; LEN1 == 4
  397.  
  398.     mov  dr7, eax
  399.    
  400.    
  401.         mov  ebx, debughandler
  402.         push ebx
  403.         push 1
  404.         call install_handler
  405.         add esp, 8
  406.  
  407.  
  408.         ; We gaan over naar een voorgedefinieerde stapel en stoppen het hoofdprogramma in de lijst
  409.         lea     esp, [mainstapel + STAPELGROOTTE]
  410.         mov     dword [takenlijst], esp
  411.         mov     dword [Huidige_Taak], takenlijst
  412.  
  413.     ; installeer de schedulerhandler op de timeronderbreking en zet deze onderbreking aan
  414.     push    schedulerhandler
  415.     push    32
  416.     call    install_handler
  417.     add esp, 0x8
  418.     ;; zet onderbreking aan
  419.         cli
  420.     in  al, 0x21
  421.     and al, 11111110b
  422.     out 0x21, al
  423.         sti
  424.  
  425.  
  426. ; .............
  427.  
  428. ; Start de taken
  429. ; .............
  430.  
  431.     ; Vraag 3 en 4
  432.  
  433.     ; Vraag 2
  434.    ; ..............
  435.  
  436.  
  437.     ;; installeer taak1
  438.     push    1
  439.     push    0
  440.     push    stapel1
  441.     push    Taak1
  442.     call    creeertaak
  443.     add esp, 16
  444.  
  445.     ;; installeer taak2
  446.     push    1
  447.     push    2500
  448.     push    stapel2
  449.     push    Taak2
  450.     call    creeertaak
  451.     add esp, 16
  452.  
  453.     ; Vraag 4
  454.    ; ..............
  455.  
  456.  
  457.     ;; De hoofd-taak gaat gewoon PrintInfoTaak direct uitvoeren
  458.     jmp PrintInfoTaak
  459.  
  460.  
  461. HoofdProgrammaGedaan:
  462.         jmp     HoofdProgrammaGedaan
  463.  
  464.  
  465. ;================================= TAKEN ==============================
  466. Taak1:
  467.         mov     eax, 0
  468.         mov     ebx, 39
  469.         mov     ecx, 1
  470.         mov     edx, 9
  471.         jmp     spiraal
  472.  
  473.  
  474.  
  475. Taak2:
  476.     mov eax,40 
  477.     mov ebx,79
  478.     mov ecx,1
  479.     mov edx,9
  480.     jmp spiraal
  481.  
  482.  
  483. Taak3:
  484.         mov     eax, 0
  485.         mov     ebx, 79
  486.         mov     ecx, 11
  487.         mov     edx, 20
  488.         jmp     spiraal
  489.  
  490.  
  491. clockstring  db "Clockticks:", 0
  492. tscstring    db "TSC: ", 0
  493. takenstring  db "Taken: ", 0
  494.  
  495. PrintInfoTaak:
  496.  ; Print informatie op het scherm
  497.   push  21
  498.   push  0
  499.   push  clockstring
  500.   call  printstring
  501.   add   esp, 12
  502.  
  503.   push  21
  504.   push  22
  505.   push  tscstring
  506.   call  printstring
  507.   add   esp, 12
  508.  
  509.   push  22
  510.   push  0
  511.   push  takenstring
  512.   call  printstring
  513.   add   esp, 12
  514.  
  515.   ; Print de labels voor de taken:
  516.   mov   edi, 0
  517. .printLabels:
  518.   mov   eax, 13
  519.   imul  edi
  520.   add   eax, 7
  521.  
  522.   ; Taaknummer
  523.  
  524.   push  eax
  525.   push  edi
  526.  
  527.   push  22
  528.   push  eax
  529.   push  edi
  530.  
  531.   add   eax, 1
  532.   push  word 22
  533.   push  ax
  534.   push  word ':'
  535.  
  536.   add   eax, 2
  537.   push  word 22
  538.   push  ax
  539.   push  word ','
  540.  
  541.   call  printchar
  542.   call  printchar
  543.   call  printint
  544.   add   esp, 12
  545.  
  546.   pop   edi
  547.   pop   eax
  548.  
  549.   add   edi, 1
  550.  
  551.   cmp   edi, MAX_TAKEN
  552.   jl    .printLabels
  553.   jmp   PrintInfoTaakLoop
  554.  
  555. PrintInfoTaakLoop:
  556.  ; Print Tijd-Info
  557.   push  21
  558.   push  13
  559.   push  dword [Huidige_Tick]
  560.   call  printhex
  561.   add   esp, 12
  562.  
  563.   push  21
  564.   push  28
  565.   rdtsc
  566.   push  edx
  567.   push  21
  568.   push  36
  569.   push  eax
  570.   call  printhex
  571.   add   esp, 12
  572.   call  printhex
  573.   add   esp, 12
  574.  
  575.   ; Print taken-info:
  576.   lea   esi, [takenlijst]
  577.   mov   ecx, 0
  578. .printTaken:
  579.   imul  edx, ecx, 12
  580.   mov   dword ebx, [esi+edx]
  581.  ; Startpos op scherm
  582.   mov   eax, 13
  583.   imul  ecx
  584.  
  585.   push  esi
  586.   push  ecx
  587.   push  ebx
  588.  
  589.   add   eax, 11
  590.  
  591.   ; Toon activatietijd (ook invullen indien taak getermineerd)
  592.   push  22
  593.   push  eax
  594.   imul  edx, ecx, 12
  595.   push  dword [esi+edx+4]
  596.  
  597.   add   eax, -2
  598.  ; Toon status: A = Actief, T = geTermineerd
  599.   cmp   ebx, 0
  600.   je    .printgeTermineerd
  601.  
  602.   push   word 22
  603.   push   ax
  604.   push   word 'A'
  605.  
  606.   jmp    .nextTaak
  607.  
  608. .printgeTermineerd:
  609.   push   word 22
  610.   push   ax
  611.   push   word 'T'
  612.  
  613.   jmp   .nextTaak
  614.  
  615. .nextTaak:
  616.   call   printchar
  617.   call   printhex
  618.   add    esp, 12
  619.  
  620.   pop    ebx
  621.   pop    ecx
  622.   pop    esi
  623.  
  624.   add   ecx, 1
  625.   cmp   ecx, MAX_TAKEN
  626.   jl    .printTaken
  627.  
  628.   push dword 1
  629.   call sleep
  630.   add esp, 4
  631.  
  632.   jmp   PrintInfoTaakLoop
  633.  
  634.  
  635. IdleTaak:
  636.        ; Schrijf naar het scherm dat de idle taak gebruikt wordt
  637.        ; Vraag 4
  638.         jmp     IdleTaak
  639.  
  640.  
  641. ;================================= SCHEDULING ==============================
  642.  
  643. creeertaak:
  644. ; voeg een taak toe aan de takenlijst
  645. ; oproepen als creeertaak(adres, stapel, wachttijd)
  646. ; ....................
  647.         push    ebx
  648.         mov eax, [esp+4]    ; adres
  649.     mov ecx, [esp+8]    ; stapel
  650.     mov edx, [esp+12]   ; wachttijd
  651.     mov     ebx, [esp+16]   ; prioriteit
  652.     ;; initalisatie van de stapel
  653.     ; sla huidige stapelpointer op in ebp
  654.     push    ebp
  655.     mov ebp, esp
  656.     ; verplaats esp naar BEGIN nieuwe stapel
  657.     lea ecx, [ecx+STAPELGROOTTE]
  658.     mov esp, ecx
  659.     ; plaats eflags op de stapel, maar zorg dat IF=1!
  660.     pushfd
  661.     mov ecx, [esp]
  662.     or  ecx, 0x200
  663.     mov [esp], ecx
  664.     ; plaats cs op de stapel
  665.     push    cs
  666.     ; plaats eip op de stapel
  667.     push    eax
  668.     ; esp in eax steken, om correcte waarde van esp te kunnen pushen
  669.     mov eax, esp
  670.     ; imiteer een pushad
  671.     push    dword 0     ; eax
  672.     push    dword 0     ; ecx
  673.     push    dword 0     ; edx
  674.     push    dword 0     ; ebx
  675.     push    eax     ; esp
  676.     push    dword 0     ; ebp
  677.     push    dword 0     ; esi
  678.     push    dword 0     ; edi
  679.     ;; initialisatie van de takenlijst:
  680.         cli
  681.         lea ecx, [takenlijst - 12]
  682. .leegzoeklus:
  683.         add ecx, 12
  684.         cmp dword [ecx], 0
  685.         jne .leegzoeklus
  686.     ; plaats de correct esp in de takenlijst
  687.     mov dword[ecx], esp
  688.     ; plaats de correcte tijd in de takenlijst
  689.     mov eax, [Huidige_Tick]
  690.     add eax, edx   
  691.     mov dword[ecx+4], eax
  692.     ; plaats de prioriteit in de takenlijst
  693.     mov     dword[ecx+8], ebx
  694.     sti
  695.     ; keer terug naar de oorspronkelijke stapel
  696.     mov esp, ebp
  697.     pop ebp
  698.     pop     ebx
  699.     ret
  700.  
  701.  
  702. ; creeer_idle_taak: ; Niet nodig in 2018-2019
  703. ; creeer_idle_taak()
  704. ; ....................
  705. ;   ret
  706.  
  707.  
  708. termineertaak: ; Vraag 5, Vraag 6
  709. ; Krijgt de offset in bytes in de takenlijst
  710. ; van de taak die getermineerd moet worden.
  711. ; termineertaak gooit de taak die deze routine oproept uit de takenlijst (vragen 4 en 5)
  712. ; en zet de uitvoering, indien nodig, verder met een andere taak uit de takenlijst (voor vraag 5)
  713. ; termineertaak(taakslotnummer)
  714.  
  715. ; ....................
  716.  
  717.  
  718. ; sleep(nr_ticks): Slaapt voor (minstens) nr_ticks ticks
  719. sleep:
  720.         push eax
  721.         mov eax, [esp+8]
  722.         pushad ; Do not clobber any registers
  723.         pushfd
  724.         push    cs
  725.         push    ebx
  726.         pushad
  727.         lea     ebx, [awake]
  728.         mov     [esp+4*8], ebx
  729.         mov     ebx, [Huidige_Taak]
  730.         cli
  731.         mov     dword [ebx],esp
  732.         mov     dword ecx, [Huidige_Tick]
  733.         add     eax, ecx
  734.         mov     dword [ebx + 4], eax
  735.         mov     edx, 0
  736.         mov     eax, 1
  737.         jmp     schedulerhandler.taakzoeklus
  738. awake:
  739.         popad
  740.         pop eax
  741.         ret
  742.  
  743. ; Implementeer deze functie (Vraag 3)
  744. ; ..............
  745. verander_huidige_prioriteit:
  746.  
  747.  
  748. ; Hou rekening met de prioriteiten (Vraag 2)
  749. ; ..............
  750. schedulerhandler:
  751.         pushad
  752.         inc     dword [Huidige_Tick]
  753.         mov al, 0x20
  754.         out 0x20, al
  755.         sti
  756.         mov ebx, [Huidige_Taak]
  757.         mov dword [ebx], esp
  758.         mov     dword [ebx + 4], 0
  759.         mov     ecx, [Huidige_Tick]
  760.         mov     edx, 0
  761.         mov     eax, 1
  762.     call    animatiestap
  763.         cli
  764. .taakzoeklus:
  765.         add ebx, 12
  766.         cmp ebx, takenlijst + (MAX_TAKEN * 12)
  767.         jl  .nog_niet_aan_het_einde
  768.         lea ebx, [takenlijst]
  769. .nog_niet_aan_het_einde:
  770.         inc     edx
  771.        
  772.         cmp     edx, MAX_TAKEN
  773.         jne     .check_taak
  774.         mov     eax, 0
  775.        
  776. .check_taak:        
  777.         cmp dword [ebx], 0
  778.         je  .taakzoeklus
  779.         cmp     dword [ebx+4], ecx
  780.         jg      .taakzoeklus
  781.         cmp     dword[ebx+8], eax
  782.         jne     .taakzoeklus
  783.        
  784.         mov     [Huidige_Taak], ebx
  785.         mov     esp, [ebx]
  786.         popad
  787.         iret
  788.  
  789.  
  790. ; Animatie om te zien of schedulerhandler opgeroepen wordt, ook al is er maar 1 taak:
  791. ANIM_X EQU 0
  792. ANIM_Y EQU 20
  793. ANIMATIE_FRAME db "/", 0
  794. CHECK_FAIL db "Check FAIL: ", 0
  795.  
  796. animatiestap:
  797. pushad
  798. cmp byte [ANIMATIE_FRAME], '/'
  799. je  animatie_1
  800. cmp byte [ANIMATIE_FRAME], '-'
  801. je  animatie_2
  802. cmp byte [ANIMATIE_FRAME], '\'
  803. je  animatie_3
  804. cmp byte [ANIMATIE_FRAME], '|'
  805. je  animatie_4
  806.  
  807. ; Dit mag niet gebeuren!!!
  808. push ANIM_Y
  809. push ANIM_X
  810. push CHECK_FAIL
  811. call printstring
  812. ; Gedaan! Loop oneindig!
  813. checkfailed_loop:
  814. jmp checkfailed_loop
  815.  
  816.  
  817. animatie_1:
  818.     mov byte [ANIMATIE_FRAME], '-'
  819.     jmp animatie_end
  820. animatie_2:
  821.     mov byte [ANIMATIE_FRAME], '\'
  822.     jmp animatie_end
  823. animatie_3:
  824.     mov byte [ANIMATIE_FRAME], '|'
  825.     jmp animatie_end
  826. animatie_4:
  827.     mov byte [ANIMATIE_FRAME], '/'
  828.     jmp animatie_end
  829.  
  830. animatie_end:
  831.  
  832. push word ANIM_Y
  833. push word ANIM_X
  834. push word [ANIMATIE_FRAME]
  835. call printchar
  836. popad
  837.  
  838. ret
  839.  
  840. ;================================= HULPFUNCTIES ==============================
  841.  
  842. ; install_handler(interruptvector, onderbrekingsroutine)
  843. ; installeer de onderbrekingsroutine
  844. ; argumenten:
  845. ;    interruptvector: nummer van de interrupt
  846. ;    onderbrekingsroutine: adres van de corresponderende ISR
  847. install_handler:
  848.     mov eax, [esp+4]
  849.     mov edx, [esp+8]
  850.     mov     word [IDTStart+8*eax+0], dx ; onderste 16 bits van offset
  851.     mov     word [IDTStart+8*eax+2], CodeSegmentSelector
  852.     mov     byte [IDTStart+8*eax+4], 0h ;
  853.     mov     byte [IDTStart+8*eax+5], 10001110b ; 1=present, dpl=00, 0, 1=32bits, 110
  854.     shr     edx, 16
  855.     mov     word [IDTStart+8*eax+6], dx ; bovenste 16 bits van offset
  856.     ret
  857.  
  858.  
  859. ; printstring(adres, kol, rij)
  860. ; print een volledige string op het scherm totdat 0 bereikt wordt.
  861. ; argumenten:
  862. ;   adres van de nulgetermineerde string
  863. ;   kolom op het scherm (0..79)
  864. ;   rij op het scherm (0..24)
  865. ;
  866. printstring:
  867.     push    ebx
  868.     mov eax,[esp+16]  ; rij
  869.     mov ebx,[esp+12]   ; kol
  870.     mov ecx,[esp+8]   ; pointer naar string
  871. printloop:
  872.     mov dl,[ecx]
  873.     cmp dl,0
  874.     je  stop
  875.     push    ax
  876.     push    bx
  877.     push    dx
  878.     call    printchar
  879.     inc ecx
  880.     inc ebx
  881.     jmp printloop
  882. stop:
  883.     pop ebx
  884.     ret
  885.  
  886. ; --------------------
  887. ; Publieke hulpfuncties
  888. ; --------------------
  889.  
  890.  
  891. ; printint(het getal, kolom, rij)
  892. ; print een natuurlijk getal op het scherm
  893. ; argumenten:
  894. ;   rij op het scherm (0..24)
  895. ;   kolom op het scherm (0..79)
  896. ; opmerking: het getal wordt omgezet in een stringvoorstelling die
  897. ; gevisualiseerd wordt zonder leidende nullen.
  898. ;
  899. printint:
  900.     push    ebp
  901.     mov ebp,esp
  902.     push    ebx
  903.     sub esp,28
  904.     mov     ecx,8
  905.     mov     byte [ebp-19],0
  906.     mov     eax, [ebp+8]    ; integer argument
  907.     mov ebx,10
  908. bindec: xor     edx,edx
  909.     idiv    ebx
  910.     add dl,'0'
  911.     mov     [ebp-28+ecx],dl
  912.     dec ecx
  913.     cmp eax,0
  914.     jnz bindec
  915.     lea ecx,[ebp-27+ecx]
  916.     push    dword [ebp+16]  ; rij
  917.     push    dword [ebp+12]  ; kolom
  918.     push    ecx
  919.     call    printstring
  920.     add esp,40
  921.     pop ebx
  922.     pop ebp
  923.     ret
  924.  
  925. ; printhex(het 32 bit patroon, kolom, rij)
  926. ; rint een 32 bit bitpatroon op het scherm in hex notatie
  927. ; argumenten:
  928. ;    rij op het scherm (0..24)
  929. ;    kolom op het scherm (0..79)
  930. ; opmerking:het getal wordt omgezet in hexadecimale voorstelling
  931. ; (8 tekens) die gevisualiseerd wordt
  932. ;
  933.  
  934. printhex:
  935.     push    ebx
  936.     push    ebp
  937.     mov ebp,esp
  938.    
  939.     sub esp,12
  940.     mov     ecx,7
  941.     mov     eax, [ebp+12]    ; argument
  942.     mov ebx,16
  943.     mov byte [ebp-4],0
  944. binhex: xor     edx,edx
  945.     idiv    ebx
  946.     cmp dl, 9
  947.     jg  alfa
  948.     add dl,'0'
  949.     jmp hex
  950. alfa:   add dl,'A'-10
  951. hex:    mov     [ebp-12+ecx],dl
  952.     dec ecx
  953.     cmp ecx,0
  954.     jge binhex
  955.     push    dword [ebp+20]  ; rij
  956.     push    dword [ebp+16]  ; kolom
  957.     push    ebp
  958.     sub dword [esp],12
  959.     call    printstring
  960.     add esp,24
  961.     pop ebx
  962.     leave
  963.     pop ebx
  964.     ret
  965.  
  966. ;
  967. ; kleine vertraging om het hoofdprogramma volgbaar te houden.
  968. ; De vertraging kan ingesteld worden via de constante 'Wachtlus'
  969. ;
  970.  
  971. ShortDelay:
  972. ; ..... (Vraag 1)
  973.     pushad
  974.     push dword 0
  975.     call sleep
  976.     add esp, 4
  977.     popad
  978.     ret
  979.  
  980. ; --------------------
  981. ; Private hulpfuncties
  982. ; --------------------
  983.  
  984. ;
  985. ; print 1 letterteken op het scherm
  986. ; op de stapel staan, in deze volgorde (telkens 16 bit)
  987. ;   rij op het scherm (0..24)
  988. ;   kolom op het scherm (0..79)
  989. ;   teken zelf (laagste byte van dit 16-bit woord)
  990. ; de rij en kolom wordt vertaald in een adres in het
  991. ; videobuffer dat begint op VGA_MEM. Op die plaats wordt het
  992. ; teken geschreven. Het videobuffer is in principe een matrix
  993. ; van woorden (rij per rij opgeslagen). Elk woord bevat een 8-bit
  994. ; ascii-teken (te visualiseren teken) + een 8-bit attribuut
  995. ; (kleur, onderstreept, enz.)
  996. ;
  997. printchar:
  998.     push    eax
  999.     push    ebx
  1000.     push    ecx
  1001.     push    edx
  1002.     xor     eax,eax
  1003.     xor     ebx,ebx
  1004.     xor     ecx,ecx
  1005.     mov ax,[esp+24]  ; rij
  1006.     mov bx,[esp+22]  ; kol
  1007.     mov cx,[esp+20]  ; char
  1008.     mov ch, 00fh
  1009.     mov     dx,ax
  1010.     shl ax,2
  1011.     add ax,dx
  1012.     shl ax,5
  1013.     shl bx,1
  1014.     add bx,ax
  1015.     mov [VGA_MEM+ebx],cx
  1016.     pop edx
  1017.     pop ecx
  1018.     pop ebx
  1019.     pop eax
  1020.     ret 6
  1021.  
  1022.  
  1023.  
  1024.  
  1025. ;
  1026. ; deze functie produceert de hoofdletters van het alfabet
  1027. ; in het laagste byte van register esi.Per oproep wordt er 1 letter
  1028. ; opgeschoven. Na Z komt terug A. Indien de oorspronkelijke waarde ' ' was,
  1029. ; dan blijft deze behouden.
  1030. ;
  1031.  
  1032. nextchar cmp    si,' '
  1033.     je  einde
  1034.     cmp si,'Z'
  1035.     je  herbegin
  1036.     inc si
  1037.     jmp     einde
  1038. herbegin:
  1039.     mov si,'A'
  1040. einde   ret
  1041.  
  1042.  
  1043.  
  1044. ; deze routine tekent een spiraal op het scherm in een gegeven rechthoek
  1045. ; input
  1046. ;   ax = meest linkse kolom
  1047. ;   bx = meest rechtse kolom
  1048. ;   cx = bovenste rij
  1049. ;   dx = onderste rij
  1050. ;
  1051. ; deze routine termineert nooit (blijft steeds maar spiralen tekenen).
  1052.  
  1053. spiraal:
  1054.         shl     eax,16
  1055.         shl     ebx,16
  1056.         shl     ecx,16
  1057.         shl     edx,16
  1058.     mov si,' '
  1059. herstart:
  1060.     cmp si,' '
  1061.     je  letters
  1062.     mov si,' '
  1063.     jmp eindelus
  1064. letters:mov si,'A'
  1065. eindelus:
  1066.         mov edi,eax
  1067.     shr edi,16
  1068.     mov ax,di
  1069.  
  1070.         mov edi,ebx
  1071.     shr edi,16
  1072.     mov bx,di
  1073.  
  1074.         mov edi,ecx
  1075.     shr edi,16
  1076.     mov cx,di
  1077.  
  1078.         mov edi,edx
  1079.     shr edi,16
  1080.     mov dx,di
  1081. lus1:  
  1082.         mov     di,ax
  1083.     cmp di,bx
  1084.     jg  herstart
  1085. lus2:  
  1086.     push    cx
  1087.     push    di
  1088.     push    si
  1089.     call    printchar
  1090.     call    nextchar
  1091.     call    ShortDelay
  1092.     inc di
  1093.     cmp di,bx
  1094.     jle lus2
  1095.         inc     cx
  1096.     mov di,cx
  1097.     cmp     di,dx
  1098.     jg  herstart
  1099. lus3:   push    di
  1100.     push    bx
  1101.     push    si
  1102.     call    printchar
  1103.     call    nextchar
  1104.     call    ShortDelay
  1105.     inc di
  1106.     cmp di,dx
  1107.     jle lus3
  1108.         dec     bx
  1109.         mov     di,bx
  1110.     cmp     di,ax
  1111.     jl  herstart
  1112. lus4:   push    dx
  1113.     push    di
  1114.     push    si
  1115.     call    printchar
  1116.     call    nextchar
  1117.     call    ShortDelay
  1118.     dec di
  1119.     cmp di,ax
  1120.     jge lus4
  1121.     dec     dx
  1122.         mov     di,dx
  1123.     cmp     di,cx
  1124.     jl  herstart
  1125. lus5:   push    di
  1126.     push    ax
  1127.     push    si
  1128.     call    printchar
  1129.     call    nextchar
  1130.     call    ShortDelay
  1131.     dec di
  1132.     cmp di,cx
  1133.     jge lus5
  1134.         inc ax
  1135.         jmp     lus1    
  1136.  
  1137.  
  1138. debuggingstring1 db " Een stack gaat buiten het vooraf gedefinieerde gebied! ", 0
  1139. debuggingstring2 db " ESP: ", 0
  1140. debuggingstring3 db " EIP: ", 0
  1141. debughandler:
  1142. ;jmp debughandler
  1143. ; timer afzetten, of staat die al af nu met deze interupt? ### TODO
  1144. ;ud2
  1145.     push 0
  1146.     push 0
  1147.     push debuggingstring1
  1148.     push 1
  1149.     push 0
  1150.     push debuggingstring2
  1151.     push 2
  1152.     push 0
  1153.     push debuggingstring3
  1154.  
  1155.     call printstring
  1156.     add   esp, 12
  1157.     call printstring
  1158.     add   esp, 12
  1159.     call printstring
  1160.     add   esp, 12
  1161.  
  1162.     mov eax, esp
  1163.     add eax, 3*4
  1164.     push 1
  1165.     push 6
  1166.     push eax
  1167.     call printhex
  1168.     add   esp, 12
  1169.  
  1170.     push 2
  1171.     push 6
  1172.     mov eax, [esp+8]
  1173.     push eax
  1174.     call printhex
  1175.     add   esp, 12
  1176.  
  1177. .debugdone:
  1178.     jmp .debugdone
  1179.  
  1180.  
  1181.  
  1182. TotalSize       EQU $-$$
  1183. TotalSectors        EQU (TotalSize + SectorSize) / SectorSize
  1184. SectorsToLoad       EQU TotalSectors - 1
  1185.     ; TotalSectors - 1 want BIOS heeft de eerste voor ons reeds geladen
  1186.  
  1187. ; technische opmerkingen:
  1188. ; we nemen aan dat A20 per default enabled is
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement