home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / assemblr / library / cpu / protex / prot1.asm next >
Encoding:
Assembly Source File  |  1989-03-20  |  31.5 KB  |  658 lines

  1.                        PAGE    ,132
  2.                         TITLE   Protected mode programming
  3.                         .286P   ; Privliged programming
  4.  
  5.  
  6. ;=============================================================================;
  7. ;                                                                             ;
  8. ;    Example "skeleton" program that creates a GDT, IDT                       ;
  9. ;    and enables Protected Mode as follows:                                   ;
  10. ;                                                                             ;
  11. ;    1)  Provides GDT containing descriptors needed by the initial            ;
  12. ;        Protected Mode Task,                                                 ;
  13. ;                                                                             ;
  14. ;    2)  Provides IDT containing a full complement of gates for CPU           ;
  15. ;        Exceptions and eight 8259A interrupts,                               ;
  16. ;                                                                             ;
  17. ;    3)  Enables 80286 Protected Mode.                                        ;
  18. ;                                                                             ;
  19. ;    This example enables access to the full 16MB physical address space.     ;
  20. ;    It DOES NOT perform task switching.                                      ;
  21. ;                                                                             ;
  22. ;    Suggested that object code is burned into two 2764 EPROM's               ;
  23. ;=============================================================================;
  24. PAGE
  25.  
  26. Descriptor  STRUC                   ; A descriptor structure
  27. Limit           Dw  ?               ; A limit in bytes
  28. BaseLowWord     Dw  ?               ; Base word
  29. BaseHighByte    Db  ?               ; Base byte high
  30. Access          Db  ?               ; Access rights byte
  31. Reserved        Dw  0               ; Reserved word
  32. Descriptor  ENDS
  33.  
  34. ;            EQUATES
  35.  
  36. GDT_ELEMENTS        EQU 16          ; Number of descriptor slots in GDT
  37. IDT_ELEMENTS        EQU 64          ; Number of slots in IDT
  38.  
  39. MAIN_CODE_SELECTOR  EQU 0038h       ; Selector for main code segment
  40. EX_CODE_SELECTOR    EQU 0040h       ; Selector for exception code
  41. INT_CODE_SELECTOR   EQU 0048h       ; Selector for interrupt code segment
  42.  
  43. ; Physical mem equates -- This deals with the EPROM's
  44.  
  45. MAIN_CODE_BASE      EQU 0068h  ;
  46. EXCEPTION_CODE_BASE EQU 0078h  ;
  47. INTERRUPT_CODE_BASE EQU 0088h  ;
  48.  
  49. ; I/O address equates
  50.  
  51. OUTPUT_DATA_PORT    EQU 03BCh       ; Address of Data out of printer
  52. OUTPUT_STATUS_PORT1 EQU 03BDh       ; Address of control latch (in)
  53. OUTPUT_STATUS_PORT2 EQU 03BEh       ; Control latch of ptr (out)
  54. STROBE_HIGH         EQU 0Dh         ;
  55. STROBE_LOW          EQU 0Ch         ;
  56. PAGE
  57. ;=============================================================================;
  58. ; Definition of EPROM contents.                                               ;
  59. ; This example assumes two 2764 (8K x 8) at high end of memory.               ;
  60. ; The Lowest address is thus FFC000h.                                         ;
  61. ; Since the 80286 CS base initially equals FF0000h, the lowest EPROM          ;
  62. ; address is referenced by an IP value of C000h.                              ;
  63. ;=============================================================================;
  64.  
  65. ; EPROM RESIDENT IMAGE OF GDT and IDT
  66. ; Initlization copies image to RAM, starting at 000000h.
  67.  
  68. INITIAL_DATA    SEGMENT
  69.                 ASSUME  cs:INITIAL_DATA
  70.  
  71. ; The size of this GDT allows 16 slots for descriptors or gates
  72.  
  73. Gdt_Image_Start:
  74.  
  75. ;---The first GDT slot is always unused (The null selector, SLECTOR - 0000h---;
  76.                 Dw      0               ;
  77.                 Dw      0               ;
  78.                 Dw      0               ;
  79.                 Dw      0               ;
  80.  
  81. ;---GDT_alias descriptor (SELECTOR - 0008h)-----------------------------------;
  82.                 Dw      7Fh             ; Limit (16 * 8) - 1
  83.                 Dw      0               ; Base at 0
  84.                 Db      0               ;
  85.                 Db      10010011b       ; Access rights for data segment
  86.                 Dw      0               ; Insure Compatability with 80386
  87.  
  88. ;---IDT_alias secriptor (SELECTOR = 0010h)------------------------------------;
  89.                 Dw      1FFh            ; IDT_alias limit (64 * 8) - 1
  90.                 Dw      80h             ; Base is after GDT in RAM
  91.                 Db      0               ;
  92.                 Db      10010011b       ; Access rights for data segment
  93.                 Dw      0               ;
  94.  
  95. ;---Level 0 stack segment descriptor (SELECTOR = 0018h)-----------------------;
  96.                 Dw      TOS - 1         ; Limit 1k (1024 - 1)
  97.                 Dw      SEG TOS         ; Follows IDT in RAM
  98.                 Db      0               ;
  99.                 Db      10010011b       ; Access rights byte
  100.                 Dw      0               ;
  101.  
  102. ;---Main data segment descriptor (SELECTOR - 0020h)---------------------------;
  103.                 Dw      0FFh            ; Limit (256 - 1)
  104.                 Dw      680h            ; Follows level 0 stack
  105.                 Db      0               ;
  106.                 Db      10010011b       ; Access rights byte
  107.                 Dw      0               ;
  108.  
  109. ;---Exception data segment descriptor (SELECTOR = 0028h)----------------------;
  110.                 Dw      0FFh            ; Limit (256 -1)
  111.                 Dw      780h            ; Base follows main
  112.                 Db      0               ;
  113.                 Db      10010011b       ; Access rights byte
  114.                 Dw      0               ;
  115.  
  116. ;---Interrupt data segment descriptor  (SELECTOR = 0030h)---------------------;
  117.                 Dw      0FFh            ; Limit of interrupt (256 - 1)
  118.                 Dw      880h            ; Base after the data segment
  119.                 Db      0               ;
  120.                 Db      10010011b       ; Acess rights byte
  121.                 Dw      0               ; Insure compatibility with 80386
  122.  
  123. ;---Main CODE segment descriptor (SELECTOR = 0038h)---------------------------;
  124.                 Dw      End_Of_Main_Code; Limit of main code
  125.                 Dw      SEG End_Of_Main_Code  ; Base address
  126.                 Db      0               ;
  127.                 Db      10011011b       ; Access rights for CODE segment
  128.                 Dw      0               ;
  129.  
  130. ;---Exception CODE segment descriptor (SELECTOR = 0040h)----------------------;
  131.                 Dw      End_Of_Exception_Code ; Limit of Excpetion CODE
  132.                 Dw      SEG End_Of_Exception_Code
  133.                 Db      0               ; Base address of Excpetion
  134.                 Db      10011011b       ; Access rights of CODE
  135.                 Dw      0               ;
  136.  
  137. ;---Interrupt CODE segment Descriptor (SELECTOR = 0048h)----------------------;
  138.                 Dw      End_Of_Interrupt_Code ; Limit
  139.                 Dw      SEG End_Of_Interrupt_Code
  140.                 Db      0               ; Base address
  141.                 Db      10011011b       ; Interrupt Acess of CODE
  142.                 Dw      0               ;
  143.  
  144. ;---Blank Descriptor slots (10-15)--------------------------------------------;
  145.                 Db      (16-10)*8 Dup(0)
  146.  
  147. Gdt_Image_End:
  148. PAGE
  149. Idt_Image_Start:
  150. ;=============================================================================;
  151. ;   IDT image in EPROM to be copied to RAM diring INIT, note gate for each    ;
  152. ;   exception by the 80286, furthurmore, assuming one 8259A int controller,   ;
  153. ;   8 int gates placed in slots 32-39.                                        ;
  154. ;   The sixe of this IDT allows 64 slots for gates.                           ;
  155. ;=============================================================================;
  156.  
  157.  
  158. ;---Divide Error (Exception 0)------------------------------------------------;
  159.                 Dw      End_Of_Exception_Code
  160.                 Dw      SEG End_Of_Exception_Code ;;
  161.                 Db      0               ; Base
  162.                 Db      11100111b       ; Acess rights for TRAP gate
  163.                 Dw      0               ; 80386 comp.
  164.  
  165. ;---Single Step (Exception 1)-------------------------------------------------;
  166.                 Dw      End_Of_Exception_Code
  167.                 Dw      SEG End_Of_Exception_Code ;;
  168.                 Db      0               ;
  169.                 Db      11100111b       ; Access rights for TRAP gate
  170.                 Dw      0               ;
  171.  
  172. ;---NMI int (Exception 2)-----------------------------------------------------;
  173.                 Dw      End_Of_Exception_Code
  174.                 Dw      SEG End_Of_Exception_Code ;;
  175.                 Db      0               ; Base
  176.                 Db      11100110b       ; Access rights of INT gate
  177.                 Dw      0               ;
  178.  
  179. ;---Breakpoint trap (Exception 3)---------------------------------------------;
  180.                 Dw      End_Of_Exception_Code
  181.                 Dw      SEG End_Of_Exception_Code ;;
  182.                 Db      0               ; Base
  183.                 Db      11100111b       ; TRAP access
  184.                 Dw      0               ;
  185.  
  186. ;---INTO trap (Exception 4)---------------------------------------------------;
  187.                 Dw      End_Of_Exception_Code
  188.                 Dw      SEG End_Of_Exception_Code ;;
  189.                 Db      0               ; Base
  190.                 Db      11100111b       ; TRAP access
  191.                 Dw      0               ;
  192.  
  193. ;---BOUNDS trap (Exception 5)------------------------------------------------;
  194.                 Dw      End_Of_Exception_Code
  195.                 Dw      SEG End_Of_Exception_Code ;;
  196.                 Db      0               ; Base
  197.                 Db      11100111b       ; TRAP access
  198.                 Dw      0               ;
  199.  
  200. ;---Invalid Opcode (Exception 6)----------------------------------------------;
  201.                 Dw      End_Of_Exception_Code
  202.                 Dw      SEG End_Of_Exception_Code ;;
  203.                 Db      0               ; Base
  204.                 Db      11100111b       ; TRAP access
  205.                 Dw      0               ;
  206.  
  207. ;---Math coprocessor not available (Exception 7)------------------------------;
  208.                 Dw      End_Of_Exception_Code
  209.                 Dw      SEG End_Of_Exception_Code ;;
  210.                 Db      0               ; Base
  211.                 Db      11100111b       ; TRAP access
  212.                 Dw      0               ;
  213.  
  214. ;---Double Fault (Exception 8)------------------------------------------------;
  215.                 Dw      End_Of_Exception_Code
  216.                 Dw      SEG End_Of_Exception_Code ;;
  217.                 Db      0               ; Base
  218.                 Db      11100111b       ; TRAP access
  219.                 Dw      0               ;
  220.  
  221. ;---Coproccessor operand partially beond segment (Exception 9)----------------;
  222.                 Dw      End_Of_Exception_Code
  223.                 Dw      SEG End_Of_Exception_Code ;;
  224.                 Db      0               ; Base
  225.                 Db      11100111b       ; TRAP access
  226.                 Dw      0               ;
  227.  
  228. ;---Invalid task state segment (Exception 10)---------------------------------;
  229.                 Dw      End_Of_Exception_Code
  230.                 Dw      SEG End_Of_Exception_Code ;;
  231.                 Db      0               ; Base
  232.                 Db      11100111b       ; TRAP access
  233.                 Dw      0               ;
  234.  
  235. ;---CS, DS, ES segment not present (Exception 11)-----------------------------;
  236.                 Dw      End_Of_Exception_Code
  237.                 Dw      SEG End_Of_Exception_Code ;;
  238.                 Db      0               ; Base
  239.                 Db      11100111b       ; TRAP access
  240.                 Dw      0               ;
  241.  
  242. ;---SS not present or stack segment violation (Exception 12)------------------;
  243.                 Dw      End_Of_Exception_Code
  244.                 Dw      SEG End_Of_Exception_Code ;;
  245.                 Db      0               ; Base
  246.                 Db      11100111b       ; TRAP access
  247.                 Dw      0               ;
  248.  
  249. ;---General protection violation (Exception 13)-------------------------------;
  250.                 Dw      End_Of_Exception_Code
  251.                 Dw      SEG End_Of_Exception_Code ;;
  252.                 Db      0               ; Base
  253.                 Db      11100111b       ; TRAP access
  254.                 Dw      0               ;
  255.  
  256. ;---Excpetion 14 reserved by intell but not used on 80286---------------------;
  257.                 Dw      0               ;
  258.                 Dw      0               ;
  259.                 Db      0               ;
  260.                 Db      0               ; Access code of 0 = invalid
  261.                 Dw      0               ;
  262.  
  263. ;---Excpetion 15 reserved by intell but not used on 80286---------------------;
  264.                 Dw      0               ;
  265.                 Dw      0               ;
  266.                 Db      0               ;
  267.                 Db      0               ; Access code of 0 = invalid
  268.                 Dw      0               ;
  269.  
  270. ;---Math coprocessor calculation error (Exception 16)-------------------------;
  271.                 Dw      End_Of_Exception_Code
  272.                 Dw      SEG End_Of_Exception_Code ;;
  273.                 Db      0               ; Base
  274.                 Db      11100111b       ; TRAP access
  275.                 Dw      0               ;
  276.  
  277. ;---Exception 17-31 reserved by intel, but unused by 80286--------------------;
  278.                 Db      (32-17)*8 Dup(0); Reserve 0 on all slots
  279.  
  280. PAGE
  281. ;-----------------------------------------------------------------------------;
  282. ; Interrupt gates are placed after intell reserved IDT slots 0-31.            ;
  283. ; 8 gates for ones generated by 8259A are init for base of 32.                ;
  284. ;-----------------------------------------------------------------------------;
  285.  
  286.  
  287. ;---Hardware Interrupt 32-----------------------------------------------------;
  288.                 Dw      End_Of_Interrupt_Code
  289.                 Dw      SEG End_Of_Interrupt_Code ;
  290.                 Db      0               ; Base
  291.                 Db      11100110b       ; Interrupt gate access byte
  292.                 Dw      0               ; 0 for compat with 80386
  293.  
  294. ;---Hardware Interrupt 33-----------------------------------------------------;
  295.                 Dw      End_Of_Interrupt_Code
  296.                 Dw      SEG End_Of_Interrupt_Code ;
  297.                 Db      0               ; Base
  298.                 Db      11100110b       ; Interrupt gate access byte
  299.                 Dw      0               ; 0 for compat with 80386
  300.  
  301. ;---Hardware Interrupt 34-----------------------------------------------------;
  302.                 Dw      End_Of_Interrupt_Code
  303.                 Dw      SEG End_Of_Interrupt_Code ;
  304.                 Db      0               ; Base
  305.                 Db      11100110b       ; Interrupt gate access byte
  306.                 Dw      0               ; 0 for compat with 80386
  307.  
  308. ;---Hardware Interrupt 35-----------------------------------------------------;
  309.                 Dw      End_Of_Interrupt_Code
  310.                 Dw      SEG End_Of_Interrupt_Code ;
  311.                 Db      0               ; Base
  312.                 Db      11100110b       ; Interrupt gate access byte
  313.                 Dw      0               ; 0 for compat with 80386
  314.  
  315. ;---Hardware Interrupt 36-----------------------------------------------------;
  316.                 Dw      End_Of_Interrupt_Code
  317.                 Dw      SEG End_Of_Interrupt_Code ;
  318.                 Db      0               ; Base
  319.                 Db      11100110b       ; Interrupt gate access byte
  320.                 Dw      0               ; 0 for compat with 80386
  321.  
  322. ;---Hardware Interrupt 37-----------------------------------------------------;
  323.                 Dw      End_Of_Interrupt_Code
  324.                 Dw      SEG End_Of_Interrupt_Code ;
  325.                 Db      0               ; Base
  326.                 Db      11100110b       ; Interrupt gate access byte
  327.                 Dw      0               ; 0 for compat with 80386
  328.  
  329. ;---Hardware Interrupt 38-----------------------------------------------------;
  330.                 Dw      End_Of_Interrupt_Code
  331.                 Dw      SEG End_Of_Interrupt_Code ;
  332.                 Db      0               ; Base
  333.                 Db      11100110b       ; Interrupt gate access byte
  334.                 Dw      0               ; 0 for compat with 80386
  335.  
  336. ;---Hardware Interrupt 39-----------------------------------------------------;
  337.                 Dw      End_Of_Interrupt_Code
  338.                 Dw      SEG End_Of_Interrupt_Code ;
  339.                 Db      0               ; Base
  340.                 Db      11100110b       ; Interrupt gate access byte
  341.                 Dw      0               ; 0 for compat with 80386
  342.  
  343. ;---IDT slots of interrupts numbered 40-63 are not used but available---------;
  344.                 Db      (64-40)*8 Dup (0)
  345.  
  346. Idt_Image_End:
  347. INITIAL_DATA    ENDS
  348. PAGE
  349. ;=============================================================================;
  350. ; Initialization code -- setup.  Made to put system in protected mode.        ;
  351. ;=============================================================================;
  352. MAIN_CODE       SEGMENT
  353.                 ASSUME  cs:MAIN_CODE    ;
  354.  
  355.                 Jmp     Flush           ; Jump to flish
  356.                                         ;
  357. Gdt_Pointer:                            ;
  358.                 Dw      Gdt_Image_End - Gdt_Image_Start - 1 ; Size of GDT area
  359.                 Dw      ?               ; Location in ram
  360.                 Dw      0               ;
  361.                                         ;
  362. Idt_Pointer:                            ;
  363.                 Dw      Idt_Image_End - Idt_Image_Start-1 ; Size of IDT
  364.                 Dw      ?               ; Location
  365.                 Dw      0               ;
  366.                                         ;
  367. Initialize:                             ; Jump far to here
  368.                 Push    Cs              ; First set up the main pointers
  369.                 Push    Cs              ; So that we can make prot mode
  370.                 Pop     Ds              ; Possible
  371.                 Pop     Es              ;
  372.                 Lea     Di,Gdt_Pointer  ; Get the offset of this
  373.                 Mov     Ax,INITIAL_DATA ; Get the segment of this
  374.                 Mov     [DI+2],Ax       ; Save the segment
  375.                 Lea     Di,Idt_Pointer  ;
  376.                 Mov     [Di+2],Ax       ;
  377.                                         ;
  378.                 Cli                     ;
  379.                 Lgdt    DWORD PTR cs:Gdt_Pointer  ; Load this
  380.                 Lidt    DWORD PTR cs:Idt_Pointer  ; And this
  381.                                         ;
  382.                 Smsw    Ax              ; Get the machone status word
  383.                 Or      Ax,1            ; Set the PE bit
  384.                 Lmsw    Ax              ; NOW WE ARE IN PROTECTED MODE
  385.                 Jmp     Fls             ; Clear the queue
  386.                                         ;
  387. Fls:                                    ;
  388.                 Mov     Ax,18h          ; Initialize SS:SP (SELECTOR 18h)
  389.                 Mov     Ss,Ax           ;
  390.                 Mov     Sp,400h         ; Inital for 1k stack
  391.                                         ;
  392.         ; JMP FAR MAIN_CODE:0   ; To make correct thing
  393.                                         ;
  394.                 Db      0EAh            ; Far jmp nm
  395.                 Dw      0               ;
  396.                 Dw      MAIN_CODE_SELECTOR
  397.                                         ;
  398. Flush:          Sti                     ;
  399.                 Mov     Al,'P'          ; Char P
  400. Tag:            Mov     Bx,Ax           ; Save
  401.                 Mov     Dx,OUTPUT_DATA_PORT
  402.                 Out     Dx,Al           ; Do this
  403.                 Mov     Dx,OUTPUT_STATUS_PORT1
  404. Tl1a:           In      Al,Dx           ; Get the status of printer
  405.                 Test    Al,80h          ; Check if ready
  406.                 Jz      Tl1a            ;
  407.                 Mov     Dx,OUTPUT_STATUS_PORT2
  408.                 Mov     Al,STROBE_HIGH  ; Strobe high
  409.                 Out     Dx,Al           ;
  410.                 Mov     Al,STROBE_LOW   ; Strobe low
  411.                 Jmp     NextInst        ; Delay
  412. NextInst:       Out     Dx,Al           ;
  413.                 Cmp     Bl,'P'          ; First or second time
  414.                 Jne     Forever         ;
  415.                 Mov     Al,0Dh          ; Carriage return
  416.                 Jmp     Tag             ;
  417.                                         ;
  418. Forever:        Jmp     Forever         ;
  419. Entry:          Cli                     ;
  420.                 Jmp     Initialize      ;
  421.  
  422. End_Of_Main_Code    Equ $               ;
  423. MAIN_CODE       ENDS
  424. PAGE
  425. ;=============================================================================;
  426. ; Exception handler code segment.                                             ;
  427. ;=============================================================================;
  428. EXCEPTION_CODE  SEGMENT
  429.                 Assume  Cs:EXCEPTION_CODE
  430.  
  431. Ex_0:                                   ;
  432.                 Push    Ax              ;
  433.                 Mov     Al,0            ;
  434.                 Call    Report_Exception;
  435.                 Pop     Ax              ;
  436.                 Iret                    ;
  437. Ex_1:                                   ;
  438.                 Push    Ax              ; Save AX
  439.                 Mov     Al,1            ; Put EXP number in Al
  440.                 Call    Report_Exception; Report to user
  441.                 Pop     Ax              ; Get number
  442.                 Iret                    ; And return
  443. ; -- NMI handled as int                 ;
  444. Ex_3:                                   ;
  445.                 Push    Ax              ; Save AX
  446.                 Mov     Al,3            ; Put EXP number in Al
  447.                 Call    Report_Exception; Report to user
  448.                 Pop     Ax              ; Get number
  449.                 Iret                    ; And return
  450. Ex_4:                                   ;
  451.                 Push    Ax              ; Save AX
  452.                 Mov     Al,4            ; Put EXP number in Al
  453.                 Call    Report_Exception; Report to user
  454.                 Pop     Ax              ; Get number
  455.                 Iret                    ; And return
  456. Ex_5:                                   ;
  457.                 Push    Ax              ; Save AX
  458.                 Mov     Al,5            ; Put EXP number in Al
  459.                 Call    Report_Exception; Report to user
  460.                 Pop     Ax              ; Get number
  461.                 Iret                    ; And return
  462. Ex_6:                                   ;
  463.                 Push    Ax              ; Save AX
  464.                 Mov     Al,6            ; Put EXP number in Al
  465.                 Call    Report_Exception; Report to user
  466.                 Pop     Ax              ; Get number
  467.                 Iret                    ; And return
  468. Ex_7:                                   ;
  469.                 Push    Ax              ; Save AX
  470.                 Mov     Al,7            ; Put EXP number in Al
  471.                 Call    Report_Exception; Report to user
  472.                 Pop     Ax              ; Get number
  473.                 Iret                    ; And return
  474. Ex_8:                                   ;
  475.                 Push    Ax              ; Save AX
  476.                 Mov     Al,8            ; Put EXP number in Al
  477.                 Call    Report_Exception; Report to user
  478.                 Pop     Ax              ; Get number
  479.                 Iret                    ; And return
  480. Ex_9:                                   ;
  481.                 Push    Ax              ; Save AX
  482.                 Mov     Al,9            ; Put EXP number in Al
  483.                 Call    Report_Exception; Report to user
  484.                 Pop     Ax              ; Get number
  485.                 Iret                    ; And return
  486. Ex_10:                                  ;
  487.                 Push    Ax              ; Save AX
  488.                 Mov     Al,10           ; Put EXP number in Al
  489.                 Call    Report_Exception; Report to user
  490.                 Pop     Ax              ; Get number
  491.                 Iret                    ; And return
  492. Ex_11:                                  ;
  493.                 Push    Ax              ; Save AX
  494.                 Mov     Al,11           ; Put EXP number in Al
  495.                 Call    Report_Exception; Report to user
  496.                 Pop     Ax              ; Get number
  497.                 Iret                    ; And return
  498. Ex_12:                                  ;
  499.                 Push    Ax              ; Save AX
  500.                 Mov     Al,12           ; Put EXP number in Al
  501.                 Call    Report_Exception; Report to user
  502.                 Pop     Ax              ; Get number
  503.                 Iret                    ; And return
  504. Ex_13:                                  ;
  505.                 Push    Ax              ; Save AX
  506.                 Mov     Al,13           ; Put EXP number in Al
  507.                 Call    Report_Exception; Report to user
  508.                 Pop     Ax              ; Get number
  509.                 Iret                    ; And return
  510. ; 80286 will not generate 14,15
  511. Ex_16:                                  ;
  512.                 Push    Ax              ; Save AX
  513.                 Mov     Al,16           ; Put EXP number in Al
  514.                 Call    Report_Exception; Report to user
  515.                 Pop     Ax              ; Get number
  516.                 Iret                    ; And return
  517. ; Expection 17-31 not here
  518.  
  519. Report_Exception:                       ;
  520.                 Push    Ax              ;
  521.                 Push    Bx              ;
  522.                 Push    Dx              ;
  523.                                         ;
  524. Tg1:            Mov     Bx,Ax           ; Save the value passed
  525.                 Mov     Dx,OUTPUT_DATA_PORT
  526.                 Out     Dx,Al           ; Do this
  527.                 Mov     Dx,OUTPUT_STATUS_PORT1
  528. Xl1a:           In      Al,Dx           ; Get the status of printer
  529.                 Test    Al,80h          ; Check if ready
  530.                 Jz      Xl1a            ;
  531.                 Mov     Dx,OUTPUT_STATUS_PORT2
  532.                 Mov     Al,STROBE_HIGH  ; Strobe high
  533.                 Out     Dx,Al           ;
  534.                 Mov     Al,STROBE_LOW   ; Strobe low
  535.                 Jmp     NextInst2       ; Delay
  536. NextInst2:      Out     Dx,Al           ;
  537.                 Cmp     Bl,0Ah          ; First or second time or last
  538.                 Je      ByBye           ;
  539.                 Cmp     Bl,0Dh          ; Carriage return?
  540.                 Je      ThrowLf         ;
  541.                 Mov     Al,0Dh          ;
  542.                 Jmp     Tg1             ;
  543. ThrowLf:        Mov     Al,0Ah          ;
  544.                 Jmp     Tg1             ;
  545.                                         ;
  546. ByBye:          Pop     Dx              ;
  547.                 Pop     Bx              ;
  548.                 Pop     Ax              ;
  549.                 Ret                     ;
  550.  
  551. End_Of_Exception_Code   EQU $
  552. EXCEPTION_CODE  ENDS
  553. PAGE
  554. ;=============================================================================;
  555. ; Interrrupt Code Segment.                                                    ;
  556. ;=============================================================================;
  557. INTERRUPT_CODE  Segment
  558.                 Assume  Cs:INTERRUPT_CODE
  559.  
  560. NMI:                                    ;
  561.                 Push    Ax              ;
  562.                 Mov     Al,2            ; NMI call
  563.                 Call    Report_Interrupt;
  564.                 Pop     Ax              ;
  565.                 Iret                    ;
  566. Int_32:                                 ;
  567.                 Push    Ax              ;
  568.                 Mov     Al,32           ; Place INT in al
  569.                 Call    Report_Interrupt; Call to report
  570.                 Pop     Ax              ; Get Ax
  571.                 Iret                    ; And Int Return
  572. Int_33:                                 ;
  573.                 Push    Ax              ;
  574.                 Mov     Al,33           ; Place INT in al
  575.                 Call    Report_Interrupt; Call to report
  576.                 Pop     Ax              ; Get Ax
  577.                 Iret                    ; And Int Return
  578. Int_34:                                 ;
  579.                 Push    Ax              ;
  580.                 Mov     Al,34           ; Place INT in al
  581.                 Call    Report_Interrupt; Call to report
  582.                 Pop     Ax              ; Get Ax
  583.                 Iret                    ; And Int Return
  584. Int_35:                                 ;
  585.                 Push    Ax              ;
  586.                 Mov     Al,35           ; Place INT in al
  587.                 Call    Report_Interrupt; Call to report
  588.                 Pop     Ax              ; Get Ax
  589.                 Iret                    ; And Int Return
  590. Int_36:                                 ;
  591.                 Push    Ax              ;
  592.                 Mov     Al,36           ; Place INT in al
  593.                 Call    Report_Interrupt; Call to report
  594.                 Pop     Ax              ; Get Ax
  595.                 Iret                    ; And Int Return
  596. Int_37:                                 ;
  597.                 Push    Ax              ;
  598.                 Mov     Al,37           ; Place INT in al
  599.                 Call    Report_Interrupt; Call to report
  600.                 Pop     Ax              ; Get Ax
  601.                 Iret                    ; And Int Return
  602. Int_38:                                 ;
  603.                 Push    Ax              ;
  604.                 Mov     Al,38           ; Place INT in al
  605.                 Call    Report_Interrupt; Call to report
  606.                 Pop     Ax              ; Get Ax
  607.                 Iret                    ; And Int Return
  608. Int_39:                                 ;
  609.                 Push    Ax              ;
  610.                 Mov     Al,39           ; Place INT in al
  611.                 Call    Report_Interrupt; Call to report
  612.                 Pop     Ax              ; Get Ax
  613.                 Iret                    ; And Int Return
  614.                                         ;
  615. Report_Interrupt:                       ;
  616.                 Push    Ax              ;
  617.                 Push    Bx              ;
  618.                 Push    Dx              ;
  619.                                         ;
  620. Tg2:            Mov     Bx,Ax           ; Save the value passed
  621.                 Mov     Dx,OUTPUT_DATA_PORT
  622.                 Out     Dx,Al           ; Do this
  623.                 Mov     Dx,OUTPUT_STATUS_PORT1
  624. Zl1a:           In      Al,Dx           ; Get the status of printer
  625.                 Test    Al,80h          ; Check if ready
  626.                 Jz      Zl1a            ;
  627.                 Mov     Dx,OUTPUT_STATUS_PORT2
  628.                 Mov     Al,STROBE_HIGH  ; Strobe high
  629.                 Out     Dx,Al           ;
  630.                 Mov     Al,STROBE_LOW   ; Strobe low
  631.                 Jmp     NextInst3       ; Delay
  632. NextInst3:      Out     Dx,Al           ;
  633.                 Cmp     Bl,0Ah          ; First or second time or last
  634.                 Je      ByeBye          ;
  635.                 Cmp     Bl,0Dh          ; Carriage return?
  636.                 Je      ThrowLf2        ;
  637.                 Mov     Al,0Dh          ;
  638.                 Jmp     Tg2             ;
  639. ThrowLf2:       Mov     Al,0Ah          ;
  640.                 Jmp     Tg2             ;
  641.                                         ;
  642. ByeBye:         Pop     Dx              ;
  643.                 Pop     Bx              ;
  644.                 Pop     Ax              ;
  645.                 Ret                     ;
  646.  
  647. End_Of_Interrupt_Code   EQU $
  648. INTERRUPT_CODE  ENDS
  649.  
  650. STACKSEG        Segment PARA    STACK   'STACK'
  651.                 db  1024 dup (0)
  652.  
  653. TOS         EQU $
  654. STACKSEG        ENDS
  655.  
  656.  
  657.                 END     Entry
  658.