Category : Files from Magazines
Archive   : PJ82.ZIP
Filename : MISC3.ASM
include asm.inc
MALLOC_MAX equ 0FFF0h ; maximum size of malloc block
.data
extw psp
error_text dw 0 ; asciiz error msg offset in DGROUP
err_default db 'Error',0
err_no_memory db 'Out of memory',0
err_too_big db 'malloc max exceeded',0
err_file_not_found db 'File not found',0
err_file_io db 'File I/O error',0
err_file_too_big db 'File too big',0
.data?
argc dw ?
argv dd ?
.code
;; exit program
;
exit_program proc
mov ax,4C00h
jmp ms_dos
exit_program endp
;; exit with error
;
exit_with_error proc
mov ax,4C01h
jmp ms_dos
exit_with_error endp
;; fatal error handler
;
fatal_error_handler proc
push ss
pop ds
mov si,NULL_POINTER
xchg si,error_text[bp]
cmp si,NULL_POINTER
jne feh1 ; if error text found
lea si,err_default[bp]
feh1: call outchr_asciiz
jmp exit_with_error
fatal_error_handler endp
;; free raw
;
; entry ES:DI storage ptr
; exit Cf if bad ptr
; uses AX
;
free_raw proc
mov ah,49h
jmp ms_dos
free_raw endp
;; isalnum
;
; entry AL character
; exit Zf if alphanumeric character
;
isalnum proc
call isalpha
jne isdigit
ret
isalnum endp
;; isalpha_
;
; entry AL character
; exit Zf if AL alphabetic or _ but not number
;
isalpha_ proc
cmp al,'_'
jne isalpha
ret
isalpha_ endp
;; isalpha
;
; entry AL character
; exit Zf if AL==A-Za-z
;
isalpha proc
cmp al,'A'
jb iap2
cmp al,'Z'
jbe iap1
cmp al,'a'
jb iap2
cmp al,'z'
ja iap2
iap1: cmp al,al
iap2: ret
isalpha endp
;; isdigit
;
; entry AL char
; exit Zf if 0..9
;
isdigit proc
cmp al,'0'
jb idg1
cmp al,'9'
ja idg1
cmp al,al
idg1: ret
isdigit endp
;; malloc raw
;
; entry CX request bytes size (may not exceed 65536-16)
; exit ES:DI storage ptr
; Cf if not enough memory available or request too large
; uses AX
;
malloc_raw proc
push bx
mov bx,cx
add bx,15
jc mar2 ; if too much requested
shr bx,1
shr bx,1
shr bx,1
shr bx,1
mov ah,48h
call ms_dos
jc mar3 ; if not enough memory
mov es,ax
xor di,di
mar1: pop bx
ret
mar2: mov error_text[bp],offset err_too_big
jmp mar1
mar3: mov error_text[bp],offset err_no_memory
jmp mar1
malloc_raw endp
;; ms dos
;
ms_dos proc
int 21h
ret
ms_dos endp
;; outchr
;
; entry AL character
; uses AX
;
outchr proc
push dx
mov ah,2
mov dl,al
call ms_dos
pop dx
ret
outchr endp
;; outchr asciiz
;
; entry DS:SI asciiz string
; exit SI updated past NULL
; uses AX
;
outchr_asciiz proc
lodsb
cmp al,NULL_CHAR
je oaz1
call outchr
jmp outchr_asciiz
oaz1: ret
outchr_asciiz endp
;; outchr asciiz dgroup
;
; entry AX offset of asciiz string in DGROUP
; uses AX
;
outchr_asciiz_dgroup proc
pushm si,ds,ss
pop ds
mov si,ax
call outchr_asciiz
popm ds,si
ret
outchr_asciiz_dgroup endp
;; outchr hex word
;
; entry AX word
; uses AX
;
outchr_hex_word proc
push ax
mov al,ah
call outchr_hex_byte
pop ax
jmp outchr_hex_byte
outchr_hex_word endp
;; outchr hex byte
;
; entry AL byte
; uses AX
; note calls OUTCHR to write chrs
;
outchr_hex_byte proc
push ax
sar al,1
sar al,1
sar al,1
sar al,1
call ohb1
pop ax
ohb1: and al,0Fh
add al,90h
daa
adc al,40h
daa
jmp outchr
outchr_hex_byte endp
;; outchr newline
;
; uses AX
;
outchr_newline proc
mov al,CR_CHAR
call outchr
mov al,LF_CHAR
jmp outchr
outchr_newline endp
;; read command line
;
; exit DS:SI program command line
;
read_command_line proc
mov ds,psp[bp]
mov si,81h
ret
read_command_line endp
;; read entire file
;
; entry DS:SI asciiz file name
; exit DS:SI ptr to storage containing file (NULL delimited)
; CX file byte count
; Cf if file not found or too big
; uses AX
;
read_entire_file proc
pushm bx,dx,di,es
mov ax,3D00h
mov dx,si
call ms_dos
jc ref3 ; if file not found
mov bx,ax ; get file size
mov ax,4202h
xor cx,cx
xor dx,dx
call ms_dos
jc ref4 ; if unexpected file i/o error
or dx,dx ; check file size
jnz ref5 ; if file too big
cmp ax,MALLOC_MAX
jae ref5 ; if file too big
mov cx,ax ; allocate storage for file contents
inc cx ; (account for delimiter)
call malloc_raw
jc ref1 ; if no memory
mov ax,4200h ; rewind file
xor cx,cx
xor dx,dx
call ms_dos
jc ref4 ; if unexpected file i/o error
mov ah,3Fh ; read entire file
mov cx,-1
mov dx,di
push es
pop ds
call ms_dos
jc ref4 ; if unexpected file i/o error
mov cx,ax ; return file byte count
mov si,di ; and storage pointer
add di,ax ; delimit file with NULL
mov al,NULL_CHAR
stosb
ref1: mov ah,3Eh ; close file
pushf ; (preserve Cf)
call ms_dos
popf
ref2: popm es,di,dx,bx
ret
ref3: mov error_text[bp],offset err_file_not_found
jmp ref2
ref4: mov error_text[bp],offset err_file_io
jmp ref1
ref5: mov error_text[bp],offset err_file_too_big
stc
jmp ref1
read_entire_file endp
;; read environment
;
; exit DS:SI environment
;
read_environment proc
xor si,si
mov ds,psp[bp]
mov ds,[si+2Ch]
ret
read_environment endp
;; set argc argv
;
; exit Cf if no memory
; uses AX,CX,DI,SI,ES,DS
;
set_argc_argv proc
mov cx,256
call malloc_raw
jc saa9 ; if no memory
mov argc[bp],1
mov wptr argv[bp],di
mov wptr argv[bp+2],es
mov ah,30h
call ms_dos
cmp al,3
jb saa10 ; if prior to DOS version 3.x
call read_environment ; skip environment
saa1: call strskp
lodsb
cmp al,NULL_CHAR
jne saa1
lodsw ; (skip 1)
call strcpy ; copy program name which appears
inc di ; after environment
saa2: call read_command_line
saa3: call strskp_white
cmp al,CR_CHAR
je saa7 ; if no more arguments
inc argc[bp]
jmp saa5
saa4: stosb
saa5: lodsb
cmp al,SPACE_CHAR
jbe saa6
cmp al,','
je saa6
cmp al,'~'
jbe saa4
saa6: cmp al,CR_CHAR
mov al,NULL_CHAR
stosb
jne saa3
saa7: inc di ; word align table
and di,-2
lds si,argv[bp] ; get ptr to first argument
mov wptr argv[bp],di ; set pointer list offset
mov cx,argc[bp] ; get list count (cannot==0)
saa8: mov ax,si ; build pointer list
stosw
call strskp
loop saa8
clc
saa9: ret
saa10: mov ax,'C'
stosw
jmp saa2
set_argc_argv endp
;; skip line
;
; entry DS:SI text ptr
; exit SI updated to next line but not past NULL
; AL delimiting char (either 0 or 0Ah)
;
skip_line proc
lodsb
cmp al,EOL_CHAR
ja skip_line
je skl1
cmp al,NULL_CHAR
jne skip_line
dec si
skl1: ret
skip_line endp
;; skip spaces tabs
;
; entry DS:SI adr
; SI updated to 1st non-white space chr
; exit AL 1st non-white space chr
;
skip_spaces_tabs proc
sst1: lodsb
cmp al,SPACE_CHAR
je sst1
cmp al,TAB_CHAR
je sst1
dec si
ret
skip_spaces_tabs endp
;; strcpy
;
; entry DS:SI source ptr
; ES:DI destination ptr
; exit SI updated past NULL
; DI updated, points to NULL
; uses AX
;
strcpy proc
lodsb
stosb
cmp al,NULL_CHAR
jne strcpy
dec di
ret
strcpy endp
;; strskp
;
; entry DS:SI asciiz string ptr
; exit SI updated past null
; uses AX
;
strskp proc
lodsb
cmp al,NULL_CHAR
jne strskp
ret
strskp endp
;; strskp white
;
; entry DS:SI text ptr
; exit SI updated past spaces and tabs
; AL non-white character
;
strskp_white proc
lodsb
cmp al,SPACE_CHAR
je strskp_white
cmp al,TAB_CHAR
je strskp_white
dec si
ret
strskp_white endp
public argc,argv,err_default,err_file_io,err_file_not_found,err_file_too_big
public err_no_memory,err_too_big,exit_program,exit_with_error
public fatal_error_handler,free_raw,isalnum,isalpha,isalpha_,isdigit
public malloc_raw,ms_dos,outchr,outchr_asciiz,outchr_asciiz_dgroup
public outchr_hex_byte,outchr_hex_word,outchr_newline,read_command_line
public read_entire_file,read_environment,set_argc_argv,skip_line
public skip_spaces_tabs,strcpy,strskp,strskp_white,error_text
end
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/