; ; Small-C Run Time Library for MS/PC-DOS ; extrn __main: near extrn _exit: near extrn __memptr: word data segment public dw 1 data ends stack segment stack dw 32 dup(?) stack ends code segment public assume cs:code start: mov ax,data ; set data segment for program mov ds,ax mov ax,es:[2] ; paragraphs of memory on system sub ax,data ; paragraphs beyond code segment cmp ah,10h ; more than 64K? jb start_1 ; no mov ax,1000h ; only use 64K start_1: mov cl,4 shl ax,cl ; byte offset to end of data/free/stack cli ; disable interrupts mov bx,ds mov ss,bx ; make data and stack segments coincide mov sp,ax ; top of stack = end of data/free/stack push ax ; force sp non-zero (if 64K used) sti ; reenable interrupts mov ax,stack ; paragraph following data sub ax,data ; number of data paragraphs shl ax,cl ; number of data bytes (offset to free/stack) mov bx,ax inc bh ; adjust for minimum stack space cmp bx,sp ; enough memory? jb start_2 ; yes mov ax,1 ; no, terminate with exit code 1 push ax call _exit start_2: mov __memptr,ax ; set memory allocation pointer ; ; ------------ release unused memory ----------- ; ------ cannot run debug with this code ------- ; mov bx,sp ; mov ah,4AH ; int 21H ; ---------------------------------------------- ; ; make sure that es -> psp, because __main requires it ; jmp __main ; __main never returns public _ccargc _ccargc: mov al,cl xor ah,ah ret ; ; Test if Secondary (BX) Primary (AX) ;-------------------------- MASM version ;compare macro name, cond ; public __&name ;__&name: ; cmp ax,bx ; j&cond true ; xor ax,ax ; returns zero ; ret ; endm ;-------------------------- ASM version compare macro name, cond public __?1 __?1: cmp ax,bx j?2 true xor ax,ax ; returns zero ret endm ;-------------------------- compare ult,a compare ugt,b compare ule,ae compare uge,be compare eq,e compare ne,ne compare lt,g compare gt,l compare le,ge compare ge,le ; ; Logical Negate of Primary ; public __lneg __lneg: or ax,ax jnz false true: mov ax,1 ; returns one ret false: xor ax,ax ; returns zero ret ; ; ; execute "switch" statement ; ; ax = switch value ; (sp) -> switch table ; dw addr1, value1 ; dw addr2, value2 ; ... ; dw 0 ; [jmp default] ; continuation ; public __switch __switch: pop bx ; bx -> switch table jmp skip ; skip the pre-increment back: add bx,4 skip: mov cx,cs:[bx] jcxz default ; end of table -- jump out cmp ax,cs:[bx+2] jnz back jmp cx ; match -- jump to case default: inc bx inc bx jmp bx ; jump to default/continuation ; ; dummy entry point to resolve the external reference _LINK ; which is no longer generated by Small-C but which exists in ; library modules and .OBJ files compiled by earlier versions ; of Small-C public __link __link: ret code ends end start