File: serial16.a86 Page 1 1 ; Use "gencmd serial data[m100]" when producing CMD file 2 3 ; print control constants 4 5 cr equ 00Dh ; carriage return 6 lf equ 00Ah ; line feed 7 bell equ 007h ; self-explanatory 8 bs equ 008h ; backspace 9 vt equ 00Bh ; vertical tab 10 11 ; ccpm call function codes 12 13 ccpm equ 224 ; ccpm interrupt 14 15 c_read equ 1 ; request single character from console 16 c_write equ 2 ; send single character to console 17 c_writebuf equ 9 ; print string terminated by '$' 18 drv_dpb equ 31 ; get DBP offset and segment base 19 drv_resetall equ 13 ; reset disk system 20 drv_set equ 14 ; select disk drive reg DL=disk # 21 ; (0=A,1=B,etc.) 22 mc_max equ 53 ; find available memory space 23 24 ; bdos function codes for direct BIOS calls 25 26 s_bios equ 50 ; direct BIOS call function code 27 read_code equ 13 ; read a 128 byte sector 28 write_code equ 14 ; write a 128 byte sector 29 30 ; program constants 31 32 blank equ 0E5h ; data which an empty (blank) 33 ; sector will contain 34 false equ -1 35 true equ 0 36 37 cseg 38 39 start: 40 ; init serial_number 41 mov cx,length ser_def 42 mov al,'0' 43 mov bx,offset serial_number 44 initlop10: 45 mov byte ptr[bx],al 46 inc bx 47 loop initlop10 48 49 ; give sign on 50 call clear ; clear the monitor screen 51 mov dx,offset msg0 ; print sign on message 52 call pmsg 53 54 ; prompt operator for source and destination drives 55 mov dx,offset msg12 ; send source message to 56 call pmsg ; console 57 call get_char ; get disk code 58 sub al,'A' ; correct it 59 mov dskS,al ; store code for source disk 60 mov dx,offset msg13 ; send destination message File: serial16.a86 Page 2 61 call pmsg ; to console 62 call get_char ; get disk code 63 sub al,'A' ; correct it 64 mov dskD,al ; store code for dest disk 65 66 ; prompt operator for source disk 67 mov dx,offset msg14 ; send message 68 call pmsg_wait 69 70 ; the reset function clears out any previous information pertaining 71 ; to format, sector size, density, etc. and the next time a disk is 72 ; selected those values will be reinitialized. 73 mov cl,drv_resetall ; reset disks 74 int ccpm 75 76 ; when a disk is selected, CP/M initializes the Disk Parameter Header 77 ; and the Disk Parameter Block to conform with the format of the 78 ; selected disk. 79 mov al,dskS ; select source disk 80 mov disk,al 81 mov cl,s_bios 82 mov dx,offset sel_dsk_tab 83 int ccpm 84 85 ; when the "select disk" function is performed using a direct BIOS call 86 ; the offset of the DPH (in system's extra segment) is returned in the 87 ; BX register. the first word of the DPH is the offset of the sector 88 ; translation table for the system. 89 mov xlt_offset,bx ; save offset of system's 90 ; sector translation table 91 92 ; move DPB into program data area 93 cld 94 mov cl,drv_dpb ; get system extra segment 95 int ccpm ; value and offset of DPB 96 push es ; save ES value 97 mov si,bx ; init source pointer 98 mov es,data_base 99 mov di,offset DPB 100 pop ds ; get system extra seg into DS 101 mov cx,15 ; init byte counter 102 rep movsb 103 push ds ; save system extra seg value 104 push es ; restore DS value 105 pop ds 106 107 ; get system sector translation table into data segment of program 108 pop es ; recover extra seg value 109 mov bx,xlt_offset ; get offset of trans table 110 mov si,es:word ptr[bx] ; into SI 111 test si,si ; if SI = 0 then system doesn't 112 jnz has_table ; have a translation table 113 mov bx,offset xlt_tab ; which means that I'll have 114 mov cx,spt ; to init "xlt_tab" myself 115 mov al,0 116 initlop0: 117 mov byte ptr[bx],al 118 inc al 119 inc bx 120 loop initlop0 File: serial16.a86 Page 3 121 mov al,1 ; set skew factor = 1 122 jmps init_addr_tab 123 has_table: 124 push es ; save extra seg again 125 mov bx,xlt_offset ; get offset of trans table 126 mov di,offset xlt_tab ; DI = offset of program sector 127 ; translation table 128 mov cx,spt ; use sectors/track as 129 ; counter value 130 mov es,data_base ; init ES value 131 pop ds ; init DS 132 rep movsb 133 push es ; restore old DS value 134 pop ds 135 136 ; make sure that serial numbers that cross sector boundries will be 137 ; found 138 init_addr_tab: 139 sub ax,ax ; init address offset 140 mov si,offset xlt_tab ; SI -> xlt-tab 141 mov cx,spt ; init counter 142 sub dh,dh ; DH = 0 143 initlop9: 144 mov bx,offset addr_tab 145 mov dl,byte ptr[si] ; get sector number 146 inc si ; move pointer 147 sub dl,xlt_tab ; subtract 1st sector number 148 add dl,dl ; multiply by 2 149 add bx,dx ; BX -> correct table entry 150 mov word ptr[bx],ax ; put address into table 151 add ax,128 ; AX = AX+bytes/sectorz 152 loop initlop9 153 154 ; depending on the system, each physical sector on a diskette can 155 ; be made up of a number of logical sectors (128 bytes long). the 156 ; following code analyses the system sector translate table to 157 ; determine the number of logical sectors in a physical sector. 158 mov bx,offset xlt_tab ; BX -> xlt_tab 159 xltlop0: 160 mov al,byte ptr[bx] ; AL = table entry 161 inc bx ; BX -> next byte in table 162 inc al 163 cmp al,byte ptr[bx] ; see if the two numbers are in 164 je xltlop0 ; the right order 165 sub bx,offset xlt_tab ; if they aren't then calculate 166 ; how long the sequence was 167 mov spb,bx ; and save the value 168 ; calculate skew of system sector translation table 169 mov al,xlt_tab[bx] ; get byte at xlt_tab+spb 170 sub al,xlt_tab ; and subtract byte at xlt_tab 171 mov bx,spb ; now divide by sectors/block 172 sub ah,ah ; prepare of division 173 div bl 174 mov skew,al 175 ; tell operator about skew 176 skew_prompt: 177 push ax ; save system skew 178 call clear ; clear screen 179 mov dx,offset msg21 ; send message 180 call pmsg File: serial16.a86 Page 4 181 pop dx ; recover skew 182 or dl,030h ; make it ASCII 183 mov cl,c_write 184 int ccpm 185 ; ask operator if he/she would like to change the sector skew 186 mov dx,offset msg16 187 call pmsg 188 call get_char ; get Y/N response 189 cmp al,'N' ; check for No 190 je dont_change 191 ; ask for new skew factor 192 mov dx,offset msg17 193 call pmsg 194 call get_1num 195 mov skew,al 196 ; make new sector translation table using skew factor supplied by 197 ; operator 198 mov si,offset xlt_tab ; BX is pointer into xlt_tab 199 mov bl,byte ptr[si] ; init beginning sector number 200 mov bh,bl 201 mov dl,sptbyte ; calculate sectors/track + 202 add dl,bl ; first sector number 203 mov cl,skew ; init loop counter 204 sub ch,ch 205 xltlop1: 206 push cx ; save loop counter 207 xltlop2: 208 mov cx,spb ; init sectors/block counter 209 push bx ; save sector # registers 210 xltlop3: 211 mov byte ptr[si],bh ; put sector number into table 212 inc si ; increment pointer 213 inc bh ; increment sector number 214 loop xltlop3 215 mov ax,spb ; calculate new starting sector 216 mov cl,skew 217 mul cl 218 pop bx ; recover sector # registers 219 add bh,al ; add skew*spt to starting 220 ; sector number 221 cmp bh,dl ; compare new starting sector # 222 ; to first sector # + spt 223 jb xltlop2 224 add bl,spbbyte ; add sectors/block to 1st 225 ; starting sector number 226 mov bh,bl ; init starting sector 227 ; number of the next sector 228 ; block 229 pop cx ; recover loop counter 230 loop xltlop1 231 dont_change: 232 ; ok, now calculate many how bytes there are on a track. 233 ; bytes/track = sectors/track * logical sector size 234 mov ax,spt 235 mov bx,128 236 mul bx 237 mov bpt,ax ; save value 238 239 mov cl,mc_max ; find 64k or less of free 240 mov dx,offset mcb ; memory File: serial16.a86 Page 5 241 int ccpm 242 243 ; check the disk for blank tracks starting at last track. blank 244 ; tracks won't be copied 245 mov dx,offset msg1 ; tell operator about search 246 call pmsg 247 cld ; set direction flag forward 248 mov dx,offset msg7 ; send 'Reading' message 249 call pmsg 250 mov cx,last_trk ; initialize track counter 251 scan_loop: 252 push cx ; save track counter 253 mov track,cl ; get current track 254 mov al,cl ; make track number ascii 255 call make_ascii 256 mov dx,offset ascii_trk ; print it 257 call pmsg 258 mov dma_addr,0 ; initialize dma offset 259 call seek ; seek to track 260 call read ; read a track 261 mov al,blank ; init AL with the character 262 ; which is found in blank 263 ; (empty) sectors 264 mov es,m_base ; init segment reg 265 mov di,0 ; offset is set to zero 266 mov cx,bpt ; how many bytes to scan 267 repe scasb ; scan until ZF=1 or CX=0 268 jne data_found ; if ZF=1 then have found data 269 call erase_trk ; erase old track message 270 pop cx ; otherwise scan another track 271 loop scan_loop ; if CX<>0 272 273 ; the diskette is blank if program flow reaches this point 274 mov dx,offset error_msg0 275 call pmsg ; inform operator that the 276 call abort ; source disk is blank and 277 ; abort operation 278 279 data_found: 280 pop cx ; if data is found then save 281 mov last_trk,cx ; the number of the non-blank 282 ; track 283 ; the information on the source disk will more than likely need to be 284 ; paged into memory. the following code calculates how many pages 285 ; or blocks will be needed. 286 mov ax,m_length ; calculate number of bytes 287 mov bx,16 ; available to be used for 288 mul bx ; a buffer area 289 mov bx,bpt 290 div bx 291 mov cx,last_trk ; CX will contain number of 292 sub cx,off ; tracks to be copied 293 cmp ax,cx ; if block1 track count to ser_def 510 mov cx,length ser_def ; init counter 511 repe cmpsb ; do compare 512 jne verlop3 513 pop cx ; recover byte counter 514 sub cx,length ser_def-1 ; correct it 515 pop si ; recover 1st buffer pointer 516 add si,length ser_def-1 ; correct it 517 jmps verlop1 518 ; verification failed so inform operator to try it again 519 verlop3: 520 call clear 521 mov dx,offset error_msg7 522 call pmsg 523 jmp new_disk 524 verlop2: 525 pop cx ; recover track counter 526 loop verlop0 527 528 dont_verify: 529 call clear ; clear monitor screen 530 cld ; insert current serial number 531 mov cx,length ser_def ; into remove message 532 mov es,data_base 533 mov si,offset serial_number 534 mov di,offset serial_2 535 rep movsb 536 537 mov dx,offset msg4 ; prompt operator to remove 538 call pmsg ; copy 539 540 call inc_serial ; increment current serial File: serial16.a86 Page 10 541 ; number 542 543 jmp new_disk ; do another disk 544 545 546 ; read a track from the selected disk 547 read: 548 mov io_tab,read_code 549 jmps track_io 550 551 ; write a track to the selected disk drive 552 write: 553 mov io_tab,write_code 554 jmps track_io 555 556 ; do track input or output on selected disk drive 557 track_io: 558 mov cx,4 ; initialize io retry counter 559 io_retry: 560 push cx ; save retry counter 561 call track_setup ; init dma base address 562 mov sector,0 ; start with sector #0 563 mov cx,spt ; init sector counter 564 io_lop: 565 push cx ; save sector counter 566 call sectran ; perform sector translation 567 mov dx,offset set_sector ; set sector thru ccpm 568 mov cl,s_bios 569 int ccpm 570 571 mov dx,offset set_dma_offset ; set dma offset thru ccpm 572 mov cl,s_bios 573 int ccpm 574 575 mov cl,s_bios ; set read/write func thru ccpm 576 mov dx,offset io_tab 577 int ccpm 578 test al,al ; io error if not zero 579 jnz io_error ; tell operator about io error 580 inc sector ; next sector to read 581 pop cx ; recover sector counter 582 loop io_lop 583 584 pop cx ; clean up stack 585 mov ax,bpt ; init dma_addr for next 586 add dma_addr,ax ; track 587 ret 588 io_error: 589 pop cx ; clean up stack 590 call home ; home disk 591 pop cx ; recover retry counter 592 loop io_retry 593 ret 594 595 track_setup: 596 mov ax,m_base ; initialize dma base address 597 mov dma_base,ax 598 mov cl,s_bios 599 mov dx,offset set_dma_base 600 int ccpm File: serial16.a86 Page 11 601 ret 602 603 ; do logical to physical sector translation 604 sectran: 605 sub ah,ah 606 mov al,sector 607 mov bx,offset xlt_tab 608 xlat xlt_tab 609 mov tsector,al 610 sub ah,ah 611 sub al,xlt_tab 612 add al,al 613 mov bx,offset addr_tab 614 add bx,ax 615 mov ax,word ptr[bx] 616 add ax,dma_addr 617 mov dma_offset,ax 618 ret 619 620 ; home the selected drive 621 home: 622 mov track,0 623 jmps seek 624 625 ; seek to the selected track on the source drive 626 seekS: 627 mov al,trackS 628 inc trackS 629 jmps display_trk 630 631 ; seek to the selected track on the destination drive 632 seekD: 633 mov al,trackD 634 inc trackD 635 display_trk: 636 mov track,al 637 call make_ascii ; make track # ascii 638 mov dx,offset ascii_trk ; send track number to 639 call pmsg ; console 640 641 ; seek to the selected track on the selected drive 642 ; "track" = desired track # 643 seek: 644 mov cl,s_bios 645 mov dx,offset seek_trk_tab 646 int ccpm 647 ret 648 649 ; select source disk 650 selectS: 651 mov dl,dskS 652 jmps select 653 654 ; select destination disk 655 selectD: 656 mov dl,dskD 657 658 ; select a disk drive for future operations 659 select: 660 mov cl,drv_set File: serial16.a86 Page 12 661 int ccpm 662 ret 663 664 ; get starting serial number from operator 665 get_serial: 666 mov dx,offset msg2 ; send prompt message 667 call pmsg ; to console 668 669 mov dx,offset con_buf0 ; point to console input buffer 670 mov cl,10 ; CP/M read console buffer 671 int ccpm 672 cmp buf0_len,length ser_def ; check for correct number 673 ; of digits 674 jne bad_serial 675 ret 676 677 bad_serial: 678 mov error_msg2,length ser_def 679 or error_msg2,030h ; make it ASCII 680 mov dx,offset error_msg1 681 call pmsg 682 jmps get_serial 683 684 ; get from the operator how many serial fields are on the source 685 ; diskette. this is a safeguard to help prevent the wrong disk 686 ; from being used. 687 get_cnt: 688 mov dx,offset msg6 ; send prompt message 689 call pmsg ; to console 690 call get_2num ; get a number (0-99) 691 ; from operator 692 mov count_num,al ; save number 693 ret 694 695 ; input two ASCII numbers into buffer 1 and translate them into a 696 ; binary number which is returned in the AL register 697 get_2num: 698 mov dx,offset con_buf1 ; get address of buffer 699 mov cl,10 700 int ccpm 701 cmp buf1_len,2 ; can't have more than 702 jbe input_ok0 ; two digits 0-99 703 input_err0: 704 mov dx,offset error_msg6 ; tell operator about 705 call pmsg ; error and try again 706 jmp get_2num 707 input_ok0: 708 cmp buf1_len,0 ; need at least one 709 je input_err0 ; digit. tell operator 710 ; if there isn't 711 mov bx,offset input_num ; bx -> input buffer 712 mov cl,buf1_len ; (cl) = digit count 713 sub ch,ch ; zero upper half of cx 714 add bx,cx ; make bx point to 715 dec bx ; units digit of input 716 717 mov dh,byte ptr[bx] ; get units digit 718 and dh,00Fh ; mask off upper nybble 719 loop tens ; if (cx) <> 2 then get 720 ; tens digit File: serial16.a86 Page 13 721 jmp got_it ; only had one digit 722 tens: 723 dec bx ; make bx -> to tens 724 ; digit 725 mov dl,byte ptr[bx] ; get tens digit 726 and dl,00Fh ; mask off upper nybble 727 mov al,10 ; load multiplier 728 mul dl ; do multiply 729 add dh,al ; add tens to units 730 got_it: 731 mov al,dh ; save number 732 ret 733 734 735 serialize: ; locate all occurrances of serial numbers in buffer 736 737 cld ; set direction forward 738 mov es,m_base ; point ES: to beginning of buffer 739 mov di,0 740 mov ax,bpt 741 mov bx,track_cnt 742 inc bx ; remember that an extra track was read 743 mul bx 744 mov cx,ax 745 next_serial: 746 mov si,offset ser_def ; point at pattern 747 lodsb ; get first char of pattern into AL 748 repne scasb ; look for next occurance of AL 749 jne no_match ; if not match, then we are done 750 751 push di ; save scan pointer 752 push cx ; save count 753 mov cx,(length ser_def)-1 ; residual length of pattern 754 repe cmpsb 755 pop cx ; recover scan count 756 pop di ; recover scan pointer 757 jne next_serial ; no, rest didn't match 758 759 push cx ; save scan pointer 760 dec di ; move di back to start of field 761 mov si,offset serial_number ; si points to current serial 762 ; number 763 mov cx,length ser_def ; counter for number of bytes to move 764 rep movsb 765 pop cx ; recover scan pointer 766 inc serial_cnt 767 jmp next_serial 768 769 no_match: 770 ret 771 772 ; increment the ASCII serial number 773 774 inc_serial: 775 mov cx,length ser_def ; length of serial number 776 mov bx,offset serial_number ; bx points to start of string 777 add bx,(length ser_def)-1 ; bx now points to end of string 778 addlop: 779 push cx ; save length of pointer 780 mov al,byte ptr[bx] ; get byte of serial number File: serial16.a86 Page 14 781 inc al ; add 1 to it 782 daa ; decimal adjust it 783 lahf ; check to see if there was a 784 and ah,10h ; carry from the lower half of 785 mov cl,4 ; the al register 786 shl ah,cl 787 jc fix ; if yes then increment the next 788 ; byte of the serial number 789 mov byte ptr[bx],al ; else save byte and stop 790 pop cx ; clean up stack 791 ret 792 fix: 793 and al,0fh ; make high nybble of byte 794 or al,30h ; equal to "3" again 795 mov byte ptr[bx],al ; save byte back in serial 796 ; number 797 dec bx ; point at next higher byte 798 pop cx ; recover length of serial 799 ; number 800 loop addlop ; do again if CX<>0 801 ret 802 803 ; translate the 8 bit digit in AL to ASCII into "ascii_trk" 804 make_ascii: 805 mov dx,' ' ; fill "ascii_trk" with blanks 806 mov ascii_trk,dx 807 mov ascii_trk+2,dx 808 mov bx,offset ascii_trk+3 ; BX -> "ascii_trk"+3 809 mov dl,10 ; init divisor 810 makelop1: 811 sub ah,ah ; make AH zero 812 div dl ; and divide by 10 813 add ah,'0' ; make remainder ascii 814 mov byte ptr[bx],ah ; store it in "ascii_trk" 815 dec bx ; move pointer to next location 816 test al,al ; see if quotient zero yet 817 jnz makelop1 ; no, got more digits 818 ret 819 820 ; print the message at [DX] and wait for RETURN key 821 pmsg_wait: 822 call pmsg ; print the message 823 wait_1: 824 mov cl,c_read ; CP/M Console Input 825 int ccpm 826 cmp al,'C'-'@' ; see if control-C 827 je abort ; terminate program 828 cmp al,cr ; see if ASCII carriage return 829 jne wait_1 ; no, try again 830 ret ; back to caller 831 832 ; abort the program 833 abort: 834 mov dx,offset abort_msg 835 call pmsg_wait 836 mov cl,0 ; CP/M reboot function 837 int ccpm 838 839 ; print the string whose offset is in dx and is terminated by '$' 840 pmsg: File: serial16.a86 Page 15 841 mov cl,c_writebuf 842 int ccpm 843 ret 844 845 ; clears the monitor screen 846 clear: 847 cmp clear_on,false ; see if clear screen enable is 848 je no_clear ; off 849 mov dx,offset clear_msg 850 call pmsg 851 no_clear: 852 ret 853 854 ; get ASCII input from operator and translate to upper case 855 get_char: 856 mov cl,c_read ; request single character 857 int ccpm ; from console 858 cmp al,'C'-'@' ; check for control-C 859 je abort ; abort operation if yes 860 and al,05Fh ; xlate lower to upper chase 861 ; echo choice back to operator 862 echo_choice: 863 push ax ; temp save 864 mov dl,bs ; write over last input 865 mov cl,c_write 866 int ccpm 867 pop dx ; get temp save 868 push dx 869 mov cl,c_write ; write it out 870 int ccpm 871 pop ax 872 ret 873 874 ; get a single ASCII number from operator and check for . 875 get_1num: 876 mov cl,c_read 877 int ccpm 878 cmp al,'C'-'@' ; check for control-C 879 je abort 880 and al,00Fh 881 ret 882 883 ; this code erases the "Reading" and "Writing" messages from the 884 ; monitor screen 885 erase_msg: 886 mov dx,offset msg10 887 call pmsg 888 ret 889 890 ; this code erases the old track numbers from the monitor screen 891 erase_trk: 892 mov dx,offset msg11 893 call pmsg 894 ret 895 896 dseg 897 org 0000h 898 899 ; Page Zero Definitions 900 File: serial16.a86 Page 16 901 code_length rw 1 ; low 16 bits code segment length 902 code_length_h rb 1 ; high 8 bits code segment length 903 code_base rw 1 ; base paragraph of code segment 904 model_8080 rb 1 ; 8080 model byte 905 data_length rw 1 ; low 16 bits data segment length 906 data_length_h rb 1 ; high 8 bits data segment length 907 data_base rw 1 ; base paragraph of data segment 908 rs 1 ; << reserved >> 909 extra_length rw 1 ; low 16 bits extra segment length 910 extra_length_h rb 1 ; high 8 bits extra segment length 911 extra_base rw 1 ; base paragraph of extra segment 912 913 914 org 0100h 915 916 seek_trk_tab db 10 ; seek track function table 917 track rb 4 918 919 sel_dsk_tab db 9 ; select disk drive 920 disk rb 4 921 922 set_dma_base db 17 ; set dma base address function table 923 dma_base rw 2 924 925 set_dma_offset db 12 ; set dma offset address function table 926 dma_offset rw 2 927 928 set_sector db 11 ; set sector function table 929 tsector rb 4 ; holds translated sector # 930 sector rb 1 ; holds untranslated sector # 931 932 io_tab rb 1 ; select read/write function table 933 rw 2 934 935 bpt rw 1 ; how many bytes per track 936 937 mcb rw 0 ; memory control block 938 m_base rw 1 ; base address (segment address) 939 m_length dw 0FFFh ; desired length of memory area 940 m_ext rw 1 941 942 ver_freqword rw 0 943 ver_freq db 0,0 ; holds verification frequency value 944 dsk_cntword rw 0 945 dsk_cnt db 0,0 ; number of copies made so far 946 947 B1_trk_cnt rw 1 948 B2_trk_cnt rw 1 949 950 block_cnt rw 1 951 952 track_cnt rw 1 953 954 tog0 rb 1 955 956 serial_cnt rb 1 957 958 count_num rs 1 ; holds number of serial fields 959 ; to expect on source disk 960 dskS db 0 File: serial16.a86 Page 17 961 dskD db 1 962 963 skew rb 1 ; reserve storage for skew factor 964 spb rw 0 ; sectors/block 965 spbbyte rb 2 966 967 DPB rb 0 ; Disk Parameter Block 968 spt rw 0 ; sector per track 969 sptbyte rb 2 970 bsh rb 1 ; block shift factor 971 blm rb 1 ; block mask 972 exm rb 1 ; extent mask 973 dsm rw 1 ; total storage capacity of drive 974 drm rw 1 ; number of directory entries 975 al0 rb 1 976 al1 rb 1 977 cks rw 1 978 off rw 1 ; number of reserved tracks 979 980 xlt_offset rw 1 ; offset of system translate table 981 982 xlt_tab rb 128 ; will contain sector translation table 983 addr_tab rw 128 ; will contain sector address offsets 984 ; from beginning of track address in 985 ; disk data buffer 986 dma_addr rw 1 ; will hold dma offset by track 987 988 trackS rb 1 989 trackD rb 1 990 991 clear_on db true 992 993 last_trk dw 76 994 995 ser_def db '654321' 996 997 msg0 db cr,lf,lf 998 db '-------------------------' 999 db '-------------------------' 1000 db '-' 1001 db cr,lf 1002 db 'SERIAL16 V1.0 Serial No. ' 1003 db 'XXXX-0000-999999' 1004 db cr,lf 1005 db 'Copyright (C) 1982' 1006 db cr,lf 1007 db 'Digital Research, Inc. ' 1008 db 'All Rights Reserved' 1009 db cr,lf 1010 db '-------------------------' 1011 db '-------------------------' 1012 db '-' 1013 db cr,lf,lf 1014 db 'Diskette Generation Utility',cr,lf 1015 db 'for CP/M-86 based systems' 1016 db '$' 1017 1018 msg2 db cr,lf,lf 1019 db 'Enter starting serial number ' 1020 db '$' File: serial16.a86 Page 18 1021 1022 msg6 db bell,cr,lf,lf 1023 db 'Enter number of serial fields on source disk' 1024 db ' ? ' 1025 db '$' 1026 1027 msg7 db 'Reading Track ' 1028 db '$' 1029 1030 msg8 db 'Writing Track ' 1031 db '$' 1032 1033 msg9 rs 0 1034 ascii_trk rw 2 1035 db ' ' 1036 db '$' 1037 1038 msg10 db bs,bs,bs,bs,bs,bs,bs,bs,bs,bs 1039 db bs,bs,bs,bs,bs,bs 1040 msg11 db bs,bs,bs,bs,bs 1041 db '$' 1042 1043 error_msg1 db cr,lf,lf 1044 db 'Serial number must be ' 1045 error_msg2 rb 1 1046 db ' digits long. Try again !!! ' 1047 db '$' 1048 1049 msg12 db cr,lf,lf,lf 1050 db 'Source Drive is (A,B,etc.) ? ' 1051 db '$' 1052 1053 msg13 db cr,lf,lf 1054 db 'Destination Drive is (A,B,etc.) ? ' 1055 db '$' 1056 1057 msg14 db cr,lf,lf 1058 db 'Insert Source Disk ' 1059 db 'and type "Return" to continue ' 1060 db cr,lf,lf 1061 db '$' 1062 1063 msg3 db cr,lf,lf 1064 db 'Insert ' 1065 serial_1 rb length ser_def 1066 db ' into destination drive' 1067 db cr,lf 1068 db 'then type "Return" to continue' 1069 db cr,lf,lf 1070 db '$' 1071 1072 msg4 db bell,cr,lf,lf 1073 db 'Remove ' 1074 serial_2 rb length ser_def 1075 db ' from destination drive' 1076 db cr,lf,lf 1077 db '$' 1078 1079 abort_msg db cr,lf,cr,lf 1080 db cr,lf,'*** Serialization terminated ***' File: serial16.a86 Page 19 1081 db cr,lf 1082 db cr,lf,'Replace disk in Drive A:' 1083 db cr,lf,' then type ENTER to reboot ','$' 1084 1085 msg16 db cr,lf,lf 1086 db 'Would you like to change the skew factor' 1087 db ' (Y/N) ? ' 1088 db '$' 1089 1090 msg17 db cr,lf,lf 1091 db 'Enter skew factor (1-9) ? ' 1092 db '$' 1093 1094 msg18 db cr,lf,lf 1095 db 'Do you want to perform copy verification' 1096 db ' (Y/N) ? ' 1097 db '$' 1098 1099 msg19 db cr,lf,lf,lf 1100 db '1 = every disk is verified' 1101 db cr,lf 1102 db '2 = every 2nd disk is verified' 1103 db cr,lf 1104 db '3 = every 3rd disk is verified' 1105 db cr,lf,'"',cr,lf,'"',cr,lf,'"',cr,lf 1106 db '99 = every 99th disk is verified' 1107 db cr,lf,lf 1108 db 'How often do you want the verification to' 1109 db ' occur (1-99) ? ' 1110 db '$' 1111 1112 msg20 db 'Verifying Track ' 1113 db '$' 1114 1115 msg21 db cr,lf,lf 1116 db 'The current sector skew is ' 1117 db '$' 1118 1119 error_msg3 db bell,cr,lf,lf 1120 db 'Did not find all of the required serial ' 1121 db 'fields' 1122 db cr,lf 1123 db '$' 1124 1125 error_msg6 db cr,lf,lf 1126 db 'Wrong. Need one or two digits' 1127 db '$' 1128 1129 error_msg7 db bell,cr,lf,lf 1130 db '**** Verification failed ****' 1131 db cr,lf,lf 1132 db 'Try it again.' 1133 db cr,lf 1134 db '$' 1135 1136 error_msg0 db bell,cr,lf,lf 1137 db ' The Source Disk is BLANK ' 1138 db cr,lf 1139 db '$' 1140 File: serial16.a86 Page 20 1141 msg1 db cr,lf,lf 1142 db 'Checking for blank tracks' 1143 db cr,lf,lf 1144 db '$' 1145 1146 clear_msg db cr,lf,lf,lf,lf,lf,lf,lf,lf,lf,lf,lf,lf,lf,lf 1147 db lf,lf,lf,lf,lf,lf,lf,lf,lf,lf,lf,lf,lf,lf,lf 1148 db lf,lf,lf,lf,lf 1149 db vt,vt,vt,vt,vt,vt,vt,vt,vt,vt,vt,vt,vt,vt,vt 1150 db vt,vt,vt,vt,vt,vt,vt,vt,vt 1151 db '$' 1152 1153 con_buf0 db 10 ; buffer used to read 1154 buf0_len rb 1 ; serial number 1155 serial_number rb length ser_def 1156 rb 10-1-length ser_def 1157 1158 con_buf1 db 5 ; another console input buffer 1159 buf1_len rb 1 1160 input_num rb 5 1161 1162 1163 db 0 ; force out end of data segment **** CROSS REFERENCE ***** abort 276, 457, 827, 833, 834, 859, 879,1079 add 148, 149, 151, 202, 219, 224, 516, 586, 612, 614, 616, 714, 729, 777, 813 addlop 778, 800 addr 122, 138, 144, 258, 374, 383, 401, 483, 490, 586, 613, 616, 983, 986 ah 6, 172, 468, 605, 610, 784, 786, 811, 813, 814 al 42, 45, 58, 59, 63, 64, 79, 80, 115, 117, 118, 121, 160, 162, 163, 169, 170, 174, 189, 195, 219, 254, 261, 312, 326, 332, 359, 360, 452, 453, 477, 478, 578, 606, 609, 611, 612, 627, 633, 636, 692, 727, 729, 731, 780, 781, 789, 793, 794, 795, 816, 826, 828, 858, 860, 878, 880 al0 975 al1 976 and 718, 726, 784, 793, 860, 880 ascii 255, 256, 637, 638, 804, 806, 807, 808,1034 ax 139, 150, 151, 177, 215, 234, 237, 286, 293, 299, 300, 302, 303, 306, 358, 362, 363, 420, 423, 425, 428, 429, 440, 441, 443, 464, 474, 475, 499, 500, 501, 585, 586, 596, 597, 614, 615, 616, 617, 740, 744, 863, 871 b1 295, 300, 362, 421, 947 b2 307, 440, 948 bad 674, 677 base 98, 130, 264, 343, 425, 499, 532, 596, 597, 599, 738, 903, 907, 911, 922, 923, 938 bell 7,1022,1072,1119,1129,1136 bh 9, 200, 211, 213, 219, 221, 226 bios 26, 81, 568, 572, 575, 598, 644 bl 173, 199, 200, 202, 224, 226 blank 32, 261 blm 971 block 296, 306, 378, 950 bpt 237, 266, 289, 382, 419, 488, 585, 740, 935 bs 8, 864,1038,1039,1040 File: serial16.a86 CROSS REFERENCE Page 21 bsh 970 buf0 669, 672,1153,1154 buf1 698, 701, 708, 712,1158,1159 bx 43, 45, 46, 89, 97, 109, 110, 113, 117, 119, 125, 144, 149, 150, 158, 160, 161, 163, 165, 167, 169, 171, 209, 218, 235, 236, 287, 288, 289, 290, 302, 305, 421, 422, 607, 613, 614, 615, 711, 714, 715, 717, 723, 725, 741, 742, 743, 776, 777, 780, 789, 795, 797, 808, 814, 815 byte 45, 117, 145, 160, 163, 199, 211, 717, 725, 780, 789, 795, 814 c 15, 16, 17, 183, 824, 841, 856, 865, 869, 876 call 50, 52, 56, 57, 61, 62, 68, 178, 180, 187, 188, 193, 194, 246, 249, 255, 257, 259, 260, 269, 275, 276, 311, 316, 320, 322, 325, 330, 331, 336, 350, 353, 354, 355, 356, 372, 373, 375, 376, 384, 386, 390, 391, 392, 395, 397, 403, 405, 409, 410, 411, 414, 448, 449, 450, 456, 457, 460, 472, 481, 482, 484, 485, 486, 487, 491, 492, 520, 522, 529, 538, 540, 561, 566, 590, 637, 639, 667, 681, 689, 690, 705, 822, 835, 850, 887, 893 ccpm 13, 74, 83, 95, 184, 241, 569, 573, 577, 600, 646, 661, 671, 700, 825, 837, 842, 857, 866, 870, 877 ch 204, 713 change 190, 231 char 57, 62, 188, 325, 855 choice 862 cks 977 cl 73, 81, 94, 183, 203, 216, 217, 239, 253, 254, 467, 568, 572, 575, 598, 644, 660, 670, 699, 712, 785, 786, 824, 836, 841, 856, 865, 869, 876 cld 93, 247, 342, 418, 530, 737 clear 50, 178, 320, 336, 520, 529, 846, 847, 848, 849, 851, 991,1146 cmp 163, 189, 221, 293, 312, 326, 436, 441, 453, 672, 701, 708, 826, 828, 847, 858, 878 cmpsb 502, 511, 754 cnt 295, 296, 300, 306, 307, 311, 338, 362, 363, 368, 378, 387, 406, 421, 440, 443, 453, 462, 687, 741, 766, 945, 947, 948, 950, 952, 956 cntword 464, 944 code 27, 28, 548, 553, 901, 902, 903 con 669, 698,1153,1158 count 452, 692, 958 cr 5, 828, 997,1001,1004,1006,1009,1013,1014,1018,1022,1043,1049, 1053,1057,1060,1063,1067,1069,1072,1076,1079,1080,1081,1082,1083, 1085,1090,1094,1099,1101,1103,1105,1107,1115,1119,1122,1125,1129, 1131,1133,1136,1138,1141,1143,1146 create 380, 435, 445 cseg 37 cx 41, 101, 114, 128, 141, 206, 208, 229, 250, 252, 266, 270, 280, 281, 291, 292, 293, 295, 303, 344, 378, 381, 382, 383, 387, 389, 393, 406, 408, 412, 419, 420, 434, 444, 465, 473, 475, 476, 480, 488, 489, 490, 493, 496, 508, 510, 513, 514, 525, 531, 558, 560, 563, 565, 581, 584, 589, 591, 714, 744, 752, 753, 755, 759, 763, 765, 775, 779, 790, 798 daa 782 data 98, 130, 268, 279, 343, 532, 905, 906, 907 db 916, 919, 922, 925, 928, 943, 945, 960, 961, 991, 995, 997, 998, 999,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011, 1012,1013,1014,1015,1016,1018,1019,1020,1022,1023,1024,1025,1027, 1028,1030,1031,1035,1036,1038,1039,1040,1041,1043,1044,1046,1047, 1049,1050,1051,1053,1054,1055,1057,1058,1059,1060,1061,1063,1064, 1066,1067,1068,1069,1070,1072,1073,1075,1076,1077,1079,1080,1081, File: serial16.a86 CROSS REFERENCE Page 22 1082,1083,1085,1086,1087,1088,1090,1091,1092,1094,1095,1096,1097, 1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1112, 1113,1115,1116,1117,1119,1120,1121,1122,1123,1125,1126,1127,1129, 1130,1131,1132,1133,1134,1136,1137,1138,1139,1141,1142,1143,1144, 1146,1147,1148,1149,1150,1151,1153,1158,1163 dec 299, 506, 715, 723, 760, 797, 815 def 41, 344, 509, 510, 514, 516, 531, 672, 678, 746, 753, 763, 775, 777, 995,1065,1074,1155,1156 dh 5, 142, 717, 718, 729, 731 di 99, 126, 265, 346, 424, 496, 506, 534, 739, 751, 756, 760 disk 80, 341, 523, 543, 920 display 629, 635 div 173, 290, 305, 467, 812 dl 145, 147, 148, 182, 201, 202, 221, 651, 656, 725, 726, 728, 809, 812, 864 dma 258, 374, 383, 401, 483, 490, 571, 586, 597, 599, 616, 617, 922, 923, 925, 926, 986 done 438, 442, 446 dont 190, 231, 466, 469, 528 dpb 18, 94, 99, 967 drm 974 drv 18, 19, 20, 73, 94, 660 ds 100, 103, 105, 131, 134, 426, 428, 432, 498, 501, 503 dseg 896 dsk 82, 338, 380, 435, 445, 462, 464, 919, 944, 945 dskd 64, 656, 961 dsks 59, 79, 651, 960 dsm 973 dw 939, 993 dx 51, 55, 60, 67, 82, 149, 179, 181, 186, 192, 240, 245, 248, 256, 274, 301, 307, 321, 329, 349, 371, 385, 404, 447, 455, 471, 521, 537, 567, 571, 576, 599, 638, 645, 666, 669, 680, 688, 698, 704, 805, 806, 807, 834, 849, 867, 868, 886, 892 e5h 32 echo 862 equ 5, 6, 7, 8, 9, 13, 15, 16, 17, 18, 19, 20, 22, 26, 27, 28, 32, 34, 35 erase 269, 376, 392, 395, 411, 414, 460, 485, 492, 885, 891 err0 703, 709 error 274, 455, 521, 579, 588, 678, 679, 680, 704,1043,1045,1119,1125, 1129,1136 es 96, 98, 104, 108, 110, 124, 130, 133, 264, 343, 427, 429, 431, 500, 532, 738 exm 972 ext 940 extra 909, 910, 911 false 34, 847 fffh 939 fh 718, 726, 793, 860, 880 fix 787, 792 found 268, 279 freq 323, 332, 943 freqword 465, 942 get 57, 62, 188, 194, 311, 316, 325, 331, 665, 682, 687, 690, 697, 706, 855, 875 got 721, 730 h 7, 8, 182, 679, 784, 794, 897, 902, 906, 910, 914 has 112, 123 home 354, 356, 590, 621 File: serial16.a86 CROSS REFERENCE Page 23 inc 46, 118, 119, 146, 161, 162, 212, 213, 462, 476, 540, 580, 628, 634, 742, 766, 774, 781 init 122, 138 initlop0 116, 120 initlop10 44, 47 initlop9 143, 152 input 702, 703, 707, 709, 711,1160 int 74, 83, 95, 184, 241, 569, 573, 577, 600, 646, 661, 671, 700, 825, 837, 842, 857, 866, 870, 877 io 548, 549, 553, 554, 557, 559, 564, 576, 579, 582, 588, 592, 932 it 721, 730 jb 223 jbe 702 jc 787 jcxz 466 je 164, 190, 327, 438, 442, 454, 504, 709, 827, 848, 859, 879 jl 294 jmp 445, 523, 543, 706, 721, 767 jmps 122, 297, 517, 549, 554, 623, 629, 652, 682 jne 268, 512, 674, 749, 757, 829 jnz 112, 469, 579, 817 jz 313 lahf 783 last 250, 281, 291, 473, 993 len 672, 701, 708, 712,1154,1159 length 41, 286, 344, 510, 514, 516, 531, 672, 678, 753, 763, 775, 777, 901, 902, 905, 906, 909, 910, 939,1065,1074,1155,1156 lf 6, 997,1001,1004,1006,1009,1013,1014,1018,1022,1043,1049,1053, 1057,1060,1063,1067,1069,1072,1076,1079,1080,1081,1082,1083,1085, 1090,1094,1099,1101,1103,1105,1107,1115,1119,1122,1125,1129,1131, 1133,1136,1138,1141,1143,1146,1147,1148 lodsb 747 loop 47, 120, 152, 214, 230, 251, 271, 394, 413, 435, 526, 582, 592, 719, 800 lop 564, 582 lop0 388, 394 lop1 407, 413 m 264, 286, 425, 499, 596, 738, 938, 939, 940 make 255, 637, 804 makelop1 810, 817 match 749, 769 max 22, 239 mc 22, 239 mcb 240, 937 model 904 mov 41, 42, 43, 45, 51, 55, 59, 60, 64, 67, 73, 79, 80, 81, 82, 89, 94, 97, 98, 99, 101, 109, 110, 113, 114, 115, 117, 121, 125, 126, 128, 130, 140, 141, 144, 145, 150, 158, 160, 167, 169, 171, 174, 179, 183, 186, 192, 195, 198, 199, 200, 201, 203, 208, 211, 215, 216, 226, 234, 235, 237, 239, 240, 245, 248, 250, 253, 254, 256, 258, 261, 264, 265, 266, 274, 281, 286, 287, 289, 291, 295, 296, 300, 302, 303, 306, 307, 321, 323, 329, 332, 338, 343, 344, 345, 346, 349, 358, 359, 360, 362, 363, 365, 368, 371, 374, 378, 382, 383, 385, 387, 401, 404, 406, 419, 420, 421, 423, 424, 425, 428, 429, 439, 440, 443, 444, 447, 452, 455, 464, 465, 471, 473, 474, 477, 478, 483, 488, 490, 496, 499, 500, 501, 509, 510, 521, 531, 532, 533, 534, 537, 548, 553, 558, 562, 563, 567, 568, 571, 572, 575, 576, 585, 596, 597, 598, 599, 606, 607, 609, 613, 615, 617, 622, 627, 633, 636, 638, 644, 645, 651, 656, File: serial16.a86 CROSS REFERENCE Page 24 660, 666, 669, 670, 678, 680, 688, 692, 698, 699, 704, 711, 712, 717, 725, 727, 731, 738, 739, 740, 741, 744, 746, 753, 761, 763, 775, 776, 780, 785, 789, 795, 805, 806, 807, 808, 809, 814, 824, 834, 836, 841, 849, 856, 864, 865, 869, 876, 886, 892 movsb 102, 132, 347, 430, 535, 764 msg 376, 395, 414, 460, 834, 849, 885,1079,1146 msg0 51, 274, 997,1136 msg1 245, 680,1043,1141 msg10 886,1038 msg11 892,1040 msg12 55,1049 msg13 60,1053 msg14 67,1057 msg16 186,1085 msg17 192,1090 msg18 321,1094 msg19 329,1099 msg2 666, 678, 679,1018,1045 msg20 471,1112 msg21 179,1115 msg3 349, 455,1063,1119 msg4 537,1072 msg6 688, 704,1022,1125 msg7 248, 371, 385, 521,1027,1129 msg8 404, 447,1030 msg9 1033 mul 217, 236, 288, 422, 728, 743 new 341, 523, 543 next 745, 757, 767 no 749, 769, 848, 851 num 194, 331, 452, 690, 692, 697, 706, 711, 875, 958,1160 number 43, 345, 533, 761, 776,1155 off 292, 358, 474, 978 offset 43, 51, 55, 60, 67, 82, 89, 99, 109, 113, 125, 126, 140, 144, 158, 165, 179, 186, 192, 198, 240, 245, 248, 256, 274, 321, 329, 345, 346, 349, 371, 385, 404, 447, 455, 471, 509, 521, 533, 534, 537, 567, 571, 576, 599, 607, 613, 617, 638, 645, 666, 669, 680, 688, 698, 704, 711, 746, 761, 776, 808, 834, 849, 886, 892, 925, 926, 980 ok 454, 458 ok0 702, 707 on 847, 991 or 182, 679, 794 org 897, 914 over0 294, 298 over01 327, 333 over07 297, 309 over09 313, 317 pmsg 52, 56, 61, 68, 180, 187, 193, 246, 249, 257, 275, 322, 330, 350, 372, 386, 405, 448, 456, 472, 522, 538, 639, 667, 681, 689, 705, 821, 822, 835, 840, 850, 887, 893 pop 100, 105, 108, 131, 134, 181, 218, 229, 270, 280, 393, 412, 431, 432, 434, 493, 503, 513, 515, 525, 581, 584, 589, 591, 755, 756, 765, 790, 798, 867, 871 prompt 176 ptr 45, 110, 117, 145, 150, 160, 163, 199, 211, 615, 717, 725, 780, 789, 795, 814 push 96, 103, 104, 124, 133, 177, 206, 209, 252, 381, 389, 408, 426, 427, 480, 489, 498, 507, 508, 560, 565, 751, 752, 759, 779, 863, File: serial16.a86 CROSS REFERENCE Page 25 868 rb 902, 904, 906, 910, 917, 920, 929, 930, 932, 954, 956, 963, 965, 967, 969, 970, 971, 972, 975, 976, 982, 988, 989,1045,1065,1074, 1154,1155,1156,1159,1160 read 15, 27, 260, 375, 391, 484, 491, 547, 548, 824, 856, 876 rep 102, 132, 347, 430, 535, 764 repe 267, 502, 511, 754 repne 748 resetall 19, 73 ret 587, 593, 601, 618, 647, 662, 675, 693, 732, 770, 791, 801, 818, 830, 843, 852, 872, 881, 888, 894 retry 559, 592 rs 908, 958,1033 rw 901, 903, 905, 907, 909, 911, 923, 926, 933, 935, 937, 938, 940, 942, 944, 947, 948, 950, 952, 964, 968, 973, 974, 977, 978, 980, 983, 986,1034 s 26, 81, 568, 572, 575, 598, 644 scan 251, 271 scasb 267, 748 sector 562, 567, 580, 606, 928, 930 sectran 566, 604 seek 259, 623, 643, 645, 916 seekd 409, 449, 482, 632 seeks 373, 390, 487, 626 sel 82, 919 select 652, 659 selectd 353, 403, 481, 655 selects 355, 384, 486, 650 ser 41, 344, 509, 510, 514, 516, 531, 672, 678, 746, 753, 763, 775, 777, 995,1065,1074,1155,1156 serial 43, 316, 345, 346, 368, 453, 454, 458, 533, 534, 540, 665, 674, 677, 682, 745, 757, 761, 766, 767, 774, 776, 956,1065,1074,1155 serialize 397, 735 set 20, 567, 571, 599, 660, 922, 925, 928 setup 561, 595 shl 786 si 97, 110, 111, 140, 145, 146, 198, 199, 211, 212, 345, 423, 495, 507, 509, 515, 516, 533, 746, 761 skew 174, 176, 195, 203, 216, 963 spb 167, 171, 208, 215, 964 spbbyte 224, 965 spt 114, 128, 141, 234, 563, 968 sptbyte 201, 969 start 39 sub 58, 63, 139, 142, 147, 165, 170, 172, 204, 292, 301, 475, 495, 514, 605, 610, 611, 713, 811 tab 82, 113, 122, 126, 138, 140, 144, 147, 158, 165, 169, 170, 198, 548, 553, 576, 607, 608, 611, 613, 645, 916, 919, 932, 982, 983 table 112, 123 tens 719, 722 test 111, 468, 578, 816 tog0 365, 436, 439, 954 track 253, 363, 387, 406, 443, 549, 554, 557, 561, 595, 622, 636, 741, 917, 952 trackd 360, 478, 633, 634, 989 tracks 359, 477, 627, 628, 988 trk 250, 256, 269, 281, 291, 295, 300, 307, 362, 392, 411, 421, 440, 473, 485, 492, 629, 635, 638, 645, 806, 807, 808, 891, 916, 947, 948, 993,1034 File: serial16.a86 CROSS REFERENCE Page 26 true 35, 991 tsector 609, 929 ver 323, 332, 465, 942, 943 verify 466, 469, 528 verlop0 479, 526 verlop1 497, 517 verlop2 504, 524 verlop3 512, 519 vt 9,1149,1150 wait 68, 350, 821, 823, 829, 835 word 110, 150, 615 write 16, 28, 183, 410, 450, 552, 553, 865, 869 writebuf 17, 841 xlat 608 xlt 89, 109, 113, 125, 126, 140, 147, 158, 165, 169, 170, 198, 607, 608, 611, 980, 982 xltlop0 159, 164 xltlop1 205, 230 xltlop2 207, 223 xltlop3 210, 214 **** end cross reference ***