; GENERAL ASSEMBLY MACROS COLLECTED BY CHEE
;       They are organized into groups:
;       -- I/O routines
;       -- basic programming constructs
;       -- dos routines
; These groups are preceded by double semicolons, ";;"
; If these macros are in a file called MAC, you can include
; these macros by putting at the beginning of your code the lines
;               IF1
;               INCLUDE MAC
;               ENDIF


; ####################################################
;; I/O ROUTINES
; ####################################################

; ****************************************************
;	Print char in byte register
;	E.g., PutChar AL
PutChar MACRO reg
	push ax
	push dx
	mov dl,reg
	mov ah,2
	int 21h
	pop dx
	pop ax
	endm

; ****************************************************
;	Print the Hex in a byte register
;	E.g. PrintHex AL
PrintHex MACRO reg
  LOCAL small1, small2
	push ax
	push dx
	push cx
	mov dl,reg
	push dx
	; put out first hex
	mov cl,4
	shr dl,cl
	add dl,30h
	cmp dl,39h
	jle small1
	add dl,27h
  small1:
	mov ah,2
	int 21h        ; print it
	; put out second hex
	pop dx
	and dl,0Fh
	add dl,30h
	cmp dl,39h
	jle small2
	add dl,27h
  small2:
	mov ah,2
	int 21h        ; print it
	;
	pop cx
	pop dx
	pop ax
	endm
; end printhex


; ****************************************************
;	Print CR,LF
;	E.g., new_line
new_line MACRO
	push ax
	push dx
	mov ah,2
	mov dl,0dh
	int 21h
	mov dl,0ah
	int 21h
	pop dx
	pop ax
	endm


; ****************************************************
;	Display String Macro
;	Synopsis:
;		DISP_STR <string>
;	will print <string> on the screen.
;	E.g.    DISP_STR 'Hello World!'
DISP_STR MACRO string
	LOCAL start,msg
; save reg:
	push ax
	push dx
	push ds
	jmp start
msg     db      STRING,'$'
start:  mov ax,cs
	mov ds,ax       ; set ds to code segment
	mov ah,9
	lea dx,msg
	int 21h
; restore reg
	pop ds
	pop dx
	pop ax
	endm

; ####################################################
;; Programming constructs
; ####################################################

; ****************************************************
;	Save any number of registers
;	Synopsis:
;		SAVE_REGS <...>
;		will save the specified registers within angle brackets.
;	E.g. SAVE_REGS <AX,BX,SI,DI>
SAVE_REGS MACRO REGS
	IRP D, <REGS>
	PUSH D
	ENDM
	ENDM


; ****************************************************
;	Restore any number of registers
;	Synopsis:
;		RESTORE_REGS <...>
;		will restore the registers.
;	E.g. RESTORE_REGS <DI,SI,BX,AX>
RESTORE_REGS MACRO regs
	irp d,<regs>
	pop d
	endm
	endm
	

; ****************************************************
;	initial ds to @data
init_ds MACRO
	push ax
	mov ax,@DATA
	mov ds,ax
	pop ax
	endm

; ####################################################
;; DOS ROUTINES
; ####################################################


; ****************************************************
;	Return to DOS Macro
;	Synopsis:
;		DOS_RTN <val>
;		will return to dos the value <val> (which is an integer)
;	E.g., DOS_RTN 0
DOS_RTN MACRO value
	mov ah,4ch
	mov al,value
	int 21h
	endm

; ****************************************************
