home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / alde_c / misc / graph / hercbios / hercbios.asm < prev    next >
Encoding:
Assembly Source File  |  1986-09-04  |  10.7 KB  |  407 lines

  1. ;*******************************************************
  2. ;*
  3. ;*    Main program file for HERCBIOS
  4. ;*
  5. ;*        Dave Tutelman - 8/86
  6. ;*
  7. ;*------------------------------------------------------
  8. ;*    
  9. ;*    INT10 -- acts as pre-handler for video interrupts
  10. ;*    (BIOS calls) for Hercules & SuperComputer
  11. ;*    monochrome graphics board.  Calls real BIOS
  12. ;*    if not a Hercules special. Handled here are:
  13. ;*
  14. ;*    Fn 0    Set mode (only 6 & 8)
  15. ;*    and all functions, when in mode 6 or 8.
  16. ;*    Actually, we've only implemented:
  17. ;*    Fn 2    Set cursor position
  18. ;*    Fn 3    Read cursor position
  19. ;*    Fn 5    New display page
  20. ;*    Fn 9    Write character with attribute
  21. ;*    Fn 10    Write character
  22. ;*    Fn 12    Write pixel
  23. ;*    Fn 13    Read pixel
  24. ;*    Fn 14    Teletypewriter-style character write
  25. ;*    Fn 15    Get video status
  26. ;*
  27. ;*    The only allowable modes for these boards are:
  28. ;*    6    IBM graphics (we handle it, but poor aspect ratio).
  29. ;*    7    Monochrome (with 2 pages)
  30. ;*    8    Hercules graphics mode.
  31. ;*
  32. ;**********************************************************
  33. ;
  34. INCLUDE    hercbios.h
  35.  
  36. extrn    writechar:near,tty:near,scroll_up:near,scroll_down:near
  37. extrn    scr_start:word,scr_length:word,num_rows:byte
  38. extrn    wr_pixel:near
  39. extrn    end_herc:near
  40. public    exit_herc_bios,int10,vid_vector
  41. public    set_mode,set_curs,read_curs,new_page,status
  42. ;-----------------------------------------
  43. page
  44. ;************************************************************
  45. ;*
  46. ;*    Install the Hercules video handler
  47. ;*
  48. ;************************************************************
  49. cseg    segment    public
  50.     assume    cs:cseg,ds:cseg
  51.  
  52.     ORG    100h
  53. ;
  54. START:
  55. ;
  56.     push    ax
  57.     push    es
  58.     push    ds
  59. ;
  60.     xor    ax,ax        ; zero the acc
  61.     mov    es,ax        ; ES points to zero (interrupt vector)
  62.     ; Get ROM BIOS video entry point, and save in "rom_bios"
  63.     mov    ax,es:[4*VIDI]
  64.     mov    word ptr cs:rom_bios,ax
  65.     mov    ax,es:[4*VIDI+2]
  66.     mov    word ptr cs:rom_bios+2,ax
  67.     ; Now plant the HERCBIOS entry point in interrupt vector
  68.     mov    ax,offset int10    ; address of video handler to AX
  69.     mov    es:[4*VIDI],ax    ; and store it in interrupt vector 10H
  70.     mov    ax,cs        ; same for the segment of video handler
  71.     mov    es:[4*VIDI+2],ax    ; ...
  72. ;
  73. ;   Leave the message that we're installed
  74.     mov    ax,cs        ; DS:DX pointing to message
  75.     mov    ds,ax
  76.     mov    dx,offset install_msg
  77.     mov    ah,9        ; display-string function
  78.     int    21h
  79.  
  80.     pop    ds
  81.     pop    es
  82.     pop    ax
  83. ;
  84.     mov    dx,offset end_herc    ; set dx to end of this program
  85.     int    27H        ; terminate, but stay resident
  86. ;
  87. install_msg    db    "BIOS for Hercules-compatible Graphics - "
  88.     db        "(DMT Aug 1986)",10,13,'$'
  89. page
  90. ;************************************************************
  91. ;*
  92. ;*    Beginning of video interrupt handler
  93. ;*
  94. ;************************************************************
  95. ;
  96. ;
  97. int10    proc    far
  98. ;
  99.     sti            ; allow further interrupts
  100.     push    ds        ; save DS
  101.     push    ax        ; save AX
  102.     mov    ax,bios_data    ; bios data segment --> AX
  103.     mov    ds,ax        ; now put bios data segment in DS
  104.     assume    ds:bios_data    ; and tell assembler about it
  105. ;            ; check current mode
  106.     mov    ah,video_mode    ; get current mode
  107.     cmp    ah,herc_mode    ; test for a graphics mode
  108.     je    herc_bios
  109.     cmp    ah,ibm_mode
  110.     je    herc_bios
  111. ;            ; setmode to a graphics mode?
  112.     pop    ax        ; restore AX
  113.     push    ax        ; ...but leave it on stack
  114.     cmp    ax,0006        ; Fn = set to IBM hi-res mode?
  115.     je    herc_bios
  116.     cmp    ax,0008        ; Fn = set to Herc graphics mode?
  117.     je    herc_bios
  118. ;
  119. norm_bios:        ; if we get here, just go to real BIOS
  120.     pop    ax        ; restore stack to pre-interrupt state
  121.     pop    ds
  122.     db    0EAh    ; opcode for FAR JUMP to rom_bios
  123. rom_bios    dd    ?    ; normal video bios address (in ROM)
  124. ;
  125. herc_bios:        ; jump table for special Hercules BIOS
  126. ;
  127.     pop    ax    ; restore ax
  128.     push    bx    ; save regs
  129.     push    cx
  130.     push    dx
  131.     push    si
  132.     push    di
  133.     push    es
  134. ;
  135.     push    ax
  136.     mov    al,ah        ; function # to AX
  137.     xor    ah,ah
  138.     shl    ax,1        ; *2 for word vector
  139.     mov    si,ax        ; put in SI to index into vector
  140.     pop    ax        ; restore old AX
  141.     cmp    si,offset vid_vec_end-offset vid_vector
  142.                 ; function number within range?
  143.     jge    exit_herc_bios    ; function number out of range
  144.     add    si,offset vid_vector
  145.     jmp    word ptr cs:[si]
  146.                 ; jump to routine via vector
  147. ;
  148.  
  149. vid_vector:        ; jump vector for hercules video routines
  150.     dw    offset set_mode            ; 0 = set mode
  151.     dw    offset exit_herc_bios        ; 1 = cursor type (NA)
  152.     dw    offset set_curs            ; 2 = set cursor position
  153.     dw    offset read_curs        ; 3 = read cursor position
  154.     dw    offset exit_herc_bios        ; 4 = light pen (NA)
  155.     dw    offset new_page            ; 5 = choose active page
  156.     dw    offset scroll_up        ; 6 = scroll up
  157.     dw    offset scroll_down        ; 7 = scroll down
  158.     dw    offset exit_herc_bios        ; 8 = read character (NA)
  159.     dw    offset writechar        ; 9 = write char & attribute
  160.     dw    offset writechar        ;10 = write character
  161.     dw    offset exit_herc_bios        ;11 = set color palette (NA)
  162.     dw    offset wr_pixel            ;12 = write pixel
  163.     dw    offset wr_pixel            ;13 = read pixel
  164.     dw    offset tty            ;14 = teletype write
  165.     dw    offset status            ;15 = return video state
  166. vid_vec_end:
  167. ;
  168. exit_herc_bios:
  169.     pop    es    ; restore regs
  170.     pop    di
  171.     pop    si
  172.     pop    dx
  173.     pop    cx
  174.     pop    bx
  175.     pop    ds
  176.     iret        ; and return
  177. page
  178. ;********************************************************************
  179. ;*
  180. ;*    FUNCTION 0 - SET VIDEO MODE
  181. ;*
  182. ;*    Only gets here to set a hi-res graphics mode
  183. ;*        6=IBM
  184. ;*        8=Hercules
  185. ;*    [ AX destroyed ]
  186. ;*
  187. ;*******************************************************************
  188. ;
  189. set_mode:
  190. ;            ; is it a graphics mode?
  191.     cmp    al,herc_mode    ; set to hercules mode?
  192.     je    g_mode
  193.     cmp    al,ibm_mode    ; set to IBM mode?
  194.     je    g_mode
  195.                 ; Neither. Leave it to normal BIOS
  196.     pop    es        ; restore regs
  197.     pop    di
  198.     pop    si
  199.     pop    dx
  200.     pop    cx
  201.     pop    bx
  202.     pop    ds
  203.     jmp    vid_bios    ; and go to MPX-16 BIOS
  204. ;
  205. g_mode:    mov    video_mode,al    ; save video mode in BIOS data area
  206.     mov    active_page,ah    ; zero the active page in BIOS data
  207.     mov    n_cols,90    ; 90 character columns in graphics mode
  208. ;
  209. ;*  clear display area
  210.     mov    ax,pixbase    ; get starting address
  211.     mov    es,ax        ; page base to ES
  212.     mov    cx,8000H    ; word counter
  213.     mov    di,0        ; start at beginning of display
  214.     cld            ; direction "up"
  215.     xor    ax,ax        ; zero AX
  216.     rep    stosw        ; write zero to both pages
  217. ;
  218. ;*  load the 6845 internal registers
  219. ;
  220. ;            ; first set up the loop
  221.     push    ds        ; save DS
  222.     mov    ax,cs        ; get cseg into DS
  223.     mov    ds,ax
  224.     assume    ds:cseg
  225.     mov    dx,vid_port    ; 6845 index port address to DX
  226.     mov    si,offset vid_parm_table
  227.                 ; table pointer to SI
  228.     mov    cx,16        ; 16 parameters in table
  229.     xor    ax,ax        ; zero AX (AH will be index counter)
  230. ;            ; now execute the loop
  231. init_6845_loop:
  232.     mov    al,ah        ; index counter to AL
  233.     out    dx,al        ; output index to 6845
  234.     inc    dx        ; point DX to data reg
  235.     mov    al,[si]        ; get table entry
  236.     out    dx,al        ; output to 6845 data reg
  237.     dec    dx        ; point DX back to index reg
  238.     inc    ah        ; bump index counter
  239.     inc    si        ; bump table pointer
  240.     loop    init_6845_loop
  241.     pop    ds        ; restore DS
  242.     assume    ds:bios_data    ; restore DS assumed
  243. ;
  244. ;*  now set the 6845 control register
  245.     mov    dx,vid_port+4    ; control port address
  246.     mov    al,0AH        ; graphics control byte
  247.     cmp    active_page,0    ; get current page
  248.     je    pg0_F0        ; skip if zero
  249.     or    al,80H        ; page 1 to control byte
  250. pg0_F0:    out    dx,al        ; and ship to 6845
  251.     mov    chip_ctrl,al    ; also save in bios data area
  252. ;
  253. ;*  save cursor position (0,0) in bios data area
  254.     xor    ax,ax        ; zero AX
  255.     mov    curs_pos,ax    ; write zero to pg.0 cursor postion
  256.     mov    curs_pos+2,ax    ; write zero to pg.1 cursor postion
  257. ;
  258. ;*  initialize scrolling parameters
  259. ;
  260.     cmp    video_mode,herc_mode
  261.     je    h_parm
  262.     mov    cs:scr_start,180    ; IBM parameters
  263.     mov    cs:scr_length,3690    ;
  264.     mov    cs:num_rows,42        ;
  265.     jmp    parm_done
  266. h_parm:    mov    cs:scr_start,270    ; Herc parameters
  267.     mov    cs:scr_length,3645    ;
  268.     mov    cs:num_rows,28        ;
  269. parm_done:
  270. ;
  271.     jmp    exit_herc_bios
  272. ;
  273. ;*  table of 6845 chip parameters
  274. ;
  275. vid_parm_table    db    53,45,46,7,91,2,87,87,2,3,62H,3,0,0,0,0
  276. ;vid_parm_table    db    54,45,46,8,91,2,87,87,2,3,62H,3,0,0,0,0
  277.                         ;DMT's monitor
  278. page
  279. ;********************************************************************
  280. ;*
  281. ;*    FUNCTION 2 - SET CURSOR POSITION
  282. ;*
  283. ;*    DX = new row (DH) and column (DL)
  284. ;*    BH = display page number
  285. ;*
  286. ;********************************************************************
  287. ;
  288. set_curs:
  289. ;
  290. ; *   save in BIOS data area
  291.     mov    bl,bh        ; page # to bl
  292.     xor    bh,bh        ; zero bh (page # = BX)
  293.     shl    bx,1        ; times 2 for word
  294.     mov    curs_pos[bx],dx    ; store in data area
  295. ;
  296. ; *   if page # = active page, then we should actually move cursor
  297. ; *          However, cursor doesn't show in graphics mode, so we won't.
  298. ;
  299.     jmp    exit_herc_bios
  300. ;
  301. page
  302. ;********************************************************************
  303. ;*
  304. ;*    FUNCTION 3 - READ CURSOR POSITION
  305. ;*
  306. ;*    on entry
  307. ;*        BH = display page number
  308. ;*
  309. ;*    on exit
  310. ;*        CX = cursor type/size
  311. ;*        DX = current row (DH) and column (DL)
  312. ;*
  313. ;********************************************************************
  314. ;
  315. read_curs:
  316. ;            ; uncover the return portion of the stack
  317.     pop    es
  318.     pop    di
  319.     pop    si
  320.     pop    dx
  321.     pop    cx
  322. ;            ; now get the data and push onto stack
  323.     push    curs_mode    ; cursor type to CX position in stack
  324.     mov    bl,bh        ; page # to BX
  325.     xor    bh,bh
  326.     shl    bx,1        ; *2 for word offset
  327.     push    curs_pos[bx]    ; cursor position for specified page
  328.                 ;   to DX position in stack
  329. ;            ; refill the stack for return
  330.     push    si
  331.     push    di
  332.     push    es
  333. ;
  334.     jmp    exit_herc_bios
  335. page
  336. ;********************************************************************
  337. ;*
  338. ;*    FUNCTION 5 - SELECT NEW DISPLAY PAGE
  339. ;*
  340. ;*    AL = new display page number
  341. ;*
  342. ;********************************************************************
  343. ;
  344. new_page:
  345.     cmp    al,2        ; page < 2?
  346.     jl    f5_1        ; yup
  347.     jmp    exit_herc_bios    ; nope. can't do it.
  348. ;
  349. f5_1:    mov    active_page,al    ; put away active page in bios data
  350. ;  * put starting address in 6845 register 12
  351.     mov    ah,al        ; save page number in AH
  352.     mov    dx,vid_port    ; index pointer address
  353.     mov    al,12        ; save in register 12
  354.     out    dx,al        ; and set index pointer to 12
  355.     mov    al,ah        ; restore page to AL
  356.     ror    al,1        ; page to high-order bit
  357.     shr    al,1        ; two bytes per word
  358.     inc    dx
  359.     out    dx,al        ; ...and output it to register
  360. ;  * put control byte in 6845 port
  361.     mov    al,ah        ; get back page number
  362.     ror    al,1        ; page to high-order bit
  363.     or    al,0AH        ; create chip control byte
  364.     mov    chip_ctrl,al    ; save it in data area
  365.     mov    dx,vid_port+4    ; control port address
  366.     out    dx,al        ; send control byte to chip
  367. ;
  368.     jmp    exit_herc_bios
  369. page
  370. ;***********************************************************************
  371. ;*
  372. ;*    FUNCTION 15 - RETURN VIDEO STATUS
  373. ;*
  374. ;*    On exit:
  375. ;*        AL = current video mode
  376. ;*        AH = number of active display columns
  377. ;*        BH = current active page number
  378. ;*
  379. ;***********************************************************************
  380. ;
  381. status:
  382. ;            ; first uncover the stack
  383.     pop    es
  384.     pop    di
  385.     pop    si
  386.     pop    dx
  387.     pop    cx
  388.     pop    bx
  389. ;            ; now get the parameters needed
  390.     mov    al,video_mode
  391.     mov    ah,90        ; all our graphics modes have 90 cols
  392.     mov    bh,active_page
  393. ;            ; and push back onto the stack for return
  394.     push    bx
  395.     push    cx
  396.     push    dx
  397.     push    si
  398.     push    di
  399.     push    es
  400. ;
  401.     jmp    exit_herc_bios
  402. ;
  403. int10    endp
  404. ;
  405. cseg    ends
  406.     end    START
  407.