home *** CD-ROM | disk | FTP | other *** search
- ;------------------
- ; WANG INTERFACE
- ;------------------
-
- ; Thanks to Alan Tschetter for providing the information necessary for me
- ; to program this interface.
-
- WANG_KEYS:
- DB 0E1 ; HELP key value
- DB 07F-FUNC ; add-quantity for FUNC
- L1:
- DB 0C2,0C9,0C0,0C8,0C4 ; DOWN, NEXT, UP, PREV, HOME
- DB 097,097 ; shift-F7 key, disabled Alt-F9 key
- N_CONTROL_KEYS EQU $-L1
-
- DW HELP_HELP ; pointer to "HELP" message, the name of Wang's HELP key
-
- L2:
- DW WANG_COPY ; VID_COPY routine
- DW WANG_ATTR ; VID_ATTR routine
- DW RET ; there is no VID_FIX necessary on the Wang
- DW WANG_BELL ; BIOS_BELL routine
- DW WANG_KEY ; BIOS_KEY routine
- DW RET
- DW RET
- DW 0F000 ; new value for VIDEO_SEG
- DB 0 ; normal-video attribute for the Wang PC
- DB 2 ; reverse-video attribute for the Wang PC
- N_BIOS_CALLS EQU ($-L2)/2
-
-
- ; Other Wang keycodes: F1--F16 80--8F
- ; Prev C8 Erase CB
- ; Insert C6 Delete C7
- ; <--- C3 ---> C1
- ; EXEC C5
- ; All the above codes add 010 for SHIFT versions.
- ; NO ALT KEY!!!
- ; Print E3 Back Tab CD
- ; Cancel E0 Shift Cancel 03
-
-
- ; WANG_CONFIG is the BIOS initialization routine for a Wang PC. We copy the
- ; values of WANG_KEYS to various locations, then we fetch the value of
- ; ENABLE_PORT, that lets us access Wang's video memory, then we move the
- ; user's cursor to the lower left corner.
-
- L1: ; console codes to move cursor to lower left corner
- DB 01B,'[25;1H' ; row 25, column 1
- L2 EQU $-L1 ; L2 is the count of bytes
-
- WANG_CONFIG:
- MOV SI,WANG_KEYS ; point to Wang's table of key codes and other values
- CALL NEW_KEYS ; plug the new values into our program's data structures
- MOV AL,1 ; function code for GET BIOS ENVIRONMENT
- INT 088 ; sets ES to a segment where we'll find port #
- ES MOV BX,[BX+10] ; fetch a pointer
- ES MOV AH,[BX+19] ; use the pointer to fetch the high of the port #
- MOV AL,010 ; low of the port # is always 010
- MOV ENABLE_PORT,AX ; store the port number
- MOV DS,CS ; point DS to our program, for console sequence
- MOV DX,L1 ; point DX to the "go to lower left" console sequence
- MOV CX,L2 ; load the number of bytes in the sequence
- MOV BH,0 ; device number, maybe? I don't know for sure
- MOV AL,0D ; function number, maybe? I don't know for sure
- INT 088 ; output escape string, user's cursor goes to lower left
- RET
-
-
- ; WANG_COPY is the Wang-PC version of the VID_COPY routine. The character
- ; and attribute bytes are reversed from what they are on the IBM-PC, so
- ; AH and AL are swapped before and after every word output. There are no
- ; snow problems; so we can get away with copying everything every time.
- ; We do need to enable the video memory, though.
-
- WANG_COPY:
- MOV DX,ENABLE_PORT ; fetch the port number for enabling video memory
- MOV AL,1 ; value 1 causes memory to be enabled
- OUT DX,AL ; we can now access the video memory
- L1: ; loop here for each character to be copied
- LODSB ; fetch the next character
- XCHG AH,AL ; swap character into AH, attribute byte into AL
- STOSW ; output the word to video memory
- MOV AH,AL ; copy the attribute byte back to AH, for next char
- LOOP L1 ; loop to copy the next character
- L2: ; common exit with WANG_ATTR
- MOV AL,0 ; value 0 shuts off access to video memory
- OUT DX,AL ; video access is now disabled
- RET
-
-
- ; WANG_ATTR is the Wang-PC version of the VID_ATTR routine. The attribute
- ; byte is the low byte of the DI-pointed video memory. Also, to access it,
- ; we must send the code that enables Wang video memory.
-
- WANG_ATTR:
- PUSH AX ; preserve the attribute code
- MOV DX,ENABLE_PORT ; fetch the port number for enabling video memory
- MOV AL,1 ; value 1 causes memory to be enabled
- OUT DX,AL ; we can now access the video memory
- POP AX ; restore the attribute code
- STOSB ; output the attribute byte to the LOW byte of video word
- JMP L2 ; join common code to disable video access
-
-
- ; WANG_KEY is the Wang-PC version of the BIOS_KEY routine.
-
- WANG_KEY:
- PUSH BX ; preserve register across call
- L1: ; loop here to wait for a key to become ready
- MOV AL,15 ; Wang BIOS function code for GET KEY STATUS
- MOV BL,2 ; another parameter for Wang BIOS - I'm not sure which
- INT 088 ; call Wang BIOS to get the status and maybe the key
- TEST AL ; do we have a key?
- JNZ L1 ; loop if not, to try again
- XCHG AX,BX ; we do: swap the key code into AL for return
- POP BX ; restore clobbered register
- RET
-
-
- ; WANG_BELL is the Wang-PC version of the BIOS_BELL routine.
-
- WANG_BELL:
- MOV BX,7 ; BL=7 is the BELL code; the BIOS also wants BH=0
- MOV AL,6 ; Wang BIOS function code for CONSOLE OUTPUT
- INT 088 ; output the BELL control code to the Wang console
- RET
-
-
- ;------------------
- ; TI-PC INTERFACE
- ;------------------
-
- ; Thanks to David R. Cook for writing the following code. I have reformatted
- ; it to look like the rest of my code, and made optimizations.
-
- TIPC_KEYS:
- DB 0B5 ; key code for F11 - the help key
- DB 0AA-FUNC ; F1 is code 0AB on the TI-PC
- L1:
- DB 0C0 ; down-arrow key
- DB 0C1 ; no PgDn key on the TI-PC, so we use alt-down-arrow code
- DB 0B8 ; up-arrow key
- DB 0B9 ; no PgUp key on the TI-PC, so we use alt-up-arrow code
- DB 0B7 ; HOME key
- DB 0CA ; shift-F7 key
- DB 0E0 ; alt-F9 key
- N_CONTROL_KEYS equ $-L1
-
- DW F11_HELP ; pointer to help message
-
- L2:
- DW TIPC_COPY ; VID_COPY routine
- DW TIPC_ATTR ; VID_ATTR routine
- DW TIPC_FIX ; VID_FIX routine
- DW TIPC_BELL ; BIOS_BELL routine
- DW TIPC_KEY ; BIOS_KEY routine
- DW RET
- DW RET
- DW 0DE00 ; new value for VIDEO_SEG
- DB 0F ; normal-video attribute for the TI-PC
- DB 01F ; reverse-video attribute for the TI-PC
- N_BIOS_CALLS equ ($-L2)/2
-
- ; Other TI keycodes:
-
- ; key +shift +alt +ctrl plain
- ; ----------------------------------
- ; F1 0C4 0D8 0CE 0AB
- ; ...
- ; F10 0CD 0E1 0D7 0B4
- ; F11 "x" "|" "z" 0B5
- ; F12 "y" "}" "{" 0B6
- ;
- ; PRNT 0E2
- ; INS 098 09A 099 0C2
- ; DEL 0A8 0AA 0A9 0C3
- ; UP AR 0F8 0B9 0F4
- ; DN AR 0F9 0C1 0E6
- ; LT AR 0FB 0BC 0E3 0BB
- ; RT AR 0FA 0BE 0E4 0BD
- ; HOME 0F6 0F5 0E7
- ; TAB 07F ignored ignored 09
-
-
-
- ; TIPC_CONFIG is the BIOS initialization routine for the TI-PC. We copy the
- ; values in TIPC_KEYS to various locations, then we drop into TIPC_FIX,
- ; to reset the cursor.
-
- TIPC_CONFIG:
- MOV SI,TIPC_KEYS ; point to configuration-table for TI-PC's BIOS
- CALL NEW_KEYS ; copy the values to our tables
- TIPC_FIX:
- MOV AH,014 ; BIOS function code for "clear graphics screen"
- INT 049 ; clear the graphics screen
- MOV AH,013 ; BIOS function code for "clear text screen"
- INT 049 ; clear the text screen
- MOV AH,2 ; BIOS function code for "position the cursor"
- MOV DX,1 BY 24 ; first column, 24th row
- INT 049 ; move the user's cursor to the bottom left corner
- RET
-
-
- ; TIPC_COPY is the VID_COPY routine for the TIPC video board. The attribute
- ; AH is written to a single memory-mapped latch in the video segment.
- ; Then the text bytes can be copied as-is.
-
- TIPC_COPY:
- ES MOV B[01801],AH ; set the attribute latch
- SHR DI,1 ; adjust the video address for bytes, not words
- REP MOVSB ; copy the text as-is
- SHL DI,1 ; restore the video address to words, not bytes
- RET
-
-
- ; TIPC_ATTR is the VID_ATTR routine for TI-PC computer. We change the
- ; attribute latch to the one provided in AL, then we add 0 to the video
- ; character in memory, causing the new latch value to take effect.
-
- TIPC_ATTR:
- SHR DI,1 ; adjust video address for bytes, not words
- ES MOV AH,B[DI] ; fetch the character
- ES MOV B[01801],AL ; rewrite the latch with the caller's value
- ES MOV B[DI],AH ; re-write the value already there, to effect the latch
- SHL DI,1 ; restore DI
- RET
-
-
- ; TIPC_KEY is the BIOS_KEY routine for TI_PC computer. We must transform the
- ; two-byte code returned by the TIPC BIOS into the single code AL expected by
- ; the rest of the debugger. The only differences to IBM_KEY are the interrupt
- ; number, and the mapping of the codes received and returned.
-
- TIPC_KEY:
- MOV AH,0 ; function code for GET KEY
- INT 04A ; get the keystroke from the TIPC BIOS
- TEST AL ; is the return AL nonzero?
- JNZ RET ; if yes then AL is our return code
- MOV AL,AH ; AL is zero, so AH determines the return code
- ADD AL,080-16 ; shift the values into a range not seen directly in AL
- RET
-
-
- ; TIPC_BELL is the BIOS_BELL routine for TIPC-PC computer. We output the code
- ; 07 to the BIOS's console output routine. The only difference to IBM_KEY is
- ; the interrupt number.
-
- TIPC_BELL:
- MOV AX,0E07 ; AH= console out function number; AL="BELL" control code
- INT 049 ; output BELL to the console
- RET
-
-
- ;------------------
- ; SANYO INTERFACE
- ;------------------
-
- ; Thanks to Jerry Farnsworth for providing the information necessary for me
- ; to program this interface.
-
- SANYO_KEYS:
- DB 0DC ; key code for Ctrl-PF5 -- the help key
- DB 0 ; same function codes as IBM-PC
- L1:
- DB 0C0 ; down-arrow key
- DB 0C1 ; PgDn key
- DB 0B8 ; up-arrow key
- DB 0B9 ; PgUp key
- DB 0B7 ; HOME key
- DB 0CA ; shift-F7 key is Ctrl 7 on the Sanyo
- DB ALT_F 9 ; Ctrl-Shift-PF4 will restore a trashed screen
- N_CONTROL_KEYS equ $-L1
-
- DW PF5_HELP ; pointer to help message
-
- L2:
- DW SANYO_COPY ; VID_COPY routine
- DW SANYO_ATTR ; VID_ATTR routine
- DW NO_ACTUAL ; VID_FIX routine
- DW IBM_BELL ; BIOS_BELL routine
- DW IBM_KEY ; BIOS_KEY routine
- DW SANYO_SAVE ; we must save the BIOS cursor position
- DW SANYO_RESTORE ; we must restore the BIOS cursor position
- DW 07C00 ; new value for VIDEO_SEG
- DB 07 ; normal-video attribute for the Sanyo-PC
- DB 0F0 ; reverse-video attribute for the Sanyo-PC
- N_BIOS_CALLS equ ($-L2)/2
-
-
- ; Other Sanyo keycodes:
-
- ; IBM Sanyo IBM Sanyo
-
- ; Alt Ctrl Shift DOWN numeric pad 5
- ; Alt Fn Ctrl Fn END numeric pad 2
- ; Shift Fn Ctrl n
- ; Ctrl 2 Ctrl ` Ctrl F12345 Ctrl ={}:"
- ; Ctrl 6 Ctrl tilde Ctrl F678910 Ctrl ;',./
-
-
-
- ; SANYO_CONFIG is the BIOS initialization routine for a Sanyo 55x. We copy the
- ; values of SANYO_KEYS to various locations, fetch and store the current
- ; video page, and set the user cursor to the lower left of the screen.
-
- ; SANYO_FIX insures a screen refresh by filling the "actual" buffers of SCREEN_P
- ; with impossible FF-values.
-
- SANYO_CONFIG:
- MOV SI,SANYO_KEYS ; point to configuration-table for SANYO's BIOS
- CALL NEW_KEYS ; copy the values to our tables
- MOV AH,15 ; function number for fetching the video page
- INT 010 ; set BH to the current video page
- MOV SANYO_PAGE,BH ; store the page throughout the debugging session
- MOV DX,24 BY 0 ; load coordinates for the lower left corner
- CALL SET_SANYO_POS ; store this position
- CALL SANYO_RESTORE ; this call causes the user cursor to move there
- NO_ACTUAL:
- MOV AX,0FFFF ; load AH and AL with the 0FF impossible-value
- FILL_ACTUAL:
- MOV ES,SS ; destination segment is our stack, for buffer-fill
- XCHG DI,AX ; save fill-value in DI
- SS MOV AX,SCREEN_P ; point to the screen buffer
- MOV AL,80 ; advance AX to the actual buffer for the first line
- XCHG AX,DI ; swap actual pointer to DI, restore fill value to AX
- MOV DL,24 ; load the count of actual lines to fill
- L2:
- MOV CX,40 ; number of words in the actual buffer
- REP STOSW ; fill the buffer with the words
- ADD DI,256-80 ; advance output pointer to the next line's actual buff.
- DEC DL ; count down lines
- JNZ L2 ; loop to fill the next line
- RET
-
-
- ; SANYO_COPY is the VID_COPY routine for the Sanyo. The Sanyo does not have
- ; a hardware character generator, so we call the BIOS to copy bit-patterns
- ; to the screen.
-
- SANYO_COPY:
- PUSH BX,BP ; preserve caller's BX and return DI value
- MOV BP,>L3
- MOV BH,0 ; load the page number
- SANYO_PAGE EQU B[$-1] ; previous immediate value is plugged in
- BP_VID_COPY:
- MOV AX,DI ; fetch the output character number
- ADD DI,CX ; add the character count
- ADD DI,CX ; add it twice, to advance by words not bytes
- PUSH DI
- CALL GET_ROWCOL ; convert character number AX into row-and-column DX
- DEC DX ; cancel the following first INC DX
- L1: ; loop here for every character already out there
- INC DX ; advance the column number DL to the next position
- LODSB ; fetch the next character
- MOV BL,AL ; save the character in BL
- XCHG AL,[SI+79] ; swap it with the already-out-there value
- CMP AL,BL ; is the character already out there?
- LOOPE L1 ; loop if it is
- JE >L2 ; jump if the characters are exhausted
- INC CX ; undo the previous LOOPE's decrement of CX
- CALL BP
- LOOP L1 ; loop to check for another output character
- L2:
- POP DI,BP,BX ; restore clobbered registers
- RET
-
- L3:
- CALL SET_IBM_CURSOR ; move the cursor to the indicated position
- MOV AL,BL ; fetch the character to be output
- MOV BL,7 ; load the attribute code, always 7 in Sanyo's case
- PUSH CX ; save the character count
- MOV CX,1 ; we are outputting 1 character in this call
- MOV AH,9 ; BIOS function number for WRITE_CHAR
- INT 010 ; write the character to the screen
- POP CX ; restore the character count
- RET
-
-
- ; SANYO_ATTR is the VID_ATTR routine for the Sanyo. We use the BIOS to
- ; move the cursor to the current position, read the character that is
- ; already there, and rewrite the character with the new attribute.
-
- SANYO_ATTR:
- PUSH BX,CX,DX,DI ; save registers across call
- PUSH AX ; save the attribute across the repositioning
- MOV AX,DI ; fetch the character number
- CALL GET_ROWCOL ; convert the character number AX to row-and-column DX
- CS MOV BH,SANYO_PAGE ; load the current page number
- CALL SET_IBM_CURSOR ; move the cursor to the required location
- MOV AH,8 ; function number for READ_CHARACTER
- INT 010 ; set AL to the character already there
- POP DX ; restore DL = new attribute byte
- MOV BL,DL ; copy the attribute to BL where the BIOS expects it
- MOV CX,1 ; we are writing one character only
- MOV AH,9 ; BIOS function number for WRITE_CHAR
- INT 010 ; write the character to the screen
- POP DI,DX,CX,BX ; restore clobbered registers
- RET
-
-
- ; GET_ROWCOL an address AX into a row number DH and column number DL. The input
- ; AX address is twice the number of characters from the start of the screen
- ; to the current cursor position.
-
- GET_ROWCOL:
- SHR AX,1 ; convert the word index into a byte index
- MOV DL,80 ; there are 80 characters in a line
- DIV DL ; compute the column number AH, row number AL
- XCHG AL,AH ; swap so AH is row, AL is column
- XCHG DX,AX ; swap so DH is row, DL is column
- RET
-
-
- ; SANYO_SAVE is the BIOS_SAVE routine for the Sanyo. We record the user's
- ; cursor position, so that it can be restored by BIOS_RESTORE.
-
- SANYO_SAVE:
- MOV AH,3 ; BIOS function number for READ_CURSOR_POSITION
- INT 010 ; set DX to the current user cursor position
- SET_SANYO_POS:
- CS MOV SANYO_POS,DX ; store the cursor position DX
- RET
-
-
- ; SANYO_RESTORE is the BIOS_RESTORE routine for the Sanyo. We set the
- ; user's sursor position to the place previously stored.
-
- SANYO_RESTORE:
- MOV DX,0 ; fetch the cursor position
- SANYO_POS EQU W[$-2] ; the above immedaite operand has been plugged
- JMP SET_IBM_CURSOR ; jump to set the user's cursor
-
-
- ;------------------------
- ; TANDY 2000 INTERFACE
- ;------------------------
-
- ; Thanks to John B. Harrell, Contributing Editor PC Resuorce, for writing
- ; the following code. I have made minor code optimizations.
-
- TANDY_KEYS:
- DB ALT_F 10 ; code for Alt-F10 -- the HELP key
- DB 0 ; F1 code same as on IBM-PC
- L1:
- DB 0C0 ; Down Arrow
- DB 0C1 ; PgDn
- DB 0B8 ; Up Arrow
- DB 0B9 ; PgUp
- DB 0B7 ; Home
- DB 0CA ; Shift F7
- DB ALT_F 9 ; Alt-F9 fixes a trashed screen
- N_CONTROL_KEYS EQU $-L1
-
- DW ALTF10_HELP ; pointer to help message
-
- L2:
- DW MONO_COPY ; VID_COPY routine
- DW IBM_ATTR ; VID_ATTR routine
- DW TANDY_FIX ; VID_FIX routine
- DW IBM_BELL ; BIOS_BELL routine
- DW IBM_KEY ; BIOS_KEY routine
- DW RET ; BIOS_SAVE routine needed for Sanyo only
- DW RET ; BIOS_RESTORE routine needed for Sanyo only
- TANDY_VSEG DW ? ; Tandy 2000 floating video segment address = VIDEO_SEG
- DB 0A ; normal video attribute on Tandy 2000
- DB 0CA ; reverse video attribute on Tandy 2000
- N_BIOS_CALLS EQU ($-L2)/2
-
- ; Other Tandy 2000 keycodes:
-
- ; key +shift +alt +ctrl plain
- ; ----------------------------------
- ; F1 0C4 0D8 0CE 0AB
- ; ...
- ; F10 0CD 0E1 0D7 0B4
- ; F11 012 "&" 01C 008
- ; F12 013 "`" 01D 009
- ;
- ; PRNT --- 0B6 0E2 010
- ; INS 0F9 010 00F 0C2
- ; DEL 0FA 00E 00D 0C3
- ; UP AR 0F5 001 000
- ; DN AR 0F6 007 006
- ; LT AR 0F7 002 0E3 0BB
- ; RT AR 0F8 --- 0E4 0BD
- ; HOME 0BA 016 0E7
- ; TAB 07F 0FE 0FD 009
- ; BKSP 008 0FC 07F 008
- ; TAB 07F 0FE 0FD 009
- ; ESC 01B 0FB 01B 01B
- ; END --- --- 0E5 0BF
- ; PGUP --- --- 0F4 0B9
- ; PGDN --- --- 0E6
-
- TANDY_CONFIG:
- INT 012 ; get reported memory size in KBytes
- MOV CL,6 ; shift count = * 64 for Kbytes to paragraphs
- SHL AX,CL ; convert to paragraphs
- ADD AX,0080 ; point to starting location of monochrome video buffer
- CS MOV TANDY_VSEG,AX ; save in data structure
- MOV SI,TANDY_KEYS ; point to configuration table for Tandy 2000
- CALL NEW_KEYS ; copy the value into BIOS tables
- TANDY_FIX:
- MOV AX,0 BY 2 ; AH= BIOS function code for SET_VIDEO_MODE; AL = mode 0
- INT 16 ; force a monochrome video mode
- JMP SET_IBM_LOW_LEFT ; move the cursor to the lower left corner
-
-
- ;-----------------------
- ; SIRIUS INTERFACE
- ;-----------------------
-
- ; BIOS interface routines for the ACT Sirius/DRG Victor 9000. Thanks to
- ; Frank Peelo, Dublin, Rep. of Ireland, for writing this code. I
- ; have made format changes and minor optimizations.
-
- SIRIUS_KEYS:
- DB 0A ; ALT-J for help, to duplicate Wordstar
- DB 0F0-FUNC ; The function keys return F0 to F8 - I don't have 9 or 10!
-
- L1:
- DB 0A1 ; Down Arrow
- DB 03 ; PgDn -- must use Ctrl-C as there's no PgDn
- DB 0A0 ; Up Arrow
- DB 012 ; PgUp -- must use Ctrl-R as there's no PgUp
- DB 0B ; Home -- Ctrl-K
- DB 01A ; Shift F7
- DB 0 ; no fixup needed on Sirius
- N_CONTROL_KEYS EQU $-L1
-
- DW ALTJ_HELP
-
- L2:
- DW SIRIUS_COPY ; Offsets of subroutines.
- DW SIRIUS_ATTR ; For the do-nothing routines, I'll let you put in
- DW RET ; no SIRIUS_FIX needed
- DW SIRIUS_BELL
- DW SIRIUS_KEY
- DW RET ; no SIRIUS_SAVE needed
- DW RET ; no SIRIUS_RESTORE needed
-
- DW 0F000 ; segment address of the Video RAM.
- DB 040 ; attribute for normal-intensity, positive video.
- DB 060 ; attribute for normal-intensity, underlined video
- ; (reverse video is 0C0)
- N_BIOS_CALLS EQU ($-L2)/2
-
- T1: DB 01B,'Y',' '+23,' ' ; ≈ Text of VT52 escape code to move
- T2 EQU $-T1 ; ≈ cursor to row 23, col 0.
-
-
- ; SIRIUS_BLOCK is a control block passed to INT 0DF, to get the pointer
- ; to the console handler routine.
-
- SIRIUS_BLOCK:
- DW 1 ; first parameter - device number (1=CON device)
- SIRIUS_BIOS DD ? ; second parameter - the vector is returned here
-
-
- SIRIUS_CONFIG:
- MOV SI,SIRIUS_KEYS ; Point to configuration table for the Sirius
- CALL NEW_KEYS ; Copy the data into D86's tables
- MOV BX,SIRIUS_BLOCK
- MOV AX,14 ; BIOS function 14 = Get Device Vector
- INT 0DF ; The variable Sirius_BIOS_Vector is now set
- MOV BX,T1 ; There is only one screen, so move the cursor
- MOV CX,T2 ; I use an escape code, through Int 29h, to skip
- L1: ; redirection, if it's in use
- MOV AL,[BX]
- PUSH BX,CX ; preserve registers across interrupt
- INT 029
- POP CX,BX ; restore clobbered registers
- INC BX
- LOOP L1
- RET
-
-
- ; SIRIUS_COPY is the VID_COPY routine for the Sirius. On the Sirius,
- ; video memory consists of 2k of 16-bit words, wherein the top 5 bits
- ; are the attributes, and the bottom 11 a pointer to the font cell. The
- ; 11 bits are multiplied by 2 to give the paragraph address, since each
- ; character definition takes 32 bytes (16x16 pixels); the font is
- ; therefore in the bottom 128k of RAM. To arrive at the standard video
- ; font address, 100xd is added to the ASCII code using 16-bit
- ; arithmetic. Note that the low 3 bits of the attribute byte are 0, so
- ; this can occupy the high byte throughout the addition without any
- ; Carry-through problems.
-
- SIRIUS_COPY:
- CALL SIRIUS_ADDR ; fix ES:DI for the Sirius
- MOV BH,AH ; store the attribute - calculating font addr clobbers AH
- L1:
- LODSB
- MOV AH,BH ; the addition of 100 can't carry into the attributes
- ADD AX,100 ; calculate the font address
- STOSW ; save the character to the screen
- LOOP L1
- SUB DI,DX ; convert DI back from memory to virtual screen offset
- RET
-
-
- SIRIUS_ATTR: ; VID_ATTR for the Sirius
- CALL SIRIUS_ADDR ; fix ES:DI for the Sirius
- ES MOV BX,W[DI] ; get the character
- AND BX,07FF ; mask off the attribute bits
- OR BH,AL ; and put in the new value
- ES MOV W[DI],BX ; put the character back
- SUB DI,DX ; restore DI
- RET
-
-
- SIRIUS_BELL: ; BIOS_BELL for the Sirius
- PUSH ES,SI,DI
- MOV CL,7 ; BIOS outputs the character in CL
- MOV AX,1 ; BIOS call 1 = output char
- CS CALL SIRIUS_BIOS
- POP DI,SI,ES
- RET
-
-
- ; SIRIUS_KEY is the BIOS_KEY routine for the Sirius. We find the next key
- ; pressed, and we translate F8 into F10, and the arrow keys into single
- ; codes.
-
- SIRIUS_KEY:
- PUSH ES,SI,DI ; registers might be clobbered by the BIOS
- SUB AX,AX ; BIOS call 0 = Console Input
- CS CALL SIRIUS_BIOS
- CMP AL,0F8 ; is it Fn key 8?
- JNZ >L1
- MOV AL,0FA ; if so, pretend it was F10
- JMP >L0 ; L0 pops registers & returns
-
- ; Escape codes. The Arrow keys return <ESC>A-up, B-down, C-right & D-left
- ; I will use Right & Left as Page Up & Page Down, respectively.
-
- C1:
- DB 0A0,0A1,0A2,0A3 ; Codes that up, down, right & left get translated to.
-
- L1:
- CMP AL,01B ; if not escape then we don't have this problem
- JNZ >L0 ; L0 pops registers returns
- MOV AX,2 ; BIOS call 2: is there any keyboard data pending?
- CS CALL SIRIUS_BIOS
- OR AL,AL ; AL=0 if no data pending, else AL=FF & AH=next char
- JZ >L2 ; If no data pending, then it was the ESC key
- CMP AH,'A' ; else check for valid code
- JB >L2 ; If <'A' or >'D', then it was the ESC key
- CMP AH,'D'
- JA >L2
- XOR AX,AX ; If we are to interpret the next key, we mustn't leave
- CS CALL SIRIUS_BIOS ; it hanging. (It's returned in AL)
- MOV BX,C1-'A' ; BX = offset of the Code table, with A=lower bound of AL
- CS XLATB
- JMP >L0
-
- L2: ; It was only an ESC after all
- MOV AL,01B
- L0:
- POP DI,SI,ES
- RET
-
-
- ; SIRIUS_ADDR converts ES:DI from an offset that the caller recognizes,
- ; into an offset that the Sirius video recognizes. The mapping is
- ; variable to allow fast scrolling. Since the buffer repeats once
- ; in the memory map, the screen occupies contiguous memory, starting
- ; at an address 2047 or less. We also return DX set to the amount
- ; DI was changed, so that SUB DI,DX will restore DI.
-
- SIRIUS_ADDR:
- PUSH DS ; We have to ask the CRTC chip for the address
- MOV DS,DX,0E800 ; of the first char on the screen
- MOV B[0],12 ; Register 12 = high byte
- MOV DH,B[1]
- MOV B[0],13 ; Register 13 = low byte
- MOV DL,B[1] ; Now ax = offset of line 0, col 0, in 16-bit words
- AND DX,2047 ; It must be modulo-2048. This will always be the
- ; case anyway, unless the user's programme has screwed up the CRTC
- SHL DX,1 ; now the offset is in bytes in DX
- ADD DI,DX ; Now ES:DI points to the right address
- POP DS ; DS is preserved
- RET
-
-
- ;--------------------------
- ; DEC RAINBOW INTERFACE
- ;--------------------------
-
- FUNC EQU 59+111
-
- ; BIOS interface routines for the DEC Rainbow A and B. Thanks to
- ; Vinzenz Esser, Moosburg, West Germany for writing this code.
- ; I have made format changes and minor optimizations.
-
- DEC_KEYS: ; Key definition for DEC_RAINBOW_100
- DB 0 ; Key code for Help key
- #if IBMSIM
- DB 0
- #else
- DB 097-FUNC ; Keypad_0 code is 097 (use instead of F1)
- #endif
-
- L1:
- DB 094 ; Down Arrow key
- DB 092 ; Next Screen key
- DB 093 ; Up Arrow key
- DB 091 ; Prev Screen key
- DB 08D ; Find key (Home)
- DB 090 ; Select key (Shift-F7)
- DB 081 ; F2 Print Screen key (Alt-F9)
- N_CONTROL_KEYS EQU $-L1
-
- DW HELP_HELP ; Pointer to "HELP" message
-
- L2:
- DW DEC_COPY ; VID_COPY routine
- DW DEC_ATTR ; VID_ATTR routine
- DW RET ; VID_FIX not needed
- #if IBMSIM
- DW IBM_BELL,IBM_KEY
- #else
- DW DEC_BELL ; BIOS_BELL routine
- DW DEC_KEY ; BIOS_KEY routine
- #endif
- DW RET ; BIOS_SAVE not needed
- DW RET ; BIOS_RESTORE not needed
- DW 0B800 ; VIDEO_SEG not needed but included for IBMSIM
- DB 0E ; Normal-video attribute
- DB 0F ; Reverse-video attribute
- N_BIOS_CALLS EQU ($-L2)/2
-
-
- ; DEC_CONFIG is the BIOS initialization routine for the DEC RAINBOW 100
-
- DEC_CONFIG:
- SS DEC B[LAST_LINE+1] ; 24-line screen: move D86 command line up
- CS DEC B[D86_LINES] ; also reduce the refresh lines count
- MOV SI,DEC_KEYS ; Point to DEC's table of keycodes
- CALL NEW_KEYS ; and plug these values into D86
- MOV DX,DEC_INIT ; Clear screen
- MOV AH,9
- INT 021
- RET
-
-
- DEC_INIT:
- DB 27,'[?3l' ; clear screen, reset all attributes, select 80 column mode
- DB 27,'[24;1H$' ; position cursor to line 24, column 1
-
-
- ; DEC_KEY is the DEC RAINBOW 100 version of the BIOS_KEY routine.
- ;
- ; The BIOS call we use returns a character code in AL, and flag bits in AH:
- ; 01 for function key, 02 shift, 04 control key, 08 caps lock in effect.
- ;
- ; We remap the keys so that function keys return consecutive codes above 80H,
- ; according to the following chart:
- ;
- ; BIOS D86 Bios D86
- ; Key Code Code Key Code Code
- ; ------------------- ---- ---- ------------------- ---- ----
- ; F1 Hold Screen XXx n/a Prev Screen 23 91
- ; F2 Print Screen 03 81 Next Screen 25 92
- ; F3 Set-Up XXx n/a Up Arrow 27 93
- ; F4 05 82 Down Arrow 29 94
- ; F5 Break 65 A9 Right Arrow 2B 95
- ; F6 Interrupt 07 83 Left Arrow 2D 96
- ; F7 Resume 09 84 Keypad 0 2F 97
- ; F8 Cancel 0B 85 Keypad 1 32 98
- ; F9 Main Screen 0D 86 Keypad 2 35 99
- ; F10 Exit 0F 87 Keypad 3 38 9A
- ; F11 (ESC) XXx n/a Keypad 4 3B 9B
- ; F12 (BS) XXx n/a Keypad 5 3E 9C
- ; F13 (LF) XXx n/a Keypad 6 41 9D
- ; Addt'l Options 11 88 Keypad 7 44 9E
- ; Help 00 FF Keypad 8 47 9F
- ; Do 01 80 Keypad 9 4A A0
- ; F17 13 89 Keypad Dash 4D A1
- ; F18 15 8A Keypad Comma 50 A2
- ; F19 17 8B Keypad Period 53 A3
- ; F20 19 8C Keypad Enter 56 A4
- ; Find 1B 8D Keypad PF1 59 A5
- ; Insert Here 1D 8E Keypad PF2 5C A6
- ; Remove 1F 8F Keypad PF3 5F A7
- ; Select 21 90 Keypad PF4 62 A8
- ; Compose Character XXx n/a
- ;
- ; XXx These keys are trapped out for special processing by firmware:
- ; F1 Hold Screen Scroll lock toggle
- ; F3 Set-Up Enter SET-UP mode to change system parameters
- ; F11 (ESC) Always generates ESC character 1Bh
- ; F12 (BS) Always generates BS character 08
- ; F13 (LF) Always generates LF character 0Ah
- ; Compose Character Introduction key to a compose character
- ; sequence to generate characters from the
- ; DEC 8-bit multinational character set
-
- ; The code assigned to each function key is presented in the column 'D86' of
- ; the function key table above. Since on the DEC RAINBOW only 8 of the
- ; function keys F1-F10 are available to an application I had to remap the
- ; keys somewhat:
- ; IBM Key DEC Key
- ; F1 Keypad 0
- ; .. ..
- ; F10 Keypad 9
- ; Alt-F9 F2 Print Screen
- ; Shift-F7 Select
- ; Home Find
- ; Alt-F10 Help
-
- ; Since the following 3 'function keys' do not set the function key flag,
- ; they end up here too:
- ; F11 (ESC) Always generates ESC character 1Bh
- ; F12 (BS) Always generates BS character 08
- ; F13 (LF) Always generates LF character 0Ah
- ;
-
-
- L0:
- TEST AL ; Is this an 8-bit character?
- JNS RET ; drop through if it is: we don't want it
- DEC_KEY:
- PUSH DI,ES ; save some registers
- L1:
- MOV DI,6 ; DEC BIOS function for GET KEY IF AVAILABLE
- INT 24 ; do it
- INC CL ; is a character available?
- JNZ L1 ; keep looking, if not
- POP ES,DI ; restore clobbered registers
- TEST AH,1 ; Check function key flag
- JZ L0 ; Go, if not a function key
- TEST AL ; Check for help key
- JZ RET ; Go, if help key
- CMP AL,02F ; is the key in the divide-by-2 range?
- JB >L2 ; jump if it is
- MOV CL,3 ; key is in the divide-by-3 range: load divisor 3
- MOV AH,0 ; extend keycode AL to AX
- DIV CL ; divide by 3
- ADD AL,088 ; add offset so that 2F,32,35,... becomes 97,98,99,...
- CMP AL,097
- IF E MOV AL,0A1
- RET
-
- L2: ; key code is in the divide-by-2 range
- SHR AX,1 ; shift in low bit of AH: now 13,15,17... becomes 89,8A,8B...
- RET
-
-
- DEC_BELL: ; ring the bell on a DEC RAINBOW
- PUSH DI,ES ; save registers
- MOV AL,7 ; code 7 is BELL
- MOV DI,0 ; function code for OUTPUT_AL
- INT 24 ; output the bell code, to ring the bell
- POP ES,DI ; restore trashed registers
- RET
-
-
- DEC_COPY: ; DEC RAINBOW 100 version of BIOS_COPY routine
- PUSH BX,CX,SI,BP ; save registers across call
- MOV AX,DI ; fetch starting output pointer
- ADD AX,CX ; add in the number of characters
- ADD AX,CX ; add twice, to reflect the output of words not bytes
- PUSH AX ; simulated beyond-output is saved for return
- MOV BP,DS ; Segment address in BP for function 14
- CALL DEC_CONV_VIDEO ; convert DI from D86 value to line BL column BH
- MOV AX,2 ; Set transfer type 2 = characters only
- CALL DATA_TO_SCREEN ; Send data to screen
- POP DI,BP,SI,CX,BX ; Restore registers
- RET
-
-
- DEC_ATTR: ; copy single attribute AL to screen at ES:DI
- PUSH AX ; push the attribute byte AL onto the stack
- CALL DEC_CONV_VIDEO ; Convert DI to line/column
- MOV AX,1 ; Set transfer type 1 = attrib only
- MOV CX,AX ; Transfer 1 character
- MOV DX,SP ; Point to attribute byte
- MOV BP,SS ; Segment address in BP
- CALL DATA_TO_SCREEN ; send the attribute to the screen
- POP AX ; pop attribute byte back off of stack
- RET
-
-
- ; DATA_TO_SCREEN copies CX characters (no more than 80) from memory to the
- ; screen at column BH (1--80) line BL (1--24). Input AX tells whether to
- ; copy attributes from BP=DS:DX (AX=1), characters from DS:SI (AX=2) or both
- ; (AX=0).
-
- DATA_TO_SCREEN:
- #if IBMSIM
- PUSH ES,DX,SI
- CS MOV ES,VIDEO_SEG
- ADD AX,AX
- PUSH AX
- MOV AL,BL
- DEC AX
- MOV AH,80
- MUL AH
- MOV BL,BH
- DEC BX
- MOV BH,0
- ADD BX,AX
- ADD BX,BX
- MOV DI,BX
- POP BX
- CS CALL >L4[BX]
- POP SI,DX,ES
- RET
-
- L4:
- DW >L0,>L1,>L2
-
- L0:
- PUSH DI
- CALL >L2
- POP DI
- L1:
- XCHG SI,DX
- L5:
- INC DI
- MOVSB
- LOOP L5
- XCHG DX,SI
- RET
-
- L2:
- MOVSB
- INC DI
- LOOP L2
- RET
-
- #else
- MOV DI,8 ; function number for DISABLE CURSOR
- INT 24 ; call the DEC BIOS to disable the cursor
- MOV DI,014 ; function number for WRITE TO SCREEN
- INT 24 ; call the DEC BIOS to write to the screen
- MOV DI,0A ; function number for ENABLE CURSOR
- INT 24 ; call the DEC BIOS to enable the cursor
- RET
- #endif
-
-
-
- ; DEC_CONV_VIDEO converts the D86 video memory address in DI to line BL (1-24)
- ; and column BH (1-80)
-
- DEC_CONV_VIDEO:
- XCHG AX,DI ; swap the D86 address in AX
- SHR AX,1 ; convert words to bytes
- MOV BL,80 ; load the number of characters in a line
- DIV BL ; compute column number AH, line number AL
- MOV BX,0101 ; load offsets to convert first numbers from 0 to 1
- ADD BX,AX ; add in the coordinates, for return in BH and BL
- RET
-
-
-