Files
86-DOS-0.11/Disk Images/86-DOS 0.11 Source Code.img
2026-02-06 23:05:05 +10:00

11835 lines
250 KiB
Plaintext

邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋86DOS A86
86DOS A86 !86DOS A86"ASM A86€#$%&'()*+,-./012邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋 for SEARCH FIRST and SEARCH NEXT
FIRCLUS:DS 2 ;First cluster of file
LSTCLUS:DS 2 ;Last cluster accessed
FILSIZ: DS 2 ;Si邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋
; INTBASE+14H: BIOS DISK READ
; INTBASE+18H: BIOS DISK WRITE
; INTBASE+40H: Long jump to CALL entry point
MAXCALL:EQU 3ASM A86€3456789:;<=>?@ABASM A86bCDEFGHIJKLMNOBOOT A86PQRCHESS A86€STUVWXYZ[\]^_`ab邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋ze of file in records
CLUSPOS:DS 2 ;Position of last cluster accessed
DIRTYFIL:DS 1 ;File has been written to if <>0
SIZCHG邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋6
MAXCOM: EQU 40
ESCCH: EQU 1BH
INTBASE:EQU 80H
INTTAB: EQU 20H
ENTRYPOINTSEG: EQU 0CH
ENTRYPOINT: EQU INTBASE+40H
CONTC:CHESS A86€cdefghijklmnopqrCHESS A86€stuvwxyz{|}~€亗CHESS A86€儎厗噲墛媽崕彁憭CHESS A86C摂晼棙櫄邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋: DS 1 ;Directory needs update if <>0
ORG 32
NR: DS 1 ;Next record
RR: DS 3 ;Random record
; Description of 16-byte 邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋 EQU INTTAB+3
EXIT: EQU INTBASE+8
LONGJUMP:EQU 0EAH
LONGCALL:EQU 9AH
MAXDIF: EQU 0FFFH
SAVEXIT:EQU 10
; Field definitionCHESS DOCCOMMAND A865潪煚、DOSIO A86DぅΗīEDLIN A86G辈炒; QDOS High-performance operating system for the 8086 version 0.11
; by Tim Paterson
; Interrupt Entry Points:
; INTB邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋directory entry (same as returned by SEARCH FIRST
; and SEARCH NEXT, functions 17 and 18).
;
; Location bytes Description
;
邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋 for FCBs
ORG 0
DS 12 ;Drive code and name
EXTENT: DS 4
ENTPOS: DS 2 ;Position of entry in directory
DRVBP: DS 2 ;BPHEX2BIN A86RDCPM A86购患SYS A86TRANS A86~究懒旅呐魄壬仕掏ASE: ABORT
; INTBASE+4: COMMAND
; INTBASE+8: BASE EXIT ADDRESS
; INTBASE+C: CONTROL-C ABORT
; INTBASE+10H: FATAL ERROR ABORT
; 0 11 File name and extension ( 0E5H if empty)
; 11 2 First allocation unit ( < 4080 )
; 13 3 File size, in byte
MOV DI,AX
SHL DI
MOV AH,DPBSIZ
MUL AX,AH
MOV BX,DRVTAB
ADD DI,BX
ADD AX,DI
MOV BP,AX
SEG CS
MOV [FATBASE],A
DB "WB" ;Skip to char
DB "UH" ;Copy line
DB "HH" ;Kill line (no change in template)
DB "RM" ;Reedit line (new template)
IT
STOW ;Set abort address--displacement
MOV AX,CS
MOV B,[ENTRYPOINT],LONGJUMP
MOV [ENTRYPOINT+1],ENTRY
MOV [ENTRYPOf first cluster
MAXCLUS:DS 2 ;Number of clusters on drive + 1
DIRTYFAT:DS 1 ;-1=FAT has been changed
FAT: DS 2 ;Start of F DX
LODW
INC AX
STOW ;MAXCLUS
XOR AL,AL
STOB
POP SI ;Restore pointer to init. table
LODW ;Allocation table dis (LSB first, 24 bits max.)
; Field definition for Drive Parameter Block
ORG 0
DRVNUM: DS 1 ;Drive number
SECSIZ: DSX
PERDEV:
SEG CS
MOV [BX],DI
INC BX
INC BX
MOV AL,CH
STOB ;DRVNUM
LODW ;Pointer to DPT
PUSH SI
MOV SI,AX
DB "DD" ;Backspace
DB "P@" ;Enter insert mode
DB "QL" ;Exit insert mode
DB ESCCH,ESCCH ;Escape character
DB ESCCH,ESCCINT+3],CS
STOW
STOW
STOW
MOV [INTBASE+4],COMMAND
MOV DI,INTBASE+14H
MOV AX,BIOSREAD
STOW
MOV AX,BIOSSEG
STOW
AT
DPBSIZ: EQU $
; BIOS entry point defintions
BIOSSEG: EQU 40H
ORG 0
DS 3
BIOSSTAT: DS 3
BIOSIN: DS 3
BIOSsplacement
SEG CS
ADD AX,[FATBASE]
STOW ;FAT
MOV DL,0
SHR DX ;FAT size in bytes
ADD AX,DX
CMP AX,BP ;Bigger th 1 ;Size of physical sector in records
CLUSMSK:DS 1 ;Records/cluster - 1
CLUSSHFT:DS 1 ;Log2 of records/cluster
FIRFAT: DS
MOVB ;SECSIZ
LODB
DEC AL
STOB ;CLUSMSK
CBW
FIGSHFT:
INC AH
SAR AL
JNZ FIGSHFT
MOV AL,AH
STOB ;CLUSSHFH ;End of table
ESCTABLEN:EQU $-ESCTAB
HEADER: DB 13,10,"86-DOS version 0.11"
DB 13,10
DB "Copyright 1980 Seattle Comp STOW ;Add 2 to DI
STOW
MOV [INTBASE+18H],BIOSWRITE
MOV DX,CS
MOV DS,DX
ADD DX,BP
MOV [DMAADD],80H
MOV [DMAADD+2],OUT: DS 3
BIOSPRINT: DS 3
BIOSAUXIN: DS 3
BIOSAUXOUT: DS 3
BIOSREAD: DS 3
BIOSWRITE: DS 3
BIOSFLUSH: DS 3
; Start of an already allocated
JBE SMFAT
MOV BP,AX
SMFAT:
INC CH ;Next I/O device number
DEC CL
JNZ PERDEV
ADD BP,15 ;True 2 ;Starting record of FATs
FATSIZ: DS 1 ;Number of records occupied by FAT
FATCNT: DS 1 ;Number of FATs for this drive
FIT
LODW
STOW ;FIRFAT (= number of reserved records)
MOV DX,AX
LODB
STOB ;FATSIZ
MOV AH,AL
PUSH AX
LODB
STOButer Products, Inc.",13,10,"$"
DOSINIT:
DI
UP
MOV AX,CS
MOV ES,AX
LODB
CBW
MOV CX,AX
SEG CS
MOV [NUMDRV],ALDX
MOV AX,[DRVTAB]
MOV [CURDRVPT],AX
MOV CX,DX
MOV BX,0FH
MEMSCAN:
INC CX
JZ HAVMEM
MOV DS,CX
MOV AL,[BX]
NOTcode
ORG 0
PUT 100H
JMP DOSINIT
ESCTAB:
DB "SC" ;Copy one char
DB "VN" ;Skip one char
DB "TA" ;Copy to char
start of free space
MOV CL,4
SHR BP,CL ;First free segment
XOR AX,AX
MOV DS,AX
MOV ES,AX
MOV DI,INTBASE
MOV AX,QURDIR: DS 2 ;Starting record of directory
DIRSIZ: DS 1 ;Number of records occupied by directory
FIRREC: DS 2 ;First record o ;FATCNT
MUL AX,AH
ADD AX,DX
STOW ;FIRDIR
MOV DX,AX
LODB
STOB ;DIRSIZ
CBW
ADD AX,DX
STOW ;FIRREC
POP AL
MOV [BX],AL
CMP AL,[BX]
NOT AL
MOV [BX],AL
JZ MEMSCAN
HAVMEM:
SEG CS
MOV [ENDMEM],CX
XOR CX,CX
MOV DS,CX
ONLY
DW SETATTRIB ;30
DW GETDSKPT
DW USERCODE
DW RNDRD
DW RNDWRT
DW FILESIZE ;35
DW SETRNDREC
; Extended FunctionPOP DX
POP SI
POP DI
POP BP
POP DS
POP ES
POP SS
SEG CS
MOV SP,[SPSAVE]
IRET
DISPATCH:
; Standard FunctionHR DI
MOV DI,[BX]
JNC ALIGNED
SHL DX
SHL DX
SHL DX
SHL DX
AND DI,0FH
JP PACKIN
ALIGNED:
AND DI,0F000H
PACKINnt
SEG CS
PUSH [TEMP] ;Stack now ordered as if INT had been used
CMP CL,MAXCALL ;This entry point doesn't get as many cal too big.
CMP BX,[BP+MAXCLUS]
JA HURTFAT
LEA DI,[SI+BX]
SHR BX
MOV DI,[DI+BX]
JNC HAVCLUS
SHR DI
SHR DI
SHR
MOV [EXIT],100H
MOV [EXIT+2],DX
MOV [INTBASE+0CH],100H
MOV [INTBASE+0EH],DX
CALL SETMEM
MOV SI,HEADER
CALL OUTMES
s
DW SETVECT
DW NEWBASE
DW BLKRD
DW BLKWRT ;40
VERSION:
GETIO:
SETIO:
WRTPROT:
GETRDONLY:
SETATTRIB:
USERCODE:s
DW ABORT ;0
DW CONIN
DW CONOUT
DW READER
DW PUNCH
DW LIST ;5
DW RAWIO
DW GETIO
DW SETIO
DW PRTBUF
DW B:
OR DI,DX
MOV [BX],DI
RET
GETFILE:
; Inputs:
; DS,DX point to FCB
; Function:
; Find file name in disk directoryls
JA BADCALL
MOV AH,CL
SAVREGS:
SEG CS
MOV [SPSAVE],SP
SEG CS
MOV [SSSAVE],SS
INC SP
INC SP
SEG CS
POP [TEDI
SHR DI
STC
HAVCLUS:
RCL BX
AND DI,0FFFH
RET
HURTFAT:
MOV SI,BADMES
CALL OUTMES
JMP ERROR
PACK:
; In
RET L
QUIT:
MOV AH,0
JP SAVREGS
COMMAND: ;Interrupt call entry point
CMP AH,MAXCOM
JBE SAVREGS
BADCALL:
MOV A
MOV AL,0
RET
READER:
CALL BIOSAUXIN,BIOSSEG
RET
PUNCH:
MOV AL,DL
CALL BIOSAUXOUT,BIOSSEG
RET
UNPACK:UFIN ;10
DW CONSTAT
DW VERSION
DW DSKRESET
DW SELDSK
DW OPEN ;15
DW CLOSE
DW SRCHFRST
DW SRCHNXT
DW DELETE
. First byte is
; drive number (0=current disk). "?" matches any
; character.
; Outputs:
; Carry set if file not found
; ELMP]
MOV SP,CS
MOV SS,SP
MOV SP,STACK
PUSH ES
PUSH DS
PUSH BP
PUSH DI
PUSH SI
PUSH DX
PUSH CX
PUSH BX
PUSputs:
; DS = CS
; BX = Cluster number
; DX = Data
; SI = Pointer to drive FAT
; Outputs:
; The data is stored in the FAT aL,0
IRET: IRET
ENTRY: ;System call entry point and dispatcher
POP AX ;IP from the long call at 5
POP AX ;Segment from
; Inputs:
; DS = CS
; BX = Cluster number
; BP = Base of drive parameters
; SI = Pointer to drive FAT
; Outputs:
; DI DW SEQRD ;20
DW SEQWRT
DW CREATE
DW RENAME
DW INUSE
DW CURDRV ;25
DW SETDMA
DW GETFATPT
DW WRTPROT
DW GETRDSE
; BP = Base of drive parameters
; DS = CS
; ES = CS
; AL = Directory record number
; BX = Pointer into directory buffer
H AX
MOV BL,AH
MOV BH,0
SHL BX
UP
SEG CS
CALL [BX+DISPATCH]
SEG CS
MOV [AXSAVE],AL
POP AX
POP BX
POP CX
t the given cluster.
; BX,DX,DI all destroyed
; No other registers affected
MOV DI,BX
SHR BX
ADD BX,SI
ADD BX,DI
Sthe long call at 5
SEG CS
POP [TEMP] ;IP from the CALL 5
PUSHF ;Start re-ordering the stack
DI
PUSH AX ;Save segme= Contents of FAT for given cluster
; Zero set means DI=0 (free cluster)
; No other registers affected. Fatal error if cluster
; SI = Pointer to First Cluster field in directory entry
; [DIRBUF] has directory record with match
; [NAME1] has file name
ame in upper case
; All registers except DX destroyed
; Carry set if bad file name or drive
MOV AX,CS
MOV ES,AX
MOV DIALL FINDNAME
JC ERRET
SAVDREC:
MOV AH,AL
RENFIL:
MOV DI,BX
MOV SI,NAME2
MOV CX,11
NEWNAM:
LODB
CMP AL,"?"
JZ er
STOW ; last cluster accessed
LODB
SHL AL
LODW
RCL AX
STOW ; size of file in records
XOR AX,AX
STOW ; po
DELETE: ; System call 19
CALL GETFILE
JC ERRET
PUSH AX
PUSH BX
CALL FATREAD
POP BX
DELFILE:
MOV B,[BX],0E5H
rectory
; entry in DIRBUF, and the top of the stack has the
; address and segment of the FCB to be opened. This
; entry point; All other registers destroyed.
CALL MOVNAME
JC RET ;Bad file name?
FINDNAME:
MOV AX,CS
MOV DS,AX
MOV AL,0
RDIRR,NAME1
MOV SI,DX
LODB
SEG ES
CMP [NUMDRV],AL
JC RET
CBW
XCHG AX,BP
SHL BP
MOV BP,[BP+CURDRVPT]
LODNAME:
; ThNOCHG
MOV [DI],AL
NOCHG:
INC DI
LOOP NEWNAM
CALL NEXTENT
JZ RENFIL
MOV AL,AH
PUSH AX
CALL DIRWRITE
POP AX
Csition of last cluster
STOW ; file not dirty
FATREAD:
TEST B,[BP+DIRTYFAT],-1
JNZ RET
CALL FIGFAT
NEXTFAT:
PUSH PUSH BX
MOV BX,[BX+11]
MOV SI,[BP+FAT]
OR BX,BX
JZ DELNXT
CMP BX,[BP+MAXCLUS]
JA DELNXT
CALL RELEASE
DELNXT:
PO is used by CREATE.
POP ES
POP DI
JC ERRET
MOV AH,[BP+DRVNUM]
INC AH
SEG ES
MOV [DI],AH
SEG ES
MOV [DI+EXTENT]EC:
PUSH AX
CALL DIRREAD
POP AX
MOV BX,DIRBUF-16
CONTSRCH:
CALL NEXTENT
JZ RET
NDIRREC:
INC AL ;Next directory is entry point copies a file name from DS,SI
; to ES,DI converting to upper case.
MOV CX,11
MOVCHK:
LODB
AND AL,7FH
CMALL NDIRREC
JNC SAVDREC ;New record read, save current number
XOR AL,AL
RET
ERRET:
MOV AL,-1
RET
MOVNAME:
DX
PUSH CX
PUSH BX
PUSH AX
CALL DREAD
OR AL,AL
POP AX
POP BX
POP CX
POP DX
JNZ BADFAT
SUB AL,[BP+FATCNT]
P BX
CALL NEXTENT
JZ DELFILE
POP AX
PUSH AX
CALL DIRWRITE
POP AX
CALL NDIRREC
PUSH AX
JNC DELFILE
POP AX
C,0 ;Set extent field to 0
ADD DI,16 ;Point to entry pos. field
MOV CX,BX
SUB CX,DIRBUF
MOV AH,CL
STOW ;directory lorecord
CMP AL,[BP+DIRSIZ]
JB RDIRREC
STC
RET
NEXTENT:
ADD BX,16
CMP BX,DIRBUF+127
JA RET
CMP B,[BX],0E5H
JZP AL,60H
JLE CASEOK
AND AL,5FH
CASEOK:
CMP AL,20H
JC RET
STOB
LOOP MOVCHK
RET
OPEN: ;System call 15
PUSH DX
; Inputs:
; DS, DX point to FCB
; Outputs:
; ES = CS
; If file name OK:
; BP has base of driver parameters
; [NAME1] has n JZ RET
NEG AL
;{Insert error code here. AL=number of bad fats.
;Since one good FAT was read, should include option
;to rewALL FATWRT
XOR AL,AL
RET
RENAME: ;System call 23
CALL MOVNAME
JC ERRET
ADD SI,5
MOV DI,NAME2
CALL LODNAME
Ccation
MOV AX,BP
STOW ;pointer to driver parameters
LEA SI,[BX+11]
LODW ;Get starting cluster
STOW ; first clust NEXTENT
MOV SI,BX
MOV DI,NAME1
MOV CX,11
WILDCRD:
REPE
CMPB
JZ RET
CMP B,[DI-1],"?"
JZ WILDCRD
JP NEXTENT
PUSH DS
CALL GETFILE
DOOPEN:
; Enter here to perform OPEN on file already found
; in directory. DS=ES=CS, BX points to dirite all FATs.}
JP FATWRT
BADFAT:
ADD DX,CX
DEC AL
JNZ NEXTFAT
POP BP
;{Insert error code here. All FATs on drive call 22
CALL MOVNAME
JC ERRET3
MOV DI,NAME1
MOV CX,11
MOV AL,"?"
REPNE
SCAB
JZ ERRET3
PUSH DX
PUSH DS
MOV
ADD DX,CX
DEC AL
JNZ EACHFAT
OKRET:
MOV AL,0
RET
BADCLOSE:
MOV B,[BP+DIRTYFAT],0
MOV AL,-1
RET
FIGFAT:sters destroyed.
MOV AL,[BP+DRVNUM]
PUSH BP
PUSH BX
PUSH CX
PUSH DX
CALL BIOSREAD,BIOSSEG
POP DX
POP DI
POP
MOV [BX+14],DX
MOV DL,0
RCR DL
MOV [BX+13],DL
CALL DIRWRITE
CHKFATWRT:
; Do FATWRT only if FAT is dirty
TEST umber
; BP = Base of drive parameters
; Function:
; Read the directory block into DIRBUF.
; Outputs:
; BP unchanged
; All are bad.}
MOV SI,BADFATMES
CALL HARDERR
JP FATREAD
CLOSE: ;System call 16
MOV DI,DX
TEST B,[DI+DIRTYFIL],-1
JZ NOAX,CS
MOV DS,AX
XOR AX,AX
RDIRREC2:
PUSH AX
CALL DIRREAD
POP AX
MOV DI,DIRBUF-16
MOV CX,8
FNDFRE:
ADD DI,16
; Loads registers with values needed to read or
; write a FAT.
MOV AL,[BP+FATCNT]
MOV BX,[BP+FAT]
MOV CL,[BP+FATSIZ] ;NBX
POP BP
JC HARDREAD
XOR AL,AL
RET
HARDREAD:
MOV SI,RDERRMES
CALL HARDERR
JP DREAD
DIRWRITE:
; Inputs:
B,[BP+DIRTYFAT],-1
JZ OKRET
FATWRT:
; Inputs:
; DS = CS
; BP = Base of drive parameter table
; Function:
; Write theother registers destroyed.
CALL DIRCOMP
DREAD:
; Inputs:
; BX,DS = Transfer address
; CX = Number of records
; DX =FLSH
PUSH DI
MOV BP,[DI+DRVBP]
MOV AL,[BP+DRVNUM]
CALL BIOSFLUSH,BIOSSEG
POP DI
NOFLSH:
TEST B,[DI+SIZCHG],-1
JZ CMP B,[DI],0E5H
LOOPNE FNDFRE
JZ FREESPOT
INC AL
CMP AL,[BP+DIRSIZ]
JC RDIRREC2
POP DS
POP DX
ERRET3:
MOV AL,-1o. of records occupied by FAT
MOV CH,0
MOV DX,[BP+FIRFAT] ;Record number of start of FATs
RET
DIRCOMP:
; Prepare reg; DS = CS
; AL = Directory block number
; BP = Base of drive parameters
; Function:
; Write the directory block into DIRBUF. FAT back to disk and reset FAT
; dirty bit.
; Outputs:
; AL = 0
; BP unchanged
; All other registers destroyed
MOV B,[ Absolute record number
; BP = Base of drive parameters
; Function:
; Calls BIOS to perform disk read. If BIOS reports
; errOKRET
MOV DX,DI
PUSH DX
PUSH DS
CALL GETFILE
POP ES
POP DI
JC BADCLOSE
MOV CX,BX
SUB CX,DIRBUF
MOV AH,CL
S
RET
FREESPOT:
MOV BX,DI
MOV SI,NAME1
MOV CX,5
MOVB
REP
MOVW
XCHG AL,AH
MOV CL,5
REP
STOB
XCHG AL,AH
isters for directory read or write
CBW
ADD AX,[BP+FIRDIR]
MOV DX,AX
MOV BX,DIRBUF
MOV CX,1
RET
CREATE: ;System
; Outputs:
; BP unchanged
; All other registers destroyed.
CALL DIRCOMP
DWRITE:
; Inputs:
; BX,DS = Transfer adBP+DIRTYFAT],0
CALL FIGFAT
EACHFAT:
PUSH DX
PUSH CX
PUSH BX
PUSH AX
CALL DWRITE
POP AX
POP BX
POP CX
POP DXors, will call HARDERR for further action.
; Outputs:
; AL = 0 if no error, otherwise non-zero
; BP preserved. All other regiEG ES
CMP AX,[DI+ENTPOS]
JNZ BADCLOSE
SEG ES
MOV CX,[DI+FIRCLUS]
MOV [BX+11],CX
SEG ES
MOV DX,[DI+FILSIZ]
SHR DXPUSH AX
PUSH BX
CALL DIRWRITE
POP BX
POP AX
JMP DOOPEN
DIRREAD:
; Inputs:
; DS = CS
; AL = Directory block ndress
; CX = Number of records
; DX = Absolute record number
; BP = Base of drive parameters
; Function:
; Calls BIOS to pe
JP FINBLK
BLKWRT: ;System call 40
MOV DI,DX
MOV AX,[DI+RR]
CALL STORE
FINBLK:
MOV [CXSAVE],CX
JCXZ FINRND
INCV SP,[SPSAVE]
MOV DS,[DSSAVE]
SEG CS
JMP L,[EXITHOLD]
SEQRD: ;System call 20
CALL GETREC
MOV CX,1
CALL LOAD
J divide by 128
ROL BX
XCHG BL,BH
JNZ CHKMAX
MOV BH,2 ;All 512 records OK
CHKMAX:
CMP CX,BX
JBE SAVCNT
MOV CX,BX
UTMES
GETINSTR:
CALL IN
OR AL,20H
CMP AL,"a"
JZ ERROR
CMP AL,"r"
JZ RET
CMP AL,"i"
JZ IGNORE
CMP AL,"c"
JNZ DX
; [NEXTADD] = Displacement of disk transfer within segment
; [DSKERR] = 0 (no errors yet)
; [TRANS] = 0 (No transfers yetrform disk write. If BIOS reports
; errors, will call HARDERR for further action.
; Outputs:
; AL = 0 if no error, otherwise AX
FINRND:
SEG ES
MOV [DI+RR],AX
SETNREX:
MOV CX,AX
AND AL,7FH
SEG ES
MOV [DI+NR],AL
AND CL,80H
ROL CX
XCHGCXZ SETNREX
INC AX
JP SETNREX
SEQWRT: ;System call 21
CALL GETREC
MOV CX,1
CALL STORE
JCXZ SETNREX
INC AX
JP MOV B,[DSKERR],2 ;Flag that trimming took place
SAVCNT:
MOV [RECCNT],CX
RET
SEGEND:
MOV B,[DSKERR],2
MOV CX,0
POP B GETINSTR
POP AX
MOV AL,1
RET
IGNORE:
POP AX
MOV AL,0
RET
ABORT:
SEG CS
MOV DS,[CSLOC]
XOR AX,AX
MOV ES,)
; If SETUP detects no records will be transfered, it returns 1 level up
; with CX = 0.
MOV BP,[DI+DRVBP]
MOV BX,DS
non-zero
; BP preserved. All other registers destroyed.
MOV AL,[BP+DRVNUM]
MOV AH,0
CMP DX,[BP+FIRREC]
RCR AH
PUSH CL,CH
SEG ES
MOV [DI+EXTENT],CX
MOV AL,[DSKERR]
RET
SETUP:
; Inputs:
; DS:DI point to FCB
; AX = Record positioSETNREX
RNDRD: ;System call 33
MOV CX,1
MOV DI,DX
MOV AX,[DI+RR]
CALL LOAD
JP FINRND
RNDWRT: ;System call 34
MX
RET
FNDCLUS:
; Inputs:
; DS = CS
; CX = No. of clusters to skip
; BP = Base of drive parameters
; SI = FAT pointAX
MOV SI,SAVEXIT
MOV DI,EXIT
MOVW
MOVW
MOVW
MOVW
ERROR:
MOV SP,BPSAVE
MOV AX,CS
MOV DS,AX
MOV ES,AX
CALLMOV ES,BX
MOV BX,CS
MOV DS,BX
MOV [RECPOS],AX
MOV [FCB],DX
MOV BX,[DMAADD]
MOV [NEXTADD],BX
MOV B,[DSKERR],0
MOVBP
PUSH BX
PUSH CX
PUSH DX
CALL BIOSWRITE,BIOSSEG
POP DX
POP DI
POP BX
POP BP
JC HARDWRITE
XOR AL,AL
RET
n in file of disk transfer
; CX = Record count
; Outputs:
; DS = CS
; ES:DI point to FCB
; CX = No. of records to transfer
OV CX,1
MOV DI,DX
MOV AX,[DI+RR]
CALL STORE
JP FINRND
BLKRD: ;System call 39
MOV DI,DX
MOV AX,[DI+RR]
CALL LOADer
; ES:DI point to FCB
; Outputs:
; BX = Last cluster skipped to
; CX = No. of clusters remaining (0 unless EOF)
; DX = Po WRTFATS
XOR AX,AX
MOV DS,AX
MOV SI,EXIT
MOV DI,EXITHOLD
MOVW
MOVW
POP BP
POP ES
POP ES
POP DS
POP SS
MO [TRANS],0
MOV SI,[BP+FAT]
ADD BX,7FH ;See if there is any space left
JC SEGEND
AND BL,80H
NEG BX ;These instructionsHARDWRITE:
MOV SI,WRTERRMES
CALL HARDERR
JP DWRITE
HARDERR:
SUB DI,CX
ADD DX,DI
CALL SHFTDI7
ADD BX,DI
CALL O
; BP = Base of drive parameters
; SI = FAT pointer
; [RECCNT] = Record count
; [RECPOS] = Record position in file
; [FCB] =sition of last cluster
; DI destroyed. No other registers affected.
SEG ES
MOV BX,[DI+LSTCLUS]
SEG ES
MOV DX,[DI+CLUSCLUSSHFT]
SHR AX,CL
MOV CX,AX
CALL FNDCLUS
OR CX,CX
JNZ LVDSK
MOV DX,0FFFH
MOV B,[BP+DIRTYFAT],-1
MOV DI,[FCB]
I+LSTCLUS],AX
MOV AX,[RECPOS]
MOV BX,[TRANS]
ADD AX,BX
SEG ES
CMP AX,[DI+FILSIZ]
JBE SAMSIZ
SEG ES
MOV [DI+FILSIuts:
; DS = CS
; BX = Physical cluster
; CX = No. of records
; DL = record within cluster
; BP = Base of drives parameters
SEG ES
MOV BX,[DI+FILSIZ]
SUB BX,AX
JBE WRTERRJ
CMP BX,CX
JNB ENUF
MOV B,[DSKERR],1
MOV [RECCNT],BX
ENUF:
MOVst cluster minus current cluster
JCXZ HAVSTART ;See if no more data
PUSH CX ;No. of clusters of first
MOV CX,AX
CALL ALPOS]
OR BX,BX
JZ NOCLUS
SUB CX,DX
JNB FINDIT
ADD CX,DX
XOR DX,DX
SEG ES
MOV BX,[DI+FIRCLUS]
FINDIT:
JCXZ RET
MOV AX,[RECPOS]
SEG ES
MOV [DI+FILSIZ],AX
SEG ES
MOV B,[DI+SIZCHG],-1
XOR CX,CX
RET
STORE:
; Inputs:
; DS:DIZ],AX
SEG ES
MOV B,[DI+SIZCHG],-1
SAMSIZ:
DEC AX
MOV DX,AX
MOV CL,[BP+CLUSSHFT]
SHR DX,CL
SEG ES
MOV [DI+CLUSPO
; [NEXTADD] = transfer address
; Outputs:
; AX = No. of records remaining
; BX = Transfer address
; CX = No. or records to CL,[BP+CLUSSHFT]
SHR AX,CL
MOV CX,AX
CALL FNDCLUS
OR CX,CX
JNZ WRTERR
MOV DL,[RECPOS]
AND DL,[BP+CLUSMSK]
MOV CLOCATE
POP CX
JC WRTERR
DEC CX
JZ NOSKIP
CALL SKPCLP
PUSH BX
WRCLUS:
POP BX
NOSKIP:
MOV DL,[RECPOS]
AND DL,[
SKPCLP:
CALL UNPACK
CMP DI,0FFFH
JZ RET
XCHG BX,DI
INC DX
LOOP SKPCLP
RET
NOCLUS:
INC CX
DEC DX
RET
L point to FCB
; AX = Position in file of disk transfer
; CX = Record count
; Outputs:
; AX = Position of last record writtenS],DX
MOV CX,BX
RET
WRTERRJ:JP WRTERR
HAVSTART:
MOV CX,AX
PUSH BX
CALL FNDCLUS
JCXZ WRCLUS
CALL ALLOCATE
Pbe transferred
; DX = Physical record address
; DI = Next cluster
; [CLUSNUM] = Last cluster accessed
; [NEXTADD] updated
;X,[RECCNT]
RDLP:
CALL OPTIMIZE
PUSH DI
PUSH AX
PUSH DS
MOV DS,[DMAADD+2]
CALL DREAD
POP DS
POP CX
POP BX
JCBP+CLUSMSK]
MOV CX,[RECCNT]
WRTLP:
CALL OPTIMIZE
PUSH DI
PUSH AX
PUSH DS
MOV DS,[DMAADD+2]
CALL DWRITE
POP DS
OAD:
; Inputs:
; DS:DI point to FCB
; AX = Position in file to read
; CX = No. of records to read
; Outputs:
; AX = Posi
; CX = No. of records written
; ES:DI point to FCB
; LSTCLUS, CLUSPOS fields in FCB set
CALL SETUP
JCXZ WRTEOF
MOV BOP BX
JNC NOSKIP
WRTERR:
MOV B,[DSKERR],1
LVDSK:
MOV AX,[RECPOS]
XOR CX,CX
MOV DI,[FCB]
RET
WRTEOF:
MOV CL,[BP+ BP unchanged. Note that segment of transfer not set.
PUSH DX
PUSH BX
MOV AL,[BP+CLUSMSK]
INC AL ;Number of records pXZ SETFCB
MOV DL,0
CMP BX,0FFFH
JNZ RDLP
MOV B,[DSKERR],1
SETFCB:
MOV AX,[CLUSNUM]
MOV DI,[FCB]
SEG ES
MOV [D POP CX
POP BX
MOV DL,0
OR CX,CX
JNZ WRTLP
CALL SETFCB
SEG ES
MOV B,[DI+DIRTYFIL],-1
RET
OPTIMIZE:
; Inption of last record read
; CX = No. of records read
; ES:DI point to FCB
; LSTCLUS, CLUSPOS fields in FCB set
CALL SETUP
X,CX
ADD BX,AX
DEC BX
MOV CL,[BP+CLUSSHFT]
SHR AX,CL
SHR BX,CL
MOV CX,AX
MOV AX,BX
CALL FNDCLUS
SUB AX,DX ;Laer cluster
MOV AH,AL
SUB AL,DL ;AL = Number of records left in first cluster
MOV DX,CX
MOV SI,[BP+FAT]
MOV CX,0
OPTCng dirty bit
; FIRCLUS field of FCB set if file was null
; SI,BP unchanged. All other registers destroyed.
PUSH BX
MOV A DI,DX
MOV AL,[DI+NR]
MOV BX,[DI+EXTENT]
SHL AL
SHR BX
RCR AL
MOV AH,BL
RET
ALLOCATE:
; Inputs:
; DS = CSputs:
; BX = Cluster in a file
; SI = Base of drive FAT
; DS = CS
; Outputs:
; BX = Last cluster in the file
; DI destroyeBH
ROR BX
MOV SI,[NEXTADD]
ADD BX,SI ;Adjust by size of transfer
MOV [NEXTADD],BX
ADD [TRANS],CX
POP DX
POP BX
I+FIRCLUS],BX
OR [SI],0FFFH
RET
RELEASE:
; Inputs:
; DS = CS
; BX = Cluster in file
; SI = FAT pointer
; BP = BaLUS:
;AL has number of records available in current cluster
;AH has number of records available in next cluster
;BX has curreX,BX
ALLOC:
MOV DX,BX
FINDFRE:
INC BX
CMP BX,[BP+MAXCLUS]
JL TRYOUT
CMP AX,1
JG TRYIN
POP BX
MOV DX,0FFFH
CA
; ES = Segment of FCB
; BX = Last cluster of file (0 if null file)
; CX = No. of clusters to allocate
; DX = Position of cld. No other registers affected.
CALL UNPACK
CMP DI,0FFFH
JZ RET
MOV BX,DI
JP GETEOF
SRCHFRST: ;System call 17
PUSH CX
MOV CL,[BP+CLUSSHFT]
DEC DX
DEC DX
SHL DX,CL
OR DL,BL
ADD DX,[BP+FIRREC]
POP CX
MOV BX,SI
RET
BLKDON:se of drive parameters
; Function:
; Frees cluster chain starting with [BX]
; AX,BX,DX,DI all destroyed. Other registers unchnt physical cluster
;CX has number of sequential records found so far
;DX has number of records left to transfer
;SI has FAT LL RELBLKS
OR [SI],0FFFH
STC
RET
TRYOUT:
CALL UNPACK
JZ HAVFRE
TRYIN:
DEC AX
JLE FINDFRE
XCHG AX,BX
CALL Uuster BX
; BP = Base of drive parameters
; SI = FAT pointer
; [FCB] = Displacement of FCB within segment
; Outputs:
; IF in CALL GETFILE
SAVPLCE:
; Search-for-next enters here to save place and report
; findings.
JC KILLSRCH
MOV [SRCHDON],AL
MOV CX,DX ;Make the total equal to the request
JP FINCLUS
GETREC:
; Inputs:
; DS:DX point to FCB
; Outputs:
; Aanged.
XOR DX,DX
RELBLKS:
; Enter here with DX=0FFFH to put an end-of-file mark
; in the first cluster and free the rest pointer
CALL UNPACK
ADD CL,AL
ADC CH,0
CMP CX,DX
JAE BLKDON
MOV AL,AH
INC BX
CMP DI,BX
JZ OPTCLUS
DEC BX
FINPACK
JZ HAVFRE
XCHG AX,BX
JP FINDFRE
HAVFRE:
XCHG BX,DX
MOV AX,DX
CALL PACK
MOV BX,AX
LOOP ALLOC
MOV DX,0FFFsufficient space
; THEN
; Carry set
; ELSE
; Carry clear
; BX = First cluster allocated
; FAT is fully updated includiMOV [PDIR],BX
MOV [SRCHBP],BP
;Information in directory entry must be copied into the first
; 16 bytes starting at the disk X = Record number determined by EXTENT and NR fields
; DS:DI point to FCB
; BX destroyed. No other registers affected.
MOVin the chain.
CALL UNPACK
JZ RET
MOV AX,DI
CALL PACK
CMP AX,0FFFH
MOV BX,AX
JNZ RELEASE
RET
GETEOF:
; InNCLUS:
MOV [CLUSNUM],BX ;Last cluster accessed
SUB DX,CX ;Number of records still needed
MOV AX,DX
MOV BX,CX
XCHG BL,H
CALL PACK
MOV B,[BP+DIRTYFAT],-1
POP BX
CALL UNPACK
XCHG BX,DI
OR DI,DI
JNZ RET
MOV DI,[FCB]
SEG ES
MOV [Dtransfer address.
MOV SI,BX
LES DI,[DMAADD]
MOV CX,8
REP
MOVW
MOV AL,0
RET
KILLSRCH:
MOV AL,-1
MOV [SRCHDONSE:
LODW
MOV BP,AX
TEST B,[BP+DIRTYFAT],-1
JZ SETBIT
STC
SETBIT:
RCL BX
LOOP CHKUSE
MOV AL,BL
RET
SETRND]
MOV [CURDRVPT],AX
WRTFATS:
; DS=CS. Writes back all dirty FATs. All registers destroyed.
MOV CL,[NUMDRV]
MOV CH,0
MO AND CL,0FEH
MOV BP,CX
JMP [BP+ESCFUNC]
ENDLIN:
STOB
CALL OUT
POP DI
MOV [DI-1],DH
INC DH
COPYNEW:
MOV BP,ESADD+2],DS
RET
GETFATPT: ;System call 27
MOV AX,CS
MOV DS,AX
MOV [DSSAVE],CS
MOV BP,[CURDRVPT]
CALL FATREAD
MOV IN:
SEG CS
MOV AL,[CARPOS]
SEG CS
MOV [STARTPOS],AL
PUSH SI
MOV DI,INBUF
MOV AH,CH
MOV BH,CH
MOV DH,CH
GETCH:],AL
RET
SRCHNXT: ;System call 18
MOV AX,CS
MOV ES,AX
MOV DS,AX
MOV AL,[SRCHDON]
CMP AL,-1
JZ RET
MOV BX,[PREC: ;System call 36
CALL GETREC
MOV [DI+33],AX
MOV AL,0
JZ BIGRR
INC AL
BIGRR:
MOV [DI+35],AL
RET
SELDSK: ;V SI,CURDRVPT+2
WRTFAT:
LODW
PUSH CX
PUSH SI
MOV BP,AX
CALL CHKFATWRT
POP SI
POP CX
LOOP WRTFAT
MOV AL,-1
C
MOV BX,DS
MOV ES,BX
MOV DS,BP
MOV SI,INBUF
MOV CL,DH
REP
MOVB
RET
CRLF:
MOV AL,13
CALL OUT
MOV AL,10
JBX,[BP+FAT]
MOV AL,[BP+CLUSMSK]
INC AL
MOV DX,[BP+MAXCLUS]
DEC DX
MOV B,[BP+DIRTYFAT],-1
MOV [BXSAVE],BX
MOV [DXSA
CALL IN
CMP AL,7FH
JZ BACKSP
CMP AL,8
JZ BACKSP
CMP AL,13
JZ ENDLIN
CMP AL,10
JZ PHYCRLF
CMP AL,"X"-"@"
JDIR]
MOV BP,[SRCHBP]
CALL CONTSRCH
JP SAVPLCE
FILESIZE: ;System call 35
PUSH DI
PUSH DX
CALL GETFILE
POP DI
System call 14
MOV DH,0
MOV BX,DX
PUSH CS
POP DS
CMP BL,[NUMDRV]
JGE RET
SHL BX
MOV AX,[BX+CURDRVPT+2]
MOV [CUALL BIOSFLUSH,BIOSSEG
RET
CURDRV: ;System call 25
SEG CS
MOV BP,[CURDRVPT]
MOV AL,[BP+DRVNUM]
RET
INUSE: ;SyMP OUT
PHYCRLF:
CALL CRLF
JP GETCH
KILNEW:
MOV AL,"\"
CALL OUT
POP SI
PUTNEW:
CALL CRLF
JMP NEWLIN
BACKSVE],DX
RET
GETDSKPT: ;System call 31
SEG CS
MOV [DSSAVE],CS
SEG CS
MOV BX,[CURDRVPT]
SEG CS
MOV [BXSAVE],BX
Z KILNEW
CMP AL,ESCCH
JZ ESC
SAVCH:
CMP DH,DL
JAE GETCH
STOB
INC DH
CALL OUT
OR AH,AH
JNZ GETCH
CMP BH,BL
POP ES
MOV AL,-1
JC RET
ADD DI,33 ;Write size in RR field
LEA SI,[BX+13]
LODB
SHL AL
LODW
RCL AX ;Round to neRDRVPT],AX
RET
BUFIN: ;System call 10
MOV AX,CS
MOV ES,AX
MOV SI,DX
MOV CH,0
LODW
OR AL,AL
JZ RET
MOV BL,stem call 24
MOV AX,CS
MOV DS,AX
MOV CL,[NUMDRV]
MOV CH,0
MOV SI,CX
SHL SI
ADD SI,CURDRVPT
MOV BX,0
DOWN
CHKUP:
OR DH,DH
JZ OLDBAK
CALL BACKUP
SEG ES
MOV AL,[DI]
CMP AL," "
JAE OLDBAK
CMP AL,9
JZ BAKTAB
CALL BACKMES
RET
DSKRESET: ;System call 13
SEG CS
MOV [DMAADD+2],DS
MOV AX,CS
MOV DS,AX
MOV [DMAADD],80H
MOV AX,[CURDRVPT+2 JAE GETCH
INC SI
INC BH
JP GETCH
ESC:
CALL IN
MOV CL,ESCTABLEN
PUSH DI
MOV DI,ESCTAB
REPNE
SCAB
POP DI
arest record
STOW
MOV AL,0
RCL AL
STOB
RET
SETDMA: ;System call 26
SEG CS
MOV [DMAADD],DX
SEG CS
MOV [DMAAH
MOV BH,CH
CMP AL,BL
JBE NOEDIT
CMP B,[BX+SI],0DH
JZ EDITON
NOEDIT:
MOV BL,CH
EDITON:
MOV DL,AL
DEC DX
NEWLOLDBAK:
OR AH,AH
JNZ GETCH1
OR BH,BH
JZ GETCH1
DEC BH
DEC SI
GETCH1:
JMP GETCH
BAKTAB:
PUSH DI
DEC DI
DOWNL,20H
JB CTRLOUT
CMP AL,7FH
JZ OUTCH
SEG CS
INC B,[CARPOS]
OUTCH:
CALL BIOSOUT,BIOSSEG
SEG CS
TEST B,[PFLAG],-1ES
JNZ NOTFND
NOT CL
ADD CL,BL
SUB CL,BH
RET
NOTFND:
POP BP
JMP GETCH
REEDIT:
MOV AL,"@"
CALL OUT
POP DIK
JZ IN
RET
RAWIO: ;System call 6
MOV AL,DL
CMP AL,-1
JNZ RAWOUT
CALL BIOSSTAT,BIOSSEG
JZ RET
CALL BIOSIN,BIOP COPYEACH
COPYSTR:
CALL FINDOLD
JP COPYEACH
COPYONE:
MOV CL,1
COPYEACH:
CMP DH,DL
JZ GETCH2
CMP BH,BL
JZ GOV AL,"^"
CALL OUT
POP AX
OR AL,40H
JP OUT
ZERPOS:
SEG CS
MOV B,[CARPOS],0
JP OUTCH
BACKPOS:
SEG CS
DEC B,
MOV CL,DH
MOV AL," "
PUSH BX
MOV BL,7
JCXZ FIGTAB
FNDPOS:
SCAB
JNA CHKCNT
SEG ES
CMP B,[DI+1],9
JZ HAVTAB
JZ STATCHK
CALL BIOSPRINT,BIOSSEG
STATCHK:
CALL BIOSSTAT,BIOSSEG
JZ RET
INCHK:
CALL BIOSIN,BIOSSEG
CMP AL,'S'-'@'
PUSH DI
PUSH ES
PUSH DS
CALL COPYNEW
POP DS
POP ES
POP SI
MOV BL,DH
JMP PUTNEW
ENTERINS:
MOV AH,-1
JMPSSEG
RET
RAWOUT:
CALL BIOSOUT,BIOSSEG
RET
LIST: ;System call 5
MOV AL,DL
CALL BIOSPRINT,BIOSSEG
RET
PRTBUF: ;ETCH2
LODB
STOB
CALL OUT
INC BH
INC DH
LOOP COPYEACH
GETCH2:
JMP GETCH
SKIPONE:
CMP BH,BL
JZ GETCH2
INC [CARPOS]
JP OUTCH
TAB:
MOV AL,0
SEG CS
XCHG AL,[CARPOS]
OR AL,0F8H
NEG AL
PUSH CX
MOV CL,AL
MOV CH,0
TABLP
DEC BL
CHKCNT:
LOOP FNDPOS
FIGTAB:
SEG CS
SUB BL,[STARTPOS]
HAVTAB:
SUB BL,DH
ADD CL,BL
AND CL,7
UP
POP BX
JNZ NOSTOP
CALL BIOSIN,BIOSSEG
NOSTOP:
CMP AL,'P'-'@'
JZ PRINTON
CMP AL,'N'-'@'
JZ PRINTOFF
CMP AL,'C'-'@'
JNZ GETCH
EXITINS:
MOV AH,0
JMP GETCH
ESCFUNC:
DW GETCH
DW TWOESC
DW EXITINS
DW ENTERINS
DW BACKSP
DW REEDIT
System call 9
MOV SI,DX
OUTSTR:
LODB
CMP AL,"$"
JZ RET
CALL OUT
JP OUTSTR
OUTMES: ;String output for internal meBH
INC SI
JMP GETCH
SKIPSTR:
CALL FINDOLD
ADD SI,CX
ADD BH,CL
JMP GETCH
FINDOLD:
CALL IN
MOV CL,BL
SUB C:
MOV AL," "
CALL OUTCH
LOOP TABLP
POP CX
RET
CONSTAT: ;System call 11
CALL BIOSSTAT,BIOSSEG
JZ RET
OR AL,-
POP DI
JZ OLDBAK
TABBAK:
CALL BACKMES
LOOP TABBAK
JP OLDBAK
BACKUP:
DEC DH
DEC DI
BACKMES:
MOV AL,8
CALL OU RET
INT CONTC ;Execute user Ctrl-C handler
RET
PRINTON:
SEG CS
MOV B,[PFLAG],1
RET
PRINTOFF:
SEG CS
MOV B,[P
DW KILNEW
DW COPYLIN
DW SKIPSTR
DW COPYSTR
DW SKIPONE
DW COPYONE
CONOUT: ;System call 2
MOV AL,DL
OUT:
CMP Assages
SEG CS
LODB
CMP AL,"$"
JZ RET
CALL OUT
JP OUTMES
SETVECT: ; Interrupt call 37
XOR BX,BX
MOV ES,BX
L,BH
JZ NOTFND
DEC CX
JZ NOTFND
PUSH ES
PUSH DS
POP ES
PUSH DI
MOV DI,SI
INC DI
REPNE
SCAB
POP DI
POP 1
RET
CONIN: ;System call 1
CALL INCHK
PUSH AX
CALL OUT
POP AX
RET
IN: ;Internal input routine
CALL INCHT
MOV AL," "
CALL OUTCH
MOV AL,8
JMP OUTCH
TWOESC:
MOV AL,ESCCH
JMP SAVCH
COPYLIN:
MOV CL,BL
SUB CL,BH
JFLAG],0
RET
CTRLOUT:
CMP AL,10
JZ OUTCH
CMP AL,13
JZ ZERPOS
CMP AL,8
JZ BACKPOS
CMP AL,9
JZ TAB
PUSH AX
MMOV BL,AL
SHL BX
SHL BX
SEG ES
MOV [BX],DX
SEG ES
MOV [BX+2],DS
RET
NEWBASE: ; Interrupt call 38
MOV ES,DX
user FCB
RECPOS: DS 2
NEXTADD:DS 2
RECCNT: DS 2
CLUSNUM:DS 2
TRANS: DS 2
DS 50 ;Stack space
AXSAVE: DS 2
BXSAVE: DS 213,10,"$"
BADFATMES:DB 13,10,"All FATs on disk are bad",13,10,"$"
RDERRMES:DB 13,10,"Disk read error",13,10,"$"
WRTERRMES:DB ction codes
PRINTMES: EQU 9
OPEN: EQU 15
CLOSE: EQU 16
DELETE: EQU 19
READ: EQU 20
SETDMA: EQU 26
MAKE: EQU 22
SEQWRT: E CX,CX
MOV DS,CX
MOV ES,DX
MOV SI,EXIT
MOV DI,SAVEXIT
MOVW
MOVW
MOVW
MOVW
SEG CS
MOV CX,[ENDMEM]
SEG ES
邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋
SEG CS
MOV DS,[CSLOC]
XOR SI,SI
MOV DI,SI
MOV CX,80H
REP
MOVW
SETMEM:
; Inputs:
; DX = Segment
; Function:
CXSAVE: DS 2
DXSAVE: DS 2
SISAVE: DS 2
DISAVE: DS 2
BPSAVE: DS 2
DSSAVE: DS 2
ESSAVE: DS 2
STACK:
SSSAVE: DS 2
SPSAVE13,10,"Disk write error",13,10,"$"
CARPOS: DB 0
STARTPOS:DB 0
PFLAG: DB 0
SRCHDON:DB -1
PDIR: DS 2
SRCHBP: DS 2
EXITHOLQU 21
;The following equates define some token values returned by GETSYM
UNDEFID:EQU 0 ;Undefined identifier (including no nMOV [2],CX
SUB CX,DX
CMP CX,MAXDIF
JBE HAVDIF
MOV CX,MAXDIF
HAVDIF:
MOV BX,ENTRYPOINTSEG
SUB BX,CX
SHL CX
SHL C邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋
; Completely prepares a program base at the
; specified segment.
; Outputs:
; DS = DX
; ES = DX
; [0] has INT 20H
; [2]: DS 2
CURDRVPT:DS 2
DRVTAB: ;Address of start of DPBs
D:DS 4
ENDMEM: DS 2
FATBASE:DS 2
INBUF: DS 255
DIRBUF: DS 128
NUMDRV: DS 1 ;Number of drives
NAME1: DS 11 ;File name buffeearby RET)
CONST: EQU 1 ;Constant (including $)
REG: EQU 2 ;8-bit register
XREG: EQU 3 ;16-bit register (except segment regisX
SHL CX
SHL CX
MOV DS,DX
MOV [6],CX
MOV [8],BX
MOV [0],20CDH ;"INT INTTAB"
MOV B,[5],LONGCALL
RET
SHFTDI7:; Seattle Computer Products 8086 Assembler version 2.00
; by Tim Paterson
; Runs on the 8086 under 86-DOS
SYMWID: EQU 10 = First unavailable segment ([ENDMEM])
; [5] to [9] form a long call to the entry point
; [10] to [13] have exit address (fro邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋r
NAME2: DS 11
DMAADD: DS 4 ;User's disk transfer address (disp/seg)
TEMP:
CSLOC: DS 2
DSKERR: DS 1
FCB: DS 2 ;Address of ters)
SREG: EQU 4 ;Segment register
ORG 100H
PUT 100H
JMP BEGIN
CPYRHT: DB 'Copyright 1979 by Seattle Computer Pro
SHL DI
SHL DI
SHL DI
SHL DI
SHL DI
SHL DI
SHL DI
RET
;***** DATA AREA *****
BADMES: DB 13,10,"Bad FAT",
FCB: EQU 5CH
BUFSIZ: EQU 128
EOL: EQU 13 ;ASCII carriage return
OBJECT: EQU 100H ;DEFAULT "PUT" ADDRESS
;System call funm INT 22H)
; [14] to [17] have ctrl-C exit address (from INT 23H)
; AX,DX,BP unchanged. All other registers destroyed.
XOR邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋ducts, Inc.'
DB 13,10,13,10,'$'
BEGIN:
MOV SP,STACK
MOV DX,HEADER
MOV CL,PRINTMES
CALL SYSTEM
MOV DX,CPYRHT
CAL AL,-1 ;Flag that no tokens have been read yet
MOV [SYM],AL
CALL ASMLIN ;Assemble the line
MOV AL,[SYM]
CMP AL,-1 ;AnBX ;DEFAULT PROGRAM COUNTER
MOV [BASE],BX ;POINTER TO ROOT OF ID TREE=NIL
MOV [RETPT],BX ;Pointer to last RET record
DEC OV DX,FCB+9
MOV BX,EXTEND ;Set extension to ASM
MOV CX,7
UP
MOV SI,BX
MOV DI,DX
REP
MOVB
MOV DX,DI
MOV BX,SI
CMP AL,'X' ;PRN file to console?
JZ NOPRN
CALL CHKDSK
NOPRN:
MOV [LSTFCB],AL
CALL ADDEXT
MOV DX,FCB
MOV CL,OPEN
for linefeed
JP GETEOL
ABORT:
MOV BX,NOMEM
PRERR:
XCHG DX,BX
MOV CL,PRINTMES
CALL SYSTEM
JMP 0
MAKFIL:
MOV L SYSTEM
MOV AL,[FCB+17]
MOV [SYMFLG],AL ;Save symbol table request flag
MOV BX,FCB+9 ;Point to file extension
MOV AL,[By tokens found on line?
JNZ L0002
CALL GETSYM ;If no tokens read yet, read first one
L0002:
CMP AL,';'
JZ ENDLN
CMPBX
MOV [LSTRET],BX ;Location of last RET
MOV BX,[6] ;HL=END OF MEMORY
MOV [HEAP],BX ;BACK END OF SYMBOL TABLE SPACE
MOV RET
CHKDSK:
SUB AL,' ' ;If not present, set zero flag
JZ RET
SUB AL,20H
JZ DSKERR ;Must be in range A-W
CMP AL,' CALL SYSTEM
MOV BX,NOFILE
INC AL
JNZ $+5
JMP PRERR
XOR AL,AL
MOV [FCB+32],AL ;Zero Next Record field
MOV DX,HEXFCSI,DX
LODB ;Get drive select byte
CMP AL,20H ;If not valid, don't make file
JNC RET
PUSH DX
INC DX
MOV BX,FCB+1
X] ;Get source drive letter
CALL CHKDSK ;Valid drive?
OR AL,AL
JZ DEFAULT ;If no extension, use existing drive spec
M AL,EOL
JZ ENDLN
MOV AL,14H ;Garbage at end of line error
JP ENDLIN
ENDJ: JMP END
ENDLN:
XOR AL,AL ;Flag no errors AL,4
MOV [BCOUNT],AL ;CODE BYTES PER RELOCATION BYTE
XOR AL,AL
MOV [IFFLG],AL ;NOT WITHIN IF/ENDIF
MOV [CHKLAB],AL ;LOOX'-'@'
JC RET
DSKERR:
MOV BX,BADDSK
JP PRERR
ERROR:
MOV AL,CL
JMP ENDLIN
NEXTCHR:
XCHG BX,[HL]
XCHG DX,[DE]B
CALL MAKFIL
MOV DX,LSTFCB
CALL MAKFIL
MOV BX,0FFH
XCHG BX,[HL]
XCHG DX,[DE]
XCHG CX,[BC]
MOV BX,START+1 ;POINT MOV CX,8
UP
MOV SI,BX
MOV DI,DX
REP
MOVB ;Copy source file name
MOV DX,DI
MOV BX,SI
POP DX
MOV CL,DELETE
OV [FCB],AL
DEFAULT:
INC BX
MOV AL,[BX] ;Get HEX file drive letter
CMP AL,'Z' ;Suppress HEX file?
JZ L0000
CALL CHK on line
ENDLIN:
MOV SP,STACK
CALL NEXLIN
JP LOOP
NEXLIN:
MOV CH,0C0H ;Put end of line marker and error code (AL)
KUP ALL LABELS
;Assemble each line of code
LOOP:
CALL NEXTCHR ;Get first character on line
CMP AL,1AH
JZ ENDJ
MOV
XCHG CX,[BC]
INC BL
JNZ GETCH
;Buffer empty so refill it
MOV DX,80H
MOV CL,SETDMA
CALL SYSTEM
XCHG DX,BX
MOV DER TO NEXT BYTE OF INTERMEDIATE CODE
MOV [CODE],BX
MOV [IY],START ;POINTER TO CURRENT RELOCATION BYTE
MOV BX,0
MOV [PC],CALL SYSTEM
MOV CL,MAKE
CALL SYSTEM
MOV BX,NOSPAC
INC AL ;Success?
JZ PRERR
MOV CL,OPEN
JMP SYSTEM
ADDEXT:
MDSK
L0000:
MOV [HEXFCB],AL
INC BX
MOV AL,[BX] ;Get PRN file drive letter
CMP AL,'Z' ;Suppress PRN file?
JZ NOPRN
CALL PUTCD
CALL GEN1
MOV AL,[CHR]
GETEOL:
CMP AL,10
JZ RET
CMP AL,1AH
JZ ENDJ
CALL NEXTCHR ;Scan over comments X,FCB
MOV CL,READ
CALL SYSTEM
OR AL,AL
MOV AL,1AH ;Possibly signal End of File
JNZ NOMOD ;If nothing read
GETCH:
SUB AL,DH ;Check if source is 16-bit register
JZ RR ;If so, AL must be zero
AND CH,0FDH ;Change direction
XCHG DX,BX ber into middle position
ADD AL,AL
ADD AL,AL
OR AL,0C0H ;Set register-to-register mode
OR AL,DL ;Combine with other reord bit
AND AL,CL ;But don't use it in word-only operations
OR AL,CH ;Combine with OP code
CALL PUT
MOV AL,BL
ADD AL JZ RET
MOV AL,UNDEFID ;Check for memory reference
CMP AL,BH
JZ STORE ;Is destination memory?
CMP AL,DH
JZ LOAD ;Is
OR AL,BL ; meaning direct load/store of accumulator
JNZ NOTAC
TEST CL,8 ;See if direct load/store of accumulator
JZMOV AL,[BX]
NOMOD:
XCHG BX,[HL]
XCHG DX,[DE]
XCHG CX,[BC]
MOV [CHR],AL
RET
MROPS:
PUSH CX ;Save type flags
;Flip which operand is first and second
MOV AL,XREG
SUB AL,DH ;Let RR perform finish the test
JP RR
STORE:
TEST CL,gister number
JMP PUT
SEGCHK:
;Come here if at least one operand is a segment register
POP CX ;Restore flags
RCR SI
,AL ;Rotate to middle position
ADD AL,AL
ADD AL,AL
OR AL,DL ;Combine register field
POP CX ;Dump return address
JMPsource memory?
RCR SI
TEST CL,1 ;Check if register-to-register operation OK
RCL SI
MOV CL,27
JZ ERROR
MOV AL,DH
C NOTAC ; means anything in this case
; Process direct load/store of accumulator
MOV AL,CH
AND AL,2 ;Preserve direction CALL GETOP
PUSH DX ;Save first operand
CALL GETOP2
POP BX ;First op in BX, second op in DX
MOV AL,SREG ;Check for a s004H ;Check if storing is OK
JNZ STERR
XCHG DX,BX ;If so, flip operands
AND CH,0FDH ; and zero direction bit
LOAD:
TEST CL,8 ;Check if segment register OK
RCL SI
MOV CL,22
JZ ERR1
MOV CX,8E03H ;Segment register move OP code
MOV AL, PUTADD ;Write the address
STERR:
MOV DH,29
MRERR:
MOV CL,DH
ERR1: JMP ERROR
GETOP2:
;Get the second operand: loMP AL,BH ;Registers must be of same length
RR:
MOV CL,22
JNZ ERROR
RR1:
AND AL,1 ;Get register length (1=16 bits)
ORbit only
XOR AL,2 ; but flip it
OR AL,0A0H ;Combine with OP code
MOV CH,AL
MOV AL,BH ;Check byte/word operation
Aegment register
CMP AL,BH
JZ SEGCHK
CMP AL,DH
JZ SEGCHK
MOV AL,CONST ;Check if the first operand is immediate
MOV CL MOV DH,25
CMP AL,BH ;Check if memory-to-memory
JZ MRERR
MOV AL,BH
CMP AL,REG ;Check if 8-bit operation
JNZ XRG
MOUNDEFID
CMP AL,DH ;Check if source is memory
JZ LOAD
CMP AL,BH ;Check if destination is memory
JZ STORE
MOV AL,XREG
ok for a comma and drop into GETOP
MOV AL,[SYM]
CMP AL,','
MOV CL,21
JNZ ERR1
GETOP:
CALL GETSYM
GETOP1:
;Enter AL,CH ;Or in to OP code
CALL PUT ;And write it
POP CX ;Dump return address
MOV AL,BL
ADD AL,AL ;Rotate register numND AL,1
OR AL,CH
POP CX ;Dump return address
JMP PUTADD ;Write the address
NOTAC:
MOV AL,BH
AND AL,1 ;Get byte/w,26
CMP AL,BH
JZ ERROR ;Error if so
POP CX ;Restore type flags
CMP AL,DH ;If second operand is immediate, then done
V DH,22
TEST CL,1 ;See if 8-bit operation is OK
JZ MRERR
XRG:
MOV AL,DL
SUB AL,6 ;Check for R/M mode 6 and register 0 here if we don't need a GETSYM first
CMP AL,'[' ;Memory reference?
JZ MEM
CMP AL,5 ;Flag ("B", "W", etc.)?
JZ FLG
Check for SI
MOV CL,4
JZ SIJ
DEC AL ;Check for DI
JZ DIJ
MOV CL,2 ;Invalid base/index register
ERR2: JMP ERROR
DIJ:SAHF
LAHF
XCHG AX,BP
SAHF
CALL GETSYM
OPERATE:
CMP AL,CONST
JNZ $+5
JMP CVAL
CMP AL,UNDEFID
JNZ $+5
JMP UVAZ PJ
LAHF
XCHG AX,BP
SAHF
MOV CH,0
RCR SI
TEST AL,010H ;Test INDEX bit
RCL SI
RCL AL ;BASE bit (zero flag not CALL GETSYM
MOV BX,[CON]
MOV [ADDR],BX
MOV BX,[UNDEF]
MOV [ALABEL],BX
MOV DL,CH
MOV DH,UNDEFID
MOV AL,DH
RET
Fr BX
SAHF
JP LPCHK
BPJ:
LAHF
XCHG AX,BP
SAHF
RCR SI
TEST AL,080H ;Check if already seen base register
RCL SI
MP AL,REG ;8-Bit register?
JZ NREG
CMP AL,XREG ;16-Bit register?
JZ NREG
CMP AL,SREG ;Segment register?
JZ NREG
VA
LAHF
XCHG AX,BP
SAHF
RCR SI
TEST AL,10H ;Check if already seen index register
RCL SI
JNZ ERR2
OR AL,30H ;FlagL
CMP AL,'"'
JNZ $+5
STRINGJ:JMP STRING
CMP AL,"'"
JZ STRINGJ
CMP AL,XREG ;Only 16-bit register may index
MOV CL,2affected)
JZ NOIND ;Jump if not indexed, with BASE bit in carry
CMC
RCL CH
RCL AL ;BP bit
RCL CH
RCL AL ;DI bit
LG:
CALL GETSYM
CMP AL,','
JZ GETOP
JP GETOP1
GETVAL:
LAHF
XCHG AX,BP
SAHF
PUSH BX
MOV BX,0
MOV [CON],B JNZ ERR2
OR AL,0C0H ;Flag seeing base register BP
LPCHK:
LAHF
XCHG AX,BP
SAHF
POP AX ;Get operator
XCHG AH,AL
L: ;Must be immediate
XOR AL,AL ;No addressing modes allowed
VAL1:
CALL GETVAL
MOV BX,[CON] ;Defined part
MOV [DATA seeing index register DI
JP LPCHK
SIJ:
LAHF
XCHG AX,BP
SAHF
RCR SI
TEST AL,010H ;Check if already seen index regi0
JNZ ERR2
LAHF
XCHG AX,BP
SAHF
RCR SI
TEST AL,1 ;Check to see if indexing is OK
RCL SI
MOV CL,1
JZ ERR2
LA RCL CH ;The low 3 bits now have indexing mode
MODE:
MOV BX,[UNDEF]
MOV AL,BH
OR AL,BL
LAHF
OR CH,080H ;If undefineX
MOV [UNDEF],BX
POP BX
MOV AL,[SYM]
CMP AL,'+'
JZ PLSMNS
CMP AL,'-'
JZ PLSMNS
MOV CH,'+'
PUSH CX
JP OPERATESAHF
CMP AL,'-' ;Can't subtract a register
MOV CL,5
JZ ERR2
NEXTER:
LAHF
XCHG AX,BP
SAHF
LAHF
OR AL,4 ;Flag t],BX
MOV BX,[UNDEF] ;Undefined part
MOV [DLABEL],BX
MOV DL,CH
MOV DH,CONST
MOV AL,DH
RET
NREG:
PUSH DX
CALL GETster
RCL SI
JNZ ERR2
LAHF
OR AL,010H ;Flag seeing index register SI
SAHF
JP LPCHK
BXJ:
LAHF
XCHG AX,BP
SAHF
HF
XCHG AX,BP
SAHF
MOV AL,DL
MOV CL,3
CMP AL,3 ;Check for BX
JZ BXJ
SUB AL,5 ;Check for BP
JZ BPJ
DEC AL ;Cd label, force 16-bit displacement
SAHF
JNZ RET
MOV BX,[CON]
CALL SIGNEXT ;Check if 8-bit with sign extended
JNZ RET
PLSMNS:
LAHF
XCHG AH,AL
PUSH AX
XCHG AH,AL
LAHF
XCHG AX,BP
SAHF
LAHF
OR AL,4 ;Flag that a sign was found
hat a term was processed
SAHF
LAHF
XCHG AX,BP
SAHF
CALL GETSYM
CMP AL,'+'
JNZ $+5
PJ: JMP PLSMNS
CMP AL,'-'
JSYM
POP DX
MOV AL,DH
RET
MEM:
CALL GETSYM
MOV AL,1
CALL GETVAL
MOV AL,[SYM]
CMP AL,']'
MOV CL,24
JNZ ERR1
RCR SI
TEST AL,080H ;Check if already seen base register
RCL SI
JNZ ERR2
LAHF
OR AL,080H ;Flag seeing base registe ;If not, use 16-bit displacement
LAHF
AND CH,07FH ;Reset 16-bit displacement
SAHF
LAHF
OR CH,040H ;Set 8-bit displaX],CONST
CALL READID
LAHF
DEC BX
SAHF
MOV AL,[BX]
MOV CL,7
MOV BX,0
CMP AL,'h'
JNZ $+5
JMP HEX
INC CL
MO only be added
MOV CL,5
ERR30: JNZ ERR3
JMP NEXTER
GETSYM:
CALL GETSY
MOV AL,[SYM]
RET
SCANB:
MOV AL,[CHR]
HL BX
SHL BX
ADD BL,AL
DEC CH
JNZ HEX1
XCHG DX,BX
RET
ERR4: JMP ERROR
GETLET:
CALL SCANB
CMP AL,EOL
STC
C CH ;If not, must be BX
JP MODE
CVAL:
MOV BX,[CON]
POP AX
XCHG AH,AL
SAHF
CMP AL,'-'
JNZ ADDCON
SBB BX,DX
AL,DL
CMP AL,EOL
MOV CL,39
JZ ERR3
CALL PUT
MOV AL,[DATSIZ]
OR AL,AL
JNZ BYTSIZ
MOV AL,DH
CALL PUT
BYTSIZ:
cement
SAHF
MOV AL,BH
OR AL,BL
JNZ RET ;Use it if not zero displacement
MOV AL,CH
AND AL,7 ;Specify no displacemenV [IX],ID
DEC:
MOV SI,[IX]
MOV AL,[SI]
INC [IX]
CMP AL,'9'+1
JC $+5
ERR3: JMP ERROR
SUB AL,'0'
MOV DX,BX
SHL B
SCANT:
CMP AL,' '
JZ NEXB
CMP AL,9
JNZ RET
NEXB:
CALL NEXTCHR
JP SCANT
DOLLAR:
MOV DX,[OLDPC]
MOV AL,CONST
JZ RET
CMP AL,';'
STC
JZ RET
MOV CL,10
OR AL,20H
CMP AL,'a'
JC ERR4
CMP AL,'z'+1
JNC ERR4
READID:
MOV BX,SETCON:
MOV [CON],BX
JMP NEXTER
ADDCON:
LAHF
ADD BX,DX
RCR SI
SAHF
RCL SI
JP SETCON
UVAL:
LAHF
XCHG AX,BMOV AL,[CHR]
MOV DL,AL
CALL GETCHR
JP STRGDAT
ZERLEN:
CALL NEXTCHR
CMP AL,CH
JNZ ERR3
RET
GETCHR:
CALL NEXTCHRt
MOV CH,AL
CMP AL,6 ;Check for BP+0 addressing mode
JNZ RET
LAHF
OR CH,040H ;If BP+0, use 8-bit displacement
SAHFX
SHL BX
ADD BX,DX
SHL BX
MOV DL,AL
MOV DH,0
ADD BX,DX
DEC CH
JNZ DEC
XCHG DX,BX
RET
STRING:
MOV CH,AL
MOV [SYM],AL
NEXTCHJ:
JMP NEXTCHR
GETSY:
CALL SCANB
CMP AL,'$'
JZ DOLLAR
MOV [SYM],AL
OR AL,20H
CMP AL,'z'+1ID
MOV CH,0
MOREID:
MOV [BX],AL
INC CH
LAHF
INC BX
SAHF
CALL NEXTCHR
CMP AL,'0'
JC NOMORE
OR AL,20H
CMP AP
SAHF
MOV CL,6
RCR SI
TEST AL,008H ;Check if undefined label has been seen
RCL SI
JNZ ERR30
LAHF
OR AL,008H ;
CMP AL,CH
JNZ RET
CALL NEXTCHR
CMP AL,CH
JZ RET
POP BX
JMP CVAL
HEX:
MOV DX,ID
DEC CH
HEX1:
MOV SI,DX
RET
SIGNEXT:
MOV AL,BH
OR AL,AL
JZ HIZERO
INC AL
JNZ RET
HIZERO:
MOV AL,BL
XOR AL,BH
AND AL,80H
RET
MOV AL,[CHR]
CMP AL,CH
MOV CL,35
MOV DL,AL
MOV DH,0
JNZ L0003
CALL ZERLEN
L0003:
CALL GETCHR
LAHF
XCHG AX,
JNC NEXTCHJ
CMP AL,'a'
JC $+5
JMP LETTER
CMP AL,'9'+1
JNC NEXTCHJ
CMP AL,'0'
JC NEXTCHJ
MOV BX,SYM
MOV B,[BL,'z'+1
JNC NOMORE
CMP AL,'9'+1
JC MOREID
CMP AL,'a'
JNC MOREID
NOMORE:
MOV CL,AL
MOV AL,CH
MOV [LENID],AL
ORFlag seeing undefined label
XCHG AX,BP
SAHF
MOV [UNDEF],BX
POP AX
XCHG AH,AL
SAHF
CMP AL,'+' ;Undefined label may LODB
INC DX
SUB AL,'0'
CMP AL,10
JC GOTIT
CMP AL,'g'-'0'
JNC ERR4
SUB AL,'a'-10-'0'
GOTIT:
SHL BX
SHL BX
SNOIND:
MOV CH,6 ;Try direct address mode
JNC RET ;If no base register, that's right
RCL AL ;Check BP bit
JC MODE
INBP
SAHF
MOV CL,37
TEST AL,002H
JZ ERR3
TEST AL,004H
MOV CL,38
JNZ ERR3
LAHF
XCHG AX,BP
SAHF
STRGDAT:
MOV AL,AL
MOV AL,CL
RET
LETTER:
CALL READID
MOV AL,CH
DEC AL
JNZ NOFLG
MOV AL,[ID]
CMP AL,'l'
MOV CL,0
MOV D080H
SAHF
MOV DX,RETSTR+2
CHKRET:
MOV SI,DX
LODB
CMP AL,[BX]
JNZ LOOKIT
LAHF
DEC BX
SAHF
LAHF
DEC DX
SA
SEGTAB: DB 'dsce'
LOOK:
MOV CH,[BX]
LAHF
INC BX
SAHF
MOV DX,ID
CALL CPSLP
JZ RET
XOR AL,80H
MOV CL,AL
LAV BX,[HEAP]
MOV DL,AL
MOV DH,0
SBB BX,DX ;Heap grows downward
MOV [HEAP],BX
XCHG DX,BX
MOV BX,[CODE] ;Check to make,REG
CMP AL,'l'
JZ SCANREG
MOV DL,4
CMP AL,'h'
JZ SCANREG
MOV DH,SREG
MOV DL,0
MOV BX,SEGTAB
CMP AL,'s'
JZ STER
MOV DX,4
LAHF
ADD BX,DX
RCR SI
SAHF
RCL SI
MOV AL,[BX]
OR AL,AL
JZ RET
LAHF
INC BX
SAHF
MOV DL,[BXX,LONG
JZ BWFLAG
CMP AL,'b'
MOV DX,FLAG
JZ BWFLAG
CMP AL,'w'
MOV CL,1
JZ BWFLAG
XOR AL,AL
NOFLG:
DEC AL
PUSHF
DEC CH
JNZ CHKRET
MOV DX,[LSTRET]
MOV AL,DL
AND AL,DH
INC AL
JZ ALLRET
MOV BX,[PC]
SBB BX,DX
CALL SIGNEXTHF
DEC BX
SAHF
MOV AL,[BX]
XOR AL,80H
CMP AL,CL
JNC SMALL
INC CH
INC CH
SMALL:
MOV DL,CH
MOV DH,0
LAHF
sure there's enough
SBB BX,DX
JB $+5
JMP ABORT
PUSH DX
MOV BX,LENID
MOV CL,[BX]
INC CL
MOV CH,0
UP
MOV SI,BCANREG
MOV DH,XREG
CMP AL,'p'
JZ PREG
CMP AL,'i'
JNZ RET
MOV DL,6
MOV AL,CL
CMP AL,'s'
JZ RET
INC DL
CMP A]
LAHF
INC BX
SAHF
MOV DH,[BX]
RET
ENTER:
PUSH BX ;Save pointer to link field
CALL CREATE ;Add the node
POPH BX
JNZ L0004
CALL REGCHK
L0004:
POP BX
MOV AL,DH
JZ SYMSAV
CALL LOOKRET
SYMSAV:
MOV [SYM],AL
RET
BWFLAG:
MOV AL,1
JZ RET
ALLRET:
MOV BX,[RETPT]
MOV AL,BH
OR AL,BL
MOV AL,0
JNZ RET
MOV BX,[HEAP]
LAHF
DEC BX
SAHADD BX,DX
RCR SI
SAHF
RCL SI
MOV DL,[BX]
LAHF
INC BX
SAHF
MOV DH,[BX]
MOV AL,DH
OR AL,DL
STC
JZ RET
XCX
MOV DI,DX
REP
MOVB ;Move identifier and length into node
MOV DX,DI
MOV BX,SI
MOV CH,4
XCHG DX,BX
NILIFY:
MOL,'d'
RET
PREG:
MOV DL,4
MOV AL,CL
CMP AL,'s'
JZ RET
INC DL
CMP AL,'b'
RET
SCANREG:
MOV AL,CL
MOV CX,4
U SI
XCHG SI,BX
PUSH SI
MOV [BX],DH ;Link new node
LAHF
DEC BX
SAHF
MOV [BX],DL
POP BX
RET ;Zero was set by
XCHG DX,BX
MOV AL,[BX]
INC AL
MOV [BX],CL
MOV CL,32
JZ $+5
JMP ERROR
MOV AL,5
JP SYMSAV
REGCHK:
MOV BX,IF
LAHF
DEC BX
SAHF
LAHF
DEC BX
SAHF
MOV [HEAP],BX
XOR AL,AL
MOV [BX],AL
MOV [RETPT],BX
RET
LOOKUP:
LAHG DX,BX
JP LOOK
LOOKRET:
MOV AL,CH
CMP AL,3 ;RET has 3 letters
JNZ LOOKUP
LAHF
DEC BX
SAHF
LAHF
OR B,[BX],V [BX],CL ;Zero left and right links
INC BX
DEC CH
JNZ NILIFY
XOR AL,AL ;Set zero flag
MOV [BX],AL ;Zero defined flP
MOV DI,BX
REPNZ
SCAB
MOV BX,DI
JNZ RET
MOV AL,CL
ADD AL,DL
MOV DL,AL
XOR AL,AL
RET
REGTAB: DB 'bdca'
CREATE
EMPTY:
CALL CREATE
MOV [BASE],DX
RET
CREATE:
MOV AL,[LENID]
ADD AL,8 ;Storage needed for the node
MOD
MOV CL,[BX]
LAHF
INC BX
SAHF
MOV AL,[BX]
MOV BX,REGTAB
MOV DH,XREG
MOV DL,0
CMP AL,'x'
JZ SCANREG
MOV DHHF
DEC BX
SAHF
LAHF
OR B,[BX],080H
SAHF
LOOKIT:
MOV BX,[BASE]
MOV AL,BH
OR AL,BL
JZ EMPTY
CALL LOOK
JC ENag
POP DX ;Restore pointer to node
RET
CPSLP:
MOV SI,DX
LODB
CMP AL,[BX]
LAHF
INC DX
INC BX
SAHF
JNZ RET6H
MOV AL,BH
CMP AL,UNDEFID
JNZ L0006
CALL STIMM
L0006:
AND AL,1
JZ BYTIMM
MOV AL,0B8H
OR AL,BL
CALL PUT
J INC CH
MOV CL,CH
MOV AL,[BX]
LAHF
INC BX
SAHF
OR AL,AL
JZ OPERR
FINDOP:
MOV CH,CL
LAHF
XCHG AX,BP
SAHF
,[CODE]
MOV [BX],AL
LAHF
INC BX
SAHF
MOV [CODE],BX
POP BX
RET
PUTWOR:
PUSH CX
MOV CH,80H
PUSH DX
PUSH B
LAHF
INC BX
SAHF
MOV [BX],DH
JMP GETLET
ERR5: JMP ERROR
ASMLIN:
MOV BX,[PC]
MOV [OLDPC],BX
CALL GETLAB
J ;Flag as pure code
CALL GEN
POP CX
POP BX
RET
GEN:
CALL PUTINC ;Save it and bump code pointer
GEN1:
MOV AL,[R
DEC CH
JNZ CPSLP
RET
GETLAB:
MOV BX,0
MOV [LABPT],BX
MOV AL,-1
MOV [FLAG],AL
MOV [LONG],AL
MOV DH,0
MOV MP PUTWOR
BYTIMM:
MOV AL,0B0H
OR AL,BL
CALL PUT
PUTBJ: JMP PUTBYT
IMMED:
MOV AL,BH
CMP AL,UNDEFID
JZ STIMM
MOV DX,ID+1
CALL CPSLP
JZ HAVOP
MOV DH,0
MOV DL,CH
INC DL
INC DL
LAHF
ADD BX,DX
RCR SI
SAHF
RCL SI
LAHFX
JP PUTBW
PUTBYT:
PUSH CX
MOV CH,40H
PUSH DX
PUSH BX
MOV BX,[DLABEL]
MOV AL,BH
OR AL,BL
JNZ PUTBW
MOV BXNC $+5
JMP ENDLN
MOV BX,LENID
MOV AL,[BX]
MOV CL,12
SUB AL,2
MOV CH,AL
JC ERR5
CMP AL,5
JNC ERR5
LAHF
INC ELOC]
RCL CH
RCL AL
RCL CH
RCL AL
MOV [RELOC],AL
MOV BX,BCOUNT
DEC B,[BX]
JNZ RET
MOV B,[BX],4
MOV BX,RELOC
AL,[CHR]
CMP AL,' '+1
JC NOT1
LAHF
OR DH,001H
SAHF
NOT1:
CALL GETLET
JC RET
CMP AL,':'
JNZ LABCHK
CALL NEXTMOV AL,BL
OR AL,AL
JZ RET
MOV AL,BH
CALL IMM
OR AL,0C0H
CALL PUT
FINIMM:
MOV AL,CL
POP CX
RCR SI
TEST AL,00
XCHG AX,BP
SAHF
DEC AL
JNZ FINDOP
OPERR:
MOV CL,12
JMP ERROR
HAVOP:
MOV DL,[BX]
LAHF
INC BX
SAHF
MOV ,[DATA]
OR AL,BH
JZ PUTBW
INC BH
JZ PUTBW
MOV CL,31
JMP ERROR
PUTBW:
MOV DX,[DLABEL]
MOV BX,[DATA]
PUTCHK:
MBX
SAHF
MOV AL,[BX]
SUB AL,'a'
MOV CL,AL
ADD AL,AL
ADD AL,AL
ADD AL,CL
ADD AL,CH
ADD AL,AL
MOV BX,OPTAB
MO
MOV AL,[BX]
MOV B,[BX],0
MOV DI,[IY]
MOV [DI],AL
MOV BX,[CODE]
PUSH BX
POP [IY]
LAHF
INC BX
SAHF
MOV [CODECHR
JP LABEL
LABCHK:
OR AL,AL
RCR SI
TEST DH,001H
RCL SI
JZ RET
LABEL:
MOV AL,[CHKLAB]
OR AL,AL
JZ $+5
JMP1H
RCL SI
JZ PUTBJ
CMP AL,83H
JZ PUTBJ
JMP PUTWOR
STIMM:
MOV AL,[FLAG]
CALL IMM
CALL PUTADD
JP FINIMM
IMDH,[BX]
LAHF
INC BX
SAHF
MOV AL,[BX] ;Get opcode
XCHG DX,BX
JMP BX
GRP1:
MOV CX,8A09H
CALL MROPS
MOV CX,0COV AL,DH
OR AL,DL
JZ NOUNDEF
MOV AL,DL
CALL PUTCD
MOV AL,DH
CALL PUTCD
MOV AL,BL
CALL PUTINC
MOV AL,BH
RCR SV DL,AL
MOV DH,0
LAHF
ADD BX,DX
RCR SI
SAHF
RCL SI
MOV DL,[BX]
LAHF
INC BX
SAHF
MOV DH,[BX]
XCHG DX,BX
],BX
RET
PUTINC:
PUSH BX
MOV BX,[PC]
LAHF
INC BX
SAHF
MOV [PC],BX
JP PUTCD1
PUTCD:
PUSH BX
PUTCD1: MOV BX GETLET
CALL LOOKUP
MOV CL,11
JNZ ERR5
MOV DX,[PC]
MOV B,[BX],1
LAHF
INC BX
SAHF
MOV [BX],DL
MOV [LABPT],BX
M:
AND AL,1
OR AL,CL
MOV CL,AL
CALL PUT
MOV AL,CH
AND AL,38H
OR AL,BL
RET
PUT:
PUSH BX
PUSH CX
MOV CH,0I
TEST CH,080H
RCL SI
JZ SMPUT
CALL GEN
JP PRET
SMPUT:
CALL PUTCD
CALL GEN1
PRET:
POP BX
POP DX
POP CX
RP4:
LAHF
XCHG AH,AL
PUSH AX
XCHG AH,AL
CALL GETOP
POP CX
CMP AL,CONST
JZ FIXED
SUB AL,XREG
DEC DL
DEC DL
L,CONST
CMP AL,BH
JZ ERR6
CMP AL,DH
JZ ERR6
MOV AL,UNDEFID
CMP AL,BH
JZ EXMEM
CMP AL,DH
JZ EXMEM1
MOV AL,BH
AL,DH
OR AL,DL
JNZ ACCJ
XCHG DX,BX
MOV BX,[DATA]
CALL SIGNEXT
XCHG DX,BX
JNZ ACCJ
LAHF
OR CL,002H
SAHF
ACCJether one- or two-byte displacement
TWOBT:
MOV BX,[ADDR]
MOV DX,[ALABEL]
JP PUTCHK
GRP2:
CALL GETOP
MOV CX,0FF30H
LAHF
ADD BX,DX
RCR SI
SAHF
RCL SI
MOV [PC],BX
XCHG DX,BX
MOV AL,-4
JP NEWLOC
EQU:
XCHG DX,BX
MOV BX,[LABPT]ET
NOUNDEF:
MOV AL,BL
MOV CL,BH
PUSH CX
MOV CH,0
CALL GEN
POP CX
MOV AL,CL
RCR SI
TEST CH,080H
RCL SI
M OR AL,DL
MOV CL,20
JNZ ERR6
MOV AL,CH
OR AL,8
JMP PUT
FIXED:
MOV AL,CH
CALL PUT
JMP PUTBYT
GRP5:
LAHF
X
CMP AL,DH
MOV CL,22
JNZ ERR6
CMP AL,XREG
JZ L0008
CALL RR1
L0008: ;RR1 never returns
MOV AL,BL
OR AL,AL
JZ : JMP ACCIMM
GRP8:
MOV CL,AL
MOV CH,0FEH
JP ONEOP
GRP9:
MOV CL,AL
MOV CH,0F6H
ONEOP:
PUSH CX
CALL GETOP
ONE:
CMP AL,UNDEFID
JZ PMEM
MOV CH,50H
CMP AL,XREG
JZ PXREG
MOV CH,6
CMP AL,SREG
JNZ $+5
JMP PACKREG
MOV CL,20
MOV AL,BH
OR AL,BL
MOV CL,34
JZ ERR7
MOV [BX],DL
LAHF
INC BX
SAHF
MOV [BX],DH
RET
ORG:
MOV [PC],BX
MOVOV CH,0
JZ PRETJ
CALL GEN
PRETJ: JP PRET
PUTADD:
PUSH CX
PUSH DX
PUSH BX
MOV CH,0
MOV CL,AL
CALL GEN ;Save CHG AH,AL
PUSH AX
XCHG AH,AL
CALL GETOP
CMP AL,CONST
JNZ ERR6
MOV BX,[DLABEL]
MOV AL,BH
OR AL,BL
MOV CL,30
JEXACC
XCHG DX,BX
MOV AL,BL
OR AL,AL
MOV AL,BH
JZ EXACC
CALL RR1
EXACC:
MOV AL,90H
OR AL,DL
JMP PUT
EXMEM:
MOV CL,26
CMP AL,CONST
JZ ERR7
CMP AL,SREG
MOV CL,22
JZ ERR7
POP CX
CMP AL,UNDEFID
JZ MOP
AND AL,1
JZ ROP
JMP ERROR
PMEM:
MOV AL,CH
CALL PUT
MOV AL,CL
OR AL,DL
JMP PUTADD
PXREG:
MOV AL,CH
OR AL,DL
JMP PUT
GRP3 AL,-2
NEWLOC:
CALL PUTCD
MOV AL,BL
CALL PUTCD
MOV AL,BH
CALL PUTCD
MOV CH,0C0H
JMP GEN1
GRP6:
MOV CH,AL
MOVthe addressing mode as pure code
MOV AL,CL
MOV CH,80H
AND AL,0C7H
CMP AL,6
JZ TWOBT ;Direct address?
AND AL,0C0H
NZ ERR6
MOV BX,[DATA]
POP AX
XCHG AH,AL
SAHF
OR AL,AL
JZ ORG
DEC AL
JZ DSJ
DEC AL
JZ EQU
DEC AL
JZ $+5
XCHG DX,BX
EXMEM1:
CMP AL,BH
JZ ERR6
MOV CL,1 ;Flag word as OK
CALL NOTAC ;NOTAC never returns
ERR6: JMP ERROR
GR RCR SI
TEST CL,001H
RCL SI
JZ ROP
MOV AL,CL
AND AL,0F8H
OR AL,DL
JMP PUT
MOP:
MOV AL,[FLAG]
AND AL,1
OR AL:
CALL GETOP
PUSH DX
CALL GETOP2
POP BX
MOV CX,8614H
MOV AL,SREG
CMP AL,BH
JZ ERR6
CMP AL,DH
JZ ERR6
MOV A CL,4
CALL MROPS
MOV CL,23
ERR7: JMP ERROR
GRP7:
MOV CH,AL
MOV CL,1
CALL MROPS
MOV CL,80H
MOV DX,[DLABEL]
MOV JZ PRET ;Indirect through reg, no displacement?
CMP AL,0C0H
JZ PRET ;Register to register operation?
MOV CH,AL ;Save wh JMP IF
PUTOP:
MOV AL,-3
JP NEWLOC
ALIGN:
MOV AL,[PC]
AND AL,1
JZ RET
MOV BX,1
DSJ:
XCHG DX,BX
MOV BX,[PC]
,CH
CALL PUT
MOV AL,CL
AND AL,38H
OR AL,DL
JMP PUTADD
ROP:
OR AL,CH
CALL PUT
MOV AL,CL
AND AL,38H
OR AL,0C0JMP PUTWOR
LONGJ:
POP AX
XCHG AH,AL
SAHF
CALL PUT
CALL PUTWOR
CALL GETOP
MOV CL,20
CMP AL,CONST
JNZ ERR8
JM,20
CMP AL,REG
JZ ERR8
CMP AL,SREG
JZ ERR8
CMP AL,XREG
JNZ NOTRG
OR DL,040H
OR DL,080H
NOTRG:
MOV AL,0FFH
CATA]
CALL SIGNEXT
JZ RET
MOV CL,31
ERR10: JMP ERROR
RET
GRP18:
CALL GETOP
CMP AL,CONST
MOV CL,20
JNZ ERR10
MUB AL,REG
MOV CL,20
DEC DL
OR AL,DL
JNZ ERR8
POP DX
MOV AL,DH
POP CX
LAHF
OR CH,002H
SAHF
PUSH CX
JMP ON
JP GETSP
NODEC:
MOV BX,[PC]
MOV [LSTRET],BX
XCHG DX,BX
MOV BX,[RETPT]
MOV AL,BH
OR AL,BL
JZ DORET
MOV B,[BX],H
OR AL,DL
JMP PUT
GRP10:
MOV CL,AL
MOV CH,0F6H
PUSH CX
CALL GETOP
MOV CL,20
MOV AL,DL
OR AL,AL
JNZ ERRJ1
P PUTWOR
GRP16:
LAHF
XCHG AH,AL
PUSH AX
XCHG AH,AL
CALL GETSYM
CMP AL,5
JZ LONGR
CMP AL,EOL
JZ NODEC
CMP ALALL PUT
POP AX
XCHG AH,AL
SAHF
AND AL,38H
OR AL,DL
MOV CH,AL
MOV AL,[LONG]
OR AL,AL
MOV AL,CH
JZ PUTADDJ
AOV BX,[DLABEL]
MOV AL,BH
OR AL,BL
JNZ GENINT
MOV BX,[DATA]
MOV DX,3
SBB BX,DX
JNZ GENINT
MOV AL,0CCH
JMP PUT
E
GRP13:
MOV CH,AL
MOV CL,1
CALL MROPS
MOV CL,80H
ACCIMM:
CALL IMMED
OR CH,004H
AND CH,0FDH
AIMM:
MOV AL,BH
1
LAHF
INC BX
SAHF
MOV [BX],DL
LAHF
INC BX
SAHF
MOV [BX],DH
MOV BX,0
MOV [RETPT],BX
DORET:
POP AX
XCHG MOV AL,DH
CMP AL,XREG
JZ G10
CMP AL,REG
ERRJ1: JNZ ERR8
G10:
LAHF
XCHG AH,AL
PUSH AX
XCHG AH,AL
CALL GETOP
,';'
JZ NODEC
GETSP:
CALL GETOP1
POP CX
CMP AL,CONST
MOV CL,20
JNZ ERR9
MOV AL,CH
AND AL,0FEH
CALL PUT
JMP ND AL,0F7H
PUTADDJ:
JMP PUTADD
DIRECT:
MOV AL,[SYM]
CMP AL,','
JZ LONGJ
POP AX
XCHG AH,AL
SAHF
DEC AL
CMP ALGENINT:
MOV AL,0CDH
CALL PUT
JMP PUTBYT
GRP19: ;ESC opcode
MOV CX,0D800H
JMP ONEOP
GRP20:
MOV CH,AL
MOV CL,1 AND AL,1
LAHF
XCHG AH,AL
PUSH AX
XCHG AH,AL
OR AL,CH
CALL PUT
POP AX
XCHG AH,AL
SAHF
JNZ $+5
JMP PUTBYT
AH,AL
SAHF
JMP PUT
GRP17:
CALL PUT
CALL GETOP
CMP AL,CONST
MOV CL,20
ERR9: JNZ ERR10
MOV BX,[DATA]
MOV DX,[PC]POP AX
XCHG AH,AL
SAHF
AND AL,1
MOV [FLAG],AL
MOV AL,DH
ONEJ: JP ONE
GRP11:
CALL PUT
MOV AL,0AH
JMP PUT
GRP12PUTWOR
LONGR:
MOV AL,[LONG]
OR AL,AL
JNZ NOTLON
POP AX
XCHG AH,AL
SAHF
OR AL,8
LAHF
XCHG AH,AL
PUSH AX
XC,0E9H
JZ GOTOP
MOV AL,0E8H
GOTOP:
CALL PUT
MOV BX,[DATA]
MOV DX,[PC]
INC DX
INC DX
SUB BX,DX
MOV [DATA],BX
CALL MROPS
MOV CL,0F6H
CALL IMMED
MOV CH,0A8H
JMP AIMM
GRP21:
CALL GETOP
CMP AL,SREG
MOV CL,28
JNZ ERR10
M JMP PUTWOR
ERR8: JMP ERROR
GRP14:
LAHF
XCHG AH,AL
PUSH AX
XCHG AH,AL
CALL GETOP
CMP AL,CONST
JZ DIRECT
MOV CL
LAHF
INC DX
SAHF
SBB BX,DX
MOV [DATA],BX
CALL PUTBYT
MOV BX,[DLABEL]
MOV AL,BH
OR AL,BL
JNZ RET
MOV BX,[D:
MOV CL,AL
MOV CH,0D0H
PUSH CX
CALL GETOP
MOV AL,[SYM]
CMP AL,','
MOV AL,DH
JNZ ONEJ
PUSH DX
CALL GETOP
SHG AH,AL
NOTLON:
CALL GETSYM
CMP AL,EOL
JZ DORET
CMP AL,';'
JZ DORET
CMP AL,','
JNZ L0011
CALL GETSYM
L0011:
OV CH,26H
PACKREG:
MOV AL,DL
ADD AL,AL
ADD AL,AL
ADD AL,AL
OR AL,CH
JMP PUT
GRP22:
CALL GETOP
MOV CX,8F00H
CNEXT RECORD field to zero
MOV [COUNT],AL
CALL STRTLIN
MOV BX,START
NEXBT:
MOV CH,4
MOV CL,[BX] ;Get flag byte
LAHF***
END:
MOV CL,4
WREND:
MOV CH,0FFH
MOV AL,CH
CALL GEN
DEC CL
JNZ WREND
MOV AL,[LSTFCB]
CMP AL,'Z'
JZ NOR CALL CONV10
CALL PRNT10
CRLF:
MOV AL,13
CALL LIST
MOV AL,10
JMP LIST
DEFBYT:
CALL FIXUP
XCHG DX,BX
CALL SIG [IFFLG],AL
RET
SKIPCD:
MOV [CHKLAB],AL
SKIPLP:
XOR AL,AL
CALL NEXLIN
CALL NEXTCHR
CMP AL,1AH
JZ END
CALL GELL LIST
CALL LIST
CALL LIST
DEC CH
JNZ BLNK
NOFIL:
CALL OUTLIN
POP BX
MOV AL,[BX]
PUSH BX
CALL REPERR
MOV AMP AL,UNDEFID
JNZ $+5
JMP PMEM
MOV CH,58H
CMP AL,XREG
JNZ $+5
JMP PXREG
MOV CH,7
CMP AL,SREG
JZ PACKREG
MOV
INC BX ;Point to code
SAHF
CDLP:
RCL CL ;Get high bit
JC TESTTYP ;Word fixup or special
RCL CL
JNC $+5
JMP DEEOPN
CALL ADDEXT
MOV DX,FCB
MOV CL,OPEN
CALL SYSTEM
MOV BX,0FFH
XCHG BX,[HL]
XCHG DX,[DE]
XCHG CX,[BC]
NOREOPN:NEXT ;See if in range +127 to -128
XCHG DX,BX
JZ OBJBTE ;If so, it's always OK
MOV AL,DH
OR AL,AL ;Check for range +2TLAB
JC SKIPLP
MOV BX,LENID
MOV DX,IFEND
MOV CH,[BX]
INC CH
CALL CPSLP
JNZ SKIPLP
XOR AL,AL
MOV [CHKLAB],AL
L,[ERR]
CALL REPERR
CALL STRTLIN
POP BX
POP CX
JP NEXCD
OUTLIN:
CALL LIST
MOV AL,[LSTFCB]
CMP AL,'Z'
JZ RETCL,20
ERR11: JMP ERROR
GRP23:
MOV [DATSIZ],AL
GETDAT:
CALL GETSYM
MOV AL,2
CALL VAL1
MOV AL,[SYM]
CMP AL,','
MOFBYT ;Byte fixup
MOV AL,[BX]
OBJBT:
CALL SAVCD
NEXCD:
INC BX
DEC CH ;Still have codes left?
JNZ CDLP
JP NEXBT
T
MOV AL,-5
MOV [HEXCNT],AL ;FLAG HEX BUFFER AS EMPTY
MOV [SKPFLG],AL
MOV BX,HEXBUF
MOV [HEXPNT],BX
MOV BX,LSTBUF
M55 to -256
JZ CHKJMP
INC AL
JZ CHKJMP
RNGERR:
MOV AL,101 ;Value out of range
MOV [ERR],AL
OBJBTE:
MOV AL,DL
JMPRET
ENDIF:
MOV BX,IFFLG
MOV AL,[BX]
MOV B,[BX],0
MOV CL,36
OR AL,AL
JZ ERR11
RET
;**************************
MOV BX,LINFLG
MOV AL,[BX]
MOV B,[BX],-1
OR AL,AL
JNZ CRLF ;Output line only if first time
OUTLN:
CALL NEXTCHR
CV AL,[DATSIZ]
JNZ ENDDAT
CALL SAVDAT
JP GETDAT
ENDDAT:
CMP AL,2
JNZ SAVDAT
MOV BX,[DATA]
LAHF
OR BL,080H
SAHFESTTYP:
RCL CL
JC $+5
JMP DEFWRD
MOV AL,[BX]
CMP AL,-10
JC $+5
JMP SPCFUN
PUSH CX
PUSH BX
MOV BX,COUNT
MOVOV [LSTPNT],BX
MOV BX,0
MOV [ERRCNT],BX
MOV [PC],BX
MOV BX,OBJECT
MOV [HEXADD],BX
XOR AL,AL
MOV [FCB+20H],AL ;Set OBJBT
CHKJMP:
;Check for short jump. If so, we're out of range; otherwise we're OK
MOV AL,[COUNT]
DEC AL ;Only one other*******************************************
;
; PASS 2
;
;******************************************************************ALL LIST
CMP AL,10 ;Output until linefeed found
JNZ OUTLN
RET
PRTCNT:
MOV BX,ERCNTM
CALL PRINT
MOV BX,[ERRCNT]
MOV [DATA],BX
SAVDAT:
OR AL,AL
JZ $+5
JMP PUTBYT
JMP PUTWOR
IF:
MOV AL,BH
OR AL,BL
MOV AL,1
JZ SKIPCD
MOV AL,6
SUB AL,[BX]
MOV B,[BX],0
MOV CH,AL
MOV AL,' '
JZ NOFIL
BLNK: ;Put in 3 blanks for each byte not present
CA byte on line?
JNZ OBJBTE ;Can't be short jump if not
MOV AL,[PREV] ;Get the first byte of this line
CMP AL,0EBH ;DirectCHG AH,AL
CALL OUTA
POP AX
XCHG AH,AL
SAHF
RET
PHEX:
MOV CH,AL
CALL UHALF
CALL LIST
MOV AL,CH
CALL LHALF
TFCB]
CMP AL,'Z'
JZ OUTRET
CMP AL,'X'
JZ LSTCON
POP AX
XCHG AH,AL
SAHF
LAHF
XCHG AH,AL
PUSH AX
XCHG AH,AL
BX,[HEAP]
MOV SP,BX
CALL NODE
ENDSYM:
MOV AL,[LSTFCB]
CMP AL,'X'
JZ EXIT
CMP AL,'Z'
JZ ERRCON ;Print error countX,BX
MOV DL,[BX] ;Get constant part
LAHF
INC BX
SAHF
MOV DH,[BX]
XCHG DX,BX
LAHF
ADD BX,CX ;Add symbol value t
POP BX
JMP NEXCD
FINI:
CALL PRTCNT
MOV AL,[HEXFCB]
CMP AL,'Z'
JZ SYMDMP
MOV AL,[HEXCNT]
CMP AL,-5
JZ L0012
short jump?
JZ RNGERR
AND AL,0FCH
CMP AL,0E0H ;LOOP or JCXZ instruction?
JZ RNGERR
AND AL,0F0H
CMP AL,70H ;Condit
JMP LIST
SPCFUN:
INC AL ;End of file?
JZ FINI
LAHF
INC BX
SAHF
MOV DL,[BX] ;Get address
LAHF
INC BX
SAH
AND AL,7FH
PUSH BX
MOV BX,[LSTPNT]
MOV [BX],AL
CALL INCBUF
MOV [LSTPNT],BX
JNZ HAVSPC
MOV BX,LSTBUF
MOV [LSTPN to console
CALL LSTEOF
MOV DX,LSTFCB
MOV CL,CLOSE
CALL 5
ERRCON:
MOV AL,'X'
MOV [LSTFCB],AL
CALL PRTCNT
EXIT: Jo constant part
RCR SI
SAHF
RCL SI
POP CX
XCHG DX,BX
OR AL,AL ;See if symbol got defined
JNZ RET
MOV AL,100 ;U
CALL ENHEXL
L0012:
MOV AL,':'
CALL PUTCHR
MOV CH,10
HEXEND:
PUSH CX
MOV AL,'0'
CALL PUTCHR
POP CX
DEC CH
ional jump?
JZ RNGERR
JP OBJBTE
DEFWRD:
CALL FIXUP
MOV AL,DL
CALL SAVCD
MOV AL,DH
JMP OBJBT
FIXUP:
PUSH CXF
MOV DH,[BX]
PUSH BX
INC AL ;ORG?
JZ DORG
INC AL ;PUT?
JZ DPUT
DDS:
;Handle DS pseudo-op
MOV BX,[PC]
LAHF
T],BX
PUSH DX
XCHG DX,BX
PUSH CX
MOV CL,SETDMA
CALL 5
MOV DX,LSTFCB
MOV CL,SEQWRT
CALL 5
POP CX
POP DX
HAVSMP 0
RET
LSTEOF:
MOV AX,[LSTPNT]
CMP AX,LSTBUF
JZ RET
MOV AL,1AH
CALL LIST
JP LSTEOF
NODE:
XCHG DX,BX
PUSHndefined - flag error
MOV [ERR],AL
MOV DX,0
RET
STRTLIN:
XOR AL,AL
MOV [ERR],AL
MOV [LINFLG],AL
MOV BX,[PC]
MJNZ HEXEND
CALL HEXCRLF
JZ L0013
CALL HEXEOF
L0013:
CALL HEXEOF
MOV CL,CLOSE
MOV DX,HEXFCB
CALL SYSTEM
SYMDMP:
MOV DL,[BX] ;Get pointer to symbol
LAHF
INC BX
SAHF
MOV DH,[BX]
LAHF
INC BX
SAHF
XCHG DX,BX
MOV AL,[BX] ; ADD BX,DX
RCR SI
SAHF
RCL SI
MOV [PC],BX
MOV BX,[HEXADD]
LAHF
ADD BX,DX
RCR SI
SAHF
RCL SI
MOV [HEXADD],BPC:
POP BX
OUTRET:
POP AX
XCHG AH,AL
SAHF
RET
LSTCON:
POP AX
XCHG AH,AL
SAHF
LAHF
XCHG AH,AL
PUSH AX
X BX
MOV DL,[BX]
MOV DH,0
LAHF
INC BX
SAHF
LAHF
ADD BX,DX
RCR SI
SAHF
RCL SI
MOV DL,[BX]
LAHF
INC BX
OV AL,BH
CALL PHEX
MOV AL,BL
PHEXB:
CALL PHEX
MOV AL,' '
LIST:
LAHF
XCHG AH,AL
PUSH AX
XCHG AH,AL
MOV AL,[LS
MOV AL,[SYMFLG]
CMP AL,'S'
JNZ ENDSYM
MOV BX,SYMMES
CALL PRINT
MOV DX,[BASE]
MOV AL,DH
OR AL,DL
JZ EXIT
MOV Whether symbol was defined
LAHF
INC BX
SAHF
MOV CL,[BX] ;Get symbol value
LAHF
INC BX
SAHF
MOV CH,[BX]
XCHG DX
JP SPEND
DPUT:
;Handle PUT pseudo-op
MOV [HEXADD],DX
JP SPEND
DORG:
;Handle ORG pseudo-op
MOV [PC],DX
SPEND:
SAHF
MOV DH,[BX]
MOV AL,DL
OR AL,DH
JZ L0014
CALL NODE
L0014:
POP BX
MOV CH,[BX]
LAHF
INC BX
SAHF
MOV ALXT:
POP AX
XCHG AH,AL
SAHF
CALL PHEXB
POP CX
MOV BX,[PC]
LAHF
INC BX
SAHF
MOV [PC],BX
MOV BX,[HEXADD]
LA'
JZ SUPZ
MOV CH,0 ;Turn off zero suppression if not zero
SUPZ:
SUB AL,CH ;Convert leading zeros to blanks
JMP LIST
XCHG AH,AL
SAHF
HEXBYT:
MOV CH,AL
MOV BX,CHKSUM
ADD AL,[BX]
MOV [BX],AL
MOV AL,CH
CALL UHALF
CALL PUTCHR
MOV MOV AL,DH
OR AL,DL
JNZ NODE
RET
CONV10:
MOV CH,16
MOV DX,0
CONVLP:
LAHF
ADD BX,BX
RCR SI
SAHF
RCL SI
XCHG AH,AL
PUSH AX
XCHG AH,AL
MOV AL,[HEXFCB]
CMP AL,'Z'
JNZ $+5
JMP OUTRET
MOV DX,[LASTAD]
MOV BX,[HEXADD]
M,SYMWID
SUB AL,CH
JNC LENOK
MOV AL,1
LENOK:
MOV DH,AL
WRTSYM:
MOV AL,[BX]
LAHF
INC BX
SAHF
CALL LIST
DEC CHF
INC BX
SAHF
MOV [HEXADD],BX
POP BX
RET
REPERR:
OR AL,AL
JZ RET
LAHF
XCHG AH,AL
PUSH AX
XCHG AH,AL
HIDIG:
CALL UHALF
JP DIGIT
HEXEOF:
MOV AL,1AH
CALL PUTCHR
JNZ HEXEOF
RET
SAVCD:
MOV [PREV],AL
PUSH BX
AL,CH
CALL LHALF
CALL PUTCHR
MOV BX,HEXCNT
INC B,[BX]
MOV AL,[BX]
CMP AL,26
JNZ RET
ENHEXL:
MOV BX,[HEXLEN]
MOV AL,DL
ADC AL,AL
DAA
MOV DL,AL
MOV AL,DH
ADC AL,AL
DAA
MOV DH,AL
RCL CL
DEC CH
JNZ CONVLP
RET
PRNT10OV [LASTAD],BX
LAHF
INC DX
SAHF
MOV AL,[HEXCNT]
CMP AL,-5
JZ NEWLIN
OR AL,AL
SBB BX,DX
JZ AFHEX
CALL ENHEXL
H
JNZ WRTSYM
MOV CH,DH
INC CH
MOV AL,' '
OUTB:
CALL LIST
DEC CH
JNZ OUTB
LAHF
INC BX
SAHF
LAHF
INC BX
MOV BX,ERRMES
CALL PRINT
POP AX
XCHG AH,AL
SAHF
CALL PHEX
MOV BX,ENDMES
CALL PRINT
MOV BX,[ERRCNT]
LAHF
INC PUSH CX
LAHF
XCHG AH,AL
PUSH AX
XCHG AH,AL
PUSH DX
CALL CODBYT
POP DX
MOV BX,COUNT
INC B,[BX]
MOV AL,[BX]
MOV CH,AL
CALL UHALF
MOV [BX],AL
CALL INCBUF
MOV AL,CH
CALL LHALF
MOV [BX],AL
MOV AL,-6
MOV [HEXCNT],AL
MOV AL:
XCHG DX,BX
MOV CH,'0'-' ' ;Enable leading zero suppression
MOV AL,CL
CALL LODIG
MOV AL,BH
CALL HIDIG
MOV AL,BH
NEWLIN:
MOV AL,':'
CALL PUTCHR
MOV AL,-4
MOV [HEXCNT],AL
XOR AL,AL
MOV [CHKSUM],AL
MOV BX,[HEXPNT]
MOV [HEXLEN] SAHF
PUSH BX
LAHF
INC BX
SAHF
LAHF
INC BX
SAHF
LAHF
INC BX
SAHF
LAHF
INC BX
SAHF
MOV AL,[BX]
CALLBX
SAHF
MOV [ERRCNT],BX
RET
PRINT:
MOV AL,[BX]
CALL LIST
OR AL,AL
JS RET
LAHF
INC BX
SAHF
JP PRINT
OCMP AL,7
JNZ NOEXT
MOV B,[BX],1
MOV AL,' '
CALL OUTLIN
MOV AL,' '
MOV CH,5
TAB:
CALL LIST
DEC CH
JNZ TAB
NOE,[CHKSUM]
ADD AL,CH
NEG AL
CALL HEXBYT
HEXCRLF:
MOV AL,13
CALL PUTCHR
MOV AL,10
PUTCHR:
MOV BX,[HEXPNT]
MO CALL LODIG
MOV AL,BL
CALL HIDIG
MOV AL,BL
MOV CH,0 ;Don't suppress last digit
LODIG:
CALL LHALF
DIGIT:
CMP AL,'0,BX
CALL HEXBYT
MOV AL,[HEXADD+1]
CALL HEXBYT
MOV AL,[HEXADD]
CALL HEXBYT
XOR AL,AL
CALL HEXBYT
AFHEX:
POP AX
PHEX
LAHF
DEC BX
SAHF
MOV AL,[BX]
CALL PHEX
CALL CRLF
POP BX
MOV DL,[BX]
LAHF
INC BX
SAHF
MOV DH,[BX]
UTA:
MOV DL,AL
MOV CL,2
SYSTEM:
PUSH CX
PUSH DX
PUSH BX
CALL 5
POP BX
POP DX
POP CX
RET
CODBYT:
LAHF
V [BX],AL
CALL INCBUF
MOV [HEXPNT],BX
JNZ RET
PUSH BX
MOV BX,SKPFLG
MOV AL,[BX]
MOV B,[BX],0 ;Buffer filled, don'tW GRP19
DB 0D8H
DB 'nd'
DW END
DB 0
E5:
DB 1
DB 'ndif'
DW ENDIF
DB 0
H3:
DB 1
DB 'lt'
DW PUT
DB 0F4H
C4:
DB 3
DB 'all'
DW GRP14
DB 9AH
DB 'mpb'
DW PUT
DB 0A6H
DB 'mpw'
DW PUT
DB 0A7H
D2:
DB 5
DB 'b'
DDB 'be'
DW GRP17
DB 76H
DB 'pe'
DW GRP17
DB 7AH
DB 'np'
DW GRP17
DB 7BH
DB 'po'
DW GRP17
DB 7BH
DB 'no'
NONE: DB 0
; 8086 MNEMONIC TABLE
A3:
DB 7
DB 'dd'
DW GRP7
DB 2
DB 'nd'
DW GRP13
DB 22H
DB 'dc'
DW GR
DW GRP17
DB 72H
DB 'a'
DW GRP17
DB 77H
DB 'g'
DW GRP17
DB 7FH
DB 'o'
DW GRP17
DB 70H
DB 's'
DW GRP17
skip next time
POP BX
OR AL,AL ;Both buffers filled?
JNZ RET
MOV CL,SETDMA
XCHG DX,BX
CALL SYSTEM
MOV DX,HEXFCB
H4:
DB 1
DB 'alt'
DW PUT
DB 0F4H
I2:
DB 2
DB 'n'
DW GRP4
DB 0E4H
DB 'f'
DW GRP5
DB 4
I3:
DB 4
DB 'ncW GRP23
DB 1
DB 'w'
DW GRP23
DB 0
DB 'm'
DW GRP23
DB 2
DB 's'
DW GRP5
DB 1
DB 'i'
DW PUT
DB 0FAH
D3:
DW GRP17
DB 71H
DB 'ns'
DW GRP17
DB 79H
J4:
DB 5
DB 'cxz'
DW GRP17
DB 0E3H
DB 'nge'
DW GRP17
DB 7CH
DP7
DB 12H
DB 'aa'
DW PUT
DB 37H
DB 'as'
DW PUT
DB 3FH
DB 'am'
DW GRP11
DB 0D4H
DB 'ad'
DW GRP11
DB 0D5
DB 78H
DB 'c'
DW GRP17
DB 72H
J3:
DB 17
DB 'mp'
DW GRP14
DB 0EAH
DB 'nz'
DW GRP17
DB 75H
DB 'ne'
DW G
MOV CL,SEQWRT
CALL SYSTEM
XCHG DX,BX
OR AL,AL
JZ RET
MOV BX,WRTERR
JMP PRERR
UHALF:
RCR AL
RCR AL
RCR AL
'
DW GRP8
DB 41H
DB 'nb'
DW GRP4
DB 0E4H
DB 'nw'
DW GRP4
DB 0E5H
DB 'nt'
DW GRP18
DB 0CCH
I4:
DB 4
DB
DB 4
DB 'ec'
DW GRP8
DB 49H
DB 'iv'
DW GRP10
DB 30H
DB 'aa'
DW PUT
DB 27H
DB 'as'
DW PUT
DB 2FH
D4:
B 'nae'
DW GRP17
DB 72H
DB 'nbe'
DW GRP17
DB 77H
DB 'nle'
DW GRP17
DB 7FH
L3:
DB 3
DB 'ea'
DW GRP6
DB 8H
A5:
DB 1
DB 'lign'
DW ALIGN
DB 0
C3:
DB 7
DB 'mp'
DW GRP7
DB 3AH
DB 'lc'
DW PUT
DB 0F8H
DB 'ld'
DWRP17
DB 75H
DB 'nl'
DW GRP17
DB 7DH
DB 'ge'
DW GRP17
DB 7DH
DB 'nb'
DW GRP17
DB 73H
DB 'ae'
DW GRP17
D
RCR AL
LHALF:
AND AL,0FH
OR AL,30H
CMP AL,'9'+1
JC RET
ADD AL,7
RET
INCBUF:
INC BX
CMP BX,HEXBUF+BUFSIZ
'mul'
DW GRP10
DB 28H
DB 'div'
DW GRP10
DB 38H
DB 'ret'
DW PUT
DB 0CFH
DB 'nto'
DW PUT
DB 0CEH
J2:
DB DB 1
DB 'own'
DW PUT
DB 0FDH
E2:
DB 1
DB 'i'
DW PUT
DB 0FBH
E3:
DB 3
DB 'qu'
DW GRP5
DB 2
DB 'sc'
DDH
DB 'ds'
DW GRP6
DB 0C5H
DB 'es'
DW GRP6
DB 0C4H
L4:
DB 5
DB 'oop'
DW GRP17
DB 0E2H
DB 'odb'
DW PUT
PUT
DB 0FCH
DB 'li'
DW PUT
DB 0FAH
DB 'mc'
DW PUT
DB 0F5H
DB 'bw'
DW PUT
DB 98H
DB 'wd'
DW PUT
DB 99HB 73H
DB 'nc'
DW GRP17
DB 73H
DB 'ng'
DW GRP17
DB 7EH
DB 'le'
DW GRP17
DB 7EH
DB 'na'
DW GRP17
DB 76H
JZ RET
CMP BX,LSTBUF+BUFSIZ
JZ RET
CMP BX,HEXBUF+BUFSIZ+BUFSIZ
JNZ RET
MOV BX,HEXBUF ;Wrap back to first buffer
RET10
DB 'p'
DW GRP17
DB 0EBH
DB 'z'
DW GRP17
DB 74H
DB 'e'
DW GRP17
DB 74H
DB 'l'
DW GRP17
DB 7CH
DB 'b' DB 0ACH
DB 'odw'
DW PUT
DB 0ADH
DB 'ahf'
DW PUT
DB 9FH
DB 'ock'
DW PUT
DB 0F0H
L5:
DB 2
DB 'oope'
DW GBH
DB 'ahf'
DW PUT
DB 9EH
T4:
DB 1
DB 'est'
DW GRP20
DB 84H
U2:
DB 1
DB 'p'
DW PUT
DB 0FCH
W4:
DB 1
PUT
DB 0F2H
DB 'epne'
DW PUT
DB 0F2H
S3:
DB 11
DB 'ub'
DW GRP7
DB 2AH
DB 'bb'
DW GRP7
DB 1AH
DB 'bc'
R5
DW NONE
DW NONE ;S
DW S3
DW S4
DW NONE
DW NONE
DW NONE ;T
DW NONE
DW T4
DW NONE
DW NONE
DW U2 ;U
DW
DB 0E6H
DB 'utw'
DW GRP4
DB 0E7H
P3:
DB 2
DB 'op'
DW GRP22
DB 8FH
DB 'ut'
DW GRP5
DB 3
P4:
DB 2
DB ';H
DW H3
DW H4
DW NONE
DW NONE
DW I2 ;I
DW I3
DW I4
DW NONE
DW NONE
DW J2 ;J
DW J3
DW J4
DW NONE
DW RP17
DB 0E1H
DB 'oopz'
DW GRP17
DB 0E1H
L6:
DB 2
DB 'oopne'
DW GRP17
DB 0E0H
DB 'oopnz'
DW GRP17
DB 0E0H
DB 'ait'
DW PUT
DB 9BH
X3:
DB 1
DB 'or'
DW GRP13
DB 32H
X4:
DB 2
DB 'chg'
DW GRP3
DB 86H
DB 'lat'
DW DW GRP7
DB 1AH
DB 'tc'
DW PUT
DB 0F9H
DB 'td'
DW PUT
DB 0FDH
DB 'ti'
DW PUT
DB 0FBH
DB 'hl'
DW GRP12
NONE
DW NONE
DW NONE
DW NONE
DW NONE ;V
DW NONE
DW NONE
DW NONE
DW NONE
DW NONE ;W
DW NONE
DW W4
DW NONush'
DW GRP2
DB 0FFH
DB 'opf'
DW PUT
DB 9DH
P5:
DB 1
DB 'ushf'
DW PUT
DB 9CH
R3:
DB 6
DB 'et'
DW GRP16NONE
DW NONE ;K
DW NONE
DW NONE
DW NONE
DW NONE
DW NONE ;L
DW L3
DW L4
DW L5
DW L6
DW NONE ;M
DW M3
DW
M3:
DB 2
DB 'ov'
DW GRP1
DB 88H
DB 'ul'
DW GRP10
DB 20H
M4:
DB 2
DB 'ovb'
DW PUT
DB 0A4H
DB 'ovw'
DWPUT
DB 0D7H
OPTAB:
DW NONE
DW A3
DW NONE
DW A5
DW NONE
DW NONE ;B
DW NONE
DW NONE
DW NONE
DW NONE
DDB 20H
DB 'hr'
DW GRP12
DB 28H
DB 'al'
DW GRP12
DB 20H
DB 'ar'
DW GRP12
DB 38H
DB 'eg'
DW GRP21
DB 26H
E
DW NONE
DW NONE ;X
DW X3
DW X4
DW NONE
DW NONE
DW NONE ;Y
DW NONE
DW NONE
DW NONE
DW NONE
DW NONE ;Z
DB 0C3H
DB 'ep'
DW PUT
DB 0F3H
DB 'ol'
DW GRP12
DB 0
DB 'or'
DW GRP12
DB 8
DB 'cl'
DW GRP12
DB 10H
M4
DW NONE
DW NONE
DW NONE ;N
DW N3
DW NONE
DW NONE
DW NONE
DW O2 ;O
DW O3
DW O4
DW NONE
DW NONE
DW N PUT
DB 0A5H
N3:
DB 3
DB 'ot'
DW GRP9
DB 10H
DB 'eg'
DW GRP9
DB 18H
DB 'op'
DW PUT
DB 90H
O2:
DB 1
DW NONE ;C
DW C3
DW C4
DW NONE
DW NONE
DW D2 ;D
DW D3
DW D4
DW NONE
DW NONE
DW E2 ;E
DW E3
DW NONE
DW ES4:
DB 5
DB 'cab'
DW PUT
DB 0AEH
DB 'caw'
DW PUT
DB 0AFH
DB 'tob'
DW PUT
DB 0AAH
DB 'tow'
DW PUT
DB 0A DW NONE
DW NONE
DW NONE
DW NONE
HEADER: DB 13,10,'Seattle Computer Products 8086 Assembler Version 2.00'
DB 13,10,'$DB 'cr'
DW GRP12
DB 18H
R4:
DB 2
DB 'epz'
DW PUT
DB 0F3H
DB 'epe'
DW PUT
DB 0F3H
R5:
DB 2
DB 'epnz'
DWONE ;P
DW P3
DW P4
DW P5
DW NONE
DW NONE ;Q
DW NONE
DW NONE
DW NONE
DW NONE
DW NONE ;R
DW R3
DW R4
DW B 'r'
DW GRP13
DB 0AH
O3:
DB 2
DB 'ut'
DW GRP4
DB 0E6H
DB 'rg'
DW GRP5
DB 0
O4:
DB 2
DB 'utb'
DW GRP4
5
DW NONE
DW NONE ;F
DW NONE
DW NONE
DW NONE
DW NONE
DW NONE ;G
DW NONE
DW NONE
DW NONE
DW NONE
DW NONE '
ERRMES: DM '***** ERROR no. '
NOSPAC: DB 13,10,'No directory space',13,10,24H
ENDMES: DM 'H',13,10
NOMEM: DB 13,10,'Insuff邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋
STACK: EQU $
START: EQU $
U 0
TARBELLDOUBLE: EQU 0
LOAD: EQU 400H ;Address to load program
SEG: EQU 40H ;LOAD/10H
SECTOR: EQU 51 ;No. of 128-byte seS 2
DLABEL: DS 2
CON: DS 2
UNDEF: DS 2
LENID: DS 1
ID: DS 80
CHR: DS 1
SYM: DS 1
BASE: DS 2
HEAP: DS 2
SYMFLG: DS 1
Cize of
;program at any address. The program is assumed to
;occupy consecutive sectors starting at track 0, sector
;2, and wiicient memory',13,10,'$'
NOFILE: DB 13,10,'File not found',13,10,'$'
WRTERR: DB 13,10,'Disk write error',13,10,'$'
BADDSK: DB邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋ctors to load
BOOTER: EQU 200H ;"B" command puts booter here
;**************************************************************ODE: DS 2
DATSIZ: DS 1
RELOC: DS 1
BCOUNT: DS 1
COUNT: DS 1
ERR: DS 1
HEXPNT: DS 2
HEXLEN: DS 2
HEXADD: DS 2
LASTAD: DSll begin exection at its load address (which
;must be a 16-byte boundary) with the Instruction
;Pointer set to zero.
; Vari 13,10,'Bad disk specifier',13,10,'$'
ERCNTM: DM 13,10,13,10,'Error Count ='
SYMMES: DM 13,10,'Symbol Table',13,10,13,10
EXTE邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋
CROMEMCO: EQU CROMEMCOLARGE+CROMEMCOSMALL
TARBELL: EQU TARBELLSINGLE+TARBELLDOUBLE
WD1771: EQU CROMEMCO+TARBELLSINGLE
W 2
HEXCNT: DS 1
CHKSUM: DS 1
SKPFLG: DS 1
LINFLG: DS 1
PREV: DS 1
IFFLG: DS 1
CHKLAB: DS 1
LSTPNT: DS 2
ERRCNT: DS 2
Lations are available for the Cromemco 4FDC with
; large disks, the 4FDC with small disks, the Tarbell
; single-density controlND: DB 'ASM',0,0,0,0
IFEND: DB 5,'endif'
RETSTR: DM 'ret'
HEXFCB: DB 0,' HEX',0,0,0,0
DS 16
DB 0
LSTFCB: DB 0,' ;This is a disk boot routine for the 1771/1791 type disk
;controllers. It would normally reside on track 0,
;sector 1, to be 邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋D1791: EQU TARBELLDOUBLE
SMALL: EQU CROMEMCOSMALL
LARGE: EQU CROMEMCOLARGE+TARBELL
IF SMALL
MAXSECT:EQU 18
ENDIF
STRET: DS 2
RETPT: DS 2
HEXBUF: DS BUFSIZ+BUFSIZ
LSTBUF: DS BUFSIZ
BC: DS 2
DE: DS 2
HL: DS 2
IX: DS 2
IY: DS 2
DS 50
ler, and the Tarbell double-
; density controller. Select one.
CROMEMCOSMALL: EQU 0
CROMEMCOLARGE: EQU 1
TARBELLSINGLE: EQ PRN',0,0,0,0
DS 16
DB 0
PC: DS 2
OLDPC: DS 2
LABPT: DS 2
FLAG: DS 1
LONG: DS 1
ADDR: DS 2
ALABEL: DS 2
DATA: Dloaded by the "B" command of the
;monitor at address 200H. By changing the equates
;below, it may be configured to load any sIF LARGE
MAXSECT:EQU 26
ENDIF
IF TARBELL
DISK: EQU 78H
ENDIF
IF CROMEMCO
DISK: EQU 30H
ENDIF
IF WD1771
REA邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋TB DISK
JP GETSTAT
BOOT:
MOV AX,SEG
MOV SS,AX
MOV ES,AX
MOV DS,AX
JMP 0,SEG

; CALLED BY: -- None
;
; CALLS: -- INITBD
; CPTRMV
; PLYRMV
;
; ARGUMENTS: NM:
OUTB DISK
IF CROMEMCO
MOV AL,WAITBYTE
OUT DISK+4 ;Turn on hardware wait
ENDIF
READ:
INB DISK+4
IF TARBEYSTEM: EQU 5
;***********************************************************
; EQUATES
;****************************************DCOM:EQU 88H
ENDIF
IF WD1791
READCOM:EQU 80H
ENDIF
IF CROMEMCOLARGE
WAITBYTE:EQU 0B1H
ENDIF
IF CROMEMCOSMALL;***********************************************************
;
; SARGON
;
; Sargon is a computer chess play邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋one
;**********************************************************
DRIVER: MOV SP,STACK ; Set stack pointer
MOV DX,CLRMSG ; ReqLL
ROL AL
JNC DONE
ENDIF
IF CROMEMCO
ROR AL
JC DONE
ENDIF
INB DISK+3
STOB
LOOP READ
GETSTAT:
INB DISK*******************
;
PAWN: EQU 1
KNIGHT: EQU 2
BISHOP: EQU 3
ROOK: EQU 4
QUEEN: EQU 5
KING: EQU 6
WHITE: EQU 0
BLACK:
WAITBYTE:EQU 0A1H
ENDIF
ORG BOOTER
PUT 100H
XOR AX,AX
MOV DS,AX
MOV ES,AX
MOV SS,AX
UP
MOV DI,LOAD
MOVing program designed
; and coded by Dan and Kathe Spracklen. Copyright 1978. All
; rights reserved. No part of this publicat邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋uest color choice
MOV CL,PRINTBUF
CALL SYSTEM
MOV CL,INCHAR ; Accept response
CALL SYSTEM
CMP AL,57H ; Did player req+4
IF TARBELL
ROL AL
JC GETSTAT
ENDIF
IF CROMEMCO
ROR AL
JNC GETSTAT
ENDIF
DONE:
IN DISK
AND AL,9CH
EQU 80H
BPAWN: EQU BLACK+PAWN
ORG 100H
PUT 100H
;***********************************************************
; MAIN P DX,SECTOR
MOV BL,2
SECT:
MOV AL,BL
OUTB DISK+2
MOV CX,128
IF TARBELL
INB DISK ;Get head load status
ENDIF
ion may be
; reproduced without the prior written permission.
;
;***********************************************************
邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋uest white ?
JZ DR05 ; Yes - branch
CMP AL,42H ; Did player request black ?
JNZ DRIVER ; No - error
XOR AL,AL
JP DR JNZ SECT
DEC DX
JZ BOOT
INC BL
CMP BL,MAXSECT+1
JNZ SECT
XOR BL,BL
INC DX
MOV AL,58H ;Step in with update
OUROGRAM DRIVER
;***********************************************************
; FUNCTION: -- To coordinate the game moves.
;
IF CROMEMCO
INB DISK+4 ;Get head load status
ENDIF
TEST AL,20H
MOV AL,READCOM
JNZ OUTCOM
MOV AL,READCOM+4
OUTCO
; SYSTEM EQUATES
;***********************************************************
INCHAR: EQU 1
PRINTBUF:EQU 9
INBUF: EQU 10
S10 ; Jump
DR05: MOV AL,BLACK ; Set computers color to black
DR10: MOV [KOLOR],AL
DR15: MOV DX,PLYDEP ; Request depth of sear given piece.
;***********************************************************
DPOINT: EQU $-TBASE
DB 20,16,8,0,4,0,0
;*******ECT -- Direction Table. Used to determine the dir-
; ection of movement of each piece.
;************************ current position
; of the board during play. The board itself
; looks like:
; FFFFFFFFF Computer move ?
JZ DR25 ; Yes - jump
DR20: CALL PLYRMV ; Do player move
DR25: CALL CPTRMV ; Do computer move
MOV BX,MO****************************
PVALUE: EQU $-TBASE-1
DB 1,3,3,5,9,10
;********************************************************ch
MOV CL,PRINTBUF
CALL SYSTEM
MOV CL,INCHAR
CALL SYSTEM
SUB AL,31H ; Subtract Ascii constant
JB DR15 ; Under mini****************************************************
; DCOUNT -- Direction Table Counter. Used to determine
; t***********************************
DIRECT: EQU $-TBASE
DB +09,+11,-11,-09
DB +10,-10,+01,-01
DB -21,-12,+08,+19
DB +21FFFFFFFFFFF
; FFFFFFFFFFFFFFFFFFFF
; FF0402030506030204FF
; FF0101010101010101FF
; VENO
INC B,[BX] ; Increment move number
JP DR20 ; Back to player move
;***********************************************
; PIECES -- The initial arrangement of the first rank of
; pieces on the board. Use to set up the board
; mum - prompt again
CMP AL,6 ; Over maximum of 6 ?
JNB DR15 ; Yes - prompt again
INC AL ; Increment by one
MOV [PLYMAXhe number of directions of movement for any
; given piece.
;******************************************************,+12,-08,-19
DB +10,+10,+11,+09
DB -10,-10,-11,-09
;***********************************************************
; DP FF0000000000000000FF
; FF0000000000000000FF
; FF0000000000000060FF
; FF00000000000***************
; TABLES SECTION
;***********************************************************
ORG 200H ; Start at 200H
STA for the start of the game.
;***********************************************************
PIECES: EQU $-TBASE
DB 4],AL ; Set desired depth
MOV DX,CRLF ; Output CRLF
MOV CL,PRINTBUF
CALL SYSTEM
XOR AL,AL
MOV [COLOR],AL ; Set color t*****
DCOUNT: EQU $-TBASE
DB 4,4,8,4,4,8,8
;***********************************************************
; PVALUE -- OINT -- Direction Table Pointer. Used to determine
; where to begin in the direction table for any
; 00000FF
; FF8181818181818181FF
; FF8482838586838284FF
; FFFFFFFFFFFFFFFFFFFF
; RT:
ORG START+80H
PUT START+80H
TBASE: EQU START+100H
;***********************************************************
; DIR,2,3,5,6,3,2,4
;***********************************************************
; BOARD -- Board Array. Used to hold theo white
INC AL
MOV [MOVENO],AL ; Set move number to 1
CALL INITBD ; Init board
MOV AL,[KOLOR] ; Get color
OR AL,AL ; Point Value. Gives the point value of each
; piece, or the worth of each piece.
;******************************* FFFFFFFFFFFFFFFFFFFF
; The values of FF form the border of the
; board, and are used to indicate wh**
ATKLST: DW 0,0,0,0,0,0,0
WACT: EQU ATKLST
BACT: EQU ATKLST+7
;***************************************************** half for white and the second half for black.
; It is used to hold the attackers of any given
; sqmy" entries for ply -1 and ply 0.
;************************************************************
SCORE: DW 0,0,0,0,0,0
; 1 -- Pawn
; 2 -- Knight
; 3 -- Bishop
; 4 -- Rook
e of which hold the position of the white
; king and the second holding the position of
; the black kien a piece
; moves off the board. The individual bits of
; the other bytes in the board array are as
******
; PLIST -- Pinned Piece Array. This is a two part array.
; PLISTA contains the pinned piece position.
uare in the order of their value.
;
; WACT -- White Attack Count. This is the first
; byte of the array and te************************************************************
; PLYIX -- Ply Table. Contains pairs of pointers, a pair
; ; 5 -- Queen
; 6 -- King
; 7 -- Not used
; ng.
;
; POSQ -- Position of Queens. Like POSK,but for queens.
;*********************************************************
; follows:
; Bit 7 -- Color of the piece
; 1 -- Black
; ; PLISTD contains the direction from the pinned
; piece to the attacker.
;****************************lls how many pieces are
; in the white portion of the attack list.
;
; BACT -- Black Attack Count. This is the for each ply. The first pointer points to the
; top of the list of possible moves at that ply.
; 0 -- Empty Square
;************************************************************
BOARD: EQU $-TBASE
BOARDA: DS 120
***
POSK: DB 24,95
POSQ: DB 14,94
DB -1
;************************************************************
; SCORE -- 0 -- White
; Bit 6 -- Not used
; Bit 5 -- Pawn attack flag for ATTACK
; Bit 4 -- *******************************
PLIST: EQU $-TBASE-1
PLISTD: EQU PLIST+10
PLISTA: DW 0,0,0,0,0,0,0,0,0,0
;************ eighth byte of
; the array and does the same for black.
;********************************************************* The second pointer points to which move in the
; list is the one currently being considered.
;**************
;************************************************************
; ATKLIST -- Attack List. A two part array, the first
; Score Array. Used during Alpha-Beta pruning to
; hold the scores at each ply. It includes two
; "dumCastle flag for Kings only
; Bit 3 -- Piece has moved flag
; Bits 2-0 Piece type
; ***********************************************
; POSK -- Position of Kings. A two byte area, the first
; byt**********************************************
PLYIX: DW 0,0,0,0,0,0,0,0,0,0
DW 0,0,0,0,0,0,0,0,0,0
;*****************T2: DW TBASE
T3: DW TBASE
INDX1: DW TBASE
INDX2: DW TBASE
NPINS: DW TBASE
MLPTRI: DW PLYIX
MLPTRJ: DW 0
SCRIX: DW 0
BEST the move list for the move that
; is currently considered the best by the
; Alpha-Beta pruning procesck can move to.
;
; PTSL -- The maximum number of points which could be lost
; through an exchange by the plal working indices. Used for various
; INDX2 purposes.
;
; NPINS -- Number of Pins. Count and pointer into the
; ent move number.
;
; PLYMAX -- Maximum depth of search using Alpha-Beta
; pruning.
;
; NPLY -- Current pl*******************************************
; STACK -- Contains the stack for the program.
;*******************************M: DW 0
MLLST: DW 0
MLNXT: DW MLIST
;************************************************************
; VARIABLES SECTION
s.
;
; MLLST -- Pointer to the previous move placed in the move
; list. Used during generation of the move liyer not on the
; move.
;
; PTSW1 -- The maximum number of points which could be won
; through an pinned piece list.
;
; MLPTRI -- Pointer into the ply table which tells
; which pair of pointers arey number during Alpha-Beta
; pruning.
;
; CKFLG -- A non-zero value indicates the king is in check.
;
; MATE*****************************
ORG START+2FFH
STACK:
;************************************************************
; T
;
; KOLOR -- Indicates computer's color. White is 0, and
; Black is 80H.
;
; COLOR -- Indicates color ofst.
;
; MLNXT -- Pointer to the next available space in the move
; list.
;
;********************************exchange by the player not on the
; move.
;
; PTSW2 -- The second highest number of points which could
; in current use.
;
; MLPTRJ -- Pointer into the move list to the move that is
; currently being processed.
;
F -- A zero value indicates no legal moves.
;
; VALM -- The score of the current move being examined.
;
; BRDC -- ABLE INDICES SECTION
;
; M1-M4 -- Working indices used to index into
; the board array.
;
; T1-T3 -- Work the side with the move.
;
; P1-P3 -- Working area to hold the contents of the board
; array for a given squar****************************
ORG START+0
PUT START+0
M1: DW TBASE
M2: DW TBASE
M3: DW TBASE
M4: DW TBASE
T1: DW TBASE
be won through a different exchange by the player
; not on the move.
;
; MTRL -- A measure of the dif; SCRIX -- Score Index. Pointer to the score table for
; the ply being examined.
;
; BESTM -- Pointer into A measure of mobility equal to the total number
; of squares white can move to minus the number
; blaing indices used to index into Direction
; Count, Direction Value, and Piece Value tables.
;
; INDX1 -- Generae.
;
; PMATE -- The move number at which a checkmate is
; discovered during look ahead.
;
; MOVENO -- Currference in material
; currently on the board. It is the total value of
; the white pieces minus the tmove entry which gives the
; board position to which the piece is moving.
;
; MLFLG -- A field in the move ent the moves for a single leg of the move tree.
;
; MLEND -- The address of the last available location
; in the**************************************************
ORG START+300H
PUT START+300H
MLIST: DS 2048
MLEND: EQU MLIST+2040
MLP
P1: DB 0
P2: DB 0
P3: DB 0
PMATE: DB 0
MOVENO: DB 0
PLYMAX: DB 2
NPLY: DB 0
CKFLG: DB 0
MATEF: DB 0
VALM: DB 0
BRDC:that
; this is the first move for the
; piece on the move.
; Bit 3 otal value of the
; black pieces.
;
; BC0 -- The value of board control(BRDC) at ply 0.
;
; MV0 -- Thry which contains flag
; information. The meaning of each bit is as
; follows:
; Bit 7 move list.
;
; MLPTR -- The Move List is a linked list of individual
; moves each of which is 6 bytes in lengTR: EQU 0
MLFRP: EQU 2
MLTOP: EQU 3
MLFLG: EQU 4
MLVAL: EQU 5
;****************************************************** DB 0
PTSL: DB 0
PTSW1: DB 0
PTSW2: DB 0
MTRL: DB 0
BC0: DB 0
MV0: DB 0
PTSCK: DB 0
BMOVES: DB 35,55,10H
DB 34,54,10H
-- This flag is set is there is a piece
; captured, and that piece has moved at
; e value of material(MTRL) at ply 0.
;
; PTSCK -- A non-zero value indicates that the piece has
; just moved it-- The color of any captured piece
; 0 -- White
; 1 -- Black
; th. The
; move list pointer(MLPTR) is the link field
; within a move.
;
; MLFRP -- The field in ******
; PROGRAM CODE SECTION
;************************************************************
; BOARD SETUP ROUTINE
;*********
DB 85,65,10H
DB 84,64,10H
;************************************************************
; MOVE LIST SECTION
;
; ML least once.
; Bits 2-0 Describe the captured piece. A
; zero value indicates no captself into a losing exchange of
; material.
;
; BMOVES -- Our very tiny book of openings. Determines
; Bit 6 -- Double move flag (set for castling and
; en passant pawn captures)
; Bit 5 -- the move entry which gives the
; board position from which the piece is moving.
;
; MLTOP -- The field in the ***************************************************
; FUNCTION: To initialize the board array, setting the
; pieIST -- A 2048 byte storage area for generated moves.
; This area must be large enough to hold all
; ure.
;
; MLVAL -- The field in the move entry which contains the
; score assigned to the move.
;
;********** the first move for the computer.
;
;************************************************************
KOLOR: DB 0
COLOR: DB 0 Pawn Promotion flag; set when pawn
; promotes.
; Bit 4 -- When set, this flag indicates ces in their initial positions for the
; start of the game.
;
; CALLED BY: DRIVER
;
; CALLS: None
;
; A PINFND
;
; CALLS: None
;
; ARGUMENTS: Direction from the direction array giving the
; constant to be add position, and setting a flag describing the
; contents:
; 0 -- New postion is emp****************************
MPIECE: XOR AL,[BX] ; Piece to move
AND AL,87H ; Clear flag bit
CMP AL,BPAWN ; Is it a black0
INC SI
DEC CH
JNZ IB2
MOV SI,POSK ; Init King/Queen position list
MOV B,[SI+0],25
MOV B,[SI+1],95
MOV B,[SI+2], AL,0
RET ; Return
PA2: MOV AL,3 ; Set off board flag
RET ; Return
;*******************************************RGUMENTS: None
;
;*************************************************************
INITBD: MOV CX,60 ; Pre-fill board with -1'ed for the new position.
;************************************************************
PATH: ADD [M2],CL ; Add direction consty
; 1 -- Encountered a piece of the
; opposite color
; Pawn ?
JNZ MP1 ; No-Skip
DEC AL ; Decrement for black Pawns
MP1: AND AL,7 ; Get piece type
MOV [T1],AL ; Save piece 24
MOV B,[SI+3],94
RET
;************************************************************
; PATH ROUTINE
;*******************************
; PIECE MOVER ROUTINE
;************************************************************
; FUNCTION: To generas
MOV DI,BOARDA
MOV AX,-1
REP
STOW
MOV CH,8
MOV SI,BOARDA
IB2: MOV AL,[SI-8] ; Fill non-border squares
MOV [SI+21tant to prev pos
MOV SI,[M2] ; Load board index
MOV AL,[SI+BOARD] ; Get contents of board
CMP AL,-1 ; In boarder area ?
2 -- Encountered a piece of the
; same color
; 3 --type
MOV DI,[T1] ; Load index to DCOUNT/DPOINT
MOV CH,[DI+DCOUNT] ; Get direction count
MOV AL,[DI+DPOINT] ; Get directio**********************************************
; FUNCTION: To generate a single possible move for a given
; piecte all the possible legal moves for a
; given piece.
;
; CALLED BY: GENMOV
;
; CALLS: PATH
; ],AL ; White pieces
LAHF
OR AL,080H
SAHF ; Change to black
MOV [SI+91],AL ; Black pieces
MOV B,[SI+31],PAWN ; White
JZ PA2 ; Yes - jump
MOV [P2],AL ; Save piece
MOV AH,AL ; Save piece in register
AND AL,7 ; Clear flags
MOV [T2],AL New position is off the
; board
;
; CALLED BY: MPIECE
; ATTACK
; n pointer
MOV [INDX2],AL ; Save as index to direct
MOV DI,[INDX2] ; Load index
MP5: MOV CL,[DI+DIRECT] ; Get move directione along its current path of motion including:
;
; Fetching the contents of the board at the new
; ADMOVE
; CASTLE
; ENPSNT
;
; ARGUMENTS: The piece to be moved.
;*********************************Pawns
MOV B,[SI+81],BPAWN ; Black Pawns
MOV B,[SI+41],0 ; Empty squares
MOV B,[SI+51],0
MOV B,[SI+61],0
MOV B,[SI+71], ; Save piece type
JZ RET ; Return if empty
XOR AH,[P1] ; Compare with moving piece
SHL AH ; Set flag
MOV AL,2
SBB
MOV AL,[M1] ; From position
MOV [M2],AL ; Initialize to position
MP10: CALL PATH ; Calculate next position
CMP AL,2 ENPSNT ; Try en passant capture
JMP MP15 ; Jump
;***********************************************************
; EN PA INC DI ; Adjust to two square move
DEC CH
TEST B,[P1],008H ; Check Pawn moved flag, has it moved before ?
JZ MP10 ; No PAWN ; Is it a Pawn ?
JNZ RET ; No - return
MOV AL,[M4] ; Get "to" position
MOV BX,M2 ; Get present "to" position
SUe type
CMP AL,KING ; King ?
JNZ RET
JMP CASTLE ; Yes - Try Castling
; ***** PAWN LOGIC *****
MP20: MOV AL,CH ; CounteD AL,10 ; Add 10 for black
EP5: CMP AL,61 ; On en passant capture rank ?
JC RET ; No - return
CMP AL,69 ; On en passant; Ready for new direction ?
JNC MP15 ; Yes - Jump
AND AL,AL ; Test for empty square
PUSHF
MOV AL,[T1] ; Get piece movSSANT ROUTINE
;***********************************************************
; FUNCTION: -- To test for en passant Pawn captu- Jump
JMP MP15 ; Jump
MP30: POPF
JNZ MP15 ; No - Jump
MP31: CALL ADMOVE ; Add to move list
JMP MP15 ; Jump
MP35: PB AL,[BX] ; Find difference
JNS EP10 ; Positive ? Yes - Jump
NEG AL ; Else take absolute value
EP10: CMP AL,10 ; Is difr for direction
CMP AL,3 ; On diagonal moves ?
JC MP35 ; Yes - Jump
JZ MP30 ; -or-jump if on 2 square move
POPF
JNZ capture rank ?
JNC RET ; No - return
MOV SI,[MLPTRJ] ; Get pointer to previous move
TEST B,[SI+MLFLG],010H ; First move ed
CMP AL,PAWN+1 ; Is it a Pawn ?
JC MP20 ; Yes - Jump
CALL ADMOVE ; Add move to list
POPF
JNZ MP15 ; No - Jump
Mre and
; to add it to the move list if it is
; legal.
;
; CALLED BY: -- MPIECE
;
; CALLSOPF
JZ MP36 ; Yes - Jump
MOV AL,[M2] ; Get "to" position
CMP AL,91 ; Promote white Pawn ?
JNC MP37 ; Yes - Jump
CMference 10 ?
JNZ RET ; No - return
OR B,[P2],040H ; Set double move flag
CALL ADMOVE ; Add Pawn move to move list
MOV MP15 ; No - jump
MOV AL,[M2] ; Get "to" position
CMP AL,91 ; Promote white Pawn ?
JNC MP25 ; Yes - Jump
CMP AL,29 for that piece ?
JZ RET ; No - return
MOV AL,[SI+MLTOP] ; Get "to" postion
MOV [M4],AL ; Store as index to board
MOV SOV AL,[T1] ; Piece type
CMP AL,KING ; King ?
JZ MP15 ; Yes - Jump
CMP AL,BISHOP ; Bishop, Rook, or Queen ?
JNC MP10 : -- ADMOVE
; ADJPTR
;
; ARGUMENTS: -- None
;*****************************************************P AL,29 ; Black Pawn promotion ?
JNC MP31 ; No- Jump
MP37: OR B,[P2],020H ; Set promote flag
JP MP31 ; Jump
MP36: CALL AL,[M1] ; Save initial Pawn position
MOV [M3],AL
MOV AL,[M4] ; Set "from" and "to" positions
; for dummy move
MOV [; Promote black Pawn ?
JNC MP26 ; No - Jump
MP25: OR B,[P2],020H ; Set promote flag
MP26: CALL ADMOVE ; Add to move list
I,[M4] ; Load board index
MOV AL,[SI+BOARD] ; Get piece moved
MOV [P3],AL ; Save it
AND AL,7 ; Get piece type
CMP AL,; Yes - Jump
MP15: INC DI ; Increment direction index
DEC CH
JNZ MP5 ; Decr. count-jump if non-zerc
MOV AL,[T1] ; Piec*******
ENPSNT: MOV AL,[M1] ; Set position of Pawn
TEST B,[P1],080H ; Check color, is it white ?
JZ EP5 ; Yes - skip
ADM1],AL
MOV [M2],AL
MOV AL,[P3] ; Save captured Pawn
MOV [P2],AL
CALL ADMOVE ; Add Pawn capture to move list
MOV AL,[k position
MOV AL,CL
MOV [M3],AL ; Store as board index
MOV SI,[M3] ; Load board index
MOV AL,[SI+BOARD] ; Get content, or both) and add it
; to the move list if it is.
;
; CALLED BY: -- MPIECE
;
; CALLS: -- ATTACK
;n
MOV [BX],CL ; Store Rook "from" position
SUB AL,CH ; Get Rook "to" position
MOV [M2],AL ; Store Rook "to" position
-- None
;
; ARGUMENTS: -- None
;*************************************************************
ADJPTR: MOV BX,[MLLST] ; AL ; Any attackers ?
JNZ CA20 ; Yes - Jump
MOV AL,[M3] ; Current position
CA15: ADD AL,CH ; Next position
MOV [M3],ALM3] ; Restore "from" position
MOV [M1],AL
;************************************************************
; ADJUST MOVEs of board
AND AL,7FH ; Clear color bit
CMP AL,ROOK ; Has Rook ever moved ?
JNZ CA20 ; Yes - Jump
MOV AL,CL ; Restor ADMOVE
; ADJPTR
;
; ARGUMENTS: -- None
;*************************************************XOR AL,AL ; Zero
MOV [P2],AL ; Zero move flags
CALL ADMOVE ; Put Rook move in list
CALL ADJPTR ; Re-adjust move list pGet list pointer
SUB BX,6 ; Back up list pointer
MOV [MLLST],BX ; Save list pointer
MOV [BX],0 ; Zero out link
RET ; ; Save as board index
MOV BX,M1 ; King position
CMP AL,[BX] ; Reached King ?
JNZ CA10 ; No - jump
SUB AL,CH ; Dete LIST POINTER FOR DOUBLE MOVE
;************************************************************
; FUNCTION: -- To adjust move le Rook position
JP CA15 ; Jump
CA10: MOV SI,[M3] ; Load board index
MOV AL,[SI+BOARD] ; Get contents of board
AND AL,AL***********
CASTLE:
TEST B,[P1],008H ; Has king moved ?
JNZ RET ; Yes - return
MOV AL,[CKFLG] ; Fetch Check Flag
AND ointer
MOV AL,[M3] ; Restore King position
MOV [M1],AL ; Store
CA20: MOV AL,CH ; Scan Index
CMP AL,1 ; Done ?
JZ RE Return
;************************************************************
;CASTLE ROUTINE
;********************************rmine King's position
SUB AL,CH
MOV [M2],AL ; Save it
MOV BX,P2 ; Address of flags
MOV B,[BX],40H ; Set double move flist pointer to link around
; second move in double move.
;
; CALLED BY: -- ENPSNT
; CASTLE ; Empty ?
JNZ CA20 ; No - Jump
MOV AL,[M3] ; Current position
CMP AL,22 ; White Queen Knight square ?
JZ CA15 ; YeAL,AL ; Is the King in check ?
JNZ RET ; Yes - Return
MOV CX,0FF03H ; Initialize King-side values
CA5: ADD CL,[M1] ; RooT ; Yes - return
MOV CX,01FCH ; Set Queen-side initial values
JMP CA5 ; Jump
;*****************************************************************
; FUNCTION: -- To determine whether castling is legal
; (Queen side, King sideag
CALL ADMOVE ; Put king move in list
MOV BX,M1 ; Addr of King "from" position
MOV AL,[BX] ; Get King's "from" positio
; (This mini-routine is not really called,
; but is jumped to to save time.)
;
; CALLS: s - Jump
CMP AL,92 ; Black Queen Knight square ?
JZ CA15 ; Yes - Jump
CALL ATTACK ; Look for attack on square
AND AL,***********************
; ADMOVE ROUTINE
;************************************************************
; FUNCTION: -- To aKFLG],AL ; Save attack count as flag
MOV DX,[MLNXT] ; Addr of next avail list space
MOV BX,[MLPTRI] ; Ply list pointer indexry on table ovflow
RET
;************************************************************
; GENERATE MOVE ROUTINE
;******ing is in check.
;
; CALLED BY: -- GENMOV
; FNDMOV
; EVAL
;
; CALLS: -- ATTACK
;
ST B,[P1],008H ; Has moved piece moved before ?
JNZ AM5 ; Yes - jump
OR B,[P2],010H ; Set first move flag
AM5: XCHG DX,DI or of piece
XOR AL,[BX] ; Test color of piece
TEST AL,080H ; Match ?
JNZ GM10
CALL MPIECE ; Yes - call Move Piece
GMdd a move to the move list
;
; CALLED BY: -- MPIECE
; ENPSNT
; CASTLE
;
; CALLS: --
INC BX ; Increment to next ply
INC BX
MOV [BX],DX ; Save move list pointer
INC BX
INC BX
MOV [MLPTRI],BX ; Save n******************************************************
; FUNCTION: -- To generate the move set for all of the
;
; ARGUMENTS: -- Color of King
;************************************************************
INCHK: MOV AL,[COLOR] ; Get col ; Address of move area
XOR AX,AX ; Store zero in link address
CLD
STOW
MOV AL,[M1] ; Store "from" move position
STO10: MOV AL,[M1] ; Fetch current board position
INC AL ; Incr to next board position
CMP AL,99 ; End of board array ?
JN None
;
; ARGUMENT: -- None
;*************************************************************
ADMOVE: MOV DX,[MLNXT] ; Addr ew index
MOV [MLLST],BX ; Last pointer for chain init.
MOV AL,21 ; First position on board
GM5: MOV [M1],AL ; Save as ind pieces of a given color.
;
; CALLED BY: -- FNDMOV
;
; CALLS: -- MIECE
; INCHK
;
; ARGUMENTS:or
INCHK1: MOV BX,POSK ; Addr of white King position
AND AL,AL ; White ?
JZ IC5 ; Yes - Skip
INC BX ; Addr of black KB
MOV AL,[M2] ; Store "to" move position
STOB
MOV AL,[P2] ; Store move flags/capt. piece
STOB
XOR AL,AL ; Store iniZ GM5 ; No - Jump
RET ; Return
;************************************************************
; CHECK ROUTINE
;****of next loc in move list
MOV BX,MLEND ; Address of list end
SUB BX,DX ; Calculate difference
JC AM10 ; Jump if out of spex
MOV SI,[M1] ; Load board index
MOV AL,[SI+BOARD] ; Fetch board contents
AND AL,AL ; Is it empty ?
JZ GM10 ; Yes - -- None
;************************************************************
GENMOV: CALL INCHK ; Test for King in check
MOV [Cing position
IC5: MOV AL,[BX] ; Fetch King position
MOV [M3],AL ; Save
MOV SI,[M3] ; Load board index
MOV AL,[SI+BOARDtial move value
STOB
MOV [MLNXT],DI ; Save address for next move
MOV DI,DX
RET ; Return
AM10: MOV [BX],0 ; Abort ent********************************************************
; FUNCTION: -- To determine whether or not the
; Kace
MOV BX,[MLLST] ; Addr of prev. list area
MOV [MLLST],DX ; Save next as previous
MOV [BX],DX ; Store link address
TEJump
CMP AL,-1 ; Is it a boarder square ?
JZ GM10 ; Yes - Jump
MOV [P1],AL ; Save piece
MOV BX,COLOR ; Address of col] ; Fetch board contents
MOV [P1],AL ; Save
AND AL,7 ; Get piece type
MOV [T1],AL ; Save
;**********************ard pointer to it
MOV DH,0 ; Init. scan count/flags
MOV SI,DIRECT+TBASE ; Load direction table
MOV AH,KING ; Check for aled
; by CASTLE or INCHK, the routine is
; terminated as soon as an attacker of the
; Restore CX reg
RET ; Return
;************************************************************
; ATTACK ADJACENT SCAN ROU; a square, this routine also takes into
; account the ability of certain pieces to
; 11
AND AL,87H ; Clear flag bit
CMP AL,PAWN ; White Pawn ?
JNZ AT15 ; No - jump
OR [BP-11],AH ; Set Pawn attack flag
**************************************
; ATTACK ROUTINE
;************************************************************
; FUNCT King
CALL ATKADJ ; Scan adjacent squares
MOV AH,KNIGHT ; Check for a Knight
CALL ATKADJ ; Scan adjacent squares
MOV A opposite color is encountered.
;
; CALLED BY: -- POINTS
; PINFND
; CASTLE
; TINE
;************************************************************
; FUNCTION: -- To scan for a specified attacker on adjac attack through another attacking piece. (For
; example a queen lined up behind a bishop
; AT15: MOV AL,[BP-9] ; Get piece at -9
AND AL,87H ; Clear flag bit
CMP AL,PAWN ; White Pawn ?
JNZ AT20 ; No - jump
OR ION: -- To find all attackers on a given square
; by scanning outward from the square
; untH,20H ; Pawn attack flag
MOV AL,[BP+11] ; Get piece at +11
AND AL,87H ; Clear flag bit
CMP AL,BPAWN ; Black Pawn ?
JNZ INCHK
;
; CALLS: -- ATKADJ
; ATKOUT
;
; ARGUMENTS: -- None
;**************************ent
; squares.
;
; CALLED BY: -- ATTACK
;
; CALLS: -- ATKCHK
;
; ARGUMENTS: -- The piece under of her same color along a diagonal.) The
; bishop is then said to be transparent to the
; [BP-9],AH ; Set Pawn attack flag
AT20: MOV SI,DIRECT+TBASE ; Load direction table
MOV AH,BISHOP ; Check for a Bishop
CALL Ail a piece is found that attacks
; that square, or a piece is found that
; doesn't attack that AT5 ; No - jump
OR [BP+11],AH ; Set Pawn attack flag
AT5: MOV AL,[BP+9] ; Get piece at +9
AND AL,87H ; Clear flag bit
**********************************
ATTACK: PUSH CX ; Save Register CX
MOV BP,[M3] ; Get piece index
ADD BP,BOARD ; Add boattack. The attacker.
;************************************************************
ATKADJ: MOV CX,8 ; 8 directions to scan
queen, since both participate in the
; attack.
;
; In the case where this routine is calTKOUT ; Scan outwards
MOV AH,ROOK ; Check for a Rook
CALL ATKOUT ; Scan outwards
XOR AL,AL ; No attackers
POP CX ; square, or the edge
; of the board is reached.
;
; In determining which pieces attack
CMP AL,BPAWN ; Black Pawn ?
JNZ AT10 ; No - jump
OR [BP+9],AH ; Set Pawn attack flag
AT10: MOV AL,[BP-11] ; Get piece at -AA5: XCHG AX,BX ; Save AX
LODB ; Get direction byte
CBW ; Convert to word
XCHG AX,BX ; Save direction and restore AXND B,[DI],0DFH ; Remove Pawn attack flag
AO22: MOV AL,[DI] ; Get piece
ADD AL,80H ; CY if black, NC if white
RCR AL ; Biand restore AX
MOV DI,BP ; Load pointer to piece
AO10: ADD DI,BX ; Add direction constant
MOV AL,[DI] ; Get attacking pi
;
; ARGUMENTS: -- The attacking piece. The piece under attack.
;***********************************************************ed attacker outwards
; from the piece under attack, until found
; or edge of the board is react.
;
; The pin piece list is checked for the
; attacking piece, and if found there, the
;
MOV DI,BP ; Load pointer to piece
ADD DI,BX ; Add direction constant
MOV AL,[DI] ; Get attacking piece
AND AL,7 ; Gt 7 set if black, bit 6 if white
AND DL,AL ; Keep only bits 6 and 7
JZ AO15 ; Nothing, next direction
CALL ATKCHK ; Cheece
AND AL,27H ; Get piece type and Pawn attack flag
JZ AO10 ; No piece, keep going
CMP AL,AH ; Same as what we want ?
*
ATKCHK: MOV AL,[DI] ; Get piece
CMP B,[T1],7 ; Call from POINTS ?
JZ ACK10 ; Yes - jump
XOR AL,[BP] ; Attacker and thed.
;
; CALLED BY: -- ATTACK
;
; CALLS: -- ATKCHK
;
; ARGUMENTS: -- The piece under attack. The attacker.
;*** piece is not included in the attack list.
;
; In the case where ATTACK is called by
; et piece type
CMP AL,AH ; Same as what we want ?
JNZ AA10 ; No - jump
CALL ATKCHK ; Check and save attacker
AA10: LOOPck and save attack
JP AO10 ; Keeping going that direction
;***********************************************************
JZ AO22 ; Yes - jump
CMP AL,QUEEN ; Queen ?
JZ AO20 ; Yes - jump
CMP AL,PAWN+20H ; Pawn with Pawn attack flag ?
JZ Aarget same color ?
JNS RET ; Yes - return
POP AX
POP AX ; Set SP level to ATTACK
MOV AX,0DFFFH ; FF (border) in AL and*********************************************************
ATKOUT: MOV CL,4 ; 4 directions to scan
AO5: MOV DX,0C0H ; Bitmask CASTLE or INCHK, control is returned to
; the aforementioned routines as soon as an
; a AA5 ; Go check for next direction
RET ; Return
;************************************************************
; ATT*
; ATTACK CHECK AND SAVE ROUTINE
;************************************************************
; FUNCTION: -- To check ifO21 ; Yes - jump
AO15: LOOP AO5 ; Go check for next direction
RET ; Return
AO20: INC DH ; Set Queen found flag
AO21: A DF in AH
CMP [BP+9],AL ; Is +9 border ?
JZ ACK5 ; Yes, jump
AND [BP+9],AH ; Remove Pawn attack flag
ACK5: CMP [BP+11],A for color flags
XCHG AX,BX ; Save AX
LODB ; Get direction byte
CBW ; Convert to word
XCHG AX,BX ; Save direction ttacker of the opposite color is encountered.
;
; CALLED BY: -- ATKADJ
; ATKOUT
;
; CALLS: -- None
ACK OUTWARD SCAN ROUTINE
;************************************************************
; FUNCTION: -- To scan for a specifi a piece can attack the target
; square and save the attacking piece value
; in the attack lisL ; Is +11 border ?
JZ ACK6 ; Yes - jump
AND [BP+11],AH ; Remove Pawn attack flag
ACK6: CMP [BP-9],AL ; Is -9 border ?
JHG AL,CL ; Save point value in AL
ADD DI,CX ; Attack list slot address
MOV CH,[DI] ; Get data already there
TEST CH,0FHOV CL,AL ; Put piece in CL
AND CL,7 ; Get piece type
MOV DI,PVALUE+TBASE ; PVALUE list address
ADD DI,CX ; Point to pie
PF1: MOV BP,DX
MOV AL,[BP] ; Get position of royal piece
AND AL,AL ; Is it on board ?
JNZ PF1A ; Yes - continue
JMP t address
ACK15: OR AL,AL ; Set flags for REP
REPZ
SCAB ; Search list for position
JNZ ACK25 ; Continue if not found
TINE
;************************************************************
; FUNCTION: -- To produce a list of all pieces pinned
;Z ACK7 ; Yes - jump
AND [BP-9],AH ; Remove Pawn attack flag
ACK7: CMP [BP-11],AL ; Is -11 border ?
JZ ACK8 ; Yes - jump
; Is first slot empty ?
JZ ACK40 ; Yes - jump
TEST CH,0F0H ; Is second slot empty ?
JZ ACK35 ; Yes - jump
INC DI ;ce value
MOV CL,[DI] ; Get point value of piece
MOV DI,ATKLST ; Init address of attack list
TEST AL,80H ; Is it white ?
PF26
PF1A: CMP AL,-1 ; At end of list ?
JZ RET ; Yes return
MOV [M3],AL ; Save position as board index
MOV SI,[M3] ;
OR AH,AH ; Is this the first find ?
JNZ ACK20 ; No - jump
MOV AH,[DI+9] ; Get direction
CMP AH,BL ; Same as attacking against the King or Queen, for both white
; and black.
;
; CALLED BY: -- FNDMOV
; AND [BP-11],AH ; Remove Pawn attack flag
ACK8: MOV AL,1 ; Set attacker found flag
POP CX ; Restore CX reg
RET ; Return Increment to King slot
MOV CH,[DI] ; Get byte
XCHG AL,CH ; Byte to AL, point value to CH
ACK35: SHL AL ; Lower bits to
JZ ACK30 ; Yes - jump
ADD DI,7 ; Attack list address
ACK30: OR DH,DH ; Queen found this scan ?
JZ ACK31 ; No - jump
Load index to board
MOV AL,[SI+BOARD] ; Get contents of board
MOV [P1],AL ; Save
MOV CH,8 ; Init scan direction count
direction ?
JZ ACK15 ; Yes - jump
NEG AH ; Opposite direction ?
CMP AH,BL ; Same as attacking direction ?
JZ ACK15 EVAL
;
; CALLS: -- PATH
; ATTACK
;
; ARGUMENTS: -- None
;******************************** from ATTACK
ACK10: PUSH CX ; Save regs
PUSH DI
MOV CL,[NPINS] ; Number of pinned pieces
JCXZ ACK26 ; No pins - jump
upper
SHL AL
SHL AL
SHL AL
OR AL,CH ; Combine with point value
ACK40: MOV [DI],AL ; Put back into attack list
POP D MOV AL,QUEEN ; Use Queen slot in attack list
ACK31: AND AL,7 ; Attacking piece type
INC B,[DI] ; Increment list count
XCXOR AL,AL
MOV [INDX2],AL ; Init direction index
MOV DI,[INDX2]
PF2: MOV AL,[M3] ; Get King/Queen position
MOV [M2],AL ;; Yes - jump
ACK20: POP AX ; Restore regs.
POP DI
POP CX
RET ; Return to ATTACK
ACK25: POP AX ; Restore AX
ACK26: M****************************
PINFND: XOR AL,AL ; Zero pin count
MOV [NPINS],AL
MOV DX,POSK ; Addr of King/Queen pos list
PUSH AX ; Save AX
MOV AX,DI ; Load piece pointer in AX
SUB AX,BOARDA ; Minus BOARDA for position
MOV DI,PLISTA ; Pin lisI ; Restore regs
POP CX
RET ; Return
;************************************************************
; PIN FIND ROU Save
XOR AL,AL
MOV [M4],AL ; Clear pinned piece saved pos
MOV CL,[DI+DIRECT] ; Get direction of scan
PF5: CALL PATH ; estore regs.
POP DX
POP CX
JNS PF25 ; Jump if pin not valid
PF20: MOV BX,NPINS ; Address of pinned piece count
INC B,[; Zero out attack list
MOV CX,7
MOV BX,ATKLST
XCHG DI,BX
CLD
REP
STOW
XCHG DI,BX
MOV AL,7 ; Set attack flag
Mwhite ?
JZ XC5 ; Yes - jump
XCHG DX,BX ; Swap list pointers
XC5: MOV CH,[BX] ; Init list counts
XCHG DX,BX
MOV CL,[BL,BL ; Piece type
CMP AL,BISHOP ; Bishop ?
JNZ PF25 ; No - jump
JMP PF20 ; Jump
JPF25: JMP PF25
PF10: MOV AL,BL ; Pitermine the exchange value of a
; piece on a given square by examining all
; attackers and defCompute next position
AND AL,AL ; Is it empty ?
JZ PF5 ; Yes - jump
CMP AL,3 ; Off board ?
JZ JPF25 ; Yes - jump
CBX] ; Increment
MOV SI,[NPINS] ; Load pin list index
MOV [SI+PLISTD],CL ; Save direction of pin
MOV AL,[M4] ; Position oOV [T1],AL
CALL ATTACK ; Find attackers/defenders
MOV BX,WACT ; White queen attackers
MOV DX,BACT ; Black queen attackeX]
XCHG DX,BX
XCHG BX,[HL]
XCHG DX,[DE]
XCHG CX,[BC] ; Restore regs.
MOV CL,0 ; Init attacker/defender flag
MOV DLece type
CMP AL,ROOK ; Rook ?
JNZ PF25 ; No - jump
JMP PF20 ; Jump
PF15: AND AL,AL ; Possible pin ?
JNZ PF25 ; No enders of that piece.
;
; CALLED BY: -- POINTS
;
; CALLS: -- NEXTAD
;
; ARGUMENTS: -- None.
;******************MP AL,2 ; Piece of same color found ?
MOV AL,[M4] ; Load pinned piece position
JZ PF15 ; Yes - jump
AND AL,AL ; Possibf pinned piece
MOV [SI+PLIST],AL ; Save in list
PF25: INC DI ; Increment direction index
DEC CH
JZ PF26 ; Done ? Yes - rs
TEST B,[P1],080H ; Is queen white ?
JZ PF19A ; Yes - skip
XCHG DX,BX ; Reverse for black
PF19A: MOV AL,[BX] ; Numbe,0 ; Init points lost count
MOV SI,[T3] ; Load piece value index
MOV DH,[SI+PVALUE] ; Get attacked piece value
SAL DH ;- jump
MOV AL,[M2] ; Save possible pin position
MOV [M4],AL
JMP PF5 ; Jump
PF19: MOV AL,[P1] ; Load King or Queen
AN*****************************************
XCHNG: XCHG BX,[HL]
XCHG DX,[DE]
XCHG CX,[BC] ; Swap regs.
MOV AL,[P1] ; Piecle pin ?
JZ JPF25 ; No - jump
MOV AL,[T2] ; Piece type encountered
CMP AL,QUEEN ; Queen ?
JZ PF19 ; Yes - jump
MOV Continue
JMP PF2
PF26: INC DX ; Incr King/Queen pos index
JMP PF1 ; Jump
;****************************************r of defenders
XCHG DX,BX ; Reverse for attackers
SUB AL,[BX] ; Defenders minus attackers
DEC AL ; Less 1
POP DI ; R Double it
MOV CH,DH ; Save
CALL NEXTAD ; Retrieve first attacker
JNZ XC10
JMP RET ; Return if none
XC10: MOV BL,AL D AL,7 ; Clear flags
CMP AL,QUEEN ; Queen ?
JNZ PF20 ; No - jump
PUSH CX ; Save regs.
PUSH DX
PUSH DI
XOR AX,AX e attacked
MOV BX,WACT ; Addr of white attkrs/dfndrs
MOV DX,BACT ; Addr of black attkrs/dfndrs
TEST AL,080H ; Is piece BL,AL ; Save piece type
MOV AL,CH ; Direction counter
CMP AL,5 ; Non-diagonal direction ?
JC PF10 ; Yes - jump
MOV A********************
; EXCHANGE ROUTINE
;************************************************************
; FUNCTION: -- To de ; Save attacker value
CALL NEXTAD ; Get next defender
JZ XC18 ; Jump if none
LAHF
CMP CH,BL ; Attacked less than att SHR AH
SHR AH
SHR AH
SHR AH
MOV [BX],AH
AND AL,0FH
DEC BX ; Decrement list pointer
ADD AL,AL ; Double it
NX6: Attack list counts
;*********************************************************
NEXTAD: INC CL ; Increment side flag
Xpiece, if any
MOV [BX],AL
AND AL,7 ; Save piece type, if any
MOV [T3],AL
CMP AL,KNIGHT ; Less than a Knight (Pawn) ?
becomes defender
JMP XC10 ; Jump
;************************************************************
; NEXT ATTACKER/DEFENDEne
;**************************************************************
POINTS: XOR AL,AL ; Zero out variables
MOV [MTRL],AL
Macker ?
JNC XC19 ; No - jump
XC15: CMP AL,BL ; Defender less than attacker ?
JC RET ; Yes - return
CALL NEXTAD ; RetrXCHG BX,[HL]
XCHG DX,[DE]
XCHG CX,[BC] ; Restore regs.
RET ; Return
;*******************************************CHG BX,[HL]
XCHG DX,[DE]
XCHG CX,[BC] ; Swap registers
XCHG CH,CL ; Swap list counts
XCHG DX,BX ; Swap list pointers
JC PT6X ; Yes - Jump
CMP AL,ROOK ; Rook, Queen or King ?
JC PT6B ; No - jump
CMP AL,KING ; Is it a King ?
JZ PT6AA R ROUTINE
;************************************************************
; FUNCTION: -- To retrieve the next attacker or defOV [BRDC],AL
MOV [PTSL],AL
MOV [PTSW1],AL
MOV [PTSW2],AL
MOV [PTSCK],AL
MOV BX,T1 ; Set attacker flag
MOV B,[BX],7
ieve next attacker value
JZ RET ; Return if none
MOV BL,AL ; Save attacker value
CALL NEXTAD ; Retrieve next defender v*****************
; POINT EVALUATION ROUTINE
;************************************************************
;FUNCTION: -- T
XOR AL,AL
CMP AL,CH ; At end of list ?
JZ NX6 ; Yes - jump
DEC CH ; Decrement list count
NX5: INC BX ; Increment li; Yes - jump
MOV AL,[MOVENO] ; Get move number
CMP AL,7 ; Less than 7 ?
JC PT6A ; Yes - Jump
JMP PT6X ; Jump
PT6AA: ender
; piece value from the attack list, and delete
; that piece from the list.
;
; CALLED
MOV AL,21 ; Init to first square on board
PT5: MOV [M3],AL ; Save as board index
MOV SI,[M3] ; Load board index
MOV ALalue
JNZ XC15 ; Jump if none
XC18: LAHF
XC19: TEST CL,001H ; Attacker or defender ?
JZ XC20 ; Jump if defender
NEG CHo perform a static board evaluation and
; derive a score for a given board position
;
; CALLED BY: -- FNDMOVst pointer
CMP AL,[BX] ; Check next item in list
JZ NX5 ; Jump if empty
MOV AL,[BX] ; Get value from list
MOV AH,AL
TEST B,[BX],010H ; Castled yet ?
JZ PT6A ; No - jump
MOV AL,+6 ; Bonus for castling
TEST B,[BX],080H ; Check piece colorBY: -- XCHNG
;
; CALLS: -- None
;
; ARGUMENTS: -- Attack list addresses.
; Side flag
; ,[SI+BOARD] ; Get piece from board
CMP AL,-1 ; Off board edge ?
JNZ PT5A
JMP PT25 ; Yes - jump
PT5A: MOV BX,P1 ; Save ; Negate value for attacker
XC20: ADD DL,CH ; Total points lost
SAHF
JZ RET ; Return if none
MOV CH,BL ; Prev attckr
; EVAL
;
; CALLS: -- ATTACK
; XCHNG
; LIMIT
;
; ARGUMENTS: -- No
JZ PT6D ; Jump if white
MOV AL,-6 ; Bonus for black castling
JP PT6D ; Jump
PT6A: TEST B,[BX],008H ; Has piece moved 3 ; No - jump
MOV [PTSCK],AL ; Save position as a flag
JP PT23 ; Jump
PT20: MOV BX,PTSW1 ; Previous maximum points won
n value
MOV AL,[P1] ; Get piece under attack
XOR AL,[COLOR] ; Compare color of side just moved with piece
TEST AL,080H ; ; Yes - jump
DEC AL ; Decrement it
PT26: MOV CH,AL ; Save it
MOV AL,[PTSW1] ; Max points won
AND AL,AL ; Is it zero ack list for square
MOV BX,BACT ; Get black attacker count addr
MOV AL,[WACT] ; Get white attacker count
SUB AL,[BX] ; C AL,[BX] ; Add new value
MOV [BX],AL ; Store
PT25: MOV AL,[M3] ; Get current board position
INC AL ; Increment
CMP ALyet ?
JZ PT6X ; No - jump
JP PT6C ; Jump
PT6B: TEST B,[BX],008H ; Has piece moved yet ?
JNZ PT6X ; Yes - jump
PT6C: MCMP AL,[BX] ; Compare to current value
JC PT21 ; Jump if greater than
MOV AL,[BX] ; Load previous max value
MOV [BX],DL Do colors match ?
MOV AL,DL ; Points lost
JNZ PT20 ; Jump if no match
MOV BX,PTSL ; Previous max points lost
CMP AL,?
JZ PT27 ; Yes - jump
MOV AL,[PTSW2] ; 2nd max points won
AND AL,AL ; Is it zero ?
JZ PT27 ; Yes - jump
DEC AL ; ompute count difference
MOV BX,BRDC ; Address of board control
ADD AL,[BX] ; Accum board control score
MOV [BX],AL ; Sa,99 ; At end of board ?
JZ PT25AA
JMP PT5 ; No - jump
PT25AA: MOV AL,[PTSCK] ; Moving piece lost flag
AND AL,AL ; Was OV AL,-2 ; Two point penalty for white
TEST B,[BX],080H ; Check piece color
JZ PT6D ; Jump if white
MOV AL,+2 ; Two poi ; Store new value as max won
PT21: MOV BX,PTSW2 ; Previous 2nd max points won
CMP AL,[BX] ; Compare to current value
JC [BX] ; Compare to current value
JC PT23 ; Jump if greater than
MOV [BX],DL ; Store new value as max lost
MOV SI,[MLPTRJDecrement it
SHR AL ; Divide it by 2
PT27: SUB AL,CH ; Subtract points lost
TEST B,[COLOR],080H ; Is color of side just mve
MOV AL,[P1] ; Get piece on current square
AND AL,AL ; Is it empty ?
JZ PT25 ; Yes - jump
CALL XCHNG ; Evaluate exit lost ?
JZ PT25A ; No - jump
MOV AL,[PTSW2] ; 2nd max points won
MOV [PTSW1],AL ; Store as max points won
XOR AL,AL nt penalty for black
PT6D: MOV BX,BRDC ; Get address of board control
ADD [BX],AL ; Add on penalty/bonus points
PT6X: XOR PT23 ; Jump if greater than
MOV [BX],AL ; Store as new 2nd max lost
PT23: TEST B,[P1],080H ; Test piece color
MOV AL,DH ] ; Load pointer to this move
MOV AL,[M3] ; Get position of lost piece
CMP AL,[SI+MLTOP] ; Is it the one moving ?
JNZ PT2oved white ?
JZ PT28 ; Yes - jump
NEG AL ; Negate for black
PT28: MOV BX,MTRL ; Net material on board
ADD AL,[BX] ; Achange, if any
XOR AL,AL ; Check for a loss
CMP AL,DL ; Points lost ?
JZ PT23 ; No - Jump
DEC DH ; Deduct half a Paw; Zero out 2nd max points won
MOV [PTSW2],AL
PT25A: MOV AL,[PTSL] ; Get max points lost
AND AL,AL ; Is it zero ?
JZ PT26AX,AX ; Zero out attack list
MOV CX,7
MOV BX,ATKLST
XCHG DI,BX
CLD
REP
STOW
XCHG DI,BX
CALL ATTACK ; Build att; Value of piece
JZ PT24 ; Jump if white
NEG AL ; Negate for black
PT24: MOV BX,MTRL ; Get addrs of material total
ADDdd exchange adjustments
MOV BX,MV0 ; Material at ply 0
SUB AL,[BX] ; Subtract from current
MOV CH,AL ; Save
MOV AL,30tive ?
JZ LIM10 ; No - jump
NEG AL ; Make positive
CMP AL,CH ; Compare to limit
JNC RET ; Return if outside limit
**************************
; FUNCTION: -- To limit the magnitude of a given value
; to another given value.L,[SI+BOARD] ; Get piece moved
TEST DH,020H ; Test Pawn promotion flag
JNZ MV15 ; Jump if set
MOV AL,DL ; Piece moved
Get material points
ADD AL,AL ; Multiply by 4
ADD AL,AL
ADD AL,DH ; Add board control
TEST B,[COLOR],080H ; Is color o FNDMOV
; VALMOV
;
; CALLS: -- None
;
; ARGUMENTS: -- None
;************************************** ; Load material limit
CALL LIMIT ; Limit to plus or minus value
MOV DL,AL ; Save limited value
MOV AL,[BRDC] ; Get boaMOV AL,CH ; Output value as is
RET ; Return
LIM10: CMP AL,CH ; Compare to limit
JC RET ; Return if outside limit
MOV
;
; CALLED BY: -- POINTS
;
; CALLS: -- None
;
; ARGUMENTS: -- Input - Value to be limited in the CH
; AND AL,7 ; Clear flag bits
CMP AL,QUEEN ; Is it a queen ?
JZ MV20 ; Yes - jump
CMP AL,KING ; Is it a king ?
JZ MV30 f side just moved white ?
JNZ PT30 ; No - jump
NEG AL ; Negate for white
PT30: ADD AL,80H ; Rescale score (neutral = 80H**********************
MOVE: MOV BX,[MLPTRJ] ; Load move list pointer
INC BX ; Increment past link bytes
INC BX
MV1: MOV rd control points
MOV BX,BC0 ; Board control at ply zero
SUB AL,[BX] ; Get difference
MOV CH,AL ; Save
MOV AL,[PTSCK] AL,CH ; Output value as is
RET ; Return
;***********************************************************
; MOVE ROUTIN register.
; - Value to limit to in the AL register.
; Output - Limite ; Yes - jump
MV5: MOV DI,[M2] ; Load "to" pos board index
OR DL,008H ; Set piece moved flag
MOV [DI+BOARD],DL ; Insert p)
MOV [VALM],AL ; Save score
MOV SI,[MLPTRJ] ; Load move list pointer
MOV [SI+MLVAL],AL ; Save score in move list
RET AL,[BX] ; "From" position
MOV [M1],AL ; Save
INC BX ; Increment pointer
MOV AL,[BX] ; "To" position
MOV [M2],AL ; S ; Moving piece lost flag
AND AL,AL ; Is it zero ?
JZ PT29 ; Yes - jump
MOV CH,0 ; Zero board control points
PT29: MOVE
;***********************************************************
; FUNCTION: -- To execute a move from the move list on the
d value in the AL register.
;************************************************************
LIMIT: TEST CH,080H ; Is value negaiece at new position
MOV B,[SI+BOARD],0 ; Empty previous position
TEST DH,040H ; Double move ?
JNZ MV40 ; Yes - jump
M; Return
;***********************************************************
; LIMIT ROUTINE
;********************************ave
INC BX ; Increment pointer
MOV DH,[BX] ; Get captured piece/flags
MOV SI,[M1] ; Load "from" pos board index
MOV D AL,6 ; Load board control limit
CALL LIMIT ; Limit to plus or minus value
MOV DH,AL ; Save limited value
MOV AL,DL ; ; board array.
;
; CALLED BY: -- CPTRMV
; PLYRMV
; EVAL
; OV AL,DH ; Get captured piece, if any
AND AL,7
CMP AL,QUEEN ; Was it a queen ?
JNZ RET ; No - return
MOV BX,POSQ ; Adposition
MOV [M2],AL ; Save
INC BX ; Increment pointer
MOV DH,[BX] ; Get captured piece/flags
MOV SI,[M2] ; Load "toy restoring the board array to its
; previous position.
;
; CALLED BY: -- VALMOV
; EVAL
;DL,0FBH ; Restore Queen to Pawn
JMP UM5 ; Jump
UM16: AND DL,0F7H ; Clear piece moved flag
JMP UM6 ; Jump
UM20: MOV BX,0: MOV BX,POSK ; Get saved King position
TEST DH,020H ; Castling ?
JZ MV21 ; No - jump
OR DL,010H ; Set King castled fif any
AND AL,8FH ; Clear flags
MOV [SI+BOARD],AL ; Return to board
TEST DH,040H ; Was it a double move ?
JNZ UM40 ; dr of saved Queen position
TEST DH,080H ; Is Queen white ?
JZ MV10 ; Yes - jump
INC BX ; Increment to black Queen pos
" pos board index
MOV DL,[SI+BOARD] ; Get piece moved
TEST DH,020H ; Was it a Pawn promotion ?
JNZ UM15 ; Yes - jump
M FNDMOV
; ASCEND
;
; CALLS: -- None
;
; ARGUMENTS: -- None
;**********************POSQ ; Addr of saved Queen position
UM21: TEST DL,080H ; Is Queen white ?
JZ UM22 ; Yes - jump
INC BX ; Increment to bllag
JMP MV21 ; Jump
MV40: MOV BX,[MLPTRJ] ; Get move list pointer
ADD BX,8 ; Increment to next move
JMP MV1 ; Jump (2Yes - jump
MOV AL,DH ; Get captured piece, if any
AND AL,7 ; Clear flag bits
CMP AL,QUEEN ; Was it a Queen ?
JNZ RET MV10: XOR AL,AL ; Set saved position to zero
MOV [BX],AL
RET ; Return
MV15: OR DL,004H ; Change Pawn to a Queen
JMP MOV AL,DL ; Get piece moved
AND AL,7 ; Clear flag bits
CMP AL,QUEEN ; Was it a Queen ?
JZ UM20 ; Yes - jump
CMP AL,KIN***************************************
UNMOVE: MOV BX,[MLPTRJ] ; Load move list pointer
INC BX ; Increment past link bytes
ack Queen pos
UM22: MOV AL,[M1] ; Get previous position
MOV [BX],AL ; Save
JMP UM5 ; Jump
UM30: MOV BX,POSK ; Address nd part of dbl move)
;**********************************************************
; UN-MOVE ROUTINE
;*******************; No - return
MOV BX,POSQ ; Address of saved Queen pos
TEST DH,080H ; Is Queen white ?
JZ UM10 ; Yes - jump
INC BX ;V5 ; Jump
MV20: MOV BX,POSQ ; Addr of saved Queen position
MV21: TEST DL,080H ; Is Queen white ?
JZ MV22 ; Yes - jump
G ; Was it a King ?
JZ UM30 ; Yes - jump
UM5: TEST DH,010H ; Is this 1st move for piece ?
JNZ UM16 ; Yes - jump
UM6: M
INC BX
UM1: MOV AL,[BX] ; Get "from" position
MOV [M1],AL ; Save
INC BX ; Increment pointer
MOV AL,[BX] ; Get "to" of saved King pos
TEST DH,040H ; Was it a castle ?
JZ UM21 ; No - jump
AND DL,0EFH ; Clear castled flag
JMP UM21 ; J***************************************
; FUNCTION: -- To reverse the process of the move routine,
; thereb Increment to black Queen pos
UM10: MOV AL,[M2] ; Queen's previous position
MOV [BX],AL ; Save
RET ; Return
UM15: AND INC BX ; Increment to black Queen pos
MV22: MOV AL,[M2] ; Get new Queen position
MOV [BX],AL ; Save
JMP MV5 ; Jump
MV3OV DI,[M1] ; Load "from" pos board index
MOV [DI+BOARD],DL ; Return to previous board pos
MOV AL,DH ; Get captured piece, ump
UM40: MOV BX,[MLPTRJ] ; Load move list pointer
ADD BX,8 ; Increment to next move
JMP UM1 ; Jump (2nd part of dbl move board, then if
; the move is legal, it evaluates it, and then
; restores the boaard position.ter
MOV AL,[VALM] ; Get new move value
CMP AL,[SI+MLVAL] ; Less than list value ?
JNC SR30 ; No - jump
SR25: MOV [BX],CHMOV
; SORTM
; ASCEND
; UNMOV
;
; ARGUMENTS: -- None
;*******************CL
MOV CL,[BX] ; Link to next move
INC BX
MOV CH,[BX]
MOV [BX],DH ; Store to link in list
DEC BX
MOV [BX],DL
XORlist
CALL POINTS ; Assign points to move
JMP UNMOVE ; Restore board array
;****************************************)
;**********************************************************
; SORT ROUTINE
;*****************************************
;
; CALLED BY: -- SORT
;
; CALLS: -- MOVE
; INCHK
; PINFND
; POI ; Link new move into list
DEC BX
MOV [BX],CL
JMP SR5 ; Jump
SR30: XCHG DX,BX ; Swap pointers
JMP SR15 ; Jump
*****************************************
FNDMOV: MOV AL,[MOVENO] ; Currnet move number
CMP AL,1 ; First move ?
JNZ L0003
AL,AL ; End of list ?
CMP AL,CH
JZ RET ; Yes - return
SR10: MOV [MLPTRJ],CX ; Save list pointer
CALL EVAL ; Evaluate *****************
; FIND MOVE ROUTINE
;*********************************************************
; FUNCTION: -- To determi*****************
; FUNCTION: -- To sort the move list in order of
; increasing move value scores.
;
; CANTS
; UNMOV
;
; ARGUMENTS: -- None
;*************************************************************
EVAL: C
;**********************************************************
; EVALUATION ROUTINE
;******************************************
CALL BOOK ; Yes - execute book opening
L0003:
XOR AL,AL ; Initialize ply number to zero
MOV [NPLY],AL
MOV BX,0 ; Inimove
MOV BX,[MLPTRI] ; Begining of move list
MOV CX,[MLPTRJ] ; Restore list pointer
SR15: MOV DL,[BX] ; Next move for compne the computer's best move by
; performing a depth first tree search using
; the techniques oLLED BY: -- FNDMOV
;
; CALLS: -- EVAL
;
; ARGUMENTS: -- None
;***************************************************ALL MOVE ; Make move on the board array
CALL INCHK ; Determine if move is legal
AND AL,AL ; Legal move ?
JZ EV5 ; Yes ****************
; FUNCTION: -- To evaluate a given move in the move list.
; It first makes the move on thetialize best move to zero
MOV [BESTM],BX
MOV BX,MLIST ; Initialize ply list pointers
MOV [MLNXT],BX
MOV BX,PLYIX-2
MOVare
INC BX
MOV DH,[BX]
XOR AL,AL ; At end of list ?
CMP AL,DH
JZ SR25 ; Yes - jump
MOV SI,DX ; Transfer move poinf alpha-beta pruning.
;
; CALLED BY: -- CPTRMV
;
; CALLS: -- PINFND
; POINTS
; GEN**********
SORTM: MOV CX,[MLPTRI] ; Move list begin pointer
MOV DX,0 ; Initialize working pointers
SR5: MOV BH,CH
MOV BL,- jump
XOR AL,AL ; Score of zero
MOV [VALM],AL ; For illegal move
JMP UNMOVE ; Jump
EV5: CALL PINFND ; Compile pinned [MLPTRI],BX
MOV AL,[KOLOR] ; Initialize color
MOV [COLOR],AL
MOV BX,SCORE ; Initialize score index
MOV [SCRIX],BX
MOV AL,[NPLY] ; Get ply counter
MOV BX,PLYMAX ; Max ply number
CMP AL,[BX] ; Beyond max ply ?
JZ FM17
JMP FM35 ; Yes - juist ?
JNZ FM15A
JMP FM25 ; Yes - jump
FM15A: MOV [MLPTRJ],DX ; Save current move pointer
MOV BX,[MLPTRI] ; Save in ply pO] ; Get move number
MOV [PMATE],AL ; Save
MOV AL,0FFH ; Pre-set checkmate score
JMP FM36 ; Jump
FM30: MOV AL,[NPLY] ; nt ply count
XOR AL,AL ; Initialize mate flag
MOV [MATEF],AL
CALL GENMOV ; Generate list of moves
MOV AL,[NPLY] ; Curr; Increment move number
FM20: MOV BX,[SCRIX] ; Load score table pointer
MOV AL,[BX] ; Get score two plys above
INC BX ; I AL,[PLYMAX] ; Get max ply number
ADD AL,2 ; Add 2
MOV CH,AL ; Save as counter
XOR AL,AL ; Zero out score table
FM1: Mmp
FM17: MOV AL,[COLOR] ; Get current color
XOR AL,80H ; Get opposite color
CALL INCHK1 ; Determine if King is in check
ointer list
MOV [BX],DL
INC BX
MOV [BX],DH
MOV AL,[NPLY] ; Current ply counter
MOV BX,PLYMAX ; Maximum ply number ?
Get ply counter
CMP AL,1 ; At top of tree ?
JZ RET ; Yes - return
CALL ASCEND ; Ascend one ply in tree
MOV BX,[SCRIX]ent ply counter
MOV BX,PLYMAX ; Address of maximum ply number
CMP AL,[BX] ; At max ply ?
JNC L0004
CALL SORTM ; No - cncrement to current ply
MOV [SCRIX],BX ; Save it
INC BX
MOV [BX],AL ; Save score as initial value
JMP FM5 ; Jump
FM25OV [BX],AL
INC BX
DEC CH
JNZ FM1
MOV [BC0],AL ; Zero ply 0 board control
MOV [MV0],AL ; Zero ply 0 material
CALL PIN AND AL,AL ; In check ?
JZ FM35 ; No - jump
JMP FM19 ; Jump (One more ply for check)
FM18: MOV SI,[MLPTRJ] ; Load move pCMP AL,[BX] ; Compare
JC FM18 ; Jump if not max
CALL MOVE ; Execute move on board array
CALL INCHK ; Check for legal m ; Load score table pointer
INC BX ; Increment to current ply
INC BX
MOV AL,[BX] ; Get score
DEC BX ; Restore pointerall sort
L0004:
MOV BX,[MLPTRI] ; Load ply index pointer
MOV [MLPTRJ],BX ; Save as last move pointer
FM15: MOV BX,[MLPTRJ]: MOV AL,[MATEF] ; Get mate flag
AND AL,AL ; Checkmate or stalemate ?
JNZ FM30 ; No - jump
MOV AL,[CKFLG] ; Get check flFND ; Complie pin list
CALL POINTS ; Evaluate board at ply 0
MOV AL,[BRDC] ; Get board control points
MOV [BC0],AL ; Savointer
MOV AL,[SI+MLVAL] ; Get move score
AND AL,AL ; Is it zero (illegal move) ?
JZ FM15 ; Yes - jump
CALL MOVE ; Exove
AND AL,AL ; Is move legal ?
JZ FM16 ; Yes - jump
CALL UNMOVE ; Restore board position
JMP FM15 ; Jump
FM16: MOV
DEC BX
JMP FM37 ; Jump
JFM15: JMP FM15
FM35: CALL PINFND ; Compile pin list
CALL POINTS ; Evaluate move
CALL UNMOV ; Load last move pointer
MOV DL,[BX] ; Get next move pointer
INC BX
MOV DH,[BX]
MOV AL,DH
AND AL,AL ; End of move lag
AND AL,AL ; Was King in check ?
MOV AL,80H ; Pre-set stalemate score
JZ FM36 ; No - jump (stalemate)
MOV AL,[MOVENe
MOV AL,[MTRL] ; Get material count
MOV [MV0],AL ; Save
FM5: MOV BX,NPLY ; Address of ply counter
INC B,[BX] ; Incremeecute move on board array
FM19: XOR B,[COLOR],80H ; Toggle color, is new color white ?
JS FM20 ; No - jump
INC B,[MOVENO] E ; Restore board position
MOV AL,[VALM] ; Get value of move
FM36: OR B,[MATEF],001H ; Set mate flag
MOV BX,[SCRIX] ; LoadY] ; Decrement ply counter
MOV BX,[MLPTRI] ; Load ply list pointer
DEC BX ; Load pointer to move list top
DEC BX
MOV DEE ROUTINE
;*********************************************************
; FUNCTION: -- To adjust all necessary parameters to
BM5: ADD B,[BX],6 ; Increment to black moves
MOV SI,[MLPTRJ] ; Pointer to opponents 1st move
MOV AL,[SI+MLFRP] ; Get "from"est move pointer
MOV AL,[SCORE+1] ; Get best move score
CMP AL,0FFH ; Was it a checkmate ?
JNZ JFM15 ; No - jump
MOV BMOV
;
; CALLS: -- None
;
; ARGUMENTS: -- None
;***********************************************************
BOOK: P score table pointer
FM37: CMP AL,[BX] ; Compare to score 2 ply above
JC FM40 ; Jump if less
JZ FM40 ; Jump if equal
NX,[BX]
MOV [MLNXT],DX ; Update move list avail ptr
DEC BX ; Get ptr to next move to undo
DEC BX
MOV DX,[BX]
MOV [MLPT
; ascend one ply in the tree.
;
; CALLED BY: -- FNDMOV
;
; CALLS: -- UNMOV
;
; ARGUMENTS: -- No position
CMP AL,22 ; Is it a Queen Knight move ?
JZ BM9 ; Yes - Jump
CMP AL,27 ; Is it a King Knight move ?
JZ BM9 X,PLYMAX ; Get maximum ply number
SUB B,[BX],2 ; Subtract 2
MOV AL,[KOLOR] ; Get computer's color
TEST AL,080H ; Is it whOP AX
MOV B,[SCORE+1],0 ; Zero out score table
MOV [BESTM],BMOVES-2 ; Init best move ptr to book
MOV BX,BESTM ; InitializeEG AL ; Negate score
INC BX ; Incr score table pointer
CMP AL,[BX] ; Compare to score 1 ply above
JC JFM15 ; Jump if lRI],BX ; Save new ply list pointer
MOV [MLPTRJ],DX ; Save next move pointer
JMP UNMOVE ; Restore board to previous ply
ne
;************************************************************
ASCEND: XOR B,[COLOR],80H ; Toggle color, is new color white ; Yes - jump
CMP AL,34 ; Is it a Queen Pawn ?
JZ BM9 ; Yes - jump
JC RET ; If Queen side Pawn opening -
; return (ite ?
JZ RET ; Yes - return
MOV BX,PMATE ; Checkmate move number
DEC B,[BX] ; Decrement
RET ; Return
FM40: CALL ASC address of pointer
MOV AL,[KOLOR] ; Get computer's color
AND AL,AL ; Is it white ?
JNZ BM5 ; No - jump
MOV AL,0 ; Loess than
JZ JFM15 ; Jump if equal
MOV [BX],AL ; Save as new score 1 ply above
MOV AL,[NPLY] ; Get current ply counter
;**********************************************************
; ONE MOVE BOOK OPENING
;**************************************?
JNS AC5 ; Yes - jump
DEC B,[MOVENO] ; Decrement move number
AC5: DEC [SCRIX] ; Decrement score table index
DEC B,[NPLP-K4)
CMP AL,35 ; Is it a King Pawn ?
JZ RET ; Yes - return (P-K4)
BM9: ADD B,[BX],3 ; (P-Q4)
RET ; Return to CPTRMV
END ; Ascend one ply in tree
JMP FM15 ; Jump
;**********************************************************
; ASCEND TRad random number (0)
TEST AL,001H ; Test random bit
JZ RET ; Return if zero (P-K4)
ADD B,[BX],3 ; P-Q4
RET ; Return
CMP AL,1 ; At top of tree ?
JNZ JFM15 ; No - jump
MOV BX,[MLPTRJ] ; Load current move pointer
MOV [BESTM],BX ; Save as b*******************
; FUNCTION: -- To provide an opening book of a single
; move.
;
; CALLED BY: -- FND
;***********************************************************
; COMPUTER MOVE ROUTINE
;*********************************ET ; No - return
MOV CL,0 ; Set player mate flag
CALL FCDMAT ; Full checkmate ?
RET ; Return
;**************** to Ascii
MOV [MVEMSG],BX ; Put in move message
MOV DX,MVEMSG ; Output move
MOV CL,PRINTBUF
CALL SYSTEM
CP1C: MOV AL,[Cr who is mated
RCL AH
JZ FM04 ; Jump if player
MOV DX,CKMSG ; Print "CHECK"
MOV CL,PRINTBUF
CALL SYSTEM
MOV DX,UWINointer variable
MOV [MLPTRJ],BX ; Pointer to move data
MOV AL,[SCORE+1] ; To check for mates
CMP AL,1 ; Mate against compV
;
; CALLS: -- None
;
; ARGUMENTS: -- The only value passed in a register is the
; flag which tell**************************
; FUNCTION: -- To control the search for the computers move
; and the display of*******************************************
; FORCED MATE HANDLING
;**********************************************************OLOR] ; Should computer call check ?
MOV CH,AL
XOR AL,80H ; Toggle color
MOV [COLOR],AL
CALL INCHK ; Check for check
; Output "YOU WIN"
MOV CL,PRINTBUF
CALL SYSTEM
JP FM08 ; Jump
FM04: MOV DX,CKMSG ; Print "CHECK"
MOV CL,PRINTBUF
Cuter ?
JNZ CP0C ; No - jump
MOV CL,1 ; Computer mate flag
CALL FCDMAT ; Full checkmate ?
CP0C: CALL MOVE ; Produce mos FCDMAT whether the computer
; or the player is mated.
;***************************************************** that move on the board
; and in the move list.
;
; CALLED BY: -- DRIVER
;
; CALLS: -- FNDMOV
; *
; FUNCTION: -- To examine situations where there exits
; a forced mate and determine whether or
; AND AL,AL ; Is enemy in check ?
MOV AL,CH ; Restore color
MOV [COLOR],AL
JZ CP24 ; No - return
MOV DX,CKMSG ; OutputALL SYSTEM
MOV DX,IWIN ; Output "I WIN"
MOV CL,PRINTBUF
CALL SYSTEM
FM08: POP BX ; Remove return addresses
POP BX
Mve on board array
MOV SI,[MLPTRJ] ; Get pointer to move
MOV DH,[SI+MLTOP] ; "To" position of the move
CALL BITASN ; Conve******
FCDMAT: MOV AL,[MOVENO] ; Current move number
MOV CH,AL ; Save
MOV AL,[PMATE] ; Move number where mate occurs
SUB FCDMAT
; MOVE
; BITASN
; INCHK
;
; ARGUMENTS: -- None
;*** not the current move is checkmate. If it is,
; a losing player is offered another game,
; "check"
MOV CL,PRINTBUF
CALL SYSTEM
CP24: MOV AL,[SCORE+1] ; Check again for mates
CMP AL,0FFH ; Player mated ?
JNZ ROV CL,INCHAR ; Input any char to play again
CALL SYSTEM
JMP DRIVER ; Jump (Rest of game init)
;*********************rt to Ascii
MOV [MVEMSG+3],BX ; Put in move message
MOV DH,[SI+MLFRP] ; "From" position of the move
CALL BITASN ; Convert AL,CH ; Number of moves till mate
AND AL,AL ; Checkmate ?
JNZ RET ; No - return
RCR AH
TEST CL,001H ; Check flag fo********************************************************
CPTRMV: CALL FNDMOV ; Select best move
MOV BX,[BESTM] ; Move list p while a loss for the computer signals the
; King to tip over in resignation.
;
; CALLED BY: -- CPTRM**************************************
; BOARD INDEX TO ASCII SQUARE NAME
;***************************************************BX] ; Get first char
CMP AL,"R" ; Restart game ?
JNZ PL05 ; Jump if not restart
JMP DRIVER
PL05: MOV AL,CH ; Get inpu; CALLED BY: -- DRIVER
;
; CALLS: -- ASNTBI
; VALMOV
;
; ARGUMENTS: -- None
;*******************nd outputs the board index in register AL.
; CF = 0 if ok. CF = 1 if invalid.
;*******************************ide
DEC DH ; Get rank on 1-8 basis
ADD AL,60H ; Convert file to Ascii (a-h)
MOV BL,AL ; Save
MOV AL,DH ; Rank
ADD ; Jump
;************************************************************
; ASCII SQUARE NAME TO BOARD INDEX
;**********************
; FUNCTION: -- To translate a hexadecimal index in the
; board array into an ascii description
;t length
CMP AL,5 ; Long enough ?
JC PL08 ; Jump if less than 5 chars
CALL ASNTBI ; Convert "from" to a board index
J*****************************************
PLYRMV: MOV DX,BUFFER ; Ask for input
MOV CL,INBUF
CALL SYSTEM
MOV DX,CRLF ; O*****************************
ATBINX: INC BX ; Increment pointer to skip a char
ASNTBI: MOV AL,[BX] ; Ascii file letter (a -AL,30H ; Convert rank to Ascii (1-8)
MOV BH,AL ; Save
RET ; Return
;********************************************************************************************
; FUNCTION: -- To convert an algebraic square name in
; Asc of the square in algebraic chess notation.
;
; CALLED BY: -- CPTRMV
;
; CALLS: -- DIVIDE
;
; ARGUC PL08 ; Jump if invalid
MOV [MVEMSG],AL ; Move list "from" position
CALL ATBINX ; Convert "to" to a board index
JC PL08utput CRLF
MOV CL,PRINTBUF
CALL SYSTEM
MOV BX,BUFFER+1 ; Point to input length
MOV AL,[BX] ; Get input length
OR AL,A h)
INC BX
SUB AL,41H ; File 1 - 8
JC RET ; Not file letter
CMP AL,8 ; Check upper bound
CMC
JC RET ; Invalid
**************
; PLAYERS MOVE ANALYSIS
;***********************************************************
; FUNCTION: -- To acceii to a hexadecimal board index.
; This routine also checks the input for
; validity.
;
; CAMENTS: -- Board index input in register DH and the
; Ascii square name is output in register BX.
;********** ; Jump if invalid
MOV [MVEMSG+1],AL ; Move list "to" position
CALL VALMOV ; Determines if a legal move
OR AL,AL ; LegaL ; Empty ?
JZ PLYRMV ; Jump if empty
MOV CH,AL ; Save length
LAHF
INC BX ; Point to actual buffer
SAHF
MOV AL,[MOV CH,AL
MOV AL,[BX]
SUB AL,31H ; Rank 1 - 8
JC RET
CMP AL,8 ; Check upper bound
CMC
JC RET
ADD AL,AL ; Multippt and validate the players move
; Also allows player to resign the game by
; entering R.
;
LLED BY: -- PLYRMV
;
; CALLS: -- None
;
; ARGUMENTS: -- Accepts the square name in pointer BX
; a**************************************************
BITASN: SUB AL,AL ; Get ready for division
MOV DL,10
CALL DIVIDE ; Divl ?
JZ RET ; Yes - return
PL08: MOV DX,INVAL ; Output "INVALID MOVE--TRY AGAIN"
MOV CL,PRINTBUF
CALL SYSTEM
JP PLYRMV ly rank by 10
MOV CL,AL
ADD AL,AL
ADD AL,AL
ADD AL,CL
ADD AL,CH ; 10 * rank + file
INC BX ; Increment pointer
ADturn
VA9: CALL UNMOVE ; Un-do move on board array
VA10: MOV AL,1 ; Set flag for invalid move
POP BX ; Restore saved regisMOV AL,[MVEMSG+1] ; "To" position
CMP AL,[SI+MLTOP] ; Is it in list ?
JZ VA7 ; Yes - jump
VA6: MOV DL,[SI+MLPTR] ; Pointer邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋*****************************
VALMOV: MOV BX,[MLPTRJ] ; Save last move pointer
PUSH BX ; Save register
MOV AL,[KOLOR] ; Co
CLRMSG: DB 13,10,"Choose your color (W/B): $"
PLYDEP: DB 13,10,"Ply depth (1-6): $"
MVEMSG: DB " ",13,10,"$"
CKMSG: DB "D AL,21
RET ; Return
;***********************************************************
; VALIDATE MOVE SUBROUTINE
;*****ter
MOV [MLPTRJ],BX ; Save move pointer
RET ; Return
;************************************************************
to next list move
MOV DH,[SI+MLPTR+1]
XOR AL,AL ; At end of list ?
CMP AL,DH
JZ VA10 ; Yes - jump
PUSH DX ; Move t邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋mputers color
XOR AL,80H ; Toggle color
MOV [COLOR],AL ; Store
MOV BX,PLYIX-2 ; Load move list index
MOV [MLPTRI],BX
CHECK",13,10,"$"
UWIN: DB "You win",13,10,"$"
IWIN: DB "I win"
CRLF: DB 13,10,"$"
INVAL: DB "INVALID MOVE--TRY AGAIN",13,10,******************************************************
; FUNCTION: -- To check a players move for validity.
;
; CALLED BY:
; POSITIVE INTEGER DIVISION
;************************************************************
DIVIDE: PUSH CX
MOV CH,8
DD04: So SI register
POP SI
JP VA5 ; Jump
VA7: MOV [MLPTRJ],SI ; Save opponents move pointer
CALL MOVE ; Make move on board ar邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋MOV BX,MLIST+1024 ; Next available list pointer
MOV [MLNXT],BX
CALL GENMOV ; Generate opponents moves
MOV SI,MLIST+1024 ;"$"
BUFFER: DB 7
DS 6
IX: DS 2
IY: DS 2
BC: DS 2
DE: DS 2
HL: DS 2
 -- PLYRMV
;
; CALLS: -- GENMOV
; MOVE
; INCHK
; UNMOVE
;
; ARGUMAL DH
RCL AL
SUB AL,DL
JS DD05
INC DH
JP DD06
DD05: ADD AL,DL
DD06: DEC CH
JNZ DD04
POP CX
RET
;*******ray
CALL INCHK ; Was it a legal move ?
AND AL,AL
JNZ VA9 ; No - jump
VA8: POP BX ; Restore saved register
RET ; Re邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋 Index to start of moves
VA5: MOV AL,[MVEMSG] ; "From" position
CMP AL,[SI+MLFRP] ; Is it in list ?
JNZ VA6 ; No - jump
邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋ENTS: -- Returns flag in register AL, 0 for valid
; and 1 for invalid move.
;*******************************************************************************
; STANDARD MESSAGES
;*******************************************************
This chess game uses algebraic chess notation. The files are lettered
"a" to "h" and the ranks are numbered 1 to 8. The lower ls each time
MOV DX,CRLF
MOV CL,PRINTBUF
CALL SYSTEM
MOV DX,COMMAND
MOV AX,2522H ;Set vector 34 (terminate)
INT 33
EN: EQU 15
CLOSE: EQU 16
MAKE: EQU 22
DELETE: EQU 19
RDBLK: EQU 39
WRBLK: EQU 40
SETDMA: EQU 26
SELDRV: EQU 14
GETDRV: Eto next position without affecting flags
SAHF
LODW ;Get address of command
JNZ FINDCOM
CALL AX ;Call command
JMP COwill consider
1. All of his possible moves
2. All of your responses to those moves.
3. All of his possible replies to youropy file name
MOV AL,9
SUB AL,CL
MOV [IDLEN],AL
MOV DI,81H
MOV CX,0
PUSH SI
COMTAIL:
LODB
STOB ;Move command eft-hand corner
(from White's viewpoint) is a1.
Moves are entered as ff-tt (f=from, t=to), so to play the white king's
pawnMOV AX,2523H ;Set vector 35 (CTRL-C)
INT 33
GETCOM:
MOV CL,GETDRV
CALL SYSTEM
ADD AL,"A"
MOV CL,OUTCH
MOV DL,AL
CQU 25
PRINTBUF:EQU 9
OUTCH: EQU 2
INBUF: EQU 10
RR: EQU 33
SYSTEM: EQU 5
ORG 100H
PUT 100H
MOV SP,STACK
CLD
MMMAND
SETDRVJ:JMP SETDRV
DRVCHK:
DEC DL ;Adjust for correct drive number
DEC AL ;Check if anything else is on line
responses.
Start at ply depth 2 to get the feel for it.
A move of "R" will restart the game.
tail to 80H
CMP AL,13
LOOPNZ COMTAIL
NOT CL
MOV [80H],CL
POP SI
MOV DI,FCB
CALL PARSENAM
MOV DI,FCB+10H
CALL P up two squares you would enter E2-E4. You must enter your file
letters in upper case, while the computer will always use lowerALL SYSTEM ;Print drive letter
MOV DL,":"
MOV CL,OUTCH
CALL SYSTEM ;Print ":"
MOV DX,LINBUF
MOV CL,INBUF
CALL SYSTOV DL,0 ;Start with drive A
SETDRV:
MOV CL,SELDRV
CALL SYSTEM
COMMAND:
MOV SP,STACK
CLD
MOV AX,CS
MOV SS,AX
MOV JZ SETDRVJ
EXTERNAL:
MOV AL,[SPECDRV]
MOV [IDLEN],AL
PUSH DS
MOV DX,TPA
ADD DX,0FH ;Round to next paragraph
SHR D邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋ARSENAM
MOV AL,[IDLEN]
MOV DL,[SPECDRV]
OR DL,DL ;Check if drive was specified
JNZ DRVCHK
DEC AL ;Check for null com case.
To castle, enter only the king's move. The computer castles the same way.
To capture En Passant, enter your pawn's acEM
MOV DL,10
MOV CL,OUTCH
CALL SYSTEM ;New line
MOV CH,0
MOV SI,FILIFO ;8 spaces
MOV DI,ID
CALL FILLBUF
MOV DI, ES,AX
MOV DS,AX
MOV CX,[6]
SUB CX,TPA
AND CL,80H ;Round down
ROL CX
XCHG CH,CL
MOV [NUMREC],CX ;Number of recordX
SHR DX
SHR DX
SHR DX ;Divide 16
MOV CX,CS
ADD DX,CX ;New segment
MOV DS,DX
MOV AH,SETBASE
INT 33
MOV DX,10FCB: EQU 5CH
DSKRESET:EQU 13
SETBASE:EQU 38
SRCHFRST:EQU 17
SRCHNXT:EQU 18
RENAM: EQU 23
INCHAR: EQU 1
GETFAT: EQU 27
OPmand
JZ GETCOM
MOV SI,COMTAB
FINDCOM:
MOV DI,IDLEN
MOV CL,[SI]
JCXZ EXTERNAL
REPE
CMPB
LAHF
ADD SI,CX ;Bump tual move.
Ply depth is the number of half-turns the computer looks ahead. For
example, with a ply depth of 3, the computer FCB
CALL FILLBUF
MOV SI,LINBUF+2
MOV DI,ID
CALL FILEDRV ;Get COM drive
MOV [SPECDRV],AL
MOV CX,8
CALL COPYNAM ;C0H
MOV CL,SETDMA
CALL SYSTEM
MOV BX,DS ;New segment into BX
POP DS
MOV DX,IDLEN
MOV AH,OPEN
INT 33
OR AL,AL
Je)
MOV CL,OUTCH
MOV DL," "
CALL SYSTEM ;Print space
MOV SI,LINBUF+2+9
MOV CX,3
CALL OUTCNT ;Print 3 chars (ext)
MP AL,13
JZ NOMATCH
CMP AL,"."
JZ RET
STOB
LOOP COPYNAM
NOMATCH:
XOR AL,AL
DEC SI
RET
FILLBUF:
LODB
MOV STOW
STOB ;Fill first 3 bytes with FF
INC AX ;AX = 0
SHR CX
JNC DOFILL
STOB ;Odd byte
DOFILL:
REP
STOW
MOVRET
CMP AL,","
JZ RET
CMP AL,";"
JZ RET
CMP AL,9 ;Check for TAB character
RET
FILEDRV:
CALL NEXTCHR
JZ FILED
INT 33
MOV SI,TPA
OUTLP:
LODB
CMP AL,1AH ;Is EOF?
JZ RET
MOV CL,OUTCH
MOV DL,AL
CALL SYSTEM
JP OUTLP
RET
NZ BADCOM
MOV [IDLEN+RR],0
MOV CX,512 ;512 records
MOV AH,RDBLK
INT 33
MOV DS,BX
MOV ES,BX
MOV SS,BX
MOV SP,40HMOV DX,CRLF
MOV CL,PRINTBUF
CALL SYSTEM ;Print new line
MOV CL,SRCHNXT
JP EACHFILE
OUTCNT:
LODB
PUSH CX
PUSH SI
CL,AL
JCXZ RET
LODB
REP
STOB
JP FILLBUF
DIR:
CMP B,[FCB+1]," "
JNZ HASNAME
MOV SI,FCBFIL
MOV DI,FCB+1
CAL AX,CS
MOV DS,AX
MOV ES,AX
MOV SI,FCBFIL
MOV DI,FCB+1
CALL FILLBUF
MOV DX,FCB
MOV CL,DELETE
CALL SYSTEM ;DeleteRV ;Skip delim
CMP AL,13
JZ NOMATCH
CMP B,[SI],":"
JNZ NOMATCH
SUB AL,40H ;Convert to drive number
INC SI
RET
CLEAR:
MOV DX,ERAMES
MOV CL,PRINTBUF
CALL SYSTEM ;Confirm erase
MOV CL,INCHAR
CALL SYSTEM
CMP AL,"Y"
JZ DOCLEA
MOV AX,0
PUSH AX
MOV AX,100H
PUSH BX
PUSH AX
MOV CL,SETDMA
MOV DX,80H
CALL SYSTEM
RET L
BADCOM:
MOV DX,BAD
MOV DL,AL
MOV CL,OUTCH
CALL SYSTEM
POP SI
POP CX
LOOP OUTCNT
RET
RENAME:
MOV CL,RENAM
MOV DX,FCB
JMP 5
L FILLBUF ;Fill 11 bytes with "?"
HASNAME:
MOV DX,LINBUF+2+1
MOV CL,SETDMA
CALL SYSTEM
MOV CL,SRCHFRST
MOV DX,FCB
E all files
MOV CL,DSKRESET
JMP 5
COPY:
MOV SI,FCB+10H
MOV DI,DSTFCB
MOVB
CMP B,[SI]," " ;Has file name?
JNZ HAS
PARSENAM:
CALL NEXTCHR
JZ ISDELIM
CMP AL,13
JNZ PARSENAM
DEC SI
ISDELIM:
CALL FILEDRV
STOB
MOV CX,11
CALL COR
CMP AL,"y"
JZ DOCLEAR
RET
DOCLEAR:
MOV DL,[FCB]
OR DL,DL
JZ CLRDSK
DEC DL
MOV CL,SELDRV
CALL SYSTEM
CLRDSKNAM
MOV CL,PRINTBUF
CALL SYSTEM
JMP COMMAND
NEXTCHR:
;Convert lower case input to upper case
LODB
CMP AL,"a"-1
J
ERASE:
MOV CL,DELETE
MOV DX,FCB
JMP 5
CREATE:
MOV CL,MAKE
MOV DX,FCB
JMP 5
TYPE:
MOV DX,TPA
MOV CL,SETDMAACHFILE:
CALL SYSTEM
INC AL ;FF = file not found
JZ RET
MOV SI,LINBUF+2+1
MOV CX,8
CALL OUTCNT ;Print 8 chars (namDSTNAM
MOV SI,FCB+1
HASDSTNAM:
MOVB
MOV CX,7
REP
MOVW
MOV DX,FCB
MOV AH,OPEN
INT 33
OR AL,AL
JNZ NOSRC
MOPYNAM
ADD DI,CX
CMP CX,3
JB RET
SUB DI,3
CMP AL,"."
JNZ NOMATCH
MOV CX,3
COPYNAM:
CALL NEXTCHR
JZ NOMATCH
C:
MOV CL,GETFAT
CALL SYSTEM
MOV CX,DX
INC DX
SHR DX
ADD CX,DX
MOV AX,DS
MOV ES,AX
MOV DI,BX
MOV AX,0FFFFH
B DELIM
CMP AL,"z"
JA DELIM
SUB AL,20H ;Lower-case changed to upper-case
DELIM:
CMP AL," "
JZ RET
CMP AL,"="
JZ
CALL SYSTEM
MOV DX,FCB
MOV AH,OPEN
INT 33
OR AL,AL
JNZ RET ;Not found
MOV [FCB+RR],0
MOV CX,512
MOV AH,RDBLKV DX,DSTFCB
MOV AH,DELETE
INT 33
MOV AH,MAKE
INT 33
MOV DX,TPA
MOV AH,SETDMA
INT 33
MOV [FCB+RR],0
MOV [DSTFCBco controllers.
; Select disk controller here
TARBELL:EQU 0
CROMEMCO:EQU 1
; For either disk controller, a custom drive 邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋OV SI,INITTAB
CALL 0,DOSSEG
MOV DX,100H
MOV AH,26 ;Set DMA address
INT 21H
MOV BX,DS
MOV AX,CS
MOV DS,AX
MOV DX 11,"?"
DB 0
SPECDRV:DS 1
NUMREC: DS 2
IDLEN: DS 1
ID: DS 8
COM: DB "COM"
DSTFCB: DS 36
LINBUF:
DB 80H,1,13
D1
READCOM:EQU 88H
WRITECOM:EQU 0A8H
ENDIF
IF TARBELL
DONEBIT:EQU 80H
DISK: EQU 78H
ENDIF
IF CROMEMCO
DONEBIT:EQ+RR],0
CPYBLK:
MOV DX,FCB
MOV CX,[NUMREC]
MOV AH,RDBLK
INT 33
JCXZ CPYDONE
MOV DX,DSTFCB
MOV AH,WRBLK
INT 33
table may be defined
CUSTOM: EQU 0
; If Tarbell disk controller, select one-sided or two-sided drives
; and single or doubl邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋,FCB
MOV AH,15
INT 21H
OR AL,AL
JNZ COMERR
MOV [FCB+33],0
MOV CX,200H
MOV AH,39 ;Load file
INT 21H
JCXZ COMERS 80H
FILIFO:
DB 8," "
DB 0
DB 12," ",4,0
DB 12," ",8,0
DB 0
COMTAB:
DB 4,"DIR"
DW DIR
DB 7,"RENAME"
DW U 1
DISK: EQU 30H
ENDIF
DOSSEG: EQU 80H
ORG 0
PUT 100H
BASE: EQU 0F0H
STAT: EQU BASE+7
DAV: EQU 2
TBMT: EQU 1
OR AL,AL
JZ CPYBLK
MOV DX,NOSPCE
MOV AH,PRINTBUF
INT 33
CPYDONE:
MOV DX,DSTFCB
MOV AH,CLOSE
INT 33
RET
NOSRC:
e density controller
DOUB1SIDE:EQU 0
DOUB2SIDE:EQU 0
SNGL1SIDE:EQU 0
; If Cromemco disk controller, select drive configura邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋R
CMP AL,1
JNZ COMERR
MOV DS,BX
MOV ES,BX
MOV SS,BX
MOV SP,40H
XOR AX,AX
PUSH AX
MOV DX,80H
MOV AH,26
INT RENAME
DB 6,"ERASE"
DW ERASE
DB 7,"CREATE"
DW CREATE
DB 5,"TYPE"
DW TYPE
DB 6,"CLEAR"
DW CLEAR
DB 5,"COPY"
D
DATA: EQU BASE+6
PSTAT: EQU BASE+0DH
PDATA: EQU BASE+0CH
JMP INIT
JMP STATUS
JMP INP
JMP OUTP
JMP PRINT
JMP AUX
MOV DX,NOTFND
MOV AH,PRINTBUF
INT 33
RET
DS 40
STACK:
BADNAM: DB "Bad command or file name"
CRLF: DB 13,10,"$"
tion
SMALLCRO:EQU 0 ;3 small drives
COMBCRO:EQU 1 ;2 large drives and 1 small one
LARGECRO:EQU 0 ;4 large drives
WD1791; I/O System for 86-DOS.
; Assumes a CPU Support card at F0 hex for character I/O,
; with disk drivers for Tarbell or Cromem21H
PUSH BX
MOV AX,100H
PUSH AX
RET L
COMERR:
MOV DX,BADCOM
MOV AH,9 ;Print string
INT 21H
EI
STALL: JP STALLW COPY
DB 0
TPA:
IN
JMP AUXOUT
JMP READ
JMP WRITE
JMP RETL ;Flush buffers
INIT:
MOV AX,CS
MOV DS,AX
MOV SS,AX
MOV SP,STACK
M
ERAMES: DB "Erase all files (Y/N)? $"
NOTFND: DB "Source file not found$"
NOSPCE: DB "Insufficient disk space$"
FCBFIL: DB: EQU DOUB1SIDE+DOUB2SIDE
WD1771: EQU CROMEMCO+SNGL1SIDE
IF WD1791
READCOM:EQU 80H
WRITECOM:EQU 0A0H
ENDIF
IF WD177
BADCOM: DB 13,10,"Bad or missing Command Interpreter",13,10,"$"
FCB: DB 1,"COMMAND COM"
DS 24
STATUS:
IN STAT
AND ent into track table
ADD BX,TRKTAB ;BX now points to track counter for this drive
MOV DI,BX
MOV AL,DL
SEG CS
XCHG AL,[BX,AX ; Prepare to index on drive number
SEG CS
MOV AL,[BX+DRVTAB]
OUT DISK+4 ; Select drive
IF CROMEMCO
OR AL,80H15ms head load delay if selecting a different drive
SEG CS
CMP AH,[CURDRV]
SEG CS
MOV [CURDRV],AH
JZ RET
OR AL,4
RSI,128
LOOP WRTLP
OR AL,AL
RET L
ERROR:
SEG CS
MOV B,[DI],-1
RET L
SEEK:
; Inputs:
; AL = Drive number
; P:
ENDIF
CMP DH,26 ;Check for overflow onto next track
JBE PUTSEC
STEP:
INC DL
MOV DH,1
MOV AL,58H ;Step in witAL,DAV
RET L
AUXIN:
INP:
IN STAT
AND AL,DAV
JZ INP
IN DATA
AND AL,7FH
RET L
AUXOUT:
OUTP:
PUSH AX
OUTLPDI] ;Xchange current track with desired track
OUT DISK+1 ;Inform controller chip of current track
CMP AL,DL
JZ ONTRK
M ;Set auto-wait bit
ENDIF
MOV AH,AL ;Save for later
XCHG AX,DX
MOV DL,26 ;26 sectors per track
IF CROMEMCO
TEET
READSECT:
CALL SETUP
JC RET
MOV BL,10
RDAGN:
OR AL,READCOM
OUT DISK
PUSH SI
RLOOP:
IN DISK+4
TEST AL,DONBX = Disk transfer address in DS
; CX = Number of sectors to transfer
; DX = Logical record number of transfer
; Function:
;h update, no verify
CALL DCOM
SEG CS
INC B,[DI] ;Update track counter
PUTSEC:
MOV AL,DH
OUT DISK+2
MOV CX,80H
:
IN STAT
AND AL,TBMT
JZ OUTLP
POP AX
OUT DATA
RET L
PRINT:
PUSH AX
PRINLP:
IN PSTAT
AND AL,TBMT
JZ PRINOV BH,3 ;Seek retry count
CMP AL,-1 ;Head position known?
JNZ NOHOME ;If not, home head
TRYSK:
CALL HOME
NOHOME:
MOST DH,10H ;Check if small disk
JNZ BIGONE
MOV DL,18 ;18 sectors on small disk track
BIGONE:
ENDIF
DIV AL,DL ;CompuEBIT
IF TARBELL
JZ RDONE
ENDIF
IF CROMEMCO
JNZ RDONE
ENDIF
IN DISK+3
MOV [SI],AL
INC SI
LOOP RLOOP
RD Seeks to proper track.
; Outputs:
; AH = Drive select byte
; DL = Track number
; DH = Sector number
; SI = Disk transfer aIF TARBELL
IN DISK ;Get head load bit
ENDIF
IF CROMEMCO
IN DISK+4 ;Get head load bit
XCHG AL,AH
OUT DISK+4 ;TurLP
POP AX
OUT PDATA
RET L
READ:
CALL SEEK
RDLP:
PUSH CX
CALL READSECT
POP CX
JC ERROR
INC DH
ADD SI,128
V AL,DL
OUT DISK+3
MOV AL,1CH
CALL MOVHEAD
AND AL,98H
JZ ONTRK
DEC BH
JNZ TRYSK
STC
ONTRK:
RET
SETUP:
te track and sector
XCHG AX,DX
INC DH ;First sector is 1, not zero
SEG CS
MOV BL,[BX+TRKPT] ;Get this drive's displacemONE:
POP SI
CALL GETSTAT
AND AL,9CH
JZ RET
MOV AL,0
DEC BL
JNZ RDAGN
STC
RET
WRITESECT:
CALL SETUP
JC Rddress in DS
; DI = pointer to drive's track counter in CS
; CX unchanged.
MOV SI,BX ; Save transfer address
CBW
MOV n on auto-wait
XCHG AL,AH
ENDIF
NOT AL
AND AL,20H ;Check head load status
JZ CHKDRV
MOV AL,4
CHKDRV:
; Turn on
LOOP RDLP
OR AL,AL
RETL: RET L
WRITE:
CALL SEEK
WRTLP:
PUSH CX
CALL WRITESECT
POP CX
JC ERROR
INC DH
ADD IF CROMEMCO
TEST AH,10H ;Check for small disk
JNZ CHKSTP
CMP DH,18 ;Only 18 sectors/track on small ones
JA STEP
CHKSTET
MOV BL,10
WRTAGN:
OR AL,WRITECOM
OUT DISK
PUSH SI
WRLOOP:
IN DISK+4
TEST AL,DONEBIT
IF TARBELL
JZ WRDONEDW 330
IF DOUB1SIDE
DRVTAB: DB 0,10H,20H,30H
TRKPT: DB 0,1,2,3
TRKTAB: DB -1,-1,-1,-1
ENDIF
IF DOUB2SIDE
DRVTAB: D 1771 we're now on track 0
RET
FASTSK:
MOV AL,6FH
OUT 4
MOV AL,18H
CALL DCOM
SKWAIT:
IN 4
TEST AL,40H
JNZ SKH
TRKPT: DB 0,0,1
TRKTAB: DB -1,-1
INITTAB:DB 3 ;Number of drives
DW LDRIVE
DW FAT0
DW LDRIVE
DW FAT1
DW SDRIVE
DK
MOV AL,50
DELAY:
DEC AL
JNZ DELAY ;Delay 100 microseconds
GETSTAT:
IN DISK+4
TEST AL,DONEBIT
IF TARBELL
JNZ 1 for 8" drives
; Bit 3 = 1 for drive 3
; Bit 2 = 1 for drive 2
; Bit 1 = 1 for drive 1
; Bit 0 = 1 for drive 0
IF LARG
ENDIF
IF CROMEMCO
JNZ WRDONE
ENDIF
LODB
OUT DISK+3
LOOP WRLOOP
WRDONE:
POP SI
CALL GETSTAT
AND AL,09CHB 0,40H,10H,50H
TRKPT: DB 0,0,1,1
TRKTAB: DB -1,-1
ENDIF
IF SNGL1SIDE
DRVTAB: DB 0F2H,0E2H,0D2H,0C0H
TRKPT: DB 0,1,2,3WAIT
MOV AL,7FH
OUT 4
MOV AL,0
RET
ENDIF
DS 20H
STACK:
LFAT: EQU 300H
SFAT: EQU 200H
CURDRV: DS 1
LDRIVW FAT2
ORG 0
FAT0: DS LFAT
FAT1: DS LFAT
FAT2: DS SFAT
ENDIF
IF SMALLCRO
; Table for 3 small drives
DRVTAB: DB 21 GETSTAT
ENDIF
IF CROMEMCO
JZ GETSTAT
ENDIF
IN DISK
RET
IF CROMEMCO
RESTORE:
MOV AL,0C4H ;READ ADDRESS cECRO
; Table for four large drives
DRVTAB: DB 31H,32H,34H,38H
TRKPT: DB 0,0,1,1
TRKTAB: DB -1,-1
INITTAB:DB 4 ;Number of dr
JZ RET
MOV AL,0
DEC BL
JNZ WRTAGN
STC
RET
HOME:
IF CROMEMCO
TEST AH,10H ;Check 8" (PerSci) bit
JNZ RESTOR
TRKTAB: DB -1,-1,-1,-1
ENDIF
IF TARBELL
INITTAB:DB 4 ;Number of drives
DW LDRIVE
DW FAT0
DW LDRIVE
DW FAT1
DWE:
DB 1 ;Records/sector
DB 4 ;Records/cluster
DW 52 ;Reserved records
DB 6 ;FAT size (records)
DB 2 ;Number of FATs
H,22H,24H
TRKPT: DB 0,1,2
TRKTAB: DB -1,-1,-1
INITTAB:DB 3
DW SDRIVE
DW FAT0
DW SDRIVE
DW FAT1
DW SDRIVE
DW FAT2
ommand to keep head loaded
OUT DISK
MOV AL,77H
OUT 4
CHKRES:
IN 4
AND AL,40H
JZ RESDONE
IN DISK+4
TEST AL,DONEBives
DW LDRIVE
DW FAT0
DW LDRIVE
DW FAT1
DW LDRIVE
DW FAT2
DW LDRIVE
DW FAT3
ORG 0
FAT0: DS LFAT
FAT1: DS E
ENDIF
MOV BL,3
TRYHOM:
MOV AL,0CH
CALL DCOM
AND AL,98H
JZ RET
MOV AL,58H ;Step in with update
CALL DCOM
D LDRIVE
DW FAT2
DW LDRIVE
DW FAT3
ORG 0
FAT0: DS LFAT
FAT1: DS LFAT
FAT2: DS LFAT
FAT3: DS LFAT
ENDIF
; CromeDB 8 ;Number of directory records
DW 482 ;Number of clusters on drive
SDRIVE:
DB 1
DB 2
DW 54
DB 4
DB 2
DB 8
ORG 0
FAT0: DS SFAT
FAT1: DS SFAT
FAT2: DS SFAT
ENDIF
IF CUSTOM
; Table for 2 large drives
DRVTAB: DB 31H,32H
TRIT
JZ CHKRES
IN DISK
JP RESTORE ;Reload head
RESDONE:
MOV AL,7FH
OUT 4
CALL GETSTAT
MOV AL,0
OUT DISK+1 ;TellLFAT
FAT2: DS LFAT
FAT3: DS LFAT
ENDIF
IF COMBCRO
; Table for two large drives and one small one
DRVTAB: DB 31H,32H,24EC BL
JNZ TRYHOM
RET
MOVHEAD:
IF CROMEMCO
TEST AH,10H ;Check 8" (PerSci) bit
JNZ FASTSK
ENDIF
DCOM:
OUT DISmco drive select byte is derived as follows:
; Bit 7 = 0
; Bit 6 = X (unassigned)
; Bit 5 = 1 (motor on)
; Bit 4 = 0 for 5",KPT: DB 0,1
TRKTAB: DB -1,-1
INITTAB:DB 2
DW LDRIVE
DW FAT0
DW LDRIVE
DW FAT1
ORG 0
FAT0: DS LFAT
FAT1: DS LFAIG:
MOV DX,TOBIG
JMP ERROR
NOTEOF:
MOV DX,NOEOF
JMP ERROR
SETUP:
MOV DX,START
MOV AH,SETDMA
INT 33
MOV CX,[6]
NOTBAK
;Open input file
MOV AH,OPEN
MOV DX,FCB
INT 33
MOV [HAVEOF],AL
OR AL,AL
JZ HAVFIL
MOV DX,NEWFIL
MOV AH, MOV DX,BADCOM
MOV AH,PRINTBUF
INT 33
JP COMMAND
GETNUM:
CALL SKIP
CMP AL,"."
JZ CURLIN
CMP AL,"#"
JZ MAXLI邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋V DX,COMBUF
MOV AH,INBUF
INT 33
MOV AL,10
CALL OUT
MOV [PARAM2],0
MOV B,[QFLG],0
MOV SI,2+COMBUF
CALL GETNUM
MT
ENDIF

SUB CX,80H
MOV [LAST],CX
MOV DI,START-1
TEST B,[HAVEOF],-1
JNZ SAVEND
CALL NUMRECS
MOV [FCB+RR],0
MOV DX,FCB
MPRINTBUF
INT 33
HAVFIL:
MOV SI,FCB
MOV DI,FCB2
MOV CX,9
REP
MOVB
MOV SI,BAK
MOVW
MOVB
MOV AH,DELFIL
MOV DN
MOV DX,0
NUMLP:
CMP AL,"0"
JB RET
CMP AL,"9"
JA RET
SUB AL,"0"
MOV BX,DX
SHL DX
SHL DX
ADD DX,BX
SHL DXFCB: EQU 5CH
RENAM: EQU 23
OPEN: EQU 15
CLOSE: EQU 16
MAKE: EQU 22
DELFIL: EQU 19
RDBLK: EQU 39
WRBLK: EQU 40
SETDMA: EQOV [PARAM1],DX
CALL SKIP1
CMP AL,","
JNZ CHKNXT
INC SI
CHKNXT:
DEC SI
CALL GETNUM
MOV [PARAM2],DX
CALL SKIP1
邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋OV AH,RDBLK
INT 33
CMP AL,2
JZ TOOBIG
JCXZ SAVEND
ROR CX
XCHG CL,CH
ADD DI,CX ;Point to last byte
DOWN
MOV ALX,FCB2
INT 33
MOV AL,"$"
MOV DI,FCB2+9
STOB
STOB
STOB
MOV AH,DELFIL
INT 33
;Create .$$$ file to make sure dire
CBW
ADD DX,AX
LODB
JP NUMLP
CURLIN:
MOV DX,[CURRENT]
LODB
RET
MAXLIN:
MOV DX,-1
LODB
RET
COMTAB: DU 26
PRINTBUF:EQU 9
OUTCH: EQU 2
INBUF: EQU 10
RR: EQU 33
PROMPT: EQU "*"
ORG 100H
PUT 100H
MOV SP,STACK
MOV CMP AL,"?"
JNZ DISPATCH
MOV [QFLG],AL
CALL SKIP
DISPATCH:
AND AL,5FH
MOV DI,COMTAB
MOV CX,NUMCOM
REPNE
SCAB
J邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋,1AH
REPNE
SCAB
JNZ NOTEOF
REPE
SCAB
INC DI
SAVEND:
CLD
INC DI
MOV B,[DI],1AH
MOV [ENDTXT],DI
MOV B,[COMBctory has room
MOV AH,MAKE
INT 33
OR AL,AL
JZ SETUP
MOV DX,NODIR
JMP ERROR
NOTBAK:
MOV DX,NOBAK
JMP ERROR
TOOBB "SFDLIE",13
NUMCOM: EQU $-COMTAB
TABLE:
DW NOCOM ;No command--edit line
DW ENDED
DW INSERT
DW LIST
DW DELETE
DX,BREAK
MOV AX,2523H
INT 33
MOV SI,BAK
MOV DI,FCB+9
MOV CX,3
;File must not have .BAK extension
REPE
CMPB
JZ NZ COMERR
MOV BX,CX
SHL BX
CALL [BX+TABLE]
JMP COMMAND
SKIP:
LODB
SKIP1:
CMP AL," "
JZ SKIP
RET
COMERR:
邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋UF],128
MOV B,[EDITBUF],255
MOV [POINTER],START
MOV [CURRENT],1
COMMAND:
MOV SP,STACK
MOV AL,PROMPT
CALL OUT
MO DW COMERR
DW COMERR
FINDLIN:
; Inputs
; BX = Line number to be located in buffer (0 means last line)
; Outputs:
; DXMOV DI,1
DISPLAY:
; Inputs:
; BX = Line number
; SI = Pointer to text buffer
; DI = No. of lines
; Function:
; OuputsDC DL,DL
LOOP CONV
MOV BL,"0"-" "
XCHG AX,DX
CALL LDIG
MOV AL,DH
CALL DIGITS
MOV AL,DL
DIGITS:
MOV DH,AL
SHR SI,2+EDITBUF
MOV DI,[POINTER]
REPLACE:
; Inputs:
; CX = Length of new text
; DX = Length of original text
; SI = Poinnal in 8-character
; format, suppressing leading zeros.
; AX, CX, DX destroyed. No other registers affected.
PUSH BX
MOVRENT]
INC BX ;Default is current line plus one
HAVLIN:
CALL FINDLIN
MOV SI,DI
MOV [CURRENT],DX
MOV [POINTER],SI
JNZ = Actual line found
; DI = Pointer to start of line DX
; Zero set if BX = DX
; AL,CX destroyed. No other registers affected. specified no. of line to terminal, each
; with leading line number.
; Outputs:
; BX = Last line output.
; All registers desAL
SHR AL
SHR AL
SHR AL
CALL LDIG
MOV AL,DH
LDIG:
AND AL,0FH
JZ ZERDIG
MOV BL,0
ZERDIG:
ADD AL,"0"
SUB AL,ter to new text
; DI = Pointer to old text in buffer
; Function:
; New text replaces old text in buffer and buffer
; size is AL," "
CALL OUT
CALL CONV10
MOV AL,":"
CALL OUT
MOV AL," "
CALL OUT
POP BX
RET
CONV10:
;Inputs:
; BX = RET
CMP SI,[ENDTXT]
JZ RET
MOV DI,2+EDITBUF
MOV CX,254
MOV DL,-1
LOADLP:
LODB
STOB
INC DL
CMP AL,13
LOOPNZ
MOV DX,[CURRENT]
MOV DI,[POINTER]
CMP BX,DX
JZ RET
JA FINDIT
MOV DX,1
MOV DI,START
CMP BX,DX
JZ RET
FINDITtroyed.
MOV CX,[ENDTXT]
SUB CX,SI
JZ RET
MOV BP,[CURRENT]
DISPLN:
PUSH CX
CALL SHOWNUM
POP CX
OUTLN:
LODB
BL
JMP OUT
LIST:
MOV BX,[PARAM1]
OR BX,BX
JNZ CHKP2
MOV BX,[CURRENT]
SUB BX,10
JA CHKP2
MOV BX,1
CHKP2:
adjusted. CX or DX may be zero.
; CX, SI, DI all destroyed. No other registers affected.
CMP CX,DX
JZ COPYIN
PUSH SI
Binary number to be displayed
; Function:
; Ouputs binary number. Five digits with leading
; zero suppression. Zero prints 5 LOADLP
MOV [EDITBUF+1],DL
MOV [OLDLEN],DL
MOV SI,[POINTER]
CALL DISPONE
CALL SHOWNUM
MOV AH,INBUF ;Get input buffer:
MOV CX,[ENDTXT]
SUB CX,DI
MOV AL,10
OR AL,AL ;Clear zero flag
FINLIN:
JCXZ RET
REPNE
SCAB
INC DX
CMP BX,DXCALL OUT
CMP AL,10
LOOPNZ OUTLN
JCXZ RET
DEC DI
JZ RET
CMP BX,BP
LAHF
INC BX
SAHF
JZ OUTLF
CMP BX,BP
JNZCALL FINDLIN
JNZ RET
MOV SI,DI
MOV DI,[PARAM2]
INC DI
SUB DI,BX
JA DISPLAY
MOV DI,21
JP DISPLAY
DISPONE:
PUSH DI
PUSH CX
MOV SI,DI
ADD SI,DX
ADD DI,CX
MOV AX,[ENDTXT]
SUB AX,DX
ADD AX,CX
CMP AX,[LAST]
JAE MEMERR
blanks.
XOR AX,AX
MOV DL,AL
MOV CX,16
CONV:
SHL BX
ADC AL,AL
DAA
XCHG AL,AH
ADC AL,AL
DAA
XCHG AL,AH
A
MOV DX,EDITBUF
INT 33
MOV AL,10
CALL OUT
MOV CL,[EDITBUF+1]
MOV CH,0
JCXZ RET
MOV DL,[OLDLEN]
MOV DH,0
MOV
JNZ FINLIN
RET
SHOWNUM:
; Inputs:
; BX = Line number to be displayed
; Function:
; Displays line number on termi DISPLN
OUTLF:
MOV AL,10
CALL OUT
JP DISPLN
RET: RET
NOCOM:
MOV BX,[PARAM1]
OR BX,BX
JNZ HAVLIN
MOV BX,[CURXCHG AX,[ENDTXT]
MOV CX,AX
SUB CX,SI
CMP SI,DI
JA DOMOV
ADD SI,CX
ADD DI,CX
STD
DOMOV:
INC CX
REP
MOVB
SI,BP
INC SI
MOV CX,[LAST]
SUB CX,BP
REP
MOVB
DEC DI
MOV [ENDTXT],DI
RET
ENDED:
;Write text out to .$$$ fileext marker
MOV SI,CX
SUB CX,DI ;Calculate number of bytes to copy
INC CX
MOV DI,[LAST]
DOWN
REP
MOVB
XCHG SI,D$"
BADCOM: DB "Entry error",13,10,"$"
NEWFIL: DB "New file",13,10,"$"
FCB2: DS 36
PARAM1: DS 2
PARAM2: DS 2
QFLG: DS 1
HAr
; RETURN (0DH) is found. Termination char not moved.
; Outputs:
; AL = Termination character
; CX = No of characters movedKFUL
ERROR:
MOV AH,PRINTBUF
INT 33
JMP 0
NUMRECS:
SUB CX,START
AND CL,80H
ROL CX
XCHG CL,CH
RET
OUT:
PUCLD
POP CX
POP DI
POP SI
COPYIN:
REP
MOVB
RET
DELETE:
MOV BX,[PARAM1]
OR BX,BX
JNZ DELFIN1
MOV BX,[CURRE
MOV DI,[ENDTXT]
MOV CX,128
MOV AL,1AH
REP
STOB
MOV CX,[ENDTXT]
CALL NUMRECS
INC CX
MOV [FCB2+RR],0
MOV DX,FI
UP
INC DI
MOV BP,SI
MOV BX,DX
INLP:
CALL SHOWNUM
MOV DX,EDITBUF
MOV AH,INBUF
INT 33
MOV AL,10
CALL OUT
VEOF: DS 1
OLDLEN: DS 1
CURRENT:DS 2
POINTER:DS 2
LAST: DS 2
ENDTXT: DS 2
COMBUF: DS 2+128
EDITBUF:DS 2+255
DS 40
ALI.
; SI points one past termination character
; DI points to next free location
XOR CX,CX
GETIT:
LODB
CMP AL,1AH
JSH DX
XCHG AX,DX
MOV AH,OUTCH
INT 33
XCHG AX,DX
POP DX
RET
BREAK:
IRET
BAK: DB "BAK"
NOBAK: DB "Cannot edNT]
DELFIN1:
CALL FINDLIN
JNZ RET
MOV [CURRENT],BX
MOV [POINTER],DI
PUSH DI
MOV BX,[PARAM2]
OR BX,BX
JNZ DELFINCB2
MOV AH,WRBLK
INT 33
OR AL,AL
JNZ WRTERR
;Close .$$$ file
MOV AH,CLOSE
INT 33
MOV SI,FCB
LEA DI,[SI+16]
MOMOV SI,EDITBUF+2
CMP B,[SI],1AH
JZ ENDINS
MOV CL,[SI-1]
MOV CH,0
MOV DX,SI
ADD DX,CX
INC DX
CMP DX,BP ;Will it fGN
STACK:
START:
Z RET
CMP AL,0DH
JZ RET
STOB
INC CX
JP GETIT
MEMERR:
MOV DX,MEMFUL
MOV AH,PRINTBUF
INT 33
JMP COMMAND
it .BAK file--rename file$"
NODIR: DB "No room in directory for file$"
TOBIG: DB "File too big to fit into memory$"
NOEOF: DB2
MOV BX,DX
DELFIN2:
INC BX
CALL FINDLIN
MOV DX,DI
POP DI
SUB DX,DI
XOR CX,CX
JP REPLACE
GETTEXT:
; InpV DX,SI
MOV CX,9
REP
MOVB
MOV SI,BAK
MOVW
MOVB
;Rename original file .BAK
MOV AH,RENAM
INT 33
MOV SI,FCB
MOit?
JNC MEMERR
REP
MOVB
MOVB
MOV AL,10
STOB
INC BX
JP INLP
ENDINS:
MOV [POINTER],DI
MOV [CURRENT],BX
MOV 邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋INSERT:
MOV BX,[PARAM1]
OR BX,BX
JNZ INS
MOV BX,[CURRENT]
INC BX
INS:
CALL FINDLIN
MOV CX,[ENDTXT] ;Get End-of-t "No end-of-file mark found in file$"
DSKFUL: DB "Disk full--file write not completed$"
MEMFUL: DB 13,10,"Memory full",13,10,"uts:
; SI points into command line buffer
; DI points to result buffer
; Function:
; Moves [SI] to [DI] until ctrl-Z (1AH) oV DI,FCB2+16
MOV CX,6
REP
MOVW
;Rename .$$$ file to original name
MOV DX,FCB2
INT 33
JMP 0
WRTERR:
MOV DX,DS; HEX2BIN
; Converts Intel hex format files to straight binary
FCB: EQU 5CH
READ: EQU 20
SETDMA: EQU 26
OPEN: EQU 15
CLOV DX,FCB
MOV AH,DELETE
INT 33
MOV AH,CREATE
INT 33
OR AL,AL
JNZ NOROOM
MOV W,[FCB+33],0
MOV DX,START
MOV AH,SET 33
INT 32
ADERR:
MOV DX,ADDR
JMP ERROR
GETCH:
CMP SI,BUFFER+BUFSIZ
JNZ NOREAD
INT 33
OR AL,AL
JNZ ERROR
邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋nt
MOV CL,AL
MOV CH,0
JCXZ DONE
CALL GETBYT ;Get high byte of load address
MOV BH,AL
CALL GETBYT ;Get low byte of 邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋SE: EQU 16
CREATE: EQU 22
DELETE: EQU 19
BLKWRT: EQU 40
BUFFER: EQU 80H
BUFSIZ: EQU 128
ORG 100H
PUT 100H
HEX2BIN:TDMA
INT 33
MOV CX,BP
SUB CX,START-7FH
AND CL,80H
JCXZ EXIT
ROL CX
XCHG CL,CH
MOV AH,BLKWRT
MOV DX,FCB
INT 3
MOV SI,BUFFER
NOREAD:
LODB
CMP AL,1AH
JZ DONE
RET
GETBYT:
CALL HEXDIG
MOV BL,AL
CALL HEXDIG
SHL BL
SHL B邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋load address
MOV BL,AL
ADD BX,START-100H ;Add in offset
MOV DI,BX
CALL GETBYT ;Throw away type byte
READLN:
CMP DI,[邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋
MOV DI,FCB+9
CMP B,[DI]," "
JNZ HAVEXT
MOV SI,HEX
MOVB
MOVW
HAVEXT:
;Get load offset (default is -100H)
MOV AH,3
MOV AH,CLOSE
INT 33
EXIT:
INT 32
NOROOM:
MOV DX,DIRFUL
JMP QUIT
HEX: DB "HEX"
COM: DB "COM"
ERRMES: DB "ErrL
SHL BL
SHL BL
OR AL,BL
RET
HEXDIG:
CALL GETCH
SUB AL,"0"
JC ERROR
CMP AL,9
JBE RET
SUB AL,"A"-"0"-10
FCB: EQU 5CH
FCB2: EQU 6CH
OPEN: EQU 15
CLOSE: EQU 16
MAKE: EQU 22
DELETE: EQU 19
SEQWRT: EQU 21
SETDMA: EQU 26
GETDRV: 6]
JAE ADERR
CMP DI,START
JB ADERR
CALL GETBYT ;Get data byte
STOB
LOOP READLN
CMP DI,BP ;Check if this is the l邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋OPEN
MOV DX,FCB
INT 33
OR AL,AL
JNZ NOFIL
MOV B,[FCB+32],0
MOV AH,READ
MOV BP,START
MOV SI,BUFFER+BUFSIZ ;Flag ior in HEX file--conversion aborted$"
NOFILE: DB "File not found$"
ADDR: DB "Address out of range--conversion aborted$"
DIRFULJC ERROR
CMP AL,15
JBE RET
ERROR:
MOV DX,ERRMES
MOV AH,9
INT 33
DONE:
MOV DI,FCB+9
MOV SI,COM
MOVB
MOVW
MOEQU 25
PRINTBUF:EQU 9
SYSTEM: EQU 5
ORG 100H
PUT 100H
JMP RDCPM
CPMTAB:
DW IBM,IBM,IBM,IBM
DW 0,0,0,0
DW 0,argest address so far
JBE READHEX
MOV BP,DI ;Save new largest
JP READHEX
NOFIL:
MOV DX,NOFILE
QUIT:
MOV AH,9
IN邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋nput buffer as empty
READHEX:
CALL GETCH
CMP AL,":" ;Search for : to start line
JNZ READHEX
CALL GETBYT ;Get byte cou: DB "Disk directory full$"
START:
0,0,0
DW 0,0,0,0
INVSRC:
MOV DX,BADSRC
JMP EXIT
NONAME:
MOV DX,BADFN
JMP EXIT
RDCPM:
MOV SP,100H
CMP B,[F JBE RDALOC
POP SI
POP CX
LOOP RDNXTAL
INC B,[FCB+12] ;Increment extent counter
JMP BEGDIR ;Scan from beginning of diADPARM:
MOV DX,SAMDSK
JMP EXIT
RDENTRY:
ADD SI,3 ;Point to AL array
MOV CX,16 ;16 AL bytes per entry
RDNXTAL:
MSK: EQU 3
EXTMSK: EQU 4
DSISIZ: EQU 5
NUMENT: EQU 7
ALBMP0: EQU 9
ALBMP1: EQU 10
DIRCKS: EQU 11
RESTRK: EQU 13
XLTTBL: DSTDRV:
DEC AX
CMP AL,[DRIVE]
JZ BADPARM
MOV CL,DELETE
MOV DX,DSTFCB
CALL SYSTEM
MOV CL,MAKE
MOV DX,DSTFCB
CALDX,DSKERR
EXIT:
MOV CL,PRINTBUF
CALL SYSTEM
JMP 0
;Translation table made up of WORDs
BIGTRK:
MOV BX,CX
SHL BX
CB+1]," "
JZ NONAME
XOR AL,AL
XCHG AL,[FCB]
OR AL,AL
JNZ HASDRV
MOV CL,GETDRV
CALL SYSTEM
INC AX
HASDRV:
DErectory
DONE:
MOV CL,CLOSE
MOV DX,DSTFCB
CALL SYSTEM
JMP 0
;Read allocation block
READSEC:
XOR DX,DX
MOV BX,[LODB
MOV AH,0
TEST B,[BP+DSISIZ+1],0FFH
JZ SMALDSK
MOV AH,[SI] ;Big disk, use words instead
INC SI
DEC CX
SMALDSEQU 15
;Below is the definition for standard single-density 8" drives
IBM:
DW 26 ;Sectors per track
DB 3 ;Block shift
L SYSTEM
MOV CL,SETDMA
MOV DX,SECBUF
CALL SYSTEM
BEGDIR:
XOR AX,AX
MOV BX,[BP+NUMENT]
READDIR:
MOV DI,DIRBUF
ADD BX,[BP+XLTTBL]
ADD DX,[BX]
JP READABS
RDDONE:
RET
DSKERR: DB 13,10,"HARD DISK ERROR",13,10,"$"
SAMDSK: DB 13,C AX
MOV [DRIVE],AL
CMP AL,15
JA INVSRC ;Invalid drive number
CBW
MOV BX,AX
SHL BX
MOV BP,[BX+CPMTAB]
OR BP,BP
BP+SPT]
DIV AX,BX
ADD AX,[BP+RESTRK]
MOV CX,DX
MUL AX,BX ;Tracks in sectors
MOV DX,AX
OR BH,BH ;Check for >255 secK:
OR AX,AX
JZ DONE
PUSH CX
MOV CH,0
PUSH SI
MOV CL,[BP+BLKSFT]
SHL AX,CL
RDALOC:
PUSH AX
OR AL,CH
PUSH C
DB 7 ;Block mask
DB 0 ;Extent mask
DW 242 ;Disk size - 1
DW 63 ;Directory entries - 1
DB 0C0H ;Directory allocation bi PUSH AX
PUSH BX
CALL READSEC
POP BX
POP AX
MOV SI,DIRBUF
ENUMDIR:
MOV DI,FCB
MOV CX,13
REPE
CMPB
JZ RDEN10,"Source and destination drives must not be the same",13,10,"$"
BADSRC: DB 13,10,"Bad source drive",13,10,"$"
BADFN: DB 13,1
JZ INVSRC
MOV SI,FCB2
MOV DI,DSTFCB
MOVB
CMP B,[FCB2+1]," "
JNZ HASDST
MOV SI,FCB+1
HASDST:
MOV CX,11
REP
tors per track
JNZ BIGTRK ;Use words instead of bytes for xlat table
MOV AX,CX
MOV BX,[BP+XLTTBL]
XLAT
ADD DX,AX ;LoX
MOV DI,SECBUF
CALL READSEC
MOV CL,SEQWRT
MOV DX,DSTFCB
CALL SYSTEM
POP CX
POP AX
INC CH
CMP CH,[BP+BLKMSK]
tmap 0
DB 0 ;Directory allocation bitmap 1
DW 16 ;Directory check vector size
DW 2 ;Tracks to skip
DW MOD6 ;Modulo-6 secTRY
ADD SI,CX
ADD SI,19 ;Point to next entry
DEC BX
JS DONE
CMP SI,DIRBUF+128
JB ENUMDIR
INC AX
JP READDIR
B0,"Bad file name",13,10,"$"
DRIVE: DS 1
DSTFCB: DS 32
DB 0
DIRBUF: DS 128
SECBUF: DS 128
SPT: EQU 0
BLKSFT: EQU 2
BLK MOVB ;Copy file name
MOV AL,[DSTFCB]
OR AL,AL
JNZ DSTDRV
MOV CL,GETDRV
CALL SYSTEM ;Use default drive
INC AX
gical sector number
READABS:
MOV CX,1
MOV BX,DI
MOV AL,[DRIVE]
PUSH BP
INT 37
POP AX
POP BP
JNC RDDONE
MOV tor translate table
MOD6:
DB 0,6,12,18,24
DB 4,10,16,22
DB 2,8,14,20
DB 1,7,13,19,25
DB 5,11,17,23
DB 3,9,15,21
ile
EOL: EQU 0DH
FCB: EQU 5CH
SYSTEM: EQU 5
OPEN: EQU 15
CLOSE: EQU 16
SETDMA: EQU 26
CREATE: EQU 22
DELETE: EQU 19
REA
END:
;'
NOCOM:
CALL PUTCH
PUTLIN:
CMP AL,EOF
JZ END
CALL GETCH
CALL PUTCH
CMP AL,10
JNZ PUTLIN
JP TRANLN
END:
MOAL
JZ BADDRV
DEC AL
JZ BADDRV
MOV [FCB],AL
MOV CX,[SECS]
MOV DX,0
MOV BX,END
MOV AL,0
INT 37
JC RDERR
POPFV CL,DELETE
CALL SYSTEM
MOV DX,PUTFCB
MOV CL,CREATE
CALL SYSTEM
INC AL
MOV DX,NOROOM
ABORTJ:
JZ ABORT
MOV DX,PU
CPMTAB2:
DW 0,0,0,0
DW 0,0,0,0
DW 0,0,0,0
DW 0,0,0,0
D: EQU 20
WRITE: EQU 21
PRNBUF: EQU 9
MOV SP,STACK
MOV DX,HEADER
MOV CL,9
CALL SYSTEM
MOV BX,FCB+12
XOR AL,AL
MO邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋V CH,127
MOV AL,1AH
FILL:
CALL PUTCH
DEC CH
JNZ FILL
MOV DX,PUTFCB
MOV CL,CLOSE
CALL SYSTEM
MOV DX,ENDMES
ABOR
MOV CX,[SECS]
MOV DX,0
MOV BX,END
MOV AL,[FCB]
MOV AH,1
INT 38
JC WRERR
MOV DX,SYSOK
JP QUIT
RDERR:
MOV TFCB
MOV CL,OPEN
CALL SYSTEM
MOV BX,PUTBUF
MOV [PUTPT],BX
MOV BX,GETBUF+80H
MOV [GETPT],BX
TRANLN:
XOR AL,AL
MO邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋V CH,4
CLRFCB:
MOV [BX],AL
INC BX
DEC CH
JNZ CLRFCB
MOV [FCB+32],AL
MOV BX,FCB
MOV DX,PUTFCB
MOV CX,16
UP
M邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋T:
MOV CL,PRNBUF
CALL SYSTEM
JMP 0
DELIM:
CALL GETCH
DELCHK:
CMP AL,EOL
JZ DOLIN
CMP AL,EOF
JZ DOLIN
CMP AL,DX,ERREAD
QUIT:
MOV AH,9
INT 33
INT 32
WRERR:
MOV DX,ERWRIT
JP QUIT
BADDRV:
MOV DX,DRVBAD
JP QUIT
SYSOV [OP1],AL
MOV [OP2],AL
MOV BX,OPCODE
CALL LOAD
MOV BX,OP1
CALL GETOP
MOV B,[BX],0
MOV BX,OP2
CALL GETOP
DOLIN:邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋OV SI,BX
MOV DI,DX
REP
MOVB
MOV DX,DI
MOV BX,SI
MOV [PUTFCB+32],AL
MOV BX,"A"+5300H ;"AS"
MOV [PUTFCB+9],BX
MO; Z80 to 8086 Translator version 2.0
; Runs on the 8086 under 86-DOS
; by Tim Paterson
;
ORG 100H
EOF: EQU 1AH ;End of f';'
JZ DOLIN
CMP AL,' '
JZ RET
CMP AL,':'
JZ RET
CMP AL,','
JZ RET
CMP AL,9
RET
HEX:
AND AL,0FH
ADD AL,90K: DB "System transfered$"
ERREAD: DB "Disk read error$"
ERWRIT: DB "Disk write error$"
DRVBAD: DB "Bad drive specification"
MOV B,[BX],0
CALL FINDOP
ENLIN:
MOV SP,STACK
MOV AL,[CHAR]
CMP AL,';'
JNZ NOCOM
MOV AL,9
CALL PUTCH
MOV AL,'FCB: EQU 5CH
ORG 100H
PUT 100H
JMP START
SECS: DW 52 ;Patch for different configs
START:
MOV AL,[FCB]
OR AL,V AL,'M'
MOV [PUTFCB+11],AL
MOV DX,FCB
MOV CL,OPEN
CALL SYSTEM
INC AL
MOV DX,NOFILE
JZ ABORTJ
MOV DX,PUTFCB
MOH
DAA
ADC AL,40H
DAA
PUTCH:
PUSH BX
PUSH DX
PUSH CX
LAHF
XCHG AH,AL
PUSH AX
XCHG AH,AL
AND AL,7FH
MOV BC AL
LAHF
XCHG AX,BP
SAHF
MOV B,[BX],'['
JP NEXCH
NOTLEF:
CMP AL,')'
JNZ NOTRIT
LAHF
XCHG AX,BP
SAHF
DEC op registers and return.
LOAD:
CALL DELIM
JZ LOADOP
EATLAB:
CALL PUTCH
CALL DELIM
JNZ EATLAB
ENLAB:
MOV AL,':'
MP AL,DL
JZ HAVRW
MOV AL,CL
OR AL,AL
MOV AL,DH
JNZ RWLK
NOTRW:
POP BX
NORW:
POP BX
ENDRW:
POP AX
XCHG AH,AL MOV DX,GETBUF ; Set `DMA address'.
MOV CL,SETDMA
CALL SYSTEM
MOV DX,FCB ; Read the next record from source file.
MOV C MOV [BX],AL
MOV CH,1
LODID:
INC BX
CALL GETCH
CALL IDCHK
JC RWCHK
MOV [BX],AL
INC CH
JP LODID
RWCHK:
LAHF
X,[PUTPT]
MOV [BX],AL
LAHF
INC BX
SAHF
MOV [PUTPT],BX
CMP BX,PUTBUF+80H
JNZ POPRET
MOV DX,PUTBUF
MOV [PUTPT],DAL
LAHF
XCHG AX,BP
SAHF
MOV B,[BX],']'
JP NEXCH
NOTRIT:
MOV [BX],AL
CMP AL,''''
JZ EATQUO
CALL IDCHK
JNC GECALL PUTCH
LOADOP:
MOV BX,OPCODE
EATEM:
CALL DELIM
JZ EATEM
LOADLP:
CALL IDCHK
JNC $+5
JMP OPERR
MOV [BX],AL
SAHF
JMP IDRET
HAVRW:
POP BX
INC CL
MOV [BX],CL
INC BX
POP DX
PUSH BX
MOV AL,CL
MOV BX,IXSI
CMP AL,RSI
L,READ
CALL SYSTEM
OR AL,AL ; Entire record read OK?
MOV AL,EOF ; Force end-of-file character in case
JNZ TESEND ; t XCHG AH,AL
PUSH AX
XCHG AH,AL
PUSH BX
DEC BX
DEC CH
MOV DL,CH
JZ LOOKRW
MOV DL,[BX]
DEC BX
DEC CH
JNZ NORX
MOV CL,SETDMA
CALL SYSTEM
MOV DX,PUTFCB
MOV CL,WRITE
CALL SYSTEM
OR AL,AL
MOV DX,WRTERR
JNZ ABORT
POPRET:
PTID
NEXCH:
INC BX
CALL GETCH
IDRET:
CALL DELCHK
JNZ OPCHAR
CMP AL,' '
JZ OPCHAR
RET
EATQUO:
INC BX
CALL GETINC BX
CALL DELIM
JNZ LOADLP
MOV B,[BX],0
CMP AL,':'
JNZ RET
MOV BX,OPCODE
CALL TRANS
JP ENLAB
GETOP:
XOR AL, JZ IXIY
MOV BX,IYDI
CMP AL,RDI
JNZ NORW
IXIY:
LAHF
XCHG AX,BP
SAHF
JZ NOTENC
LAHF
XCHG AX,BP
SAHF
CALL Ohere is nothing in the record.
MOV BX,GETBUF ; Reset buffer pointer.
GETIT:
MOV AL,[BX] ; Get next character from buffer.
W
LOOKRW:
MOV AL,[BX]
MOV DH,AL
PUSH BX
MOV BX,RWTAB
MOV CX,LENRW
RWLK:
UP
MOV DI,BX
REPNZ
SCAB
MOV BX,DI
OP AX
XCHG AH,AL
SAHF
NOTAF:
POP CX
POP DX
POP BX
RET
;
; Get character from source file.
;
GETCH:
PUSH BX
CH
MOV [BX],AL
CMP AL,';'
JZ L0000
CALL DELCHK
L0000:
CMP AL,''''
JNZ EATQUO
JP NEXCH
IDCHK:
CMP AL,'0'
JC AL
LAHF
XCHG AX,BP
SAHF
GETLP:
CALL DELIM
JZ GETLP
OPCHAR:
CMP AL,'('
JNZ NOTLEF
LAHF
XCHG AX,BP
SAHF
INUTSTR
JP NORW
NOTENC:
LAHF
XCHG AX,BP
SAHF
POP BX
DEC BX
MOV B,[BX],'['
INC BX
ADD AL,RIX-1
MOV [BX],AL
I
LAHF
INC BX ; Point to next character.
SAHF
MOV [GETPT],BX ; Save new pointer.
TESEND:
MOV [CHAR],AL
JP NOTAF ; P
JNZ NOTRW
PUSH BX
PUSH CX
MOV CX,LENRW-1
LAHF
ADD BX,CX
RCR SI
SAHF
RCL SI
MOV AL,[BX]
POP CX
POP BX
CPUSH DX
PUSH CX
MOV BX,[GETPT] ; Get buffer pointer.
CMP BX,GETBUF+80H ; Past end-of-buffer?
JNZ GETIT ; Jump if not.
RET
CMP AL,'9'+1
CMC
JNC RET
CMP AL,40H
JC RET
AND AL,5FH
CMP AL,'A'
JC RET
CMP AL,'Z'+1
CMC
RET
GETID:
NC BX
MOV B,[BX],']'
INC BX
JP ENDRW
RET
FINDOP:
MOV BX,OPCODE
MOV CX,5
XOR AL,AL
UP
MOV DI,BX
REPNZ
SCABMP AL,RDX
RET
ONEOP:
CALL OUTSTR
TRNOP1:
MOV AL,9
TRAN1:
MOV BX,OP1
JP PTRANS
IN:
MOV AL,[OP1]
CMP AL,RAL
rence?
JNZ TWOOPS
MOV AL,[OP1+1] ;Referencing IX as a word?
CMP AL,RIX
JZ TWOOPS
CMP AL,RIY
JZ TWOOPS
MOV AL,[OP2]X,STAX1
JP LSAX
TRNTOK:
CMP AL,' '
JC $+5
JMP PUTCH
PUSH BX
PUSH CX
MOV CL,AL
MOV CH,0
MOV BX,TOKTAB-2
LAHF[BX]
MOV BX,[BX+2]
JMP DX
NEXOP:
RCR SI
TEST B,[BX],080H
RCL SI
LAHF
INC BX
SAHF
JZ NEXOP
MOV DX,4
LAHF
AHF
PUSH BX
MOV CX,80
MOV AL,']'
UP
MOV DI,BX
REPNZ
SCAB
MOV BX,DI
LAHF
DEC BX
SAHF
MOV B,[BX],0
POP B
MOV BX,DI
JNZ OPERR
MOV AL,4
SUB AL,CL
JZ RET
DEC AL
JZ OPERR
MOV CL,AL
DEC BX
DEC BX
OR B,[BX],080H
MO
XCHG DX,BX
MOV BX,OP2
JZ GETPORT
MOV BX,SAVEAX
CALL OUTSTR
CALL OUTSTR
MOV BX,OP2
CALL GETPORT
MOV BX,MOV0
C
CMP AL,20H ;Could be immediate?
MOV AL,9
JC L0001
CALL BFLAG ;Add "B,"
L0001:
CALL TRAN1
JP TRNOP2
TWOOPS:
C
ADD BX,CX
RCR SI
SAHF
RCL SI
LAHF
ADD BX,CX
RCR SI
SAHF
RCL SI
MOV AL,[BX]
CALL PUTCH
INC BX
MOV AL,[ ADD BX,DX
RCR SI
SAHF
RCL SI
JP LOOKOP
OPERR:
MOV BX,OPCODE
CALL OUTSTR
CALL TWOOPS
MOV BX,OPCDER
CALL OUTSTX
NOBRAK:
MOV AL,[BX]
CMP AL,RGCL
JNZ FIXPOR
MOV BX,IO1
CALL OUTSTR
XCHG DX,BX
CALL OUTSTR
MOV AL,RDX
CALL TRV AL,[OPCODE]
SUB AL,'A'
JC OPERR
ADD AL,AL
MOV DL,AL
MOV DH,0
MOV BX,OPTAB
LAHF
ADD BX,DX
RCR SI
SAHF
RCLALL ONEOP
MOV AL,','
CALL PUTCH
MOV AL,RAL
CALL TRNTOK
IODONE:
MOV BX,RESTAX
JMP OUTSTR
OUT:
MOV AL,[OP2]
XCHGALL TRNOP1
TRNOP2:
MOV AL,','
TRAN2:
MOV BX,OP2
PTRANS:
CALL PUTCH
TRANS:
MOV AL,[BX]
LAHF
INC BX
SAHF
OR ALBX]
POP CX
POP BX
OR AL,AL
JZ RET
JMP PUTCH
PUSH:
MOV DX,PUSHAF
JP AFCHK
POP:
MOV DX,POPAF
AFCHK:
MOV AL,[OR
JMP ENLIN
LD:
CALL OUTSTR
MOV BX,OP1
MOV DX,OP2+1
CALL LCHECK
JNZ $+5
JMP LDAX
XCHG DX,BX
DEC BX
INC DX
NTOK
MOV BX,IO2
JMP OUTSTR
GETOUT:
CALL GETPORT
JNC RET
MOV BX,BADIO
JMP OUTSTR
FIXPOR:
XCHG DX,BX
CALL OUTSTR SI
MOV DL,[BX]
INC BX
MOV DH,[BX]
XCHG DX,BX
MOV AL,9
CALL PUTCH
LOOKOP:
MOV AL,[BX]
OR AL,AL
JZ OPERR
MOV DX,BX
MOV BX,OP1
CMP AL,RAL
JZ GETOUT
MOV BX,SAVEAX
CALL OUTSTR
MOV BX,MOVAL
CALL OUTSTR
CALL TRNOP2
MOV BX,C,AL
JZ RET
CALL TRNTOK
JP TRANS
LCHECK:
MOV AL,[BX]
CMP AL,RAL
JNZ RET
MOV SI,DX
LODB
CMP AL,RCX
JZ RET
CP1]
CMP AL,RAX
JNZ ONEOPJ
XCHG DX,BX
OUTSTR:
MOV AL,[BX]
OR AL,AL
JNZ L0002
CALL NEWOP
L0002:
CALL PUTCH
IN CALL LCHECK
JNZ $+5
JMP STAX
;If immediate move, check for byte memory reference
MOV AL,[OP1]
CMP AL,'[' ;Memory refe
XCHG DX,BX
JMP TRANS
LDAX:
MOV BX,LDAX1
LSAX:
CALL OUTSTR
MOV SI,DX
LODB
CALL TRNTOK
JP OUTSTR
STAX:
MOV B DX,OPCODE+1
MOV CH,CL
LOOKLP:
MOV SI,DX
LODB
CMP AL,[BX]
JNZ NEXOP
INC DX
INC BX
DEC CH
JNZ LOOKLP
MOV DX,RLFTB
CALL OUTSTR
MOV BX,OP1
CALL GETOUT
JP IODONE
GETPORT:
MOV AL,[BX]
CMP AL,'['
JNZ NOBRAK
LAHF
INC BX
SC BX
ADD AL,AL
JNC OUTSTR
RET
NEWOP:
MOV AL,13
CALL PUTCH
MOV AL,10
CALL PUTCH
MOV AL,9
RET
LDDR:
CALL OUTX]
CMP AL,'9'+1
JNZ RET
MOV B,[BX],'0'
LAHF
DEC BX
SAHF
JP NEXLAB
EX:
MOV AL,[OP1]
CMP AL,RAX
JZ OUTSTRJ1
ET
MOV AL,CY
RET
RETURN:
MOV AL,[OP1]
OR AL,AL
JZ OUTSTRJ
MOV BX,'R'+4500H ;"RE"
MOV [OP2],BX
MOV BX,'T'
MOV OPS,MOPS,NOPS,OOPS
DW POPS,QOPS,ROPS,SOPS,TOPS
DW UOPS,VOPS,WOPS,XOPS,YOPS
DW ZOPS
AOPS:
DM 'DD'
DW ADD,OPCODE
DM '
CALL OUTSTR
XCHG DX,BX
MOV BX,OPCODE-1
CALL ONEOP
XCHG DX,BX
OUTSTRJ:
JMP OUTSTR
JUMP:
MOV AL,[OP1]
CMP AL,'['X
JMP OUTSTR
BFLAG:
CALL PUTCH
MOV AL,'B'
CALL PUTCH
MOV AL,','
RET
GETBIT:
MOV AL,[OP1+1]
OR AL,AL
STC
STR
MOV BX,BLMOVE
JP OUTSTR
CPDR:
CALL OUTSTR
MOV BX,CMPREP
JP OUTSTR
ADD:
MOV AL,[OP1]
CMP AL,RBX
JZ DAD
ARI MOV AL,[OP1+1]
CMP AL,STP
JZ XTHL
MOV BX,XCHG
CALL OUTSTR
JMP TWOOPS
XTHL:
MOV BX,XTHL1
CALL OUTSTR
CALL TRNOP[OP2+2],BX
JP DIRECT
ONEOPJ1:
JMP ONEOP
DOCALL:
MOV AL,[OP2]
OR AL,AL
JZ ONEOPJ1
CALL FIXCON
DEC AL
XOR AL,1
DC'
DW ARITH,OPCODE
DM 'ND'
DW ARITH,OPCODE
DB 0
BOPS:
DM 'IT'
DW BITSET,TESBIT
DB 0
COPS:
DM 'ALL'
DW DOCAL
JNZ DIRECT
MOV AL,[OP1+1]
MOV [OP1],AL
XOR AL,AL
MOV [OP1+1],AL
DIRECT:
MOV AL,[OP2]
OR AL,AL
JZ ONEOPJ
CALL
JNZ RET
MOV AL,[OP1]
SUB AL,'0'
JC RET
CMP AL,8
CMC
JC RET
MOV CH,AL
INC CH
XOR AL,AL
STC
SHFT:
RCL AL
TH:
CALL OUTSTR
MOV AL,[OP2]
OR AL,AL
JZ $+5
JMP TWOOPS
MOV AL,9
CALL PUTCH
MOV AL,RAL
CALL TRNTOK
MOV AL,',2
MOV BX,XTHL2
OUTSTRJ1:
JMP OUTSTR
PSEUDO:
CALL ONEOP
MOV AL,[OP2]
OR AL,AL
JZ RET
JMP TRNOP2
RET
BITSET:
INC AL
MOV BX,LABEL
CALL OUTCON
MOV BX,OPCODE-1
CALL OUTSTR
MOV AL,[OP2]
OR AL,AL
MOV AL,9
MOV BX,OP2
JZ L000L,OPCODE
DM 'P'
DW ARITH,CMP
DM 'PL'
DW ACCUM,NOT
DM 'PIR'
DW OUTSTR,CPIR
DM 'PDR'
DW CPDR,DOWN
DM 'CF'
DW O FIXCON
MOV BX,OP2
OUTCON:
MOV CH,AL
MOV AL,'J'
CALL PUTCH
MOV AL,CH
CALL TRNTOK
MOV AL,9
CALL PTRANS
MOV AL,
DEC CH
JNZ SHFT
XOR AL,CL
MOV CH,AL
MOV AL,'0'
CALL PUTCH
MOV AL,CH
RCR AL
RCR AL
RCR AL
RCR AL
CALL HEX'
JMP TRAN1
ACCUM:
CALL OUTSTR
MOV AL,9
CALL PUTCH
MOV AL,RAL
JMP TRNTOK
ONEOPJ: JMP ONEOP
DAD:
MOV BX,DAD1
CMOV CL,0
JP SETRES
RES:
MOV CL,-1
SETRES:
CALL OUTSTR
PUSH BX
MOV AL,[OP2]
CMP AL,'['
MOV AL,9
JNZ L0004
CAL3
CALL PTRANS
L0003:
MOV BX,CRLF
CALL OUTSTR
CALL TRANS
CALL OUTSTR
MOV BX,LABEL+4
NEXLAB:
INC [BX]
MOV AL,[BUTSTR,CMC
DB 0
DOPS:
DM 'EC'
DW INCDEC,OPCODE
DM 'JNZ'
DW ONEOP,DJNZ
DM 'AA'
DW OUTSTR,OPCODE
DM 'I'
DW OUTSTCH
CMP AL,ODDPAR
MOV BX,WARNPA
JZ OUTSTRJ
CMP AL,EVEPAR
JZ OUTSTRJ
RET
FIXCON:
MOV AL,[OP1]
CMP AL,RGCL
JNZ R
MOV AL,CH
CALL HEX
MOV AL,'H'
JMP PUTCH
OPTAB:
DW AOPS,BOPS,COPS,DOPS,EOPS
DW FOPS,GOPS,HOPS,IOPS,JOPS
DW KOPS,LALL OUTSTR
CALL TWOOPS
MOV BX,DAD2
JP OUTSTR
INCDEC:
MOV AL,[OP1]
CMP AL,RCX+1 ;16-bit?
JNC ONEOPJ
MOV BX,LAHF
L BFLAG
L0004:
CALL TRAN2
MOV AL,','
CALL PUTCH
CALL GETBIT
MOV BX,BITERR
JNC L0005
CALL OUTSTR
L0005:
POP BR,OPCODE
DM 'W'
DW PSEUDO,OPCODE
DM 'B'
DW PSEUDO,OPCODE
DM 'M'
DW PSEUDO,OPCODE
DM 'S'
DW ONEOP,OPCODE
DB 0
'AX',0,'XCHG',9,'AH,AL',0,'SAHF'
DOWN: DM 'DOWN'
UP: DB 'UP'
BLMOVE: DB 0,'MOV',9,'SI,BX',0,'MOV',9,'DI,DX'
DB 0,'REP',0,'MT'
DW ONEOP,CALL
DB 0
SOPS:
DM 'UB'
DW ARITH,OPCODE
DM 'BC'
DW ARITH,SBB
DM 'LA'
DW ONEOP,SAL
DM 'RA'
DW ON 9,'MOV',9,'DI,[IY]',13,10
RESTAX: DB 0
SAVEAX: DM 'XCHG',9,'AX,SI'
CRLFTB: DM 13,10,9
INB: DM 'INB',9
OUTB: DM 'OUTB',9
XCODE
DB 0
OOPS:
DM 'R'
DW ARITH,OPCODE
DM 'UT'
DW OUT,OUTB
DM 'RG'
DW ONEOP,OPCODE
DB 0
POPS:
DM 'OP'
DW P
BADIO: DM 13,10,'; *** WARNING: Flags not same as Z80.'
BITERR: DM 13,10,' *** ERROR: Cannot determine bit number.'
SETBIT: EOPS:
DM 'X'
DW EX,EXAF
DM 'I'
DW OUTSTR,OPCODE
DM 'XX'
DW OUTSTR,EXX
DM 'QU'
DW ONEOP,OPCODE
DM 'NDIF'
DW OOVB',0,'MOV',9,'DX,DI'
DM 0,'MOV',9,'BX,SI'
CPIR: DB 'UP'
CMPREP: DB 0,'MOV',9,'DI,BX',0,'REPNZ',0,'SCAB'
DM 0,'MOV',9,'BXEOP,SAR
DM 'RL'
DW ONEOP,SHR
DM 'CF'
DW OUTSTR,STC
DM 'ET'
DW BITSET,SETBIT
DB 0
TOPS:
DB 0
UOPS:
DB 0
VOPSCHG: DM 'XCHG'
JMP: DM 'JMP'
JR: DM 'JP'
RCL: DM 'RCL'
RCR: DM 'RCR'
ROL: DM 'ROL'
ROR: DM 'ROR'
SAL: DM 'SAL'
SAR: DM 'OP,OPCODE
DM 'USH'
DW PUSH,OPCODE
DB 0
QOPS:
DB 0
ROPS:
DM 'ET'
DW RETURN,OPCODE
DM 'LA'
DW ACCUM,RCL
DM 'RADM 'LAHF',0,'OR'
DM 0,'SAHF'
RESBIT: DM 'LAHF',0,'AND'
DM 0,'SAHF'
TESBIT: DM 'RCR',9,'SI',0,'TEST'
DM 0,'RCL',9,'SI'
XUTSTR,OPCODE
DB 0
FOPS:
DB 0
GOPS:
DB 0
HOPS:
DM 'ALT'
DW OUTSTR,HLT
DB 0
IOPS:
DM 'NC'
DW INCDEC,OPCODE
D,DI'
DAD1: DM 'LAHF',0,'ADD'
DAD2: DM 0,'RCR',9,'SI',0,'SAHF',0,'RCL',9,'SI'
LAHF: DM 'LAHF'
DM 0,'SAHF'
DJNZ: DB 'DEC',9,:
DB 0
WOPS:
DB 0
XOPS:
DM 'OR'
DW ARITH,OPCODE
DB 0
YOPS:
DB 0
ZOPS:
DB 0
LDAX1: DM 9,'SI,'
DM 0,'LODB'
SSAR'
SHR: DM 'SHR'
STC: DM 'STC'
IRET: DM 'IRET'
HLT: DM 'HLT'
CMC: DM 'CMC'
NOT: DM 'NOT'
MOV0: DB 0
MOV: DM 'MOV'
CMP'
DW ACCUM,RCR
DM 'LCA'
DW ACCUM,ROL
DM 'RCA'
DW ACCUM,ROR
DM 'L'
DW ONEOP,RCL
DM 'R'
DW ONEOP,RCR
DM 'LC'
THL1: DM 'POP',9,'SI',0,'XCHG',9,'SI'
XTHL2: DM 0,'PUSH',9,'SI'
EXX: DB 'XCHG',9,'BX,[HL]',0,'XCHG',9,'DX,[DE]',0
DM 'XCHG',M 'N'
DW IN,INB
DM 'F'
DW ONEOP,OPCODE
DB 0
JOPS:
DM 'R'
DW JUMP,JR
DM 'P'
DW JUMP,JMP
DB 0
KOPS:
DB 0
LO'CH',13,10
DB '; *** WARNING: DJNZ does not affect flags - DEC does.',0
DM 'JNZ'
WARNPA: DM 13,10,'; *** WARNING: Parity flTAX1: DM 9,'DI,'
DM 0,'STOB'
PUSHAF: DB 'LAHF',0,'XCHG',9,'AH,AL',0,'PUSH',9,'AX',0
DM 'XCHG',9,'AH,AL'
POPAF: DM 'POP',9,: DM 'CMP'
SBB: DM 'SBB'
CALL: DM 'CALL'
TOKTAB:
DB 'SIDI'
DB 'PEPOS',0,'NSNZZ',0,'NCC',0
DB 'AXSPBXDXCX'
DB 'BLBHDLD DW ONEOP,ROL
DM 'RC'
DW ONEOP,ROR
DM 'ES'
DW RES,RESBIT
DM 'ETI'
DW OUTSTR,IRET
DM 'ETN'
DW OUTSTR,IRET
DM 'S9,'CX,[BC]'
EXAF: DM 'LAHF',0,'XCHG',9,'AX,BP',0,'SAHF'
MOVAL: DM 0,'MOV',9,'AL'
IXSI: DM 9,'MOV',9,'SI,[IX]',13,10
IYDI: DMPS:
DM 'D'
DW LD,MOV
DM 'DIR'
DW OUTSTR,UP
DM 'DDR'
DW LDDR,DOWN
DB 0
MOPS:
DB 0
NOPS:
DM 'EG'
DW ACCUM,OPag not always same as Z80.'
IO1: DB 'MOV',9,'DI,DX',0,'MOV',9,'DL,CL',0
DM 'XOR',9,'DH,DH',13,10,9
IO2: DM 0,'MOV',9,'DX,DI'HCLCHALIXIY'
RWTAB:
DB 'ABCDEHLBDHSACNZNPMPPII'
LENRW: EQU $-RWTAB
DB 0,0,0,0,0,0,0,'CELPF',0,'C',0,'Z',0,0,'OEYX'
HEADER邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋U $
ORG 1 ;This is really just for equates without EQU
RSI: DS 1
RDI: DS 1
ODDPAR: DS 1
EVEPAR: DS 1
DS 5 ;MINUS,PLUS,NO邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋: DB 13,10,'Z80 to 8086 Translator version 2.0',13,10,'$'
NOROOM: DB 13,10,'Insufficient directory space to create file',13,10邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋T ZERO,ZERO,NOT CARRY
CY: DS 1
RAX: DS 1
STP: DS 1
RBX: DS 1
RDX: DS 1
RCX: DS 1
RBL: DS 1
RBH: DS 1
RDL: DS 1
RDH: DS邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋,'$'
NOFILE: DB 13,10,'File not found',13,10,'$'
ENDMES: DB 13,10,'Translation complete',13,10,'$'
WRTERR: DB 13,10,'Out of d邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋 1
RGCL: DS 1
RCH: DS 1
RAL: DS 1
RIX: DS 1
RIY: DS 1
邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋isk space',13,10,'$'
OPCDER: DM 13,10,'*** Opcode Error '
CRLF: DM 13,10
LABEL: DB 'L0000',0
DM ':',9
PUTPT: DS 2
GETPT: 邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋DS 2
CHAR: DS 1
DB 0
OPCODE: DS 80
OP1: DS 80
OP2: DS 80
PUTBUF: DS 128
GETBUF: DS 128
PUTFCB: DS 33
DS 50
STACK: EQ邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋邋