textfiles/programming/asmxmple.pro

737 lines
16 KiB
Prolog
Raw Permalink Normal View History

2021-04-15 11:31:59 -07:00
page 44,100
TITLE ASMXMPLE
Video equ 10h ;video functions interrupt number
Keyboard equ 16h ;keyboard functions interrupt number
DOS equ 21h ;call DOS interrupt number
PrtSc equ 5h ;Print Screen Bios interrupt
CRTstatus equ 03DAh
CRTmode equ 03D8h
CursOff equ 16134
portb equ 61h ;I/O port B
STACK Segment Para Stack 'Stack'
Stak db 64 dup ("stack ")
STACK EndS
PARMSEG Segment Para 'data'
Asciiz db 63 dup (?) ;Device ID, path and filespec,
Xasciiz db '$' ; followed by at least one byte of
; of binary zero.
Handle dw ? ;Place to put 16 bit handle number
Bufseg dw ? ;Segment address of buffer
Bufoff dw ? ;Offset of buffer
Bufsiz dw ? ;Max bytes to read/write
Actsiz dw ? ;Actual bytes read
Dskerr dw ? ;DOS error code, if error occurs
Parmseg EndS
DATASEG Segment Para 'data'
IObuffer db 4096 dup (?) ;I/O buffer for reading screens
; from disk.
Pgmstat db 0 ;program status switch
Cover db 'ICOVER.SCN'
db 0
FileSpec db 'INSTRC**.SCN'
db 0
PageNbr db 0
NewPage db ' '
Ten db 10
EdgeTab db 7,7,3,0,0,0,0,0
db 0,0,0,0,7,7,4,0
db 6,6,3,0,3,6,6,6
db 7,0,2,5,5,5,3,6
db 6,6,6,3,6,6,6,6
db 3,3,11,15,10,0,0,0
StartOff dw 0
Keycodes dw 0
Answer db 256 dup (?)
MaxChars dw 0
Attributes dw 0
Buzzit db 0
Dataseg EndS
ScreenSeg Segment at 0B800h ;location of color screen mem
Page0 db 4096 dup (?)
Page1 db 4096 dup (?)
Page2 db 4096 dup (?)
Page3 db 4096 dup (?)
ScreenSeg EndS
CODE Segment Para 'code'
assume cs:CODE
MAIN Proc Far
push ds
mov ax,0
push ax
assume ds:dataseg
mov ax,dataseg
mov ds,ax
mov dl,0 ;set starting page number to zero
mov PageNbr,dl
call ShowCover ;Put instructions cover on screen
cmp Pgmstat,0
jne InstructX ;some was wrong
PageMore:
call PutScreen ;Get instruction screen from disk
; and display it.
call NextNumber ;get next page number, etc.
cmp PageNbr,255
jne PageMore
InstructX:
mov ah,11 ;set color palette
mov bh,0 ;set boarder color
mov bl,0 ;black
int video ;call bios video routine
mov ah,0 ;set mode function
mov al,3 ;80 x 25 color
int video ;bios call to video rom routines
mov ah,5 ;select active display page
mov al,0 ;page 0
int video ;bios call
mov ah,1
mov ch,7
mov cl,7
ret ;return to dos
MAIN EndP
ShowCover Proc Near
push ds
push es
call Cover1
assume ds:dataseg
cmp PageNbr,0
jne CoverX
AnyKey:
mov ah,0 ;read next key struck from keyboard
int keyboard ;call bios keyboard routine
CoverX:
pop es
pop ds
ret
ShowCover EndP
Cover1 Proc Near
push ds
push es
assume ds:dataseg
assume es:parmseg
mov ax,parmseg
mov es,ax
cmp PageNbr,0
jne CoverOk
;Set disk parms, start by moving file spec to Asciiz.
mov si,offset cover
mov di,offset asciiz
mov cx,64
cld
rep movsb
mov es:bufseg,ds ;set segment address of buffer
mov ax,offset IObuffer ;set offset of buffer
mov es:bufoff,ax
mov ax,4008 ;set size of screen block
mov es:bufsiz,ax
call GetFile ;get screen from disk
cmp es:DskErr,0
je CoverOK ;read was OK
mov al,1
mov pgmstat,al
jmp CoverX
Coverok:
mov al,3 ;80 x 25 color
mov ah,0 ;set mode
int video ;call bios video routine
mov ah,5 ;select active display page
mov al,3 ;active page 3
int video ;call bios video routine
mov ah,11 ;set color palette
mov bh,0 ;set boarder color
mov bl,1 ;dark blue
int video ;call bios video routine
mov ah,1 ;make cursor invisible
mov ch,31
mov cl,31
int video
cmp PageNbr,0
jne Cover1X
mov dx,CRTmode ;turn off the display
mov al,29h ;mode byte for 80 column color
and al,11110111b
out dx,al
assume es:screenseg
mov ax,screenseg
mov es,ax
mov si,offset IObuffer+7 ;Move screen from I/O buffer to
mov di,offset Page3 ; to actual screen memory.
cld
mov cx,2000
rep movsw
mov dx,CRTmode ;turn display back on
mov al,29h ;80 x 25 color mode byte
out dx,al
call beep
Cover1X:
pop es
pop ds
ret
Cover1 EndP
PutScreen Proc Near
push ds
push es
ReStart:
assume ds:dataseg
mov al,PageNbr ;get instruction screen page number
call ConvByte ;convert to decimal display
mov FileSpec+6,dh ;and put it into the file spec
mov FileSpec+7,dl
assume es:parmseg
mov ax,parmseg
mov es,ax
;Set disk parms, start by moving file spec to Asciiz.
mov si,offset FileSpec
mov di,offset asciiz
mov cx,64
cld
rep movsb
mov es:bufseg,ds ;set segment address of buffer
mov ax,offset IObuffer ;set offset of buffer
mov es:bufoff,ax
mov ax,4008 ;set size of screen block
mov es:bufsiz,ax
call GetFile ;get screen from disk
cmp es:DskErr,0
je ScreenOK ;read was OK
jmp NoPage ;not a valid screen page number
ScreenOK:
call SetEdge
mov dx,CRTmode ;turn off the display
mov al,29h ;mode byte for 80 column color
and al,11110111b
out dx,al
assume es:screenseg
mov ax,screenseg
mov es,ax
mov si,offset IObuffer+7 ;Move screen from I/O buffer to
mov di,offset Page3 ; to actual screen memory.
cld
mov cx,2000
rep movsw
mov dx,CRTmode ;turn display back on
mov al,29h ;80 x 25 color mode byte
out dx,al
call beep
jmp PSexit
NoPage:
call buzz
call ClearAns
mov al,0
mov PageNbr,al
jmp ReStart
PSexit:
pop es
pop ds
ret
PutScreen EndP
NextNumber Proc Near
push ds
push es
WaitInput:
mov si,CursOff ;offset to cursor position on screen
mov cx,2 ;max characters in answer
mov dh,0BCh ;cursor color atribute
mov dl,031h ;answer color atribute
call Xanswer
assume es:dataseg
mov ax,dataseg
mov es,ax
cmp dh,1
je PrevPage ;go to previous page
cmp dh,2
je NextPage ;go to next page
cmp cx,0
je PageZero ;go to page 0
cmp cx,01FFh
je MainMenu ;escape back to main menu
push cx
mov di,offset NewPage ;move answer to local work area
cld
mov cx,2
rep movsb
pop cx
cmp cx,1
jne TwoDigit
OneDigit:
call ConvOne
cmp ah,0
jne BadNumber
mov es:PageNbr,al
jmp NNexit
TwoDigit:
call ConvTwo
cmp ah,0
jne BadNumber
mov es:PageNbr,al
jmp NNexit
PrevPage:
cmp es:PageNbr,0
je BadNumber
dec es:PageNbr
jmp NNexit
Nextpage:
inc es:PageNbr
jmp NNexit
PageZero:
mov al,0
mov es:PageNbr,al
jmp NNexit
MainMenu:
mov al,255
mov es:PageNbr,al
jmp NNexit
BadNumber:
call buzz
call ClearAns
jmp WaitInput
NNexit:
pop es
pop ds
ret
NextNumber EndP
ConvOne Proc Near
push ds
push es
assume ds:dataseg
mov ax,dataseg
mov ds,ax
mov al,NewPage
cmp al,30h
jl NotNumber1
cmp al,39h
jg NotNumber1
sub al,30h ;convert to binary
mov ah,0
jmp COexit
NotNumber1:
mov ah,1
COexit:
pop es
pop ds
ret
ConvOne EndP
ConvTwo Proc Near
push ds
push es
assume ds:dataseg
mov ax,dataseg
mov ds,ax
mov al,NewPage
cmp al,30h
jl NotNumber2
cmp al,39h
jg NotNumber2
sub al,30h ;convert to binary
mul Ten ;multiply by 10
mov dl,al ;save in dl
mov al,NewPage+1
cmp al,30h
jl NotNumber2
cmp al,39h
jg NotNumber2
sub al,30h ;convert to binary
add al,dl ;add 10's value
mov ah,0
jmp CTexit
NotNumber2:
mov ah,1
CTexit:
pop es
pop ds
ret
ConvTwo EndP
ClearAns Proc Near
push ds
push es
assume ds:screenseg
mov ax,screenseg
mov ds,ax
mov al,20h
mov bx,CursOff
mov [page0 + bx],al
inc bx
mov [page0 + bx],al
inc bx
mov [page0 + bx],al
pop es
pop ds
ret
ClearAns EndP
SetEdge Proc Near
push ds
push es
assume ds:dataseg
mov ax,dataseg
mov ds,ax
mov bl,PageNbr
mov bh,0
mov ch,[EdgeTab + bx]
mov ah,11
mov bh,0
mov bl,ch
int video
pop es
pop ds
ret
SetEdge EndP
;Subroutine to get a binary block of data from disk.
;It opens file, reads entire file (as one block of data)
;into memory, closes file.
;
;Enter with:
; - Device, path, filespec and binary zero in Asciiz.
; - Segment address of buffer in Bufseg.
; - Offset of buffer in Bufoff.
; - Max number of bytes to read, in Bufsiz.
;
;On exit:
; - Handle will contain handle number.
; - Actsiz will contain actual number of bytes read, or
; zero if file was not found on disk.
; - Dskerr will contain the DOS error code, or zero if
; no error.
Getfile Proc Near
push ds ;save registers of calling routine
push es
push si
push di
push ax
push bx
push cx
push dx
assume ds:parmseg
mov ax,parmseg ;set DS to PARMSEG segment
mov ds,ax ; -which sets DS to Asciiz
mov dx,offset asciiz ; -set offset to Asciiz
mov al,0 ;set AL to "open for reading"
mov ah,3dh ;set AH to "open a file" function
int DOS ;call DOS
jc gfopenerr ;error on open
mov handle,ax ;save handle
mov bx,handle ;load BX with file handle
mov cx,bufsiz ;load CX with # of bytes to read
mov dx,bufoff ;load DX with offset of buffer
mov ax,bufseg ;load DS with segment address
mov ds,ax ; of buffer
mov ah,3fh ;"read from a file" function
int DOS ;call DOS
push ax ;save # of bytes read on stack
mov ax,parmseg ;restore DS to diskparms segment
mov ds,ax ;
pop ax ;get # of bytes read
jc gfreaderr ;error on read
mov actsiz,ax ;save # of bytes read, in diskparms
mov bx,handle ;load BX with file handle
mov ah,3eh ;"close a file handle" function
int DOS ;call DOS
jc gfcloserr ;error on close
mov dskerr,0 ;set error code to zero (no error)
Gfback:
pop dx ;restore registers of calling
pop cx ; routine.
pop bx
pop ax
pop di
pop si
pop es
pop ds
ret ;return to calling routine
;ERROR ON OPEN: Possible error returns are:
; 2 - File not found
; 4 - To many open files (no handles left)
; 5 - Access denied
; 12 - Invalid access code
Gfopenerr:
mov ah,1 ;set AH to 1 for open error,
;AL already contains error code
mov dskerr,ax ;put error code in diskparms
jmp gfback
;ERROR ON READ: Possible error returns are:
; 5 - Access denied
; 6 - Invalid handle
Gfreaderr:
mov ah,2 ;set AH to 2 for read error
mov dskerr,ax ;put error code in diskparms
jmp gfback
;ERROR ON CLOSE: Possible error return is:
; 6 - Invalid handle
Gfcloserr:
mov ah,3 ;set AH to 3 for close error
mov dskerr,ax ;put error code in diskparms
jmp gfback
Getfile EndP
Beep Proc Near
push ax ;save registers of calling program
push dx
push cx
push bx
mov ax,0
mov dx,12h
mov cx,7d0h
div cx
mov bx,ax
mov al,10110110b
out 43h,al
mov ax,bx
out 42h,al
mov al,ah
out 42h,al
in al,portb
or al,3
out portb,al
mov cx,07fffh ;set up counter for duration of beep
wait:
loop wait
in al,portb
and al,11111100b
out portb,al
pop bx ;restore registers of calling pgm
pop cx
pop dx
pop ax
ret
BEEP EndP
BUZZ Proc Near
push ax ;save registers of calling program
mov ax,ds
push ax
push bx
push cx
push dx
assume ds:dataseg
mov ax,dataseg ;set DS for this routine
mov ds,ax
mov buzzit,16 ;set buzz counter
Buzzone:
mov ax,0
mov dx,12h
mov cx,900
div cx
mov bx,ax
mov al,10110110b
out 43h,al
mov ax,bx
out 42h,al
mov al,ah
out 42h,al
in al,portb
or al,3
out portb,al
mov cx,0affh
Buzz1:
loop buzz1
in al,portb
and al,11111100b
out portb,al
mov cx,7ffh
Buzz2:
loop buzz2
dec buzzit
jnz buzzone
pop dx
pop cx
pop bx
pop ax
mov ds,ax
pop ax
ret
BUZZ EndP
;Enter with binary value in AL.
;On return, the result is in: (assume result is 234)
; AH = 2, DH = 3, DL = 4
Convbyte Proc Near
push ds
push es
mov ah,48
mov dh,48
mov dl,48
Test1:
cmp al,100
jl test2
sub al,100
inc ah
jmp test1
Test2:
cmp al,10
jl test3
sub al,10
inc dh
jmp test2
Test3:
add dl,al
pop es
pop ds
ret
Convbyte EndP
;Enter with:
; SI = offset of cursor position in screen memory
; CX = maximum number of characters in answer
; DH = color atribute of cursor
; DL = color atribute of answer
;On return:
; The answer is on the screen, followed by the cursor.
; The answer is also in a string pointed to by DS SI,
; with CX set to the number of characters in the answer.
; If Escape was pushed CX will = 01FFh.
; DH will = 0, unless PgUp pushed then DH = 1
; or PgDn pushed then DH = 2.
Xanswer Proc Near
push ds
push es
assume ds:screenseg
mov ax,screenseg
mov ds,ax
assume es:dataseg
mov ax,dataseg
mov es,ax
mov es:Attributes,dx ;save color attributes
mov es:StartOff,si ;save beginning offset
mov es:MaxChars,cx ;save maximum number of characters
; in answer.
mov cx,256
mov bx,0
mov al,20h
ClearAnswer:
mov [es:answer + bx],al
inc bx
loop ClearAnswer
mov cx,0 ;initialize character counter
NextChar:
call PutCursor ;Put cursor on screen
mov ah,0
int keyboard ;read next keyboard entry
mov es:keycodes,ax ;save codes
cmp al,20h
jl ChekEdit ;not a printable character
cmp al,7Eh
jg ChekEdit ;not a printable character
cmp cx,es:MaxChars
jge BadChar ;already have max number of char's
call PutChar ;put character on screen
inc si ;bump offset to screen by 1 char'
inc si ; which is 2 bytes.
mov bx,cx ;move counter to pointer
mov ax,es:keycodes ;get character code
mov [es:Answer + bx],al ;and put in answer string
inc cx ;bump character counter
jmp NextChar
ChekEdit:
cmp ax,0E08h ;backspace
je BackUp
cmp ax,4B00h ;left arrow
je BackUp
cmp ax,1C0Dh ;return
je Return
cmp ax,011Bh ;escape
je Escape
cmp ah,49h ;PgUp
je PageUp
cmp ah,51h ;PgDn
je PageDown
BadChar:
call buzz ;invalid character or control
jmp NextChar
BackUp:
cmp cx,0
jle BadChar ;can't back up
mov es:keycodes,02020h ;set keycodes to space
call PutChar ;blank out cursor on screen
dec cx ;decrement character counter
dec si ;decrement offset pointer
dec si ; (2 bytes per character)
jmp NextChar ;and start over
Escape:
mov cx,01FFh
mov dh,0
jmp Return2
PageUp:
mov dh,1
jmp Return2
PageDown:
mov dh,2
jmp Return2
Return:
mov dh,0
Return2:
mov es:keycodes,02020h ;set keycodes to space
call PutChar ;blank out cursor on screen
assume ds:dataseg
mov ax,dataseg
mov ds,ax
mov si,offset answer
pop es
pop ds
ret
Xanswer EndP
PutCursor Proc Near
assume ds:screenseg
assume es:dataseg
mov bx,es:attributes
mov bl,219
mov dx,CRTstatus
Wait1:
in al,dx
test al,1
jnz Wait1
Wait2:
in al,dx
test al,1
jz Wait2
cli
mov [Page0 + si],bl
mov [Page0 + 1 + si],bh
sti
ret
PutCursor EndP
PutChar Proc Near
push dx
assume ds:screenseg
assume es:dataseg
mov bx,es:attributes
mov bh,bl
mov ax,es:keycodes
mov bl,al
mov dx,CRTstatus
WaitA:
in al,dx
test al,1
jnz WaitA
WaitB:
in al,dx
test al,1
jz WaitB
cli
mov [Page0 + si],bl
mov [Page0 + 1 + si],bh
sti
pop dx
ret
PutChar EndP
CODE EndS
END