SlideShare a Scribd company logo
Assembly Language
Requirement
Submitted by:
Pierre Paul Balanon
#1
Chips
; calling convention:
;
; int chips( void );
;
; returns:
;
; tucked away neatly in your AX....
;
; you get back 8x if an 8088/8086
; 18x if an 80186/80188
; 28x if an 80286
; 38x if an 80386
; 20x for a NEC V20/V30
; AND
; xx0 if NO NDP is found
; xx1 if an 8087
; xx2 if an 80287
; xx3 for an 80387
;
; OR.....
;
; >>> A return of 280 means you got an 80286 machine with no NDP, <<<
; >>> 383 means you have an 80386/80387 rig to work with, and a <<<
; >>> return of 81 sez that you have 8088/8086 CPU with an 8087. <<<
; >>> A 200 tells you that you got an NEC V20/V30 without an NDP. <<<
; >>> ETC., Etc., etc. <<<
;
; NOTE:
;
; There are lotsa ways of handling the way this function returns
; it's data. For my purposes, I have elected this one because
; it requires only int arithmetic on the caller's end to extract
; all the info I need from the return value. I think that I'm
; well enough 'commented' in the following code so that you will
; be able to tinker and Putz until you find the best return tech-
; nique for Ur purposes without having to reinvent the wheel.
;
; >>>> Please see TEST.C, enclosed in this .ARC. <<<<
;
; REFERENCES:
;
; _chips is made up of two PROC's, cpu_type and ndp_type.
;
; cpu_type is based on uncopyrighted, published logic by
; Clif (that's the way he spells it) Purkiser of Intel -
; Santa Clara.
;
; ndp_type is adopted from Ted Forgeron's article in PC
; Tech Journal, Aug '87 p43.
;
; In the event of subsequent republication of this function,
; please carry forward reference to these two gentlemen as
; original authors.
;
.MODEL SMALL
.CODE
PUBLIC _chips
_chips PROC
control dw 0 ; control word needed for the NDP test
push BP ; save where Ur at
mov BP,SP ; going in.....
push DI
push SI
push CX ; not really needed for MSC but kinda
; nice to do cuz someone else might
; want to use the function and we do
; use CX later on
call cpu_type ; find out what kinda CPU you got and
; and save it in DX for future reference
call ndp_type ; check for math coprocessor (NDP) type
; and hold that result in AX
add AX,DX ; add the two results together and hold
; 'em in AX for Ur return to the caller
pop CX ; put things back the way that you
pop SI ; found 'em when you started this
pop DI ; little drill off.....
pop BP
; AND
ret ; go back to where you came from....
; ( ===> the calling program )
; with Ur results sittin' in AX !!
_chips endp
cpu_type PROC
pushf ; pump Ur flags register onto the stack
xor DX,DX ; blow out Ur DX and AX to start off
xor AX,AX ; with a clean slate
push AX ; put AX on the stack
popf ; bring it back in Ur flags
pushf ; try to set bits 12 thru 15 to a zero
pop AX ; get back Ur flags word in AX
and AX, 0f000h ; if bits 12 thru 15 are set then you got
cmp AX, 0f000h ; an Intel 8018x or a 808x or maybe even
jz dig ; a NEC V20/V30 ??? - gotta look more...
; OTHERWISE....
; Here's the BIG one.... 'tells the difference between an 80286 and
; an 80386 !!
mov AX, 07000h ; try to set FLAG bits 12 thru 14
; - NT, IOPL
push AX ; put it onto the stack
popf ; and try to pump 07000H into Ur flags
pushf ; push Ur flags, again
pop AX ; and bring back AX for a compare
and AX,07000h ; if Ur bits 12 thru 14 are set
jnz got386 ; then Ur workin' with an 80386
mov DX, 0280 ; save 280 in DX cuz it's an 80286
jmp SHORT CPUbye ; and bail out
got386: mov DX, 0380 ; save 380 in DX cuz it's an Intel 80386
jmp SHORT CPUbye ; and bail out
; here's we try to figger out whether it's an 80188/80186, an 8088/8086
; or an NEC V20/V30 - 'couple of slick tricks from Clif Purkiser.....
dig: mov AX, 0ffffh ; load up AX
mov CL, 33 ; HERE's the FIRST TRICK.... this will
; shift everything 33 times if it's
; 8088/8086, or once for a 80188/80186!
shl AX, CL ; on a shift of 33, all bits get zeroed
jz digmor ; out so if anything is left ON it's
; gotta be an 80188/80186
mov DX,0180 ; save 180 in DX cuz it's an 80188/80186
jmp SHORT CPUbye ; and bail out
digmor: xor AL,AL ; clean out AL to set ZF
mov AL,40h ; ANOTHER TRICK.... mul on an NEC duz NOT
mul AL ; effect the zero flag BUT on an Intel
jz gotNEC ; 8088/8086, the zero flag gets thrown
mov DX,0080 ; 80 into DX cuz it's an Intel 8088/8086
jmp SHORT CPUbye ; and bail out
gotNEC: mov DX,0200 ; it's an NEC V20/V30 so save 200 in DX
CPUbye: popf ; putchur flags back to where they were
ret ; and go back to where you came from
; (i.e., ===> _chips) with the CPU type
; tucked away in DX for future reference
cpu_type endp
; Check for an NDP.
;
; >>>>NOTE: If you are using an MASM version < 5.0, don't forget to
; use the /R option or you will bomb cuz of the coprocessor instruc-
; tions. /R is not needed for version 5.0.<<<<<<<<<<<<<<<<<<<<<<<<<
ndp_type PROC
do_we: fninit ; try to initialize the NDP
mov byte ptr control+1,0 ; clear memory byte
fnstcw control ; put control word in memory
mov AH,byte ptr control+1 ; iff AH is 03h, you got
cmp AH,03h ; an NDP on board !!
je chk_87 ; found somethin', keep goin'
xor AX,AX ; clean out AX to show a zero
jmp SHORT NDPbye ; return (i.e., no NDP)
; 'got an 8087 ??
chk_87: and control,NOT 0080h ; turn ON interrupts (IEM = 0)
fldcw control ; load control word
fdisi ; turn OFF interrupts (IEM = 1)
fstcw control ; store control word
test control,0080h ; iff IEM=1, 8087
jz chk287 ; 'guess not! March on....
mov AX,0001 ; set up for a 1 return to
jmp SHORT NDPbye ; show an 8087 is on board
; if not.... would you believe an 80287 maybe ??
chk287: finit ; set default infinity mode
fld1 ; make infinity
fldz ; by dividing
fdiv ; 1 by zero !!
fld st ; now make a
fchs ; negative infinity
fcompp ; compare Ur two infinities
fstsw control ; iff, for 8087 or 80287
fwait ; sit tight 'til status word is put away
mov AX,control ; getchur control word
sahf ; putchur AH into flags
jnz got387 ; NO GOOD.... march on !!
mov AX,0002 ; gotta be a 80287 cuz we already tested
jmp SHORT NDPbye ; for an 8087
; We KNOW that there is an NDP on board otherwise we would have bailed
; out after 'do_we'. It isn't an 8087 or an 80287 or we wouldn't have
; gotten this far. It's gotta be an 80387 !!
got387: mov AX,0003 ; call it an 80387 and return 3
NDPbye: ret ; and go back where you came from
; (i.e., ===> _chips) carrying the NDP
; type in Ur AX register
ndp_type endp
_text ends
End
#2
Game Port
; GAMEPORT.ASM
;
.MODEL TINY
.DATA
yes DB 13,10,"Game port is installed.",13,10,"$"
no DB 13,10,"Game port is not installed.",13,10,"$"
.CODE
ORG 100h
start: mov al, 1 ;value to write to port
mov dx, 201h ;port number
out dx, al ;write to port
mov cx, 0F00h ;# of loops
port_loop:
in al, dx ;read from port
and al, 0Fh ;if jstick present, then AL should be
cmp al, 0Fh ; 0Fh after ANDing with 0Fh.
je jstick_exists
loop port_loop
mov dx, OFFSET no ;gameport not installed
jmp SHORT done
jstick_exists:
mov dx, OFFSET yes ;gameport installed
done: mov ah, 9h
int 21h
mov ax, 4c00h
int 21h
END start
#3
Clock
CGROUP GROUP VECTOR,CODESEG
VECTOR SEGMENT AT 0H
DB 6CH DUP(?) ;FILLER
TIME_LO DW ? ;DOS TIME
TIME_HI DW ? ;DOS TIME
VEC_IP DW ;CLOCK UPDATE VECTOR IP
VEC_CS DW ;CLOCK UPDATE VECTOR CS
VECTOR ENDS
CODESEG SEGMENT PARA
ASSUME CS:CODESEG,DS:CGROUP
ORG 100H
CLK PROC FAR
JMP SETUP ;ATTACH TO DOS
INTRPT LABEL DWORD
INT_IP DW 0 ;OLD UPDATE VECTOR IP
INT_CS DW 0 ;OLD UPDATE VECROR CS
TICKS DW 0 ;TICK COUNTER
SCR_OFF DB 0,0 ;SCREEN OFFSET IN BUFFER
CRT_PORT DW 0 ;SCREEN STATUS PORT
flag db 0
TIME DB 8 DUP(':',0BH) ;TIME SAVE AREA
CLK_INT LABEL NEAR
PUSH AX ;SAVE REGISTERS
PUSH CX
PUSH DI
PUSH SI
PUSH DS
PUSH ES
PUSHF ; AND FLAGS
CALL CS:[INTRPT] ;DO OLD UPDATE INTERRUPT
MOV CX,0040H ;GET SEGMENT OF DOS TABLE
MOV DS,CX ;PUT IN DS
MOV CX,CS:TICKS ;GET TICK COUNT
INC CX ;INCREMENT IT
CMP CX,20 ;01F4H ;HAS A MINUTE GONE BY?
JB NO_MINUTE ;NO, MOVE ON
CALL UPDATE ;YES, UPDATE CLOCK AND
MOV CX,0 ; RESET TICK COUNTER
NO_MINUTE:
MOV CS:TICKS,CX ;SAVE UPDATED TICK COUNT
MOV CX,0B000H ;GET VIDEO SEGMENT
MOV ES,CX ;PUT IN ES
MOV DX,CS:CRT_PORT ;GET CRT STATUS PORT ADDR
MOV DI,WORD PTR CS:SCR_OFF ;GET SCREEN BUFFER OFFSET
LEA SI,CS:TIME ;GET DOS TIME
MOV CX,16 ;SET UP TO MOVE 10 BYTES
CLI ;DISABLE OTHER INTERRUPTS
WAIT1: IN AL,DX ;READ CRT STATUS
TEST AL,1 ;CHECK FOR VERTICAL RETRACE
JNZ WAIT1 ;WAIT FOR RETRACE LOW
MOV AH,CS:[SI] ;GET FIRST BYTE TO MOVE
WAIT2: IN AL,DX ;GET CRT STATUS
TEST AL,1 ;CHECK FOR VERTICAL RETRACE
JZ WAIT2 ;WAIT FOR RETRACE HIGH
MOV ES:[DI],AH ;MOVE BYTE TO SCREEN
INC DI ;INCREMENT INDEX
INC SI
LOOP WAIT1 ;MOVE NEXT BYTE
STI ;ENABLE INTERRUPTS
POP ES ;RESTORE REGISTERS
POP DS
POP SI
POP DI
POP CX
POP AX
IRET ;RETURN FROM INTERRUPT
CLK ENDP
UPDATE PROC NEAR
PUSH AX ;SAVE REGISTERS
PUSH BX
PUSH CX
PUSH DX
PUSH DS
MOV AX,0040H ;GET ADDRESS OF DOS TABLE
MOV DS,AX ;PUT IN DS
MOV AX,TIME_HI ;GET HIGH BYTE OF DOS TIME
mov flag,0 ;am flag
HOUR: CMP AX,0CH ;CONVERT TO HOURS
JLE H1
mov flag,1 ;set to pm
SUB AX,0CH
JMP HOUR
H1: AAM ;CONVERT TO ASCII
ADD AX,3030H
LEA BX,CS:TIME ;GET ADDRESS OF TIME AREA
MOV CS:[BX],AH ;SAVE HOURS FIRST DIGIT
MOV CS:[BX+2],AL ;SAVE HOURS SECOND DIGIT
MOV AX,TIME_LO ;GET DOS TIME LOW BYTE
MOV CX,8H ;CONVERT TO MINUTES
SHR AX,CL
MOV DX,3CH
MUL DL
SHR AX,CL
AAM ;CONVERT TO ASCII
ADD AX,3030H
MOV CS:[BX+6],AH ;SAVE MINUTES FIRST DIGIT
MOV CS:[BX+8],AL ;SAVE MINUTES SECOND DIGIT
mov byte ptr cs:[bx+12],'a'
cmp flag,0 ;is it am?
jz goahead
mov byte ptr cs:[bx+12],'p'
goahead:
mov byte ptr cs:[bx+14],'m'
POP DS ;RESTORE REGISTERS
POP DX
POP CX
POP BX
POP AX
RET
UPDATE ENDP
SETUP: MOV AX,0 ;GET ADDRESS OF VECTOR TABLE
MOV DS,AX ;PUT IN DS
CLI ;DISABLE FURTHER INTERRUPTS
MOV AX,[VEC_IP] ;GET ADDRESS OF OLD UPDATE IP
MOV CS:[INT_IP],AX ;SAVE IT
MOV AX,[VEC_CS] ;GET ADDRESS OF OLD UPDATE CS
MOV CS:[INT_CS],AX ;SAVE IT
MOV VEC_IP,OFFSET CLK_INT ;PUT ADDRESS OF CLK IN VECTOR IP
MOV VEC_CS,CS ;PUT CS OF CLK IN VECTOR CS
STI ;ENABLE INTERRUPTS
MOV AH,0FH ;READ VIDEO STATUS
INT 10H
SUB AH,8 ;SUBTRACT 8 CHAR TIME FROM NCOLS
SHL AH,1 ;MULTIPLY BY 2 FOR ATTRIBUTE
MOV CS:SCR_OFF,AH ;SAVE SCREEN TIME LOCATION
MOV WORD PTR CS:CRT_PORT,03BAH ;SAVE MONO STATUS PORT ADDR
TEST AL,4 ;CHECK FOR COLOR MONITOR
JNZ MONO ;IF MONO, MOVE ON
ADD WORD PTR CS:SCR_OFF,8000H ;ADD COLOR OFFSET TO TIME OFFSET
MOV WORD PTR CS:CRT_PORT,03DAH ;SAVE COLOR STATUS PORT ADDR
MONO: CALL UPDATE ;DO FIRST UPDATE & PRINT TIME
MOV DX,OFFSET SETUP ;GET END ADDRESS OF NEW INTERRUPT
INT 27H ;TERMINATE AND REMAIN RESIDENT
DB 117 DUP(0) ;FILLER
CODESEG ENDS
END CLK

More Related Content

PDF
Bolascriollas
PDF
8051 experiments1
PPTX
Embedded JavaScript
DOC
DOCX
Kepad lcd 8051
DOCX
CODING IN ARDUINO
PPT
W8_2: Inside the UoS Educational Processor
PDF
Scale17x buffer overflows
Bolascriollas
8051 experiments1
Embedded JavaScript
Kepad lcd 8051
CODING IN ARDUINO
W8_2: Inside the UoS Educational Processor
Scale17x buffer overflows

What's hot (19)

PDF
Return Oriented Programming - ROP
PDF
OptimizingARM
PDF
20161021_master_lesson_no_feedback
PDF
Solution manual 8051 microcontroller by mazidi
PDF
Docfoc.com ericsson commands
PDF
Advanced cfg bypass on adobe flash player 18 defcon russia 23
TXT
Comande oss
PPT
Buy Embedded Systems Projects Online,Buy B tech Projects Online
KEY
Fosscon 2012 firewall workshop
PPT
Ilfak Guilfanov - Decompiler internals: Microcode [rooted2018]
DOC
Commands...
PDF
selected input/output - sensors and actuators
PDF
Pipeline
PDF
Connectivity for Local Sensors and Actuators Using nRF24L01+
PDF
Nxll24 i pv6
PDF
At89c51 datasheet
PDF
Zn task - defcon russia 20
PDF
ROP 輕鬆談
PDF
Embedded systems io programming
Return Oriented Programming - ROP
OptimizingARM
20161021_master_lesson_no_feedback
Solution manual 8051 microcontroller by mazidi
Docfoc.com ericsson commands
Advanced cfg bypass on adobe flash player 18 defcon russia 23
Comande oss
Buy Embedded Systems Projects Online,Buy B tech Projects Online
Fosscon 2012 firewall workshop
Ilfak Guilfanov - Decompiler internals: Microcode [rooted2018]
Commands...
selected input/output - sensors and actuators
Pipeline
Connectivity for Local Sensors and Actuators Using nRF24L01+
Nxll24 i pv6
At89c51 datasheet
Zn task - defcon russia 20
ROP 輕鬆談
Embedded systems io programming
Ad

Similar to Assembly language (20)

PPT
Chapter6-mikroprocessor
PDF
Lab manual mp
PPT
Addressing mode and instruction set using 8051
PPTX
Assembly Language and microprocessor
PPTX
MPMC Architecture of 8085 Microprocessor and Programming.pptx
PDF
Assembly Complete 8086 Instruction Set
PDF
Intel codetable
PDF
The PDP-10 - and me
PPTX
PPT
Microcontroller 8051- soft.ppt
PPTX
UNIT II MICROPROCESSOR AND MICROCONTROLLER
PPTX
MICROPROCESSORS AND MICROCONTROLLERS
PPTX
PPTX
8085 MICROPROCESSOR.pptx
PPTX
UNIT II –8085 MICROPROCESSOR AND 8051 MICROCONTROLLER---ME6702– MECHATRONICS
PDF
Taller practico emu8086_galarraga
PPT
8085-micropprocessor power ponts7-phpapp01.ppt
PPT
Introduction to-microprocessors
PPTX
20ME702– MECHATRONICS -UNIT-2.pptx
Chapter6-mikroprocessor
Lab manual mp
Addressing mode and instruction set using 8051
Assembly Language and microprocessor
MPMC Architecture of 8085 Microprocessor and Programming.pptx
Assembly Complete 8086 Instruction Set
Intel codetable
The PDP-10 - and me
Microcontroller 8051- soft.ppt
UNIT II MICROPROCESSOR AND MICROCONTROLLER
MICROPROCESSORS AND MICROCONTROLLERS
8085 MICROPROCESSOR.pptx
UNIT II –8085 MICROPROCESSOR AND 8051 MICROCONTROLLER---ME6702– MECHATRONICS
Taller practico emu8086_galarraga
8085-micropprocessor power ponts7-phpapp01.ppt
Introduction to-microprocessors
20ME702– MECHATRONICS -UNIT-2.pptx
Ad

Assembly language

  • 2. #1 Chips ; calling convention: ; ; int chips( void ); ; ; returns: ; ; tucked away neatly in your AX.... ; ; you get back 8x if an 8088/8086 ; 18x if an 80186/80188 ; 28x if an 80286 ; 38x if an 80386 ; 20x for a NEC V20/V30 ; AND ; xx0 if NO NDP is found ; xx1 if an 8087 ; xx2 if an 80287 ; xx3 for an 80387 ; ; OR..... ;
  • 3. ; >>> A return of 280 means you got an 80286 machine with no NDP, <<< ; >>> 383 means you have an 80386/80387 rig to work with, and a <<< ; >>> return of 81 sez that you have 8088/8086 CPU with an 8087. <<< ; >>> A 200 tells you that you got an NEC V20/V30 without an NDP. <<< ; >>> ETC., Etc., etc. <<< ; ; NOTE: ; ; There are lotsa ways of handling the way this function returns ; it's data. For my purposes, I have elected this one because ; it requires only int arithmetic on the caller's end to extract ; all the info I need from the return value. I think that I'm ; well enough 'commented' in the following code so that you will ; be able to tinker and Putz until you find the best return tech- ; nique for Ur purposes without having to reinvent the wheel. ; ; >>>> Please see TEST.C, enclosed in this .ARC. <<<< ; ; REFERENCES: ; ; _chips is made up of two PROC's, cpu_type and ndp_type. ; ; cpu_type is based on uncopyrighted, published logic by ; Clif (that's the way he spells it) Purkiser of Intel -
  • 4. ; Santa Clara. ; ; ndp_type is adopted from Ted Forgeron's article in PC ; Tech Journal, Aug '87 p43. ; ; In the event of subsequent republication of this function, ; please carry forward reference to these two gentlemen as ; original authors. ; .MODEL SMALL .CODE PUBLIC _chips _chips PROC control dw 0 ; control word needed for the NDP test push BP ; save where Ur at mov BP,SP ; going in..... push DI push SI push CX ; not really needed for MSC but kinda ; nice to do cuz someone else might
  • 5. ; want to use the function and we do ; use CX later on call cpu_type ; find out what kinda CPU you got and ; and save it in DX for future reference call ndp_type ; check for math coprocessor (NDP) type ; and hold that result in AX add AX,DX ; add the two results together and hold ; 'em in AX for Ur return to the caller pop CX ; put things back the way that you pop SI ; found 'em when you started this pop DI ; little drill off..... pop BP ; AND ret ; go back to where you came from.... ; ( ===> the calling program ) ; with Ur results sittin' in AX !! _chips endp cpu_type PROC
  • 6. pushf ; pump Ur flags register onto the stack xor DX,DX ; blow out Ur DX and AX to start off xor AX,AX ; with a clean slate push AX ; put AX on the stack popf ; bring it back in Ur flags pushf ; try to set bits 12 thru 15 to a zero pop AX ; get back Ur flags word in AX and AX, 0f000h ; if bits 12 thru 15 are set then you got cmp AX, 0f000h ; an Intel 8018x or a 808x or maybe even jz dig ; a NEC V20/V30 ??? - gotta look more... ; OTHERWISE.... ; Here's the BIG one.... 'tells the difference between an 80286 and ; an 80386 !! mov AX, 07000h ; try to set FLAG bits 12 thru 14 ; - NT, IOPL push AX ; put it onto the stack popf ; and try to pump 07000H into Ur flags pushf ; push Ur flags, again pop AX ; and bring back AX for a compare and AX,07000h ; if Ur bits 12 thru 14 are set jnz got386 ; then Ur workin' with an 80386 mov DX, 0280 ; save 280 in DX cuz it's an 80286
  • 7. jmp SHORT CPUbye ; and bail out got386: mov DX, 0380 ; save 380 in DX cuz it's an Intel 80386 jmp SHORT CPUbye ; and bail out ; here's we try to figger out whether it's an 80188/80186, an 8088/8086 ; or an NEC V20/V30 - 'couple of slick tricks from Clif Purkiser..... dig: mov AX, 0ffffh ; load up AX mov CL, 33 ; HERE's the FIRST TRICK.... this will ; shift everything 33 times if it's ; 8088/8086, or once for a 80188/80186! shl AX, CL ; on a shift of 33, all bits get zeroed jz digmor ; out so if anything is left ON it's ; gotta be an 80188/80186 mov DX,0180 ; save 180 in DX cuz it's an 80188/80186 jmp SHORT CPUbye ; and bail out digmor: xor AL,AL ; clean out AL to set ZF mov AL,40h ; ANOTHER TRICK.... mul on an NEC duz NOT mul AL ; effect the zero flag BUT on an Intel jz gotNEC ; 8088/8086, the zero flag gets thrown mov DX,0080 ; 80 into DX cuz it's an Intel 8088/8086 jmp SHORT CPUbye ; and bail out
  • 8. gotNEC: mov DX,0200 ; it's an NEC V20/V30 so save 200 in DX CPUbye: popf ; putchur flags back to where they were ret ; and go back to where you came from ; (i.e., ===> _chips) with the CPU type ; tucked away in DX for future reference cpu_type endp ; Check for an NDP. ; ; >>>>NOTE: If you are using an MASM version < 5.0, don't forget to ; use the /R option or you will bomb cuz of the coprocessor instruc- ; tions. /R is not needed for version 5.0.<<<<<<<<<<<<<<<<<<<<<<<<< ndp_type PROC do_we: fninit ; try to initialize the NDP mov byte ptr control+1,0 ; clear memory byte fnstcw control ; put control word in memory mov AH,byte ptr control+1 ; iff AH is 03h, you got cmp AH,03h ; an NDP on board !! je chk_87 ; found somethin', keep goin' xor AX,AX ; clean out AX to show a zero
  • 9. jmp SHORT NDPbye ; return (i.e., no NDP) ; 'got an 8087 ?? chk_87: and control,NOT 0080h ; turn ON interrupts (IEM = 0) fldcw control ; load control word fdisi ; turn OFF interrupts (IEM = 1) fstcw control ; store control word test control,0080h ; iff IEM=1, 8087 jz chk287 ; 'guess not! March on.... mov AX,0001 ; set up for a 1 return to jmp SHORT NDPbye ; show an 8087 is on board ; if not.... would you believe an 80287 maybe ?? chk287: finit ; set default infinity mode fld1 ; make infinity fldz ; by dividing fdiv ; 1 by zero !! fld st ; now make a fchs ; negative infinity fcompp ; compare Ur two infinities fstsw control ; iff, for 8087 or 80287 fwait ; sit tight 'til status word is put away
  • 10. mov AX,control ; getchur control word sahf ; putchur AH into flags jnz got387 ; NO GOOD.... march on !! mov AX,0002 ; gotta be a 80287 cuz we already tested jmp SHORT NDPbye ; for an 8087 ; We KNOW that there is an NDP on board otherwise we would have bailed ; out after 'do_we'. It isn't an 8087 or an 80287 or we wouldn't have ; gotten this far. It's gotta be an 80387 !! got387: mov AX,0003 ; call it an 80387 and return 3 NDPbye: ret ; and go back where you came from ; (i.e., ===> _chips) carrying the NDP ; type in Ur AX register ndp_type endp _text ends End
  • 11. #2 Game Port ; GAMEPORT.ASM ; .MODEL TINY .DATA yes DB 13,10,"Game port is installed.",13,10,"$" no DB 13,10,"Game port is not installed.",13,10,"$" .CODE ORG 100h start: mov al, 1 ;value to write to port mov dx, 201h ;port number out dx, al ;write to port mov cx, 0F00h ;# of loops port_loop:
  • 12. in al, dx ;read from port and al, 0Fh ;if jstick present, then AL should be cmp al, 0Fh ; 0Fh after ANDing with 0Fh. je jstick_exists loop port_loop mov dx, OFFSET no ;gameport not installed jmp SHORT done jstick_exists: mov dx, OFFSET yes ;gameport installed done: mov ah, 9h int 21h mov ax, 4c00h int 21h END start
  • 13. #3 Clock CGROUP GROUP VECTOR,CODESEG VECTOR SEGMENT AT 0H DB 6CH DUP(?) ;FILLER TIME_LO DW ? ;DOS TIME TIME_HI DW ? ;DOS TIME VEC_IP DW ;CLOCK UPDATE VECTOR IP VEC_CS DW ;CLOCK UPDATE VECTOR CS VECTOR ENDS CODESEG SEGMENT PARA ASSUME CS:CODESEG,DS:CGROUP ORG 100H CLK PROC FAR JMP SETUP ;ATTACH TO DOS INTRPT LABEL DWORD INT_IP DW 0 ;OLD UPDATE VECTOR IP INT_CS DW 0 ;OLD UPDATE VECROR CS TICKS DW 0 ;TICK COUNTER SCR_OFF DB 0,0 ;SCREEN OFFSET IN BUFFER
  • 14. CRT_PORT DW 0 ;SCREEN STATUS PORT flag db 0 TIME DB 8 DUP(':',0BH) ;TIME SAVE AREA CLK_INT LABEL NEAR PUSH AX ;SAVE REGISTERS PUSH CX PUSH DI PUSH SI PUSH DS PUSH ES PUSHF ; AND FLAGS CALL CS:[INTRPT] ;DO OLD UPDATE INTERRUPT MOV CX,0040H ;GET SEGMENT OF DOS TABLE MOV DS,CX ;PUT IN DS MOV CX,CS:TICKS ;GET TICK COUNT INC CX ;INCREMENT IT CMP CX,20 ;01F4H ;HAS A MINUTE GONE BY? JB NO_MINUTE ;NO, MOVE ON CALL UPDATE ;YES, UPDATE CLOCK AND MOV CX,0 ; RESET TICK COUNTER NO_MINUTE: MOV CS:TICKS,CX ;SAVE UPDATED TICK COUNT MOV CX,0B000H ;GET VIDEO SEGMENT MOV ES,CX ;PUT IN ES
  • 15. MOV DX,CS:CRT_PORT ;GET CRT STATUS PORT ADDR MOV DI,WORD PTR CS:SCR_OFF ;GET SCREEN BUFFER OFFSET LEA SI,CS:TIME ;GET DOS TIME MOV CX,16 ;SET UP TO MOVE 10 BYTES CLI ;DISABLE OTHER INTERRUPTS WAIT1: IN AL,DX ;READ CRT STATUS TEST AL,1 ;CHECK FOR VERTICAL RETRACE JNZ WAIT1 ;WAIT FOR RETRACE LOW MOV AH,CS:[SI] ;GET FIRST BYTE TO MOVE WAIT2: IN AL,DX ;GET CRT STATUS TEST AL,1 ;CHECK FOR VERTICAL RETRACE JZ WAIT2 ;WAIT FOR RETRACE HIGH MOV ES:[DI],AH ;MOVE BYTE TO SCREEN INC DI ;INCREMENT INDEX INC SI LOOP WAIT1 ;MOVE NEXT BYTE STI ;ENABLE INTERRUPTS POP ES ;RESTORE REGISTERS POP DS POP SI POP DI POP CX POP AX IRET ;RETURN FROM INTERRUPT
  • 16. CLK ENDP UPDATE PROC NEAR PUSH AX ;SAVE REGISTERS PUSH BX PUSH CX PUSH DX PUSH DS MOV AX,0040H ;GET ADDRESS OF DOS TABLE MOV DS,AX ;PUT IN DS MOV AX,TIME_HI ;GET HIGH BYTE OF DOS TIME mov flag,0 ;am flag HOUR: CMP AX,0CH ;CONVERT TO HOURS JLE H1 mov flag,1 ;set to pm SUB AX,0CH JMP HOUR H1: AAM ;CONVERT TO ASCII ADD AX,3030H LEA BX,CS:TIME ;GET ADDRESS OF TIME AREA MOV CS:[BX],AH ;SAVE HOURS FIRST DIGIT MOV CS:[BX+2],AL ;SAVE HOURS SECOND DIGIT MOV AX,TIME_LO ;GET DOS TIME LOW BYTE MOV CX,8H ;CONVERT TO MINUTES SHR AX,CL
  • 17. MOV DX,3CH MUL DL SHR AX,CL AAM ;CONVERT TO ASCII ADD AX,3030H MOV CS:[BX+6],AH ;SAVE MINUTES FIRST DIGIT MOV CS:[BX+8],AL ;SAVE MINUTES SECOND DIGIT mov byte ptr cs:[bx+12],'a' cmp flag,0 ;is it am? jz goahead mov byte ptr cs:[bx+12],'p' goahead: mov byte ptr cs:[bx+14],'m' POP DS ;RESTORE REGISTERS POP DX POP CX POP BX POP AX RET UPDATE ENDP SETUP: MOV AX,0 ;GET ADDRESS OF VECTOR TABLE MOV DS,AX ;PUT IN DS CLI ;DISABLE FURTHER INTERRUPTS MOV AX,[VEC_IP] ;GET ADDRESS OF OLD UPDATE IP
  • 18. MOV CS:[INT_IP],AX ;SAVE IT MOV AX,[VEC_CS] ;GET ADDRESS OF OLD UPDATE CS MOV CS:[INT_CS],AX ;SAVE IT MOV VEC_IP,OFFSET CLK_INT ;PUT ADDRESS OF CLK IN VECTOR IP MOV VEC_CS,CS ;PUT CS OF CLK IN VECTOR CS STI ;ENABLE INTERRUPTS MOV AH,0FH ;READ VIDEO STATUS INT 10H SUB AH,8 ;SUBTRACT 8 CHAR TIME FROM NCOLS SHL AH,1 ;MULTIPLY BY 2 FOR ATTRIBUTE MOV CS:SCR_OFF,AH ;SAVE SCREEN TIME LOCATION MOV WORD PTR CS:CRT_PORT,03BAH ;SAVE MONO STATUS PORT ADDR TEST AL,4 ;CHECK FOR COLOR MONITOR JNZ MONO ;IF MONO, MOVE ON ADD WORD PTR CS:SCR_OFF,8000H ;ADD COLOR OFFSET TO TIME OFFSET MOV WORD PTR CS:CRT_PORT,03DAH ;SAVE COLOR STATUS PORT ADDR MONO: CALL UPDATE ;DO FIRST UPDATE & PRINT TIME MOV DX,OFFSET SETUP ;GET END ADDRESS OF NEW INTERRUPT INT 27H ;TERMINATE AND REMAIN RESIDENT DB 117 DUP(0) ;FILLER CODESEG ENDS END CLK