The Assembly Language Magazine 1
VOL1 NUMBER1
FEBRUARY 20,1989
Written by and for assembly language programmers.
For the month of February 1989, we have:
Contents
- Introduction
- Article Suggestions
- What Started It
- Review of the A86 Assembler
- FAST Memory Moves
- Source code
- A Few Good Programs
- Keyboard Trapping-How When and Where
- Source code
- Book Reviews
- Guidelines for Contributors
NOTE: *** WE NEED CONTRIBUTORS! *** Read Article Suggestions and Guidelines and start sending those articles in!
Special to Electronic Magazines
The source files included here are complete asm files and you only need to edit them out with a text editor and then assemble them.
Produced by Patrick & David O'Riva
Edited, arranged, sent, etc. by same
Always available at:
The AsmLang & CFS BBS
(408) 259-2223 (woof! 143/37)
2726 Hostetter Rd, San Jose, CA 95132
Assembly Language 'Magazine'
In this, the first issue, the only editorial you are going to get is this short introduction to the magazine and an even shorter one to myself.
This is to be a publication devoted to Assembly language programming and to the Assembly language programmer. At first look it might appear that it is to be a pclone only forum, but that is not the intention or the desire. My current system is pclone and therefore where I have begun, but the same needs exist on other systems as well: 6502, 6800, 68000 and so forth. If there is to be any restriction it would be in the direction away from pure operating systems and into user visible applications, but that line is far too hazy to consider.
The hope is to present this 'magazine' monthly with a transmission date of the 15th. If YOUR interest is not communicated to me by way of comments and article submissions this publication will evaporate immediately.
Your editor is no one you would have heard about. My first programming was done by setting toggle switches on the front of the machine and hitting the enter button. I have worked on operating systems and interfaces on the 8088, Z80, 6800 and 6502. I am currently disabled and some months my productive time approaches 0 but with the cooperation of my son (an excellent programmer) I hope to coordinate this far into the future.
Policy on Piracy
As you well know programming is not easy. It is always time consuming and often very tedious. A good program is as creative as a book or a work of art. Even a bad program entails many man hours of effort. This time should not be stolen from the authors. With conventional marketing piracy is illegal.In Shareware the same moral obligations exist. If we use it we should pay for it. Many of the programs to be discussed I expect to be in this category.
I don't generally recommend publication of source code unless it is your intention to put it in the public domain, however illustrative pieces in an article could be of benefit to us all. No code not wholly written by the author should be submitted.
Suggestions for articles to be submitted
Reviews of programs- Reviews are always interesting because they can save someone a great deal of time in checking out something that will not meet their needs.
Bugs and idiosyncrasies- Undocumented facts about common tools
- COM vs EXE
- How to write a good TSR
- Math libraries- All about
- What is a good user interface
- Public key signatures and Encryption- no viruses in Shareware
- Most anything else of interest to you
The Beginning
This was sent out on the FidoNet 80XXX echo in December 1988. Enough favorable replies were received to continue the project.
I am interested in starting a national magazine devoted to the use of assembly language. The principle aims would be as follows:
- Improving the skills and knowledge of us all
- Widening the awareness of the benefits of assembly
- Provide reviews of new tools
Is there a need for such a publication? In terms of mass readership, probably not. But in the desires of the select group of people who program in assembly I feel that there is.
Magazine is really the wrong term. I don't think there is a term for what this would likely have to be. If there was a large enough market for a normal publication I'm sure one of the major publishers would have done it. I foresee an electronic distribution possibly carried on the 80xx Echo then those interested could print it out, copy it, and make it available to others who would be interested. Eventually a more formal distribution might be arranged if there were enough interest. If anyone reading this is interested in contributing articles or just making comments I would like to hear from you.
EDITORIAL (JUST TO SPARK CONTROVERSY)
Higher level languages are primarily a method of producing software useful for corporations, because it can be written and understood by programmers with little knowledge of the equipment. This work can then be passed on to another after he leaves, and little is lost. This same work can also be moved to another environment simply by changing compilers. Complex programs can be written quickly (This may be a fiction) and sent to market.
This all sounds pretty good, right? No. The price that we have to pay for this is far too high. The size of these programs is becoming absurd. This forces users (and that's what we all are) into a continual quest for larger memory. The major debugging programs available leave no room in a 512k pclone to fit the program being debugged. Spreadsheet and database programs are as bad and get worse with every new release of an 'improved' version.
The main program we use continuously is a major offender this way. DOS has grown almost geometrically and has come to occupy a significant fraction of available memory while adding few (if any) improvements since version 2.0 (the continuing standard of compatibility).
This situation is bad enough, but it is just the tip of the real damage done by the NECESSARY use of high level language by the leading software companies. Speed-- the magic word in computing is so thoroughly compromised that the hardware industry is just holding its head above the morass.
Within the last year I have tried the latest release of the assembler package from a major software company. I'm sure you know which one I mean, but I'd rather not use names at this time so I don't have to strictly document my figures. It was significantly larger than the previous version (though somewhat faster 35 seconds as opposed to 50 seconds on the program I tested it with). It would not assemble my source code from the previous version without a number of silly modifications. The involved syntax this package has traditionally used has annoyed me since the first version I purchased. About this same time I tried a shareware assembler that supports largely the same functions though in slightly differing form to reflect the preference of the author. I won't say that it was without flaws. No program is. After *removing* the instructions that have so irritated me in the other I assembled the same program with this. It is a fraction of the size (about 20k). It loaded itself, loaded and assembled my program, delivered a complete COM file, and inserted some trivial error messages *into* a copy of my original source file in ** 4 ** seconds. This is around the same length of time it took the other assembler to load itself.
The editor contained in the commercial package while very versatile, and using some very clever techniques to speed up the usage, the first time I tried to load a file in I thought my poor machine had bombed and I reset it, but then I noticed that the disk was being accessed and it even- tually displayed my file. The same situation occurred when I asked it to show me it's help file. The shareware editor I am using now allows me even greater versatility, only occupies about 15% of the memory and I can be editing my file long before the other one would have loaded itself. And it's not even completely written in assembly.
In summation, while high level language may have its place, it is not in programs expected to have high usage or when speed or size are significant factors. The end users need to be given a choice and shown the difference between quality programming and the corporate programming (much of it vaporware) that they are now being offered.
A86 Assembler Review
A86 is a full featured Assembler for the 8088 80286 8087 80287 v20 and v30 microprocessors. It is not fully MASM compatible, though it comes close (except in the area of macros - its macro support is quite strong but entirely different from MASM). Some of its unique features are support of entirely local variables so that a new and unique name need not be thought up for each local jump. It synthesizes the move segment register to segment register moves with pushes and pops and has some interesting commands to jmp far on condition, using the inverse jshort instruction and a local label. This saves a good amount of typing and actually makes the code more readable. It is a tiny program, less than 24k and the assembly speed is astounding. The claim is 1000 lines per second. It will directly produce a COM file, usually so quickly you don't even need to pause in your typing. EXE files are also supported but as the COM format is so simple I haven't really checked that out too well, and the support is not complete. The documentation is good for the operation of the assembler but it is not a tutorial in assembly language programming.
So much for the advantages. It is not MASM compatible. While it will work with most MASM source files without macros, MASM will not accept an A86 file. Most of the formatting commands of MASM (the proc and assume statements) are more or less ignored. The segment end statements are ignored, as a segment statement closes the current segment. This simplified syntax can greatly reduce the amount of typing necessary in a program, but somewhat more care is needed by the programmer.
One of the worst flaws as I see it is the lack of support for include files though its acceptance of multiple command line modules and library files partially makes up for this.
Overall, this is a very high quality program but not to be considered if you require MASM compatibility. This is a shareware offering by Eric Isaccson, available from most BBS's.
There is a companion symbolic debugger D86 also available.
MASM is a trademark of Microsoft Corporation
DMA Transfers for FAST Memory Moves
If you ever have the need for super fast moves of blocks of memory and you can put up with a lot of restrictions in order to gain the speed there is a method in the PC environment to move bytes at the rate of one every 3 clock cycles. Compare that to the clocks for a rep movsb and then say that isn't fast. This isn't for every programmer and it certainly isn't for every time you need to move a few bytes.
The DMA chip is a four channel device. Channel 0 is reserved for refresh of memory that requires at least 256 consecutive bytes be read somewhere in memory at intervals less than about 4ms. The other three channels are available for such things as transferring information to and from the disk drives or the ports. Interesting trivia so far, but not very useful in moving memory around. It gets worse. The 8259 DMA doesn't know anything about segments. It only knows a 64k universe. This is where the Page registers come in. The page registers decide which page (on 64k boundaries) the 8259 will look at for any operation. There are not, as you might guess, 4 page registers, but only 2 plus a default. If it is not channel 1 or 2 then it uses the default register programmed as channel 3.
A careful reading of the data sheet of the 8259 discloses that it is capable of doing a memory to memory transfer but only between channels 0 and 1. That is why this method is a little tricky to use. In order to set up your own parameters you have to disable the timer from asking for a DMA from channel 0 every x milliseconds and reconfigure the 8259 and assume the responsibility for doing the memory refresh. It actually sounds worse than it is. The configuring and re configuring of the 8259 doesn't take all that long, so the time is made up after only moving a few tens of bytes, and if you move at least 256 CONSECUTIVE bytes the memory refresh requirement is met for another 2 or 3 milliseconds. The page registers are taken care of by setting channels 1 and 3 to the same value.
Given below is an example of a program I wrote just to test the idea. A lot of the setup is too complex to explain in this short article, but if you are interested in checking it all out you will need a data sheet on the 8259. This worked nicely on my machine and should on most compatibles just the way it is. With the not-so-compatible it may very well not. I hope this listing is well enough commented so you can figure it out and make use of it sometime.
` DMA SOURCE
PAGE 60,132
TITLE DMA MEMORY TO MEMORY
DMA EQU 0
STACK SEGMENT PUBLIC 'STACK'
DB 32 DUP('STACK')
STACK ENDS
DATA SEGMENT PUBLIC 'DATA'
SOURCE DW 08000H
TARGET DW 09000H
NUMBER DW 800H
INCDEC DB 0
PAGER DB 0BH ;PAGE (O TO F)
FILL DB 0 ;2 IF A FILL OP
DATA ENDS
ASSUME CS:CODE,DS:DATA,ES:DATA
CODE SEGMENT PUBLIC 'CODE'
START:
MOV AX,DATA
MOV DS,AX
MOV AX,0B800H
MOV ES,AX
PAGE:
MOV AL,PAGER ;PAGE TO OPERATE IN
OUT 83H,AL
UNDMA:
OUT 0DH,AL ;MASTER RESET OF DMA
MOV DX,03D8H
MOV AL,1
OUT DX,AL
MOV AX,SOURCE ;WHERE IS IT COMING FROM
OUT 0H,AL
MOV AL,AH
OUT 0H,AL
MOV AX,TARGET ;WHERE TO PUT IT
OUT 2H,AL
MOV AL,AH
OUT 2H,AL
MOV AX,NUMBER ;HOW MANY
OUT 3H,AL
MOV AL,AH
OUT 3H,AL
MOV AL,009H ;ENABLE M TO M,COMPRESSED
OR AL,FILL ;WILL BE 2 IF FILL OP
OUT 8H,AL
MOV AL,088H ;BLOCK MODE, INC, READ
OR AL,INCDEC ;WILL BE 20H IF DEC
OUT 0BH,AL
MOV AL,85H ;BLOCK MODE, INC, WRITE
OR AL,INCDEC ;WILL BE 20H IF DEC
OUT 0BH,AL
MOV AL,4 ;THIS IS THE REQUEST
OUT 9,AL ;DO IT
MOV AL,9
OUT DX,AL
RESET: OUT 0DH,AL ;THIS IS A MASTER RESET
OUT 0CH,AL ;RESET F/L F/F
MOV AL,01
OUT 0,AL
OUT 0,AL
REINIT:
MOV AL,0
OUT 83H,AL ;MOVES REFRESH TO BASE PAGE
MOV AL,0FFH
OUT 1,AL
PUSH AX
OUT 1,AL
OUT 0BH,AL
INC AL ;MODE CHAN3
OUT 0BH,AL
PUSH AX
POP AX
POP AX
POP AX
MOV AH,4CH
INT 21H
CODE ENDS
END START
`
All Programs Small and Fast
The programs mentioned here are ones that I use regularly or have been recommended to me by those whose opinion I trust. In the later case, I have tried them but they just don't fit with the way I do things. You will notice some obvious holes in this list. These are cases where I have found nothing that I am pleased enough to pass on. Not all of them are written in assembly but they still work well in an assembly programming environment. Most of them are Shareware products, and while this is not by design on my part it is not by chance either. They were written by talented programmers in a non-corporate setting.
Xhelp
This is a TSR pop-up. It comes with a file containing the DOS 3.2 instruction set (about 50 pages worth) and an IBM/ascii table. It will also accept and integrate any other documents that you care to enter. It implements searches, index, and table of contents. Place marker is maintained between pop-ups. I resent its size, but it is fast and well implemented.
Exwells Software Company
7677 Oakport St Suite 110
Oakland,CA 94621
CED
One of the command line editors. It has extended functions to make DOS commands resident and other programs can be invoked with arguments as though from a batch file with a specified synonym. Small and fast. Also works inside programs that strictly use DOS editing functions keeping internal and external commands separate. Shareware.
List
Version 6.3+. I don't think this needs much said. It is by Vern Buerg, is small and fast. If you don't have it, get it! Shareware
TSR
A collection of TSR handling programs. The Mark records the machine state, including vectors, environment, and most anything else it can. Release, looks for the latest Mark and restores that machine state, then erases the Mark. Thus any TSR's are removed completely. This is very useful for development work. Shareware.
Qedit
This is a full screen editor. It is small, super fast, has too many features to begin to list. You can configure the keyboard any way you like it very quickly and easily. 10 file concurrent editing, 99 nameable buffers etc. One of the finest pieces of software available. Shareware.
Microspell
A spelling checker. Unbelievable speed, compatible with most word processors. Supports auxiliary dictionaries and allows entries into the main dictionary.
Trigram systems
5840 Northumberland St.
Pittsburgh,PA 15217
412-422-8976
Assemblers
This is a blank entry. A86 comes very close to qualifying; it is small, fast but is lacking some useful tools such as include files. I am still using grudgingly predominantly MASM 4 but may switch over. TASM from Borland is receiving some interesting comments, but is still large 97k, and not as fast as it might be. I've also heard of PASM. A review of it would be greatly appreciated. Late break: OPTASM may be reasonable as well...
Word Processors
This is also a blank entry. ChiWriter by Horstman Software is decent. It is versatile, easy, but large and slow. The big NAMES I've tried I have thrown away in disgust. Target size: <40k, plus fonts. Should scroll at typematic rate. 100k search <1 sec. Configurable command keys(!).
Getting User Input, Part One
by David O'Riva
Most of you are familiar with the various ways to read the keyboard. One can ask DOS, through interrupt 21H, and get keystrokes coming from the keyboard (or from whatever device or file the user told DOS to use instead of the keyboard).
Alternatively, if you want to be sure that you're getting actual *keyboard* input, and/or you want more information than DOS is willing to provide, you can go through INT 16H:
MOV AH,0
INT 016H ;get a key & scancode
MOV DX,AX ;save keystroke in DX
MOV AH,2
INT 016H ;get shift state in AL
... would give you the key pressed, it's scan code, and the shift states in effect at the time of the press. Information on all the INT 16H modes is available from many references, and we will not delve any deeper into that here.
Now, if you NEED to know exactly what the keyboard state is, or to get a keystroke the micro-second it is pressed, or to interpret and act on multiple keystrokes (for example: you're writing a game, and you want one half of the keyboard to be controls for player 1, and the other half to be controls for player two.) then you need an IRQ 1 trap.
The following sequence of events occurs for every key that is pressed:
* KEYPRESS *
IRQ 1 is pulled high
The 8259 interrupt controller halts the system and does an INT 09H
The BIOS code for INT 09H polls the keyboard for the scan code, converts the code into an IBM scan code, which is for the most part identical to the scan codes from the keyboard.
If the CTRL-ALT-DEL sequence was pressed, control is given to the warm boot code. Other special keys are serviced (i.e. SYSREQ on ATs, soft turbo mode switches, etc...)
The keystroke is placed in the buffer, if there is room.
The INT 09H code resets the 8259 and leaves.
INT 16H (when called) pulls the keystroke out of the buffer and hands it to the application, or to DOS, which hands it to the application.
Note that the INT 09H code in BIOS will only respond to a keyboard MAKE code, except for shift keys. The keyboard itself handles typematic repeating, except on PCjrs.
An IRQ 1 server needs to be installed BEFORE the BIOS code, and can respond in varying ways to keystrokes. Here are some examples of IRQ 1 servers for specific tasks:
1. For HOT-KEY popup
- a) poll the keyboard, find out whether it's a MAKE or BREAK code
- b) if it's a BREAK code
- b1) is it the BREAK code for our hot-key?
- b2) if so, did we trap the make code?
- b3) if we did, clear the keyboard latch, reset the 8259, and leave.
- c) if it's a MAKE code
- c1) is it the MAKE code for our hot-key?
- c2) if so, are we allowed to pop up now? (you don't want to start multiple iterations of your popup program...)
- c3) if we are, set a flag to wait for the BREAK code, clear the keyboard latch and 8259, and start the popup.
- d) if it wasn't acted upon before, leave the keyboard latch and interrupt mask as they are and continue down the INT 09H chain.
2. For multiple-key trapping
First, set up an array that corresponds to the keys you want to trap.
- a) poll the keyboard, find out whether it's a MAKE or BREAK code.
- b) if it's a MAKE code
- b1) is it one of the keys we want to know about?
- b2) if so, set the element in the array that corresponds to this key.
- b3) You will *usually* want to clear the KB latch and 8259 to prevent the BIOS keyboard buffer from overflowing...
- c) if it's a BREAK code
- c1) is it one of the keys we want to know about?
- c2) if so, clear the element in the array that corresponds to this key.
- c3) if you prevented the MAKE code from reaching BIOS, do the same for this BREAK code.
- d) if it wasn't acted upon, continue down the INT 09H chain (alternatively, you can trap a key other keys here, like your "end the game" key, and prevent ANY keystrokes from reaching BIOS. This would prevent a CTRL-C from invoking DOS's critical-error handler, a CTRL-ALT-DEL from blowing the game if files are open, etc...)
- e) in your game's code, use the array to determine which keys are pressed and what to do.
As you can see, this sort of trap can be extremely powerful. The only caveat is that this requires a very-compatible PClone. And this may not be that bad, since I know that at least two very large game companies are using a method similar to this for their games.
Included with this article is a program called SHOWKEY.ASM, which installs an IRQ 1 trap and prints on the screen the scan code that it received from polling the keyboard, the current shift state, and the key and scan code that a call to INT 16H returned (dashes are printed if the key was not passed to the buffer). The only thing I ask in relation to this code is that if you distribute it unmodified, you leave my copyright message in. The code should be commented well enough that it is understandable.
Next month: Pop-up TSR'S. How to write, how to invoke, how to run, how to remove from memory. Watch for it!
NOTE: This is my first effort at writing an article for programmers on a complicated subject. Any comments or suggestions on writing style or clarity of explanation would be welcomed. Send to FidoNet node 143/37 - Dave.
` PAGE 60,132
TITLE SHOWKEY - Shows key codes
;
;
COMMENT~*********************************************************************
* --++**> All code in this file is Copyright 1989 by David O'Riva <**++-- *
*****************************************************************************
* *
* Written for the Microsoft Macro Assembler version 5.1 *
* *
* MUST BE CONVERTED INTO A .COM FILE BEFORE RUNNING!!! *
* *
* *
* Short advertisement - use QEdit! Get it from 143/37! *
* *
****************************************************************************~
.XLIST
;
; Macros used by this program
;
?PLevel = 0
PNPROC MACRO PNAME ;;declare near public procedure
IF2
%OUT Routine: &PNAME
ENDIF
PUBLIC &PNAME
&PNAME PROC NEAR
?PLevel = ?PLevel+1 ;;next level of nesting
@@SAVE_NAME &PNAME,%?PLevel
ENDM
ENDPROC MACRO
@@REC_NAME %?PLevel
@@EP1 %@@TEMP
?PLevel = ?PLevel-1
ENDM
@@SAVE_NAME MACRO PNAME,LVL
?PN&LVL EQU <&PNAME>
ENDM
@@REC_NAME MACRO LVL
@@TEMP EQU <?PN&LVL>
ENDM
@@EP1 MACRO PNAME
&PNAME ENDP
ENDM
PUSHM MACRO LST
IRP REG,<&LST&>
PUSH REG
ENDM
ENDM
POPM MACRO LST
IRP REG,<&LST&>
POP REG
ENDM
ENDM
@CHANGE_VECT MACRO INUM,GARB,NEW,GARB2,SAVEAREA
MOV AX,0
MOV ES,AX
MOV AX,ES:[INUM*4]
MOV DX,ES:[INUM*4+2]
MOV WPTR CS:[SAVEAREA],AX
MOV WPTR CS:[SAVEAREA+2],DX
MOV AX,OFFSET CS:NEW
CLI
MOV ES:[INUM*4],AX
MOV ES:[INUM*4+2],CS
STI
ENDM
@RESTORE_VECT MACRO INUM,GARB,SAVEAREA
MOV AX,0
MOV ES,AX
MOV AX,WPTR CS:[SAVEAREA]
MOV DX,WPTR CS:[SAVEAREA+2]
CLI
MOV ES:[INUM*4],AX
MOV ES:[INUM*4+2],DX
STI
ENDM
BPTR EQU <BYTE PTR>
WPTR EQU <WORD PTR>
DPTR EQU <DWORD PTR>
CR EQU <13>
LF EQU <10>
JR EQU <JMP SHORT>
INT_CTRL EQU 020H ;Interrupt control port
EOI EQU 020H ;Reset interrupt controller command
KB_DATA EQU 060H ;Keyboard data port
KB_CTRL EQU 061H ;Keyboard control port
;
;****************************************************************************
;
BIOSDATA SEGMENT AT 00040H
;----------------------------------------------------------------------------
;Keyboard Data Area
;----------------------------------------------------------------------------
ORG 00017H
KB_FLAG LABEL BYTE
;----- Shift flag equates within KB_FLAG
INS_STATE EQU 80H ;INSERT state is active
CAPS_STATE EQU 40H ;CAPS LOCK state toggled
NUM_STATE EQU 20H ;NUM LOCK state toggled
SCROLL_STATE EQU 10H ;SCROLL LOCK state toggled
ALT_SHIFT EQU 08H ;ALT key depressed
CTRL_SHIFT EQU 04H ;CTRL key depressed
LEFT_SHIFT EQU 02H ;left SHIFT key depressed
RIGHT_SHIFT EQU 01H ;right SHIFT key depressed
ORG 00018H
KB_FLAG_1 LABEL BYTE
;----- Shift flag equates within KB_FLAG_1
INS_SHIFT EQU 80H ;INSERT key depressed
CAPS_SHIFT EQU 40H ;CAPS LOCK key depressed
NUM_SHIFT EQU 20H ;NUM LOCK key depressed
SCROLL_SHIFT EQU 10H ;SCROLL LOCK key depressed
HOLD_STATE EQU 08H ;suspend key has been toggled
ORG 00019H
ALT_INPUT LABEL BYTE ;storage for alternate keypad entry
ORG 0001AH
BUFFER_HEAD LABEL WORD ;pointer to head of keyboard buffer
ORG 0001CH
BUFFER_TAIL LABEL WORD ;pointer to tail of keyboard buffer
ORG 0001EH
KB_BUFFER LABEL WORD ;keyboard buffer
ORG 0003EH
KB_BUFFER_END LABEL WORD
;----- HEAD = TAIL indicates that the buffer is empty
NUM_KEY EQU 69 ;scan code for NUM LOCK
SCROLL_KEY EQU 70 ;sc for SCROLL LOCK
ALT_KEY EQU 56 ;sc for ALT key
CTL_KEY EQU 29 ;sc for CTRL key
CAPS_KEY EQU 58
LEFT_KEY EQU 42
RIGHT_KEY EQU 54
INS_KEY EQU 82
DEL_KEY EQU 83
BIOSDATA ENDS
.LIST
.SALL
;
;****************************************************************************
;
CODE SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE
MAIN PROC FAR
ORG 100H
ENTRY: JMP INSTALL
;============================================================================
;
; MY LOCAL DATA
;
;
;
OLD9 DD ? ;old INT 9 vector
;
;
LAST_KEY DB ? ;make code from key trap
LAST_SHIFT DB ? ;shift state on trap
KEYPRESSED DB ? ;TRAP flag - non-zero = key was trapped
LINECOUNT DB ? ;current count of lines on screen
SHIFTOVL DB 'RLCA' ;
NOTICE LABEL BYTE
DB CR,LF
DB 'SHOWKEY v1.0 12-01-1988',CR,LF
DB 'COPYRIGHT 1988 ORIVATION',CR,LF
DB CR,LF
DB 'SHOWKEY shows the incoming scan codes from the keyboard hardware',CR,LF
DB ' and from the BIOS, and the shifts in effect at the press.',CR,LF
DB ' Type a "Q" to quit.',CR,LF
LINE0 DB '+INCOMING CODES--+------+------+------+',CR,LF
DB '| ASCII | SHIFTS | KEYB | BIOS | EXTD |',CR,LF
DB '| CHAR | RLCA | CODE | CODE | CODE |',CR,LF
DB '+-------+--------+------+------+------+',CR,LF,'$'
ILINE DB '| '
ACHAR DB ' '
DB ' | '
SHIFTS DB 'RLCA'
DB ' | '
KBC DB '00'
DB ' | '
BIOSC DB '00'
DB ' | '
EXTC DB '00'
DB ' |',CR,LF,'$'
;
;
;============================================================================
PAGE
;****************************************************************************
; START - main program loop
;
;
; ENTRY: from command line
;
; EXIT: ???
;
; DESTROYED: ALL
;
;----------------------------------------------------------------------------
PNPROC START
PUSHM <CS,CS>
POPM <ES,DS>
;----------------------------------------------------------------------------
; print copyright notice
;----------------------------------------------------------------------------
MOV AH,9
MOV DX,OFFSET NOTICE
INT 021H
MOV LINECOUNT,20
;----------------------------------------------------------------------------
;
;
; MAIN LOOP
;
;
;----------------------------------------------------------------------------
NEXT_CHAR_IN: DEC LINECOUNT
JNZ S_1
;
; reprint column headers if scrolled off screen
;
MOV DX,OFFSET LINE0
MOV AH,9
INT 021H
MOV LINECOUNT,20
;----------------------------------------------------------------------------
; wait until our trap finds something
;----------------------------------------------------------------------------
S_1: CMP CS:KEYPRESSED,0
JZ S_1
;----------------------------------------------------------------------------
; reset trap and get 'make' code of key pressed
;----------------------------------------------------------------------------
MOV CS:KEYPRESSED,0
MOV AL,LAST_KEY
MOV SI,OFFSET KBC
CALL REGISTERTOTEXT
;----------------------------------------------------------------------------
; did BIOS pick up on the key?
;----------------------------------------------------------------------------
MOV AH,1
INT 016H
S_2: JNZ S_3
;----------------------------------------------------------------------------
; if BIOS didn't get it, print dashes instead
;----------------------------------------------------------------------------
MOV WPTR BIOSC,('-'*256+'-')
MOV WPTR EXTC,('-'*256+'-')
MOV ACHAR,' '
JR S_6
;----------------------------------------------------------------------------
; print the key BIOS found
;----------------------------------------------------------------------------
S_3: MOV AH,0
INT 016H
PUSH AX
MOV ACHAR,AL
;
; since we're using cooked console output, only print chars > 32
;
CMP AL,' '
JAE S_5
MOV ACHAR,' '
;
; get ASCII code of character
;
S_5: MOV SI,OFFSET BIOSC
CALL REGISTERTOTEXT
;
; and get extended (scan) code from BIOS
;
MOV SI,OFFSET EXTC
POP AX
MOV AL,AH
CALL REGISTERTOTEXT
;----------------------------------------------------------------------------
; read shift states in effect at the time of the press
;----------------------------------------------------------------------------
S_6: MOV AX,WPTR SHIFTOVL ;* restore shift characters to
MOV WPTR SHIFTS,AX ;| output string
MOV AX,WPTR SHIFTOVL+2 ;|
MOV WPTR SHIFTS+2,AX ;*
MOV SI,OFFSET SHIFTS ;SI -> shift info to display
MOV AL,LAST_SHIFT ;AL = shift codes in BIOSDATA
MOV CX,4 ;CX = # of shifts to check
S_7: SHR AL,1 ;shift bit -> carry flag
JC S_8 ;if set, bypass this one
MOV BPTR [SI],' ' ;clear this shift character
S_8: INC SI ;SI -> next shift character
LOOP S_7 ;check it
;----------------------------------------------------------------------------
; print a line of information about the keypress
;----------------------------------------------------------------------------
MOV AH,9
MOV DX,OFFSET ILINE
INT 021H
;----------------------------------------------------------------------------
; if this character was a 'Q', then leave now
;----------------------------------------------------------------------------
MOV AL,ACHAR
CMP AL,'Q'
JZ S_OUT
;----------------------------------------------------------------------------
; more characters in BIOS buffer?
;----------------------------------------------------------------------------
MOV AH,1
INT 016H
JNZ S_2
;----------------------------------------------------------------------------
; do next key
;----------------------------------------------------------------------------
JMP NEXT_CHAR_IN
;----------------------------------------------------------------------------
; leave
;----------------------------------------------------------------------------
S_OUT: JMP UNLOAD
ENDPROC
;****************************************************************************
; REGISTERTOTEXT - Converts AL into ASCII hex digits in CS:[SI]
;
;
; ENTRY: AL = register to translate
; SI = place to put translated digits
;
; EXIT: AX = hex digits
;
; DESTROYED: AX
;
;----------------------------------------------------------------------------
ASSUME ds:NOTHING,es:NOTHING
PNPROC REGISTERTOTEXT
;----------------------------------------------------------------------------
; split AL into two nibbles
;----------------------------------------------------------------------------
MOV AH,AL
SHR AH,1
SHR AH,1
SHR AH,1
SHR AH,1
AND AL,0FH
;----------------------------------------------------------------------------
; convert AL into a hex digit
;----------------------------------------------------------------------------
ADD AL,'0' ;AL = actual digit
CMP AL,'9'
JBE R_1
ADD AL,'A'-'0'-10
;----------------------------------------------------------------------------
; convert AH into a hex digit
;----------------------------------------------------------------------------
R_1: ADD AH,'0' ;AH = actual digit
CMP AH,'9'
JBE R_2
ADD AH,'A'-'0'-10
;----------------------------------------------------------------------------
; store hex number in [SI]
;----------------------------------------------------------------------------
R_2: MOV CS:[SI],AH
MOV CS:[SI+1],AL
RET
ENDPROC
PAGE
;****************************************************************************
; TRAPPER9 - Intercepts the incoming keyboard scan code
;
; This routine intercepts the keyboard hardware interrupt, looking
; for a valid "make" code. If such a code is found, it is stored in local
; data along with the current shift state, and a flag is set indicating that
; a keypress was trapped.
;
; ENTRY: from IRQ 1, machine state is ???
;
; EXIT: continues KB interrupt chain
;
; DESTROYED: none
;
;----------------------------------------------------------------------------
ASSUME ds:BIOSDATA,es:NOTHING
PNPROC TRAPPER9
STI ;since the keyboard interrupt mask
;is never cleared within this routine,
;there is no chance of accidental
;re-entry with interrupts enabled
PUSHM <AX,BX,DS> ;save everthing I use
MOV AX,SEG BIOSDATA ;DS-> BIOS's data seg
MOV DS,AX
IN AL,KB_DATA ;Poll keyboard controller
TEST AL,080H ;See if we got a 'make' code
JNZ T_ChainOn ;If it's a 'break' code, ignore it...
;----------------------------------------------------------------------------
; ignore the four shift keys (CTRL, ATL, L-SHIFT, R-SHIFT)
;----------------------------------------------------------------------------
CMP AL,038H
JZ T_ChainOn
CMP AL,02AH
JZ T_ChainOn
CMP AL,01DH
JZ T_ChainOn
CMP AL,036H
JZ T_ChainOn
;----------------------------------------------------------------------------
; save info about this key
;----------------------------------------------------------------------------
MOV CS:LAST_KEY,AL ;save key make code
MOV AL,KB_FLAG
MOV CS:LAST_SHIFT,AL;save current shift state
MOV CS:KEYPRESSED,1 ;set 'TRAPPED' flag
;----------------------------------------------------------------------------
; Continue down the KB handler chain...
;----------------------------------------------------------------------------
T_chainon: POPM <DS,BX,AX>
JMP DWORD PTR CS:OLD9
ENDPROC
PAGE
;****************************************************************************
; UNLOAD - Unhooks all vectors and exits
;
;
; ENTRY: nothing
;
; EXIT: never exits.
;
; DESTROYED: this program.
;
;----------------------------------------------------------------------------
ASSUME ds:CODE,es:CODE
PNPROC UNLOAD
@RESTORE_VECT 9 FROM OLD9 ;Restore keyboard vector
MOV AX,04C00H ;Exit w/ERRORLEVEL 0
INT 021H
ENDPROC
PAGE
;****************************************************************************
; INSTALL - Installs traps, then runs the program.
;
;
; ENTRY: called on entry to the program
;
; EXIT: starts running main code
;
; DESTROYED: assume ALL but DS
;
;----------------------------------------------------------------------------
ASSUME ds:CODE,es:CODE
PNPROC INSTALL
;----------------------------------------------------------------------------
; install our keyboard hardware interrupt trap
;----------------------------------------------------------------------------
@CHANGE_VECT 9 TO TRAPPER9 SAVEIN OLD9
;----------------------------------------------------------------------------
; continue program execution
;----------------------------------------------------------------------------
JMP START
ENDPROC
MAIN ENDP
;
;****************************************************************************
;
CODE ENDS
END ENTRY`
Book Reviews - February
With the wide assortment of books available for the IBM PC series and the greatly differing quality some sort of review is desirable before entering the bookstore. It is all too likely that you will come out poorer by $100.00 or more. It is also important to purchase a book that matches your level of experience.
Novice:
This is the most important of the levels. The basic information must be complete, practical and be presented in a manner that informs without confusing. The books that accomplish this are few indeed.
8088 Assembler Language Programming: The IBM PC
written by David C. Willen & Jeffery I. Krantz
published by Howard W. Sams & Co., Inc.
This book is a well-written introduction to the 8088 instruction set and some of the hardware on a standard PC. Has a complete explanation of hexadecimal & binary numbering systems, an explanation of what assembly language is and what it's good for. Has chapters on keyboard, joystick, monitor text modes, sound, interrupts, a bit about file handling and more. Includes programming examples. Slightly outdated, uses DOS 1 functions and assumes MASM v1.0, but worth the price.
IBM PC-DOS Handbook
written by Richard Allen King
published by Sybex
This is a complementary book to the one above. They really contain different material and together make a good starting point. This volume deals with the interface to DOS versions 1 and 2. Designed so that you can focus on one thing you want to do, and look up everything DOS will do for you towards that. No programming examples.
Advanced:
These are books that assume a reasonable knowledge of assembly language and delve deeply into the topics they cover.
Writing MSDOS device drivers
written by Robert S. Lai
published by The Waite Group (Addison-Wesley Publishing Company)
Quite possibly the definitive book on device drivers. Assumes that you are comfortable with assembly language. Explains device drivers completely, with lots(!!) of examples. The most in-depth and complete reference on the subject I've seen.
Includes a Console, Printer, Clock, and RAM Disk driver.
Programmer's Guide to PC & PS/2 Video Systems
written by Richard Wilton
published by the Microsoft Press
The best book I've seen for video. Assumes complete knowledge of assembly language and the ability to interpret hardware terms. Unfortunately, the examples are written such that they interface with C, but that could be easily changed. Has complete information on MDA, HGC, CGA, EGA, VGA, and MCGA adapters. Includes line, arc, area-fill, and adapter identification routines to name a few, along with complete port programming information. A must for graphics programmers.
DOS Programmer's reference
written by Terry R. Dettmann
published by QUE Corporation
The front of this book isn't that impressive (contains basic info about DOS, BIOS, screen handling, memory etc.) but the last 400 pages are a VERY impressive reference to all the BIOS interrupts, DOS interrupts (including more undocumented functions than I've seen anywhere else), Microsoft Mouse interrupt functions, which aren't documented in the mouse package anymore, and the EMS interrupt functions (version 3.2). If you need a good all-in-one reference, this is it.
NOTE: I am positive that I overlooked a number of extremely good books here. We need you (the readers) to write reviews of books that deal with assembly language and/or hardware for IBM PC's or any other system. Since our main work is done on PClones and we don't really have access to any other sort of system, we need reviews of books for 680x0, 6502, and whatever else you're using. Send all reviews in ASCII text form to FidoNet node 143/37. Thanx. - Dave
GUIDE LINES FOR CONTRIBUTORS AND 'ADVERTISERS'
Name and address must be included with all articles and files
Executable file size and percent of assembly code (when available) should be included when a program is mentioned and is required from an author or publisher.
Any article of interest to Assembly language programmers will be considered for inclusion. Quality of writing will not be a factor, but I reserve the right to try and correct spelling errors and minor mistakes in grammar. Non-exclusive copyright must be given. No monetary compensation will be made.
Outlines of projects that might be undertaken jointly are welcome. For example: One person who is capable with hardware needs support from a user friendly programmer and a math whiz.
Advertisements as such are not acceptable. Authors and publishers wishing to contribute reviews of their own products will be considered and included as space and time permit. These must include executable file size, percent of assembly code and time comparisons.
Your editor would like information on math libraries, and reviews of such.
Articles must be submitted in pclone readable format or sent E-mail.
Address: Patrick O'Riva
2726 Hostetter Rd
San Jose, CA 95132
Money: Your editor has none. Therefore no compensation can be made for articles included. Subscription fees obviously don't exist. Publication costs I expect to be nil (NUL). Small contributions will be accepted to support the BBS where back issues are available as well as files and programs mentioned in articles (if PD or Shareware ONLY).