IMD 1.15: 16/05/2007 8:35:23 DOUBLE SIDED RELEASE DISK 4 OF 7 10/14/84 DAB COPY SOURCE & GENERATION DISK V1.2 SSDD AAACOPY ASM COPY HEX %&'()*+,-./COPY ASM!"123456?@BCDSYSS1 AST AHEXCOM OM #$COPY HEXB0789:;<=>COPY ASMEFGHIJKLMNOPQRSTCOPY ASMUVWXYZ[\]^_`bcdeCOPY ASM4fstuvwCOPY COMEghijklmnoACT COMtaqrxyz{|}~GENCOPY DOCpRAMS10 AS SYSS1 ASTBSCOPY BABCOPY BAK>=SCOPY BAK;.Date: 10/5/84 ;.Last Modified: DAB ;.Title: Executive DISK UTILITY ;.Comments: V1.2 ; +---------------+ ; | | ; | EXECUTIVE | ; | DISK | ; | UTILITY | ; | | ; +---------------+ ; ; (c) 1983, 1984 Osborne Computer Corporation, ; 26538 Danti Court, ; Hayward, CA 94545 ; ; Change synopsis: ; ; 10/05/84 (V1.2): ; Installed code to support DSDD diskettes. ; ; 3/24/83: ; Fixed bug in FORMAT. FORMAT would produce errors on all tracks if ; one attempted to format an OCC single density diskette. This ; happened because the parameters for the format were set up ; first for double density (especially SAVTYP), and then a check ; for information was done. ; ; The info check calls SENDEN in the ROM which changes SAVTYP to ; correspond to the density in the ROM. Then the disk would be ; formatted and not verified properly, resulting in errors. ; ; This has been fixed by putting the parameter initialization code ; after the info check and immediately before the disk is formatted. ; page ; include High RAM data structure definitions: LINK RAMS10.ASM ;RAM memory locations and constants ; ; Conditional assembly equates: ; ; ; Generation toggles: ; BETA_TEST = true ; ; ROM terminal emulation supported: ; IF BETA_TEST TVI950 = false ENDIF IF NOT BETA_TEST TVI950 = true ENDIF TVI912 = not TVI950 ; ; ROM format fix supported: ; IF BETA_TEST FMT_FIX = true ENDIF IF NOT BETA_TEST FMT_FIX = false ENDIF ; ; Copy and format data areas: ; BUFF = 4000H ;VERIFY BUFFER(5120 BYTES) BUFF1 = BUFF+5120 SSMASK = 0000_0010B ;Side select mask 841006 SDTYP = 0000_0101B ;SINGLE DENSITY SAVTYP DDTYP = 0000_1100B ;DOUBLE DENSITY SAVTYP DSTYP = DDTYP OR SSMASK ;Double sided savtyp 841006 DSEC = 5 ;DOUBLE DENSITY SECTORS/TRACK SSEC = 10 ;SINGLE DENSITY SECTORS/TRACK ; ; ROM JMP vectors: ; RHM_RTN = 157h ;RDRV (Home drive) SEN_RTN = 160h ;SENDEN (Sense density) RD_RTN = 15Ah ;RSEC (Read physical sector from disk) WRT_RTN = 15Dh ;WSEC (Write physical sector to disk) FMT_RTN = 163h ;FORMAT (Format track) SDRV_RTN = 166h ;SELDRV (Select drive) STP_O_RTN = 16Ch ;STEP OUT (Step drive out) STP_RTN = 169h ;STEP (Step drive in same direction as last ;step) ; ; BDOS function numbers: ; PR_STR_FN = 9 ;BDOS print string function OS_VER_FN = 12 ;BDOS version number function SRC_FIRST = 17 ;BDOS search for first matching file SET_ER_MD = 45 ;BDOS set error mode (CP/M Plus only) ; ; Macro definitions: ; PUSHAL MACRO PUSH BC PUSH DE PUSH HL ENDM POPALL MACRO POP HL POP DE POP BC ENDM ; ; Character definitions: ; CTRL_G = 'G' - 40h CTRL_H = 'H' - 40h CTRL_J = 'J' - 40h CTRL_K = 'K' - 40h CTRL_L = 'L' - 40h CTRL_S = 'S' - 40h CTRL_Z = 'Z' - 40h ;Control-Z ; ; Executive definitions: ; CP_RG_CH = CTRL_S ;Copyright character ; ; CP/M definitios: ; WBOOTE = 0000H ;Warm boot emtry point TPA_Base = 0100h ;Base of TPA EOF_Mark = CTRAL_Z ;CP/M logical end-of-file marker CPM_PLUS = 30h ;Value returned by function 12 is greater than ;or equal to this if running CP/M Plus. ; ; Console definitions: ; BELL_Char = CTRL_G ;Char to ring bell. CLR_SCR = CTRL_Z ;Char to clear screen (or current window) ;VEGH ;Clear Graphics mode esc seqn defined in ;systext ;VSGH ;Set Graphics mode esc seqn defined in ;systext ;VWDEF ;Define window esc seqn defined in systext ; ; Keyboard definitions: ; RAW_UP = 8ah ;Untranslated cursor up char RAW_DOWN = 8ch ;Untranslated cursor down char PAGE ORG TPA_Base ;Start code at base of TPA JMP START ;Jump around copyright and version stamp ;to start of code. JMP SW0 ;Entry pt to set window 0 for debugging ; ; Copyright and version stamp: ; DB cr,lf DB ' Copyright ' DB ESC,VSGH,CP_RG_CH,ESC,VEGH ;Set graphics mode, show ;copyright char and clr ;graphics DB ' 1983 Osborne Computer Corporation,',cr,lf DB ' 26538 Danti Court, Hayward, CA 94545.',cr,lf DB ' V1.2',EOF_Mark SW0: LK HL,W0S ;Set window 0 CALL OUT_STRING RET W0S: DB ESC,'s0',0 PAGE START: ;Start of COPY main program. LDK SP,STACK ;Set up local stack PROC ; ; Make sure CP/M Plus is running. ; LK C,OS_VER_FN ;Get OS version # CALL BDOS MOV A,H ;Check for H = 0 OR A JNZ :OS_BAD ;H ne 0, not running CP/M ; MOV A,L ;Check for L => 30 CMP CPM_PLUS ; JNC :OS_OK ;L => 30... ; :OS_BAD: ;Not running CP/M 3.X or greater LK HL,OS_BAD_MSG ;Print message and quit CALL OUT_STRING JMP 0 ;Warm Boot... ; :OS_OK: ;OS ok, continue... LK E,0FFh ;Set BDOS error return mode to RETURN ERRORS LK C,SET_ER_MD ; CALL SYS PAGE ; Menu screen driver begins here: ; BDOS EQU 0005h ;BDOS entry point UP EQU CTRL_K ;TVI character for cursor up DOWN EQU CTRL_J ;TVI char for cursor down RIGHT EQU CTRL_L ;TVI char for cursor right LEFT EQU CTRL_H ;TVI char for cursor left ENTER EQU cr ;Char entered by user to execute command PAGE PROC START1: ; ; Driver initialization code: ; CALL SET_STUFF ;Initialize windows used by driver LK HL,SCR_TOP ;Display program name and vers num CALL OUT_STRING LK HL,COPYR_MSG ;Display copyright message CALL OUT_STRING CALL SET_M1 ;Make current menu menu #1: main menu: ;Select copy or format :COPY: ; ; Return point for driver function execution ; ; ; See if current menu has already been displayed: ; LD DE,MAIN ;Load address of current menu LD HL,OLD_MN ;and compare with address of last ;menu displayed. STC CMC SBC HL,DE JZ :NO_DSP ;Menu already displayed, don't re- ;display. ; STO DE,OLD_MN ;Menu must be displayed. Save address ;of menu as last displayed. INC DE ;Bump ptr past address of command INC DE ;string table to start of menu display ;data. LK C,PR_STR_FN ;Tell BDOS to print it. CALL BDOS LD A,Y_COORD ;Hilight default selection CALL HI_CURR LK HL,DIR_MSG ;Display arrow key directions CALL OUT_STRING CALL CMD_DESC ;Display command description for ;this menu's default selection CALL SET_CURSOR ;Set cursor next to default selection. ; ; Branch point if current menu already displayed: ; :NO_DSP: LK DE,:COPY ;Load address of top of driver loop PUSH DE ;and push on stack as return address ;for the next user command. ; ; Wait for user to enter char and process accordingly: ; :GET_CH: ;Return here if invalid char entered. CALL GET_CHAR ;Wait for char to A CMP UP ;Is it TVI cursor up char? JZ MOVE_UP ;Yes, move up. ; ;No. CMP RAW_UP ;Is it raw (untranslated) up char? JZ MOVE_UP ;Yes, move up. ; CMP DOWN ;Is it TVI move down? JZ MOVE_DOWN ;Yes... ; ;No. CMP RAW_DOWN ;Is it raw down char? JZ MOVE_DOWN ;Yes... ; ; CMP RIGHT ;Horizontal motion not supported. ; JZ MOVE_RIGHT ; CMP 08Bh ; JZ MOVE_RIGHT ; CMP LEFT ; JZ MOVE_LEFT ; CMP 08Dh ; JZ MOVE_LEFT ;:10010000C37601C36B010D0A20436F707972696772 :100110006874201B67131B472031393833204F7315 :10012000626F726E6520436F6D70757465722043E7 :100130006F72706F726174696F6E2C0D0A203236A7 :100140003533382044616E746920436F7572742CA6 :1001500020486179776172642C204341203934351D :1001600034352E0D0A2056312E321A217201CDF36C :1001700002C91B73300031003F0E0CCD05007CB767 :10018000C289017DFE30D29201217B0CCDF302C3E6 :1001900000001EFF0E2DCD0500CDFE0121FB0CCD74 :1001A000F302219B0DCDF302CD0E04ED5BF9032A82 :1001B000FC01373FED52CAD601ED53FC0113130E7B :1001C00009CD05003A7F14CD970321D110CDF3025C :1001D000CD1303CD020311AB01D5CDE702FE0BCA4F :1001E0003E02FE8ACA3E02FE0ACA6802FE8CCA6845 :1001F00002FE0DCA6203CDD702C3DA010000210B53 :1002000002CDF302213302CDF302C91B7A3124342B :100210002B701B7A32342037701B7A332D203370C9 :100220001B7A352A2030701B7A362D2030701B73D4 :10023000301A001B66001B7A3426342F7000217F91 :10024000143A7914FE0028032187147EFE20281416 :10025000F53D77F1CDCD033A7F14CD9703CD130350 :10026000CD0203C9CDD702C9217F143A7A914FE000B :10027000280F2187143A8A14C61F477EB8282018F1 :100280000A3A7814C61F477EB82814F53C77F1CD9A :10029000CD033A7F14CD9703CD1303CD0203C9CD0F :1002A000D702C93A8A14FE0028153A7914FE0128AB :1002B0000E3E013279143E20328714CD0203C9CD9F :1002C000D702C93A7914FE0028093E00327914CDCC :1002D0000203C9CDD702C91E070E02CD0500C91EF3 :1002E0001A0E02CD0500C91EFF0E06CD0500FE0048 :1002F00028F5C97E23FE00C80E025FE5CD0500E1AA :1003000018F12182143A7914FE012803217A14CDC0 :10031000F302C93A7F14D620876F2600ED5BF50300 :10032000195E23562A3E03373FED52CA3D03ED5373 :100330003E031A328A14130E09CD0500C9C9000004 :1003400021D110CDF3023A7F14D620876F2600ED1D :100350005BF503195E23561A328A14130E09CD0574 :1003600000C9219203CDF3023A7F14D620876F266D :1003700000ED5BF703195E2356EB117F03D5E9ED22 :100380005BF9032AFC01373FED52C0CD4003CD029B :1003900003C91B73351A00F5C604323902323B0219 :1003A000F1D6202AF9035E2356EB5F160019195E79 :1003B0002356EBE511030019366A213602CDF3020C :1003C000E1E5CDF302E111030019366BC9F5C6046E :1003D000323902323B02F1 CMP ENTER ;Is it enter command? JZ DO_COMMAND ;Yes, process current command. ; CALL BEEP ;Char invalid. Ring bell. JMP :GET_CH ;and wait for another char... ; ; Local storage to save address of last menu displayed. ; OLD_MN: DW 0 PAGE SET_STUFF: ; Initialize driver: set up necessary windows. Disable function key ; translation. ; ; ENTRY: ; None. ; EXIT: ; Windows initialized. ; LK HL,INIT_STRING ;Point at window init string. CALL OUT_STRING ;Send it to console LK HL,XL_OFF ;Point at fn key xlate off string CALL OUT_STRING ;send it RET ;and return. ; INIT_STRING: ;Windows for screen driver. Window 4 is defined on ;the fly to display command string in reverse video. W1BIAS = 4 ;Bias into window 1 ; ; Window 1 is used for current menu: ; DB ESC,VWDEF,'1',32+W1BIAS,32+20 ,32+11 ,32+80 ; ; Window 2 is used for completion or error message reporting: ; DB ESC,VWDEF,'2',32+20 ,32 ,32+23 ,32+80 ; ; Window 3 is used for execution status while performing commands ; (such as copy or format): ; DB ESC,VWDEF,'3',32+13,32,32+19,32+80 ; ; Window 5 is used for general directions applicable to all commands: ; DB ESC,VWDEF,'5',32+10,32+0,32+16,32+80 ; ; Window 6 is used for command specific directions: ; DB ESC,VWDEF,'6',32+13,32+0,32+16,32+80 ; ; Reselect window zero after defining windows: ; DB ESC,'s','0','Z'-040h D 0 ; ; String to disable fn. key xlate: ; XL_OFF: IF TVI950 DB 0 ENDIF IF TVI912 DB ESC,'f',0 ENDIF ; ; String to define window 4: ; W_STR: DB ESC,VWDEF,'4' ;String to define window used for W_PCH_1: DB 32+6,32+20 ;displaying cmd string in reverse W_PCH_2: DB 32+15,32+80,0 ;video PAGE MOVE_UP: ; User entered cursor up key. Make selection above the current in menu ; the new current selection if the top most selection is not already ; current. In other words, move up if not at tup. ; ; ENTRY: ; Y_COORD = line # of current selection. ; Current selection is highlighted on screen. ; ; EXIT: ; Y_COORD = line # of current selection. ; Current selection is highlighted on screen. ; PROC L HL,Y_COOR ;Poin a lin o curren selection ;for 'main' menu. LD A,SIDE ;What side are we on (left or right)? CMP 0 ; JRZ :LEFT ;We're on left (main) side... ; ;We're on right (sub command side) LK HL,Y_SUB_COORD ;Point at line # for sub menu. :LEFT: LD A,[HL] ;Load line # of current selection CMP 32 ;Are we at top? JRZ :AT_TOP ;Yes... ; ;No. PUSH AF ;Save line number of old selection DEC A ;Compute and save new selection STO A,[HL] POP AF ;Restore line # of old selection CALL UN_HI_CR ;Un highlight it LD A,Y_COORD ;Load line # of current CALL HI_CURR ;and highlight it CALL CMD_DESC ;Print description for new command CALL SET_CURSOR ;Place cursor next to current selection RET ;and return ; :AT_TOP: ;Can't go up 'cause we're already at ;top. CALL BEEP ;Ring the bell RET ;and return PAGE MOVE_DOWN: ; User entered cursor down key. Make selection below the current in menu ; the new current selection if the botttom most selection is not already ; current. In other words, move down if not at bottom. ; ; ENTRY: ; Y_COORD = line # of current selection. ; Current selection is highlighted on screen. ; ; EXIT: ; Y_COORD = line # of current selection. ; Current selection is highlighted on screen. ; PROC LK HL,Y_COORD ;Point at line # for main menu LD A,SIDE ;Are we on the main menu side? CMP 0 JRZ :LEFT ;Yes... ; ;No. LK HL,Y_SUB_COORD ;Point at line # for sub-menu LD A,NUM_SUB_CMDS ;Load # of sub-commands. ADD A,31 ;Bias by 32 MOV B,A ;and save in B LD A,[HL] ;Load line # of current selection CMP B ;Are they the same (are we at bottom)? JRZ :AT_BOTTOM ;Yes... ; JR :9 ;No... ; :LEFT: ;Main menu is current. ; ; Are we at bottom? ; LD A,NUM_OPTIONS ;Load total # of commands A ADD A,31 ;Bias by 32 MOV B,A ;save in B LD A,[HL] ;Load line # of current selection CMP B ;Are they the same? JRZ :AT_BOTTOM ;Yes...at bottom already... ; :9: ;Not at bottom yet. PUSH AF ;Save line # of old setting INC A ;Bump to next one down STO A,[HL] ;Save in appropriate data structure ;(main or sub) POP AF ;Restore old line # CALL UN_HI_CR ;Un highlight current LD A,Y_COORD ;load line # of current CALL HI_CURR ;Highlight it CALL CMD_DESC ;Display description for current ;command CALL SET_CURSOR ;Place cursor next to current RET ;selection and return. ; :AT_BOTTOM: ;Current selection is the bottom one. ;Can't move down any more. CALL BEEP ;Ring bell RET ;and return. PAGE MOVE_RIGHT: ; Move right not implemented. ; LD A,NUM_SUB_CMDS CMP 0 JRZ :6 ;NO SUB MENU ! LD A,SIDE CMP 1 JRZ :6 LK A,1 STO A,SIDE LK A,32 STO A,Y_SUB_COORD CALL SET_CURSOR RET :6: CALL BEEP RET PAGE MOVE_LEFT: ; Move left not implemented. ; LD A,SIDE CMP 0 JRZ :7 LK A,0 STO A,SIDE CALL SET_CURSOR RET :7: CALL BEEP RET PAGE BEEP: ; Ring the bell as a warning. ; ; ENTRY: ; None. ; EXIT: ; None. ; LK E,BELL_Char LK C,2 CALL BDOS ;Tell BDOS to print char RET PAGE CLS: ; Clear the current window on the screen. ; ; ENTRY: ; None. ; EXIT: ; None. ; LK E,CLR_SCR LK C,2 CALL BDOS ;Tell BDOS to print char RET PAGE GET_CHAR: ; Wait for user to enter char. ; Uses BDOS direct console I/O so no chars are filtered. ; ; ENTRY: ; None. ; EXIT: ; A = character entered. ; LK E,0FFh ;Ask BDOS for a char LK C,6 CALL BDOS ;BDOS returns 0 if no chars CMP 0 ;Is there a char? JRZ GET_CHAR ;No, ask again. RET ;Yes. Return. PAGE OUT_STRING: ; Send string pointed to by HL to console. String is terminated in a ; byte of 0. ; ; ENTRY: ; HL ==> string ; EXIT: ; None. ; LD A,[HL] ;Load current char INC HL ;Bump ptr to next char CMP 0 ;Is current byte 0 (end of string)? RZ ;Yes, return ; LK C,2 ;No, tell BDOS to send char to console MOV E,A PUSH HL ;Save ptr to next char in string CALL BDOS POP HL ;Restore ptr JR OUT_STRING ;and do next char... PAGE SET_CURSOR: ; Place the cursor next to the currently selected option. ; ; ENTRY: ; SIDE = 0 if on main menu side (always true in COPY) ; PUT_CURSOR is a cursor positioning string which is patched with ; the line number of the current selection (relative 32) in Y_COORD. ; ; EXIT: ; None. ; PROC LK HL,PUT_SUB_COORD ;Point at cursor positioning ;string for sub menu LD A,SIDE ;Are we on sub menu side? CMP 1 ; JRZ :SUB_SIDE ;Yes...position cursor there ; ;No. LK HL,PUT_CURSOR ;Point at cursor positioning ;string for main menu. :SUB_SIDE: CALL OUT_STRING ;Position cursor RET ;and return PAGE CMD_DESC: ; Display command description for currently selected command. ; Command description is NOT re-displayed if it has already been ; displayed. ; ; ; The first two bytes of a menu data structure is a pointer to a ; table of pointers to the command descriptions for that menu. ; ; ENTRY: ; Y_COORD = line # of current command ; ; EXIT: ; Sets NUM_SUB_CMDS according to number of sub-commands for command ; description (not used in COPY). ; PROC LD A,Y_COORD ;Load line # of current ;selection (relative-32). SUB 32 ;Make A relative 0 ADD A ;Double it to index into ;pointer table. MOV L,A ;Load it to HL LK H,0 LD DE,MENU_TABLE ;Load address of pointer table ADD HL,DE ;Index to pointer for current ;selection. LD E,[HL] ;Load pointer to current INC HL LD D,[HL] LD HL,O_SUB_MN ;Load address of last-displayed ;command description. STC CMC SBC HL,DE ;Is it same as new one? JZ :NO_DSP ;Yes, don't re-display it ; ;No. Display it STO DE,O_SUB_MN ;Save description as last LD A,[DE] ;Load number of subcommands for ;this menu STO A,NUM_SUB_CMDS ;Save it INC DE ;Bump DE to beginning of ;command description display ;data. LK C,PR_STR_FN ;Tell BDOS to print description CALL BDOS RET ;and return ; :NO_DSP: RET ;Current same as last, so don't display it ; ; ; Local storage for address of last command description displayed: ; O_SUB_MN: DW 0 PAGE F_CMD_DESC: ; Display general direction message and force re-display of command ; description for currently selected command. ; ; Command description IS re-displayed even if it has already been ; displayed. ; ; This routine is called after DO_COMMAND processes the current command. ; DO_COMMAND erases the command description and general directions and ; they must be restored even though the description has already been ; displayed. ; ; The first two bytes of a menu data structure is a pointer to a ; table of pointers to the command descriptions forAD6202AF9035E2356EB72 :1003E0005F160019195E2356EBE5213602CDF302A4 :1003F000E1CDF302C90000000000001106040E095F :10040000CD0500C300001B73301A1B650024218C2E :100410000422F50321920422F703213B0E22F90363 :100420003E033278143E20327F14C921980422F50D :100430000321A00422F703219B0E22F9033E04327C :1004400078143E20327F14C921A80422F50321B27A :100450000422F70321390F22F9033E053278143EB6 :1004600021327F143E01328B04C921BC0422F503E2 :1004700021C60422F70321051022F9033E05327834 :10048000143E21327F14AF328B04C9017411B411B0 :10049000F511D004D404FB0309140914C813F51191 :1004A000E204EE042005FB03321232127E13C8135D :1004B000F511FA04050510052005FB03B312B3126C :1004C0003413C813F511FA04050510052005FB03C4 :1004D000CD2B04C93A8B04B72004CD6A04C9CD489A :1004E00004C9CD24053E41CDAE05CD2405C9CD249A :1004F000053E42CDAE05CD2405C93E410644CD3072 :1005000005CD2405C93E420644CD3005CD2405C99C :10051000218B043E01AE2804CD4804C9CD6A04C92C :10052000CD0E04C9212B05CDF302C91B73331A006C :1005300032FE18327819D6413250FD7832AD05AF0F :1005400032560CC34B053EFF32560CCD73063A565D :100550000CB7C276053A50FDCD4806CA760521D5BE :10056000183DCA6805215019CD0B0CCD7F06F5CD7D :100570007306F1FE4EC83AAD05CD9406CDA906CD61 :100580007907F50E0DCD0500F1FE5121191D281337 :10059000B7213F1C280D21B11CCD0B0CCD1F0CCD5C :1005A0007306C9CD0B0CCD160CCD7306C900F5EE44 :1005B0000332FE18327819F1D6413293163250FDCB :1005C000AF32560CC3CC053EFF32560CCD7306CD70 :1005D0001C0BC23B063A51FDFE0EC2E1053E01185E :1005E00001AF32550CCDA906CD440721BE1BC23147 :1005F000063A560CB7C21B063A9316EE01CD4806D2 :10060000CA1B0621D5183DCA0D06215019CD0B0C69 :10061000CD7F06F5CD7306F1FE4EC8CD4008F50E30 :100620000DCD0500F1FE5121A91A2805B7C021D131 :1006300019CD0B0CCD160CCD7306C9219616CD0B1A :100640000CCD1F0CCD7306C947C53250FDCD1C0B18 :10065000C1C26A06783C32570C11570C0E11CD05F9 :10066000003CC26C06AFB4C26F06AFC9AF3CC93E16 :1006700002B7C9217A06CD0B0CC91B73321A00CD03 :10068000280CE65FFE59CA8E06FE4EC27F06F5CDE7 :100690002F0CF1C9FE53CAA1063E0C3251FD0605CE :1006A000C93E053251FD060AC978324E0CF6FF32BA :1006B0004D0C3A51FDFE05CACF06FE0CCAC406FE1B :1006C0000EC2E00678FE05C2E00621390C18097852 :1006D000FE0AC2E00621400C11470C010700EDB0F4 :1006E000CDEA06CD1307CD2F07C93A4E0C672E0071 :1006F000CB2CCB1D3A51FDCB3FCB3FE60347CA0481 :10070000072910FD22530C3A550CB7CA0F072922AE :100710004F0CC9AF2A0600110054ED52ED5B4F0C8F :100720000600AFED5204D22307057832510CC93AC6 :10073000510C473E280E0090CA3F070CD23707796C :1007400032520CC93A4D0CB7C821121BCD0B0CCD3F :10075000160C3A51FD57D53A9316EE013250FDCDA5 :100760001C0BD13A4E0CB8C03A51FDBAC07A325186 :10077000FD3A93163250FDAFC921AF14CDA20B3E06 :1007800001324DFDCD150BC21F08219414CD0B0C69 :10079000AF325723324EFDAF3222083223083A518E :1007A000FDE6FD3251FDCDAE0A3A23084FCDF30AE6 :1007B000210040224BFDDB00324AFDCD310BC2DA75 :1007C000073A2308B7C2CF073A2208B7C2D507CDE8 :1007D0002408C2DA073E2AC3DF073E45325723CD3D :1007E000950B3E08CD950BCD8D0BC83A2208B7C2AC :1007F0000A083C3222083A8B04B728033223083A0D :1008000051FDEE023251FDC3A6073E0CCD950B3AC9 :100810004EFD3CFE28C294073A5723B720 that menu. ; ; ENTRY: ; Y_COORD = line # of current command ; ; EXIT: ; Sets NUM_SUB_CMDS according to number of sub-commands for command ; description (not used in COPY). ; ; PROC LK HL,DIR_MSG ;Display general (arrow key) directions CALL OUT_STRING LD A,Y_COORD ;Load line # of current ;selection (relative-32). SUB 32 ;Make A relative 0 ADD A ;Double it to index into ;pointer table. MOV L,A ;Load it to HL LK H,0 LD DE,MENU_TABLE ;Load address of pointer table ADD HL,DE ;Index to pointer for current ;selection. LD E,[HL] ;Load pointer to current INC HL LD D,[HL] LD A,[DE] ;Load number of subcommands for ;this menu STO A,NUM_SUB_CMDS ;Save it INC DE ;Bump DE to beginning of ;command description display ;data. LK C,PR_STR_FN ;Tell BDOS to print description CALL BDOS RET ;and return PAGE DO_COMMAND: ; Process the currently selected command on the currently selected ; menu.  ; ; Clears current command description but re-displays it only if ; menu has NOT changed. ; ; ENTRY: ; Y_COORD = line # of current command. ; COM_TABLE = address of table of pointers to command routine for ; current menu. ; ; EXIT: ; None. ; PROC LK HL,:CLR_W_5 ;Clear command description for current CALL OUT_STRING ;command. LD A,Y_COORD ;Load line # of current command. SUB 32 ;Make relative - 0 ADD A ;Double to index into command ptr table MOV L,A LK H,0 LD DE,COM_TABLE ;Index into command table ADD HL,DE LD E,[HL] ;Load ptr to command routine INC HL LD D,[HL] EX DE,HL ;Put ptr in HL LK DE,:DO_RET ;Load address of return point PUSH DE ;and save as return address JMP [HL] ;Jump to command routine ; :DO_RET: ;Return point from command routine. LD DE,MAIN ;Has main menu changed? LD HL,OLD_MN STC CMC SBC HL,DE RNZ ;Yes, command descr must have changed, ;so return to driver without ;re-displaying iAt. CALL F_CMD_DESC ;Force re-display of command ;description and general directions CALL SET_CURSOR ;and reposition cursor at current ;choice RET ; ; String used to clear window 5: ; :CLR_W_5: DB ESC,'s5','Z'-40h,0 PAGE HI_CURR: ; Highlight (in reverse video) current command string on screen. ; ; ENTRY: ; A = line # (relative-32) of command string in window 1 ; Assumes ATT_OFS-th char of command string is attribute byte of attribute ; definition escape sequence (ESC-G-X) ; ; EXIT: ; None. ; PROC IF TVI912 :ATT_OFS = 3 ;Offset in command string to attribute ;byte :INV_ON = 'j' ;Reverse video on attribute char :INV_OFF = 'k' ;Reverse video off attribute char ENDIF IF TVI950 :ATT_OFS = 4 ;Offset in command string to attribute ;byte :INV_ON = '4' ;Reverse video on attribute char :INV_OFF = '0' ;Reverse video off attribute char ENDIF PUSH AF ;Save line # ADI W1BIAS ;Add bias for window 1 STO A,W_PCH_1 ;Save a ; +-------------------------------+ ; | | ; | SHELLY SYSTEXT | ; | | ; +-------------------------------+ ; I/O PORTS SYS_DTA = 00H ;System PIA data A SYS_CNA = 01H ;System PIA control A SYS_DTB = 02H ;System PIA data B SYS_CNB = 03H ;System PIA control B TIM_CT0 = 04H ;8253 Timer counter 1 TIM_CT1 = 05H ;8253 Timer counter 2 TIM_CT2 = 06H ;8253 Timer counter 3 TIM_CNL = 07H ;8253 Timer control register DSK_CMD = 08H ;Floppy disk DISK COMMAND REG (WRITE) DSK_STS = DSK_CMD ;STATUS REG (READ) DSK_TRK = DSK_CMD+1 ;TRACK REG DSK_SEC = DSK_CMD+2 ;SECTOR REG DSK_DAT = DSK_CMD+3 ;DATA REG (R/W) SIO_DTA = 0CH ;SIO data reg A SIO_CNA = 0DH ;SIO control reg A SIO_DTB = 0EH ;SIO data reg B SIO_CNB = 0FH ;SIO control reg B PAR_DTA = 10H ;Parallel port PIA data A PAR_CNA = 11H ;Control register A PAR_DTB = 12H ;Parallel port PIA data B PAR_CNB = 13H ;Control register B KEYBD = 14H ;Keyboard PAGE  ;SYSTEM PIA COMMANDS ;DATA A: +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ; ROM enable <-+ | | | | | | | ; VIDEO enable <---+ | | | | | | ; Bank 6 enable <------+ | | | | | ; Bank 5 enable <----------+ | | | | ; Bank 4 enable <--------------+ | | | ; Bank 3 enable <------------------+ | | ; Bank 2 enable <----------------------+ | ; Bank 1 enable <--------------------------+ ;DATA B: +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ; RI(act low) <+ | | | | | | | ; DSR(act low) <---+ | | | | | | ; TX clock select <----+ | | | | | ; RX clock select <--------+ | | | | ; Speaker <--------------------+ | | | ; Drive B (act low) <--------------+ | | ; Drive A (act low) <------------------+ | ; Double density (act low) <---------------+ ;Data DATA_INIT = 1000_0000B ;Enable ROM DATB_INIT = 0000_0111B ;Deselect drives A & B, single density ;spkr off ;Direction DIRA_INIT = 1111_1111B ;Select all lines as outputs DIRB_INIT = 0011_1111B ;Select RI & DSR as inputs, rest as outputs ;Masks ROM_BANK = 1000_0000B ;ROM bank VID_BANK = 0100_0000B ;VIDEO bank SPEAKER = 0000_1000B ;Speaker bit PAGE ;SYSTEM PIA CONTROL REGISTERS ; +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ; INTERRUPT FLAGS: | | | | | | | | ; A: DMA Interrupt | | | | | | | | ; B: Real time clock interrupt <---+ | | | | | | | ; | | | | | | | ; Not used <-------+ | | | | | | ; | | | | |  | ; CONTROL 2: | | | | | | ; A: 110 = 64 columns, 111 = 80 columns | | | | | | ; B: 110 = 60 Hz, 111 = 50 Hz <---+---+---+ | | | ; | | | ; DDRA: | | | ; A & B: 1 = Data register, 0 = Direction register <--+ | | ; | | ; CONTROL 1: | | ; A: DMA interrupt request (hw) | | ; B: Real time clock interrupt | | ; | | ; 1 = active high <--------------------------------+ | ; 1 = enable <------------------------------------+ ;Control CA_DAT = 00_110_1_00B ;64 columns ;enable DATA reg ;Disable interrupts CA_DIR = 00_110_0_00B ;64 columns ;enable DIRECTION reg ;disable interrupts CA_64C = 00_110_1_01B ;64 columns ;enable data reg ;enable interrupts CB_DAT = 00_110_1_10B ;60Hz ;enable DATA reg ;Disable interrupts CB_DIR = 00_110_0_10B ;60Hz ;enable DIRECTION reg ;disable interrupts CB_A 60H = 00_110_1_11B ;60Hz ;enable data reg ;Enable interrupts ;Control masks COL_MSK = 00_001_0_00B ;64/80 Column mask INT_MSK = 00_000_0_01B ;Interrupt enable mask PAGE ;SERIAL PORT -- SIO COMMANDS ;SIO WRITE REGISTERS ;WRITE REG 0: +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ;CRC RESET CODES: | | | | | | | | ; Null 0 0 | | | | | | ; Reset Rx CRC checker 0 1 | | | | | | ; Reset Tx CRC generator 1 0 | | | | | | ; Reset Tx Underrun/EOM latch 1 1 | | | | | | ;COMMAND BITS: | | | | | | ; Null 0 0 0 | | | ; Send Abort 0 0 1 | | | ; Reset EXT/Status interrupt 0 1 0 | | | ; Channel reset 0 1 1 | | | ; Enable int on next Rx character 1 0 0 | | | ; Reset Tx int pending 1 0 1 | | | ; Error reset 1 1 0 | | | ; Return from int (Chan A only) 1 1 1 | | | ;POINTER BITS: | | | ; Register 0 0 0 0 ; Register 1 0 0 1 ; Register 2 0 1 0 ; Register 3 0 1 1 ; Register 4 1 0 0 ; Register 5 1 0 1 ; Register 6 1 1 0 ; Register 7 1 1 1 ;WRITE REG 1: +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ;WAIT/READY: | | | | | | | | ; Wait/Ready Enable <-+ | | | | | | | ; ~Wait/Ready Function <--+ | | | | | | ; Wait/Ready on Rx/Tx <------+ | | | | | ;Rx INTERRUPT MODE: | | | | | ; Rx interrupts disabled 0 0 | | | ; Rx int on first char 0 1 | | | ; Int on all Rx chars 1 0 | | | ; Int on all Rx chars 1 1 | | | ;Status Affects Vector (Chan B only) <--------------+ | | ;Tx Int Enable <---------------------------------------+ | ;Ext Int Enable <-------------------------------------------+ PAGE ;WRITE REG 2: +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ; | | | | | | | | ;Interrupt Vector <--------------+---+---+---+---+---+---+---+ ;WRITE REG 3: +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ;RECEIVER BITS/CHARAbsolute line # in window defn STO A,W_PCH_2 ;string: begin and end line POP AF ;Restore line # SUB 32 ;Make it relative-0 LD HL,MAIN ;Get address of command line table LD E,[HL] ; INC HL ; LD D,[HL] ; EX HL,DE ;Put cmd line table addr in HL MOV E,A ;Index into it by cmd # LK D,0 ; ADD HL,DE ; ADD HL,DE ; LD E,[HL] ;Load addr of cmd line INC HL ; LD D,[HL] ; EX HL,DE ;Put it in HL PUSH HL ;Save addr LK DE,:ATT_OFS ;Index into cmd line string to attribute ADD HL,DE ;byte STO :INV_ON,[HL] ;Set attribute byte to reverse video LK HL,W_STR ;Set window for current line CALL OUT_STRING ; POP HL ;Restore address of cmd string PUSH HL ;Save it CALL OUT_STRING ;Display cmd string in reverse video POP HL ;restore cmd string addr LK DE,:ATT_OFS ;Index back to attribute byte ADD HL,DE ; STO :INV_OFF,[HL] ;Set it to normal RET ;and return PAGE UN_HI_CR: ; Remove highlighting from command string on screen ;  ; ENTRY: ; A = line # (relative-32) of command string in window 1 ; ; EXIT: ; None. ; PUSH AF ;Save line # ADI W1BIAS ;Add bias for window 1 STO A,W_PCH_1 ;Save absolute line # in window defn STO A,W_PCH_2 ;string: begin and end line POP AF ;Restore line # SUB 32 ;Make it relative-0 LD HL,MAIN ;Get address of command line table LD E,[HL] ; INC HL ; LD D,[HL] ; EX HL,DE ;Put cmd line table addr in HL MOV E,A ;Index into it by cmd # LK D,0 ; ADD HL,DE ; ADD HL,DE ; LD E,[HL] ;Load addr of cmd line INC HL ; LD D,[HL] ; EX HL,DE ;Put it in HL PUSH HL ;Save it LK HL,W_STR ;Define window for current line CALL OUT_STRING ;Redisplay cmd string in normal mode POP HL ;Restore addr of cmd str CALL OUT_STRING ;Redisplay cmd string in normal mode RET ;and return PAGE ;------------------------------------------------------------------------------ ; Local storage for driver data structures follows. ; ; MENU_TABLE i A ÀCP/M Version 3.0COPYRIGHT 1982, DIGITAL RESEARCH251082654321!9"k1G \!m!w# š!v6H#6E#6X!e6C#6O#6M<<&:g.".g"?S:2n!`w #4o"c*e{ozg"hj:]@*c"\y!5C*^N{zb+"^*^*`*h"!j4&"h"y:b<5*kG!gwxS0  *cN,*cN{zҽ{,*c*e{ozg ~*c#"c> :[ >  X N*c>:> !:q#G*eDM*h ERROR: $DISK READ$LOAD ADDRESS LESS THAN 100$DISK WRITE$LOAD ADDRESS $ERROR ADDRESS $INVALID HEX DIGIT$CHECKSUM ERROR $FIRST ADDRESS $LAST ADDRESS $BYTES READ $RECORDS WRITTEN $CANNOT OPEN SOURCE FILE$DIRECTORY FULL$CANNOT CLOSE FILE$HEXCOM VERS: 3.00 $ LDK A,0FFH STO A,CLZA ;SET TO IGNORE LEADING ZERO RET CLZA: DB '0' WBOOT: LDK A,'Z'-40H CALL COUT JMP WBOOTE PRINT: LD A,[HL] ORA A RZ PUSH HL CALL COUT POP HL INC HL JR PRINT GVCHR: ; Read a char: allow only carriage return. ; CALL C1 ;Get a char CMP CR ;Is it Carriage return? JNZ GVCHR ;No, get another ; RET ;Yes, return GET_ESC: ; Wait for user to enter ESC ; :GE: CALL C1 CMP ESC JNZ :GE ; RET C1: CALL CIN ORA A JRZ C1 RET COUT: MOV E,A JR F6 CIN: LDK E,0FFH F6: LDK C,06H JMP SYS TITLE 'CONSTANTS' ;DOUBLE DENSITY PARAMETERS DDPARM: DW DLIFMT ;LIFMT FOR DOUBLE DENSITY DW DOUBTO ;TRKOFS FOR DD DW DFORDAT ;FORDAT FOR DD DB 0 ;OSBORNE FORMAT ;SINGLE DENSITY PARAMETERS SDPARM: DW SLIFMT ;LIFMT FOR SINGLE DENSITY DW SINGTO ;TRKOFS FOR SD DW SFORDAT ;FORDAT01C9F683 :10082000FFC90000010040ED434BFDED435423DBC5 :1008300000324AFD3A4E0C47CD230BC0CD9A0AC96F :10084000AF3213093A51FDCB8F3251FD21E515CD61 :10085000A20B3E01324DFDAF329516CD9C082148CA :1008600017C28A08FE51C8CD3809215418C2900811 :10087000FE51C83A520C473A95163CB8C258083A4D :100880001309B7C821CF17C39008219616C3900843 :10089000CD0B0CCD1F0CCD7306F6FFC93A93163263 :1008A00050FDCD1C0BC03A51FDE6FD3251FDAF327B :1008B0009416CD5D0A3A4EFDFE28C8CD8D0BC8CDED :1008C000720ACD1609CAF0083EFF3213093A4EFDEE :1008D0006F2600117917CDCA0B214817CD0B0CCD0F :1008E0007F06F5CD7306F1FE59CAF008AF3E51C937 :1008F0003A550CB7CA04093A51FDEE023251FDCB0C :100900004FC2B20821510C3A94163CBEC83294161C :10091000C3B2080000002A4EFD115516CDCA0B21A6 :100920002416CDA20B2A5423224BFDDB00324AFDB4 :100930003A4E0C47CD230BC93A9316EE013250FDC7 :100940003A9516B7C24D09CD150BC01804CD1C0B36 :10095000C03A51FDE6FD3251FDAF329416CD5D0A2D :100960003A4EFDFE28C8CD8D0BC8CD720ACD940934 :10097000C03A550CB7CA85093A51FDEE023251FD15 :10098000CB4FC25D0921510C3A94163CBEC832943B :1009900016C35D092A4EFD118C16CDCA0B215B16BC :1009A000CDA20B3A550CB7C2BD093A51FDCBCF329F :1009B00051FDCD070A3A51FDCB8F3251FDCD070ACB :1009C000C078B7C83E023253232A5423224BFDDBA2 :1009D00000324AFD3A4E0C47CD2A0BC0210040227E :1009E0004BFDDB00324AFD3A4E0C47CD230BC0EDE8 :1009F0004B530C1100402A5423CD750BC83A532396 :100A00003DC2C909F6FFC93A4D0CB7C2590ACD5DBE :100A10000BCDAE0A3A550CB7CA220A3A51FDE6028E :100A2000CB1F4FCDF30A210040224BFDDB00324AA1 :100A3000FDCD310BC0CD690B3A550CB7C2450A3A12 :100A400051FDCB4FC0CD9A0A200FCD5D0BCD2408B0 :100A5000F5CD690BF1C0AF47C906FFAFC93A510CDC :100A60003D473A95164F8110FD473A941680324E15 :100A7000FDC9210000ED5B4F0C3A9416B7CA840AF9 :100A8000471910FD110054193A51FDE602B7CA96F4 :100A90000AED5B530C19225423C9ED4B530C2A5415 :100AA000233EE5EDA1E2AC0ACAA30AC9AFC911020F :100AB000402A4B0CED4B470CEDB03E013292163AFA :100AC0004E0C3D47C5D5FDE12A4B0CED4B470CEDD7 :100AD000B0219216343A51FDFE057ECAE30AFD7735 :100AE000761803FD771AC110DBEB010240ED4222BC :100AF0000040C9210140ED5B490C193A4E0C47ED0D :100B00005B470C3A4EFD7723712B1910F9C93A0255 :100B100000672E5AE9115701CD0E0BC9116001CDA6 :100B20000E0BC9115A01CD0E0BC9115D01CD0E0B73 :100B3000C93E02325323116301CD0E0BC82153234A :100B400035C2360BF6FFC9C9116601CD0E0BC911AE :100B50006C01CD0E0BC9116901CD0E0BC901581BDB :100B6000115823210040EDB0C901581B110040214C :100B70005823EDB0C9C5D5E578B1CA890B1ABEF5C1 :100B800013230BF1CA780BF6FFE1D1C1C9CD320CAA :100B9000E65FFE51C9C5D5E55F0E02CD0500E1D186 :100BA000C1C9C5D5E5EB0E09CD0500E1D1C1C9012B :100BB000F0D8CDDD0BCDEC0B0118FCCDDD0BCDEC71 :100BC0000B019CFFCDDD0BCDEC0B01F6FFCDDD0B5A :100BD000CDEC0B7DC630123E3032020CC93E30D512 :100BE0005D543C09DAE00B3D6B62D1C9473A020C17 :100BF000B8C2F90B3E201213C97812133EFF32021D :100C00000CC9303E1ACD2F0CC300007EB7C8E5CD0D :100C10002F0CE12318F5CD280CFE0DC2160CC9CD02 :100C2000280CFE1BC21F0CC9CD320CB728FAC95FB5 :100C300018021EFF0E06C30500A0047500B31E00B7 :070C400030011900831D00C3 :100C5700003F3F3F3F3F3F3F3F3F3F3F3F00000099 :100C670000000000000 A 0000000000000000000007D :100C770000000000434F5059207265717569726515 :100C8700732043502F4D20332E58206F72206772E8 :100C970065617465722E0D0A436F707972696768B2 :100CA70074201B67131B472031393833204F736279 :100CB7006F726E6520436F6D707574657220436F38 :100CC70072706F726174696F6E2C0D0A323635332C :100CD700382044616E746920436F7572742C204804 :100CE7006179776172642C2043412039343534357A :100CF7002E0D0A001B73301A1B3D202020202020B8 :100D070020202020202020202020202020202020DC :100D1700202020202020202020204469736B20558C :100D270074696C6974792050726F6772616D0D0A0E :100D370020202020202020202020202020202020AC :100D4700202020202020204F73626F726E6520457F :100D5700584543555449564520436F6D7075746522 :100D6700722053797374656D0D0A2020202020208E :100D7700202020202020202020202020202020206C :100D87002020202020202020202020202020205626 :100D9700312E32001B73321A2020201B67131B478A :100DA7002031393833204F73626F726E6520436F7D :100DB7006D707574657220436F72706F72617469BC :100DC7006F6E2C2032363533382044616E746920BB :100DD700436F7572742C20486179776172642C2097 :100DE70043412039343534350D0A20202020202076 :100DF700202020201B67131B472031393834204619 :100E070075747572652053797374656D732C20380A :100E17003238204E6F622048696C6C204176656ECF :100E270075652C2050696E6F6C65204341203934FD :100E370035363400950E1B73311A1B3D20202020B8 :100E47001B6B20436F7079204469736B65747465FD :100E570073201B6B000D0A20201B6B20466F726DE1 :100E67006174204469736B6574746573201B6B0030 :100E77000D0A20201B6B2052455455524E20544FCB :100E87002043502F4D201B6B000D0A0D0A24450EE1 :100E97005E0E790E310F1B73311A1B3D2020202067 :100EA7001B6B20436F70792066726F6D20447269E7 :100EB7007665204120746F20447269766520422050 :100EC7001B6B000D0A20201B6B20436F7079206677 :100ED700726F6D204472697665204220746F2044DA :100EE700726976652041201B6B000D0A20201B6B61 :100EF7002052657475726E20746F20746865204D7A :100F070061696E204D656E75201B6B000D0A2020F0 :100F17001B6B2052657475726E20746F2043502FBF :100F27004D201B6B000D0A0D0A24A50ECC0EF30EE7 :100F3700150FFB0F1B73311A1B3D202020201B6B45 :100F470020466F726D6174204469736B65747465B4 :100F570020696E2044726976652041201B6B000D65 :100F67000A20201B6B20466F726D617420446973E1 :100F77006B6574746520696E2044726976652042DA :100F8700201B6B000D0A20201B6B204368616E67D6 :100F97006520666F726D61742064656E736974791C :100FA70020746F2053494E474C452073696465642C :100FB700201B6B000D0A20201B6B20526574757275 :100FC7006E20746F20746865204D61696E204D65D1 :100FD7006E75201B6B000D0A20201B6B2052657459 :100FE70075726E20746F2043502F4D201B6B000DC0 :100FF7000A0D0A24430F680F8D0FBD0FDF0FC710AF :101007001B73311A1B3D202020201B6B20466F725B :101017006D6174204469736B6574746520696E2013 :1010270044726976652041201B6B000D0A20201B46 :101037006B20466F726D6174204469736B657474BD :101047006520696E2044726976652042201B6B001B :101057000D0A20201B6B204368616E676520666F51 :10106700726D61742064656E7369747920746F2082 :10107700444F55424C45207369646564201B6B00DF :101087000D0A20201B6B2052657475726E20746FD9 :1010970020746865204D61696E204D656E75201B53 :1010A7006B000D0A20201B6B2052657475726E2031 :1010B700746F2043502F4D201B6B000D0A0D0A241F :1010C7000F10341059108910AB101B73351A2020DC :1010D7002020202020202020202020202020202009 :1010E70020202020205573652074686520415252C6 :1010F7004F57206B65797320746F20706F73697415 :10110700696F6E207468650D0A202020202020203A :1011170020202020202020202020202020202020C8 :10112700637572736F72206E65787420746F2074A4 :10113700686520646573697265642063686F6963B5 :10114700650D0A202020202020202020202020207C :101157002020202020202020202020202020202088 :10116700202020202020202020206F7200001B73C9 :10117700361A202020202020202020202020202058 :101187002020202020202020507265737320524594 :101197005455524E20746F2073656C6563742061DB :1011A70020434F5059206F7074696F6E24001B7372 :1011B700361A202020202020202020202020202018 :1011C7002020202020202050726573732052455420 :1011D70055524E20746F2073656C656374206120CF :1011E700464F524D4154206F7074696F6E24001B37 :1011F70073361A2020202020202020202020202085 :1012070020202020202020202020202050726573BD :10121700732052455455524E20746F205265747591 :10122700726E20746F2043502F4D24001B73361AA3 :1012370020202020202020202020202020202020A7 :1012470020202020496E73657274206120446973E1 :101257006B6574746520696E2073656C656374656E :101267006420647269766520616E640D0A2020200F :1012770020202020202020202020202020205072E5 :101287006573732052455455524E20746F20737402 :1012970061727420666F726D617474696E67204441 :1012A7004F55424C4520736964656424001B7336AF :1012B7001A2020202020202020202020202020202D :1012C7002020202020496E736572742061204469B4 :1012D700736B6574746520696E2073656C656374E0 :1012E700656420647269766520616E640D0A20204A :1012F70020202020202020202020202020202050B7 :10130700726573732052455455524E20746F207383 :101317007461727420666F726D617474696E672090 :1013270053494E474C4520736964656424001B7319 :10133700361A2020202020202020202020507265CF :1013470073732052455455524E20746F2063686161 :101357006E676520666F726D617474696E6720646D :10136700656E7369747920746F20444F55424C45FC :1013770020534944454424001B73361A202020205B :101387002 A 02020202020205072657373205245545E :1013970055524E20746F206368616E676520666FD3 :1013A700726D617474696E672064656E73697479B0 :1013B70020746F2053494E474C45205349444544B8 :1013C70024001B73361A20202020202020202020D4 :1013D7002020202020202020202050726573732099 :1013E70052455455524E20746F2072657475726E53 :1013F70020746F20746865204D61696E204D656E9D :101407007524001B73361A2020202020202020203E :1014170020202020202020202020202020202020C5 :101427002020202020496E73657274204469736BF5 :10143700657474657320616E640D0A202020202076 :101447002020202020202020202020202020202095 :101457002020202020205072657373205245545558 :10146700524E20746F20537461727420434F505949 :101477002400001B73311B3D2020001B73321B3DD2 :0314870020200022 :10148B00001B73321A1B7331241B73330D0A0A0AA8 :10149B002020202020202020202020202020202041 :1014AB00202020001B73351A0D0A2020202020201D :1014BB002020202020202020202020202020202021 :1014CB00507265737320616E6420486F6C64205199 :1014DB0020746F205175697420466F726D6174743E :1014EB00696E671B73331A202020202020202020B8 :1014FB0020202020202020202020202020202020E1 :10150B0020202020202020547261636B20466F72B4 :10151B006D61747465643A0D0A2020202020202010 :10152B0020202020202020202020202030202020A0 :10153B00202020202020312020202020202020208F :10154B00322020202020202020203320202020206B :10155B00202020200D0A20202020202020202020A9 :10156B0020202020202020202030313233343536EB :10157B003738393031323334353637383930313218 :10158B003334353637383930313233343536373802 :10159B00390D0A0D0A202020202020202020202079 :1015AB002020202A20496E6469636174657320478B :1015BB006F6F6420466F726D617420202020204570 :1015CB0020496E6469636174657320466F726D6147 :1015DB0074204572726F720D0A241B73351A0D0A33 :1015EB0020202020202020202020202020202020F0 :1015FB002020202020202020507265737320616EE4 :10160B006420486F6C64205120746F20517569748D :10161B0020436F7079696E67241B73332020202061 :10162B0020202020202020202020202020202020AF :10163B0020202020202020202020202052656164A3 :10164B00696E6720547261636B20585820202024E8 :10165B001B7333202020202020202020202020201E :10166B00202020202020202020202020202020206F :10167B0020202057726974696E6720547261636B06 :10168B0020585820202024000000001B73321A2001 :10169B00202020202020202020202020202020203F :1016AB002020202020466174616C207265616420CB :1016BB006572726F72206F636375727265642E2030 :1016CB004D616B6520737572650D0A2020202020FB :1016DB0020202020202020202020202020202020FF :1016EB0020736F75726365206469736B2069732057 :1016FB00696E20706C61636520616E642074727911 :10170B0020616761696E2E0D0A2020202020202089 :10171B0020202020202020202020202020202020BE :10172B0020202020202050726573732045534320C6 :10173B00746F20636F6E74696E75652E001B733248 :10174B001A20202020202020202020202020202094 :10175B002052656164206572726F72206F636375CE :10176B0072726564206F6E20747261636B205858BF :10177B002E20436F6E74696E75652028592F4E2984 :10178B003F2000202020202020202020202020204F :10179B0020202052656164206572726F72206F6326 :1017AB00637572726564206F6E20747261636B2057 :1017BB0058582E20436F6E74696E75652028592F0B :1017CB004E293F201B73321A20202020434F5059A3 :1017DB0020636F6D706C6574656420776974682025 :1017EB0052454144206572726F72732E20446573AB :1017FB0074696E6174696F6E206469736B204D41FF :10180B005920636F6E7461696E206261642064613C :10181B0074612E0D0A202020202020202020202043 :10182B0020202020202020202020202020202020AD :10183B00202050726573732045534320746F2063CF :10184B006F6E74696E75652E001B73321A20202023 :10185B002020202020205772697465206572726FDA :10186B0072206F636375727265642E205265747299 :10187B007920776974682061206469666665726592 :10188B006E742064657374696E6174696F6E206425 :10189B0069736B2E0D0A2020202020202020202071 :1018AB00202020202020202020202020202020202D :1018BB0020202050726573732045534320746F2092 :1018CB00636F6E74696E75652E001B73321A202060 :1018DB0020202020202020202020202020202020FD :1018EB00204469736B6574746520696E204472695A :1018FB007665205820636F6E7461696E7320696E14 :10190B00666F726D6174696F6E2E0D0A2020202038 :10191B0020202020202020202020202020202020BC :10192B00202020204973206974204F4B2074s a pointer to the table of pointers to command ; descriptions for each command in the current menu. ; MENU_TABLE: DW 0 ; ; COM_TABLE is a pointer to a table of pointers to command routines ; for each command in the current menu. ; COM_TABLE: DW 0 ; ; MAIN is a pointer to the current menu. ; MAIN: DW 0 PAGE EXIT: ; Program exit point. Program returns to CP/M from here: ; Sends termination string to console: sets window 0, clears screen ; and enables fn. key xlate. ; ; ENTRY: ; None. ; ; EXIT: ; None. ; LK DE,GOOD_BYE ;Send termination string to ;console. LK C,PR_STR_FN CALL BDOS JMP WBOOTE ;and warm start. ; GOOD_BYE: DB ESC,'s','0','Z'-040h ; ; For TVI 912 emulation, include string to enable fn. key xlate: ; IF TVI912 DB ESC,'e',0 ENDIF DB '$' PAGE SETM1: ; Make main menu the current menu. ; Main menu allows selection of copy or format. ; ; ENTRY: ; None. ; ; EXIT: ; Parameters set for main menu. ; PROC LK  A HL,MENU1 ;Point to description table STO HL,MENU_TABLE ;for main menu LK HL,COM1 ;Point to routine table for STO HL,COM_TABLE ;main menu LK HL,MAIN1 ;Point to main menu data STO HL,MAIN ;structure. LK A,NO_OPT_1 ;Set # options for main menu STO A,NUM_OPTIONS LK A,32 ;Make COPY the default ;selection. STO A,Y_COORD RET ;and return PAGE SETM2: ; Make copy menu the current menu. ; Copy menu allows selection of Copy A to B or B to A. ; ; ENTRY: ; None. ; ; EXIT: ; Parameters set for copy menu. ; PROC LK HL,MENU2 ;Point to description table STO HL,MENU_TABLE ;for copy menu LK HL,COM2 ;Point to routine table for STO HL,COM_TABLE ;copy menu LK HL,MAIN2 ;Point to copy menu data STO HL,MAIN ;structure. LK A,NO_OPT_2 ;Set # options for copy menu STO A,NUM_OPTIONS LK A,32 ;Make COPY A to B the default ;selection. STO A,Y_COORD RET ;and return PAGE SETM3: ; Make format double sided menu the current menu. ; Format menu allows selection of format A or B or change ; density. ; ; ENTRY: ; None. ; ; EXIT: ; Parameters set for format menu double sided menu and format (FDENS) ; PROC LK HL,MENU3 ;Point to description table STO HL,MENU_TABLE ;for format menu LK HL,COM3 ;Point to routine table for STO HL,COM_TABLE ;format menu LK HL,MAIN3 ;Point to format menu data STO HL,MAIN ;structure. Lˠ A,NO_OPT_3 ;Se option fo format menu STO A,NUM_OPTIONS LK A,33 ;Make FORMAT B the default ;selection. STO A,Y_COORD LK A,1 ;Set flag for dsdd STO A,FDENS RET ;and return PAGE SETM4: ; Make format single sided menu the current menu. ; Format menu allows selection of format A or B or change ; density. ; ; ENTRY: ; None. ; ; EXIT: ; Parameters set for format single sided menu and format (FDENS) ; PROC LK HL,MENU4 ;Point to description table STO HL,MENU_TABLE ;for format menu LK HL,COM4 ;Point to routine table for STO HL,COM_TABLE ;format menu LK HL,MAIN4 ;Point to format menu data STO HL,MAIN ;structure. Lˠ A,NO_OPT_4 ;Se option fo format menu STO A,NUM_OPTIONS LK A,33 ;Make FORMAT B the default ;selection. STO A,Y_COORD XOR A ;Set flag for ssdd STO A,FDENS RET ;and return ; FDENS: DB 1 ;Set double sided as default PAGE ;------------------------------------------------------------------------------ ; Menu command description and routine tables follow: ; MENU1: ;Table for main menu DW SEL_COPY DW SEL_FMT DW RET_CPM COM1: DW M_COPY ;Table for main menu DW M_FORMAT DW EXIT MENU2: DW CPY_DSK ;Table for COPY menu DW CPY_DSK DW RET_MN DW RET_CPM COM2: DW COPY_A_B ;Table for COPY menu DW COPY_B_A DW EX_MAIN DW EXIT MENU3: DW FM_DK_DS ;Table for FORMAT DW FM_DK_DS DW SS_CH_MSG DW RET_MN DW RET_CPM COM3: DW FMT_A ;Table for FORMAT DW FMT_B DW CHG_DNS DW EX_MAIN DW EXIT MENU4: DW FM_DK_SS ;Table for FORMAT DW FM_DK_SS DW DS_CH_MSG DW RET_MN DW RET_CPM COM4: DW FMT_A ;Table for FORMAT DW FMT_B DW CHG_DNS DW EX_MAIN DW EXIT PAGE ;------------------------------------------------------------------------------ ; Command routines called when user requests action. Routine ; called depends on what the current selection is. DO_COMMAND ; determines the address of the routine to execute (which ; depends on the current menu and the current selection in that ; menu). M_COPY: ; Copy selected from main menu. Set current menu to copy menu. ; CALL SETM2 RET M_FORMAT: ; Format selected from main menu. Set current menu to format menu. ; Sets DS menu (3) if FDENS = 1, else set SS menu (4). ; PROC LD A,FDENS OR A JRNZ :S3 ; CALL SETM4 RET ; :S3: CALL SETM3 RET PAGE COPY_A_B: ; Copy from A to B selected from copy menu. ; Do copy. ; CALL CLR_W_3 ;Clear window used for status LK A,'A' ;Specify A as source disk  CALL KOPY ;Copy disks CALL CLR_W_3 ;Clear window used for status RET COPY_B_A: ; Copy from A to B selected from copy menu. ; Do copy. ; CALL CLR_W_3 ;Clear window used for status LK A,'B' ;Specify B as source CALL KOPY ;Copy disks CALL CLR_W_3 ;Clear window used for status RET PAGE FMT_A: ; Format, drive A selected. ; Do format. ; LK A,'A' ;Specify drive A LK B,'D' ;Specify double-density CALL FMAT ;Format the disk CALL CLR_W_3 ;Erase message window RET FMT_B: ; Format, drive B selected. ; Do format. ; LK A,'B' ;Specify drive B LK B,'D' ;Specify double-density CALL FMAT ;Format the disk CALL CLR_W_3 ;Erase message window RET PAGE CHG_DNS: ; Change from ssdd format to dsdd or vice versa. ; PROC LK HL,FDENS ;Point at current density flag LK A,1 ;Set low order bit of A XOR [HL] ;Change state of flag JRZ :S4 ;New state is ssdd, set current menu to 4 ; CALL SETM3 ;New state is dsdd, set current men A6F2096 :10193B006F76657277726974652069742028792FC8 :10194B006E293F20001B73321A20202020202020DC :10195B0020202020202020202020204469736B652C :10196B0074746520696E2044726976652058204D29 :10197B00415920636F6E7461696E20696E666F7278 :10198B006D6174696F6E2E0D0A202020202020209F :10199B00202020202020202020202020202020203C :1019AB00204973206974204F4B20746F206F76652C :1019BB007277726974652069742028792F6E293FBC :1019CB0020000D0A0A001B73321A20202020202031 :1019DB0020202020202020202020202020202020FC :1019EB0020202020434F505920636F6D706C65741D :1019FB006564207375636365737366756C6C792EA0 :101A0B000D0A2020202020202020202020202020F4 :101A1B0020202020202020202020202020507265F4 :101A2B0073732052455455524E20746F20636F6E62 :101A3B0074696E75652E001B73321A2020202020CE :101A4B00202020202020202020202020202020208B :101A5B0020202020202020202020202020434F50F9 :101A6B0059204552524F522E0D0A20202020202063 :101A7B00202020202020202020202020202020205B :101A8B002020202020202050726573732045534363 :101A9B0020746F20636F6E74696E75652E001B73F7 :101AAB00321A20202020202020202020202020201F :101ABB00202020202020202020202020202020201B :101ACB00202020434F50592041424F525445442E21 :101ADB000D0A202020202020202020202020202024 :101AEB002020202020202020202020202050726524 :101AFB0073732052455455524E20746F20636F6E92 :101B0B0074696E75652E001B73321A2020202020FD :101B1B0020202020202020202020202020202020BA :101B2B00202020536F75726365206469736B657435 :101B3B007465206973206E6F7420666F726D6174AB :101B4B007465640D0A2020202020202020202020D6 :101B5B002020202020202020202020202077697486 :101B6B00682061207374616E64617264204F7362CC :101B7B006F726E6520666F726D61742E0D0A202078 :101B8B00202020202020202020202020202020204A :101B9B00202020202020202020507265737320529B :101BAB00455455524E20746F20636F6E74696E7579 :101BBB00652E001B73321A2020202020202020208D :101BCB00536F7572636520616E642064657374690D :101BDB006E6174696F6E206469736B657474657381 :101BEB0020646F6E27742068617665206D61746365 :101BFB0068696E6720666F726D6174732E0D0A20B3 :101C0B0020202020202020202020202020202020C9 :101C1B00202020202020202020205072657373204C :101C2B0052455455524E20746F20636F6E74696E1B :101C3B0075652E001B73321A2020202020202020B7 :101C4B002020202020202020202020202020202089 :101C5B0020464F524D415420636F6D706C65746517 :101C6B0064207375636365737366756C6C792E0D85 :101C7B000A2020202020202020202020202020206F :101C8B00202020202020202020202020507265732F :101C9B00732052455455524E20746F20636F6E74EF :101CAB00696E75652E001B73321A202020202020B0 :101CBB002020202020202020202020202020202019 :101CCB002020202020202020202020464F524D4134 :101CDB0054204552524F522E0D0A202020202020F6 :101CEB0020202020202020202020202020202020E9 :101CFB0020202020202020507265737320455343F1 :101D0B0020746F20636F6E74696E75652E001B7384 :101D1B00321A2020202020202020202020202020AC :101D2B0020202020202020202020202020202020A8 :101D3B002020464F524D41542041424F525445446E :101D4B002E0D0A20202020202020202020202020A3 :101D5B0020202020202020202020202020205072F6 :101D6B006573732052455455524E20746F20636F28 :101D7B006E74696E75652E00FFFFFFFFFFFFFFFF9F :101D8B00FFFFFFFFFFFFFFFFFF000000000000FE53 :101D9B0000000101F7FFFFFFFFFFFFFFFFFFFFFF4A :101DAB00000000000000FBE5E5E5E5E5E5E5E5E520 :101DBB00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5C8 :101DCB00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5B8 :101DDB00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5A8 :101DEB00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E598 :101DFB00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E588 :101E0B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E577 :101E1B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E567 :101E2B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E557 :101E3B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E547 :101E4B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E537 :101E5B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E527 :101E6B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E517 :101E7B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E507 :101E8B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5F7 :101E9B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E7 :101EAB00E5E5E5E5E5E5E5F74E4E4E4E4E4E4E4E7D :101EBB004E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E37 :101ECB004E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E27 :101EDB004E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E17 :101EEB004E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E07 :101EFB004E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4EF7 :101F0B004E4E4E4E4E4E4E4E4E4E4E4E000000001E :101F1B000000000000000000F5F5F5FE00000103D5 :101F2B00F74E4E4E4E4E4E4E4E4E4E4E4E4E4E4E1D :101F3B004E4E4E4E4E4E4E00000000000000000074 :101F4B00000000F5F5F5FBE5E5E5E5E5E5E5E5E59F :101F5B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E526 :101F6B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E516 :101F7B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E506 :101F8B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5F6 :101F9B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E6 :101FAB00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5D6 :101FBB00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5C6 :101FCB00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5B6 :101FDB00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5A6 :101FEB00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E596 :101FFB00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E586 :10200B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E575 :10201B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E565 :10202B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E555 :10203B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E545 :10204B00E5E5E5E5E5E5E5E5E5AE5E5E5E5E5E5E535 :10205B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E525 :10206B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E515 :10207B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E505 :10208B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5F5 :10209B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5 :1020AB00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5D5 :1020BB00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5C5 :1020CB00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5B5 :1020DB00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5A5 :1020EB00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E595 :1020FB00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E585 :10210B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E574 :10211B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E564 :10212B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E554 :10213B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E544 :10214B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E534 :10215B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E524 :10216B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E514 :10217B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E504 :10218B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5F4 :10219B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E4 :1021AB00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5D4 :1021BB00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5C4 :1021CB00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5B4 :1021DB00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5A4 :1021EB00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E594 :1021FB00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E584 :10220B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E573 :10221B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E563 :10222B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E553 :10223B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E543 :10224B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E533 :10225B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E523 :10226B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E513 :10227B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E503 :10228B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5F3 :10229B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E3 :1022AB00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5D3 :1022BB00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5C3 :1022CB00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5B3 :1022DB00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5A3 :1022EB00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E593 :1022FB00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E583 :10230B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E572 :10231B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E562 :10232B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E552 :10233B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E542 :0D234B00E5E5E5E5E5E5E5F700000000004B :00010010 C,xxxTRK,xxxDSK must be maintained ; along with length (1,2,1). SAVSEC DS 1 ;last sector requested SAVTRK DS 2 ;last track requested SDISK DS 1 ;selected disk drive (0,1) SAVTYP DS 1 ;SELECTED TYPE (sector size) IE_ADR: DS 1 CURPOS: DS 2 ;Current cursor position ; VARIABLES FOR HIGH RAM ROUTINES TEMSAV DS 1 ;Used by jump bank routine SRCBANK DS 1 ;Source bank for block move DESTBANK DS 1 ;Destination bank for block move ;JMPSPOT and JMPADDR must stay next to each other JMPSPOT DS 1 ;To be filled in with a JMP instruction by the ROM JMPADDR DS 2 ;Address to jump to for BANKJMP and BANKCALL JMPBANK DS 1 ;Bank to jump to for BANKJMP and BANKCALL EMRAM = * ; INTERRUPT VARIABLES USR_BNK DS 1 ;Uu to 3 RET ;Return ; :S4: CALL SETM4 ;Set menu 4 RET ;and return PAGE EX_MAIN: ; Return to main menu requested. Set current menu to main ; menu. ; CALL SETM1 RET PAGE CLR_W_3: ; Routine to clear window 3. Window 3 is used for execution ; status while performing an operation. ; LK HL,:CLR_3_STR ;Point at string to clear window CALL OUT_STRING ;and send to console. RET ; :CLR_3_STR: ; String to clear window 3. Selects window 3 and sends clear screen ; character. ; DB ESC,'s3',CLR_SCR,0 PAGE FMAT: ; Disk format routine ;ENTRY ; A = Disk to format ('A' or 'B') ; B = Density in which to format ('S' or 'D') ;EXIT ;NONE PROC :LOOP: STO A,D_FMT_D STO A,D_FMT_D2 SUI 'A' STO A,SDISK MOV A,B STO A,TMP_DEN ;Save density until after we check ;for info on disk. ; CMP ESC ;Check for disk not empty check ;override ; JZ :OVR ; XOR A ;Don't override... STO A,OVRD_FLAG JMP :CO ; :OVR: LK A,0FFH STO A,OVRD_FLAG :CO: CALL CLR_W_2 LD A,OVRD_FLAG ;Check for blank disk check override OR A JNZ :OVRD ; LD A,SDISK ;See if destination disk contains info CALL CK_INFO JZ :BLK_DSK ;No...format it ; LK HL,DSK_FMT ;Assume it does DEC A ;Does it (i.e., is A = 1) ? JZ :ASK ;It does, ask user if it should be ;overwritten ; LK HL,DK_MB_FMT ;Disk MAY have info. Ask user if it ;should be overwritten. :ASK: CALL PRINT CALL Y_N PUSH AF ;Save response CALL CLR_W_2 ;Clear question POP AF ;Restore response CMP 'N' ;No, RZ ;Don't format ; ;Yes, format disk :OVRD: :BLK_DSK: LD A,TMP_DEN ;Restore density specification CALL STSAVTYP ;SET DENSITY CALL SETPARM ;SET PARAMITERS CALL FORMAT ;FORMAT DISKETTES PUSH AF ;Save return code from FORMAT LK C,0DH ;so the disk system can be reset. CALL SYS ;The disk system must be reset since ;the disk has effectively been changed ;by formatting it. POP AF ;Restore return code from FORMAT CPI ACTER: | | | | | | | | ; 5 bits 0 0 | | | | | | ; 6 bits 0 1 | | | | | | ; 7 bits 1 0 | | | | | | ; 8 bits 1 1 | | | | | | ;Auto Enables <--------------------------+ | | | | | ;Enter Hunt Phase (not used) <---------------+ | | | | ;Rx CRC Enable <---------------------------------+ | | | ;Address Search Mode (not used) <--------------------+ | | ;SYNC Char Load Inhibit (not used) <---------------------+ | ;Rx Enable <---------------------------------------------+ ;WRITE REG 4: +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ;CLOCK MODE: | | | | | | | | ; X1 Clock Mode 0 0 | | | | 'Q' LDK HL,ABTFMT ;FORMAT aborted JRZ :DONE ;If aborted ORA A LDK HL,GDFMT ;FORMAT completed successfully JRZ :DONE ;IF NO ERRORS :BAD: LDK HL,BDFMT ;ERROR IN FORMAT CALL PRINT CALL GET_ESC CALL CLR_W_2 RET ; :DONE: CALL PRINT CALL GVCHR CALL CLR_W_2 RET ; TMP_DEN DB 0 ;Local temporary storage for density spec PAGE KOPY: ; Disk copy routine ;ENTRY ; A = Source diskette ('A' or 'B') ;EXIT ;NONE PROC :LOOP: PUSH AF ;Save disk # XRI 03H ;Compute destination drive letter STO A,D_FMT_D ;Save in message STO A,D_FMT_D2 POP AF ;Restore disk # SUI 'A' STO A,SOURCE ;SET SOURCE STO A,SDISK ;SET DISK ; CMP ESC ;Check for disk not empty check ;override ; JZ :OVR ; XOR A ;Don't override... STO A,OVRD_FLAG JMP :CO ; :OVR: LK A,0FFH STO A,OVRD_FLAG :CO: CALL CLR_W_2 CALL SENDEN ;GET DENSITY JNZ :1 ;IF ERROR LD A,SAVTYP ;Set NSIDES = 1 if dsdd, else 0 841006 CPI DSTYP ; 841006 JNZ :SSD ;  841006 ; LK A,1 ; 841006 JR :DSD ; 841006 ; :SSD: XOR A ;NSIDES = 0 841006 :DSD: STO A,NSIDES ; 841006 CALL SETPARM ;SET PARAMETERS CALL MATCHFMT ;MAKE SURE SOURCE AND DESTINATION ;IF NOT OSBORNE FORMAT LDK HL,BADDEN JNZ :DONE ;IF FORMATS DON'T MATCH LD A,OVRD_FLAG ;Check for blank disk check override OR A JNZ :OVRD ; LD A,SOURCE ;Get source drive XRI 0000_0001B ;Convert to destination drive CALL CK_INFO ;See if destination disk has info JZ :BLK_DSK ;No...format it ; LK HL,DSK_FMT ;Assume it does DEC A ;Does it (i.e., is A = 1) ? JZ :ASK ;It does, ask user if it should be ;overwritten ; LK HL,DK_MB_FMT ;Disk MAY have info. Ask user if it ;should be overwritten. :ASK: CALL PRINT CALL Y_N PUSH AF ;Save response CALL CLR_W_2 ;Clear question POP AF ;Restore response CMP 'N' ;No, RZ ;Don't copy ; ;Yes, copy disk :OVRD: :BLK_DSK: CALL COPY ;COPY A DISKETTE PUSH AF ;Save return code from COPY LK C,0DH ;so the disk system can be reset. CALL SYS ;The disk system must be reset since ;the disk has effectively been changed ;by copying to it. POP AF ;Restore return code from COPY. CPI 'Q' ;See if user aborted. LDK HL,ABTCPY ;COPY aborted JRZ :DONE OR A ;User did not abort. See if COPY good. RNZ ;Not good, COPY routine displayed ;err already, so return ; LDK HL,GMES ;COPY completed successfully :DONE: CALL PRINT ;Display message pointed to by HL CALL GVCHR ;Wait for user to enter RETURN CALL CLR_W_2 ;Clear message window. RET ; :1: LK HL,F_RD_ERR ;Fatal read error in COPY CALL PRINT CALL GET_ESC CALL CLR_W_2 RET PAGE CK_INFO: ; Checks to see if there is info on disk. Calls sense density routine ; to see if the disk is formatted. If it is not formatted, there is no ; info. ; If disk is formatted, checks for files in directory. ; ; ENTRY: ; A = # of disk on which to check for info ; 0 means drive A, ; 1 means drive B. ; ; EXIT: ; A = 0 if disk has no info, ; A = 1 if disk has info and ; A = 2 if disk MAY HAVE info (i.e., can't be determined). ; Additionally: ; Z flag set if disk has no info ; Z flag clear if disk has or may have info. ; ; SIDE EFFECT: ; SDISK set to disk # (whatever A is on entry) ; PROC MOV B,A ;Save drive spec in B PUSH BC ;Save on stk STO A,SDISK ;Select disk for SENDEN CALL SENDEN ;Check for unformatted disk. Z is clear ;if disk no formatted. POP BC ;Restore disk # JNZ :NO_INFO ;Return code indicating no info ; MOV A,B ;Restore disk # to A INC A ;Make disk # relative-one per BDOS STO A,AMB_FCB ;Put drive spec in FCB for search for first LK DE,AMB_FCB ;Point at ambiguous FCB to check for any files. LK C,SRC_FIRST ;Tell BDOS to do search-for-first. CALL SYS ;Returns A = 0FFh if no files or if error INC A ;A = 0FFH? JNZ :INFO_FOUND ;No... ; XOR A ;Check for error. OR H ;Is H = 0? JNZ :CANT_TELL ;No, errAor occurred. ; :NO_INFO: ;No error, no info. XOR A ;Clear A and set Z flag RET ; :INFO_FOUND: ;Info on disk XOR A ;Return Z clear and A = 1 INC A RET :CANT_TELL: ;May be info. LK A,2 ;Return A = 2 and Z clear OR A RET PAGE CLR_W_2: PROC LK HL,:CLR_2_STR CALL PRINT RET ; :CLR_2_STR: DB ESC,'s2','Z'-40h,0 PAGE Y_N: PROC :YNLP: CALL C1 AND 5FH CMP 'Y' JZ :ECHO ; CMP 'N' JNZ :YNLP ; :ECHO: PUSH AF CALL COUT POP AF RET PAGE STSAVTYP: ;SET SAVTYP FOR FORMAT ;ENTRY ;A = 'S' FOR SINGLE DENSITY ;EXIT ;B = # OF SECTORS/TRACK PROC CPI 'S' JZ :SING ;IF SINGLE DENSITY ;DOUBLE DENSITY LDK A,DDTYP STO A,SAVTYP LDK B,5 ;SECTORS/TRACK RET ;SINGLE DENSITY :SING: LDK A,SDTYP STO A,SAVTYP LDK B,10 ;SECTORS/TRACK RET PAGE SETPARM: ;SET UP PARAMETERS THAT DEPEND ON DENSITY ;ENTRY ;B = # OF SECTORS/TRACK ;SAVTYP = SET ;EXIT ;PARAMETERS SET PROC MOV A,B STO A,NMSEC ;SECTORS/TRACK ORI 0FFH STO A,OSBFMT ;INITIALIZE TO NON-OSBORNE FORMAT ;CHECK FOR STANDARD OSBORNE DENSITIES LD A,SAVTYP CPI SDTYP JZ :SING ;IF SINGLE DENSITY SAVTYP ;DOUBLE DENSITY CPI DDTYP JZ :DD ;IF DOUBLE DENSITY SAVTYP 841006 ; CPI DSTYP ;DSDD uses same parameters as ssdd 841006 JNZ :2 ;Not dsdd 841006 ; :DD: MOV A,B ;VERIFY # OF SECTORS CPI DSEC JNZ :2 ;IF WRONG # OF SECTORS LDK HL,DDPARM ;DOUBLE DENSITY PARAMETERS JR :1 ;SINGLE DENSITY :SING: MOV A,B ;VERIFY SECTORS/TRACK CPI SSEC JNZ :2 ;IF NOT STANDARD SINGLE DENSITY LDK HL,SDPARM ;SINGLE DENSITY PARAMETERS ;MOVE OSBORNE PARAMETERS TO PARM :1: LDK DE,PARM LDK BC,7 LDIR ;SET UP REMAINING PARAMETERS :2: CALL STRKLEN ;SET NUMBER OF BYTES PER TRACK CALL SNUMTRK ;SET NUMBER OF TRACKS PER BLOCK CALL SNUMBLK ;SET NUMBER OF BLOCKS PER DRIVE RET PAGE STRKLEN: ;SET NUMBER OF BYTES PER 'Physical' and 'Logical' TRACK ; Logical track length (TRKLEN) is used to compute # tracks per 841006 ; block; physical track len (PTRKLEN) is used for verifying data 841006 ; on read/write. ;ENTRY ;NMSEC = SECTORS/TRACK ;SAVTYP SET ;EXIT ;TRKLEN = BYTES/TRACK PROC ;SET HL = SECTORS/TRACK * 128 LD A,NMSEC MOV H,A LDK L,0 ;HL = NMSEC * 256 SRA H RR L ;HL = NMSEC * 128 ;GET BYTES/SECTOR LD A,SAVTYP SRL A SRL A ANI 0000_0011B ;GET SECTOR LENGTH ;(00 = 128, 01 = 256, 10 = 512, 11 = 1024) MOV B,A JZ :2 ;DONE IF 128-BYTE SECTORS ;CALCULATE BYTES/TRACK ;HL = HL * (2**B) :1: DAD HL,HL ;HL * 2 DJNZ :1 :2: STO HL,PTRKLEN ;Save physical trk len 841006 LD A,NSIDES ;Dbl sided or single? 841006 OR A ; 841006 JZ :3 ;Single... 841006 ; ADD HL,HL ;Double; logical = 2 * physical 841006 :3: STO HL,TRKLEN RET PAGE SNUMTRK: ;SET NUMBER OF TRACKS PER BLOCK ;ENTRY ;NONE ;EXIT ;NONE PROC ;GET TOTAL BUFFER LENTH XRA A ;RESET CARRY FLAG LD HL,SYS+1 ;GET TOP OF TPA LDK DE,BUFF1 ;FBA OF BUFF1 SBC HL,DE ;HL = TOTAL SPACE AVALIBLE ;GET NUMBER OF TRACKS PER BUFFER LD DE,TRKLEN ;GET TRACK LENTH LDK B,0 ;SET COUNT TO ZERO XRA A ;RESET CARRY FLAG :LOOP: SBC HL,DE ; - ONE TRACK INC B ;B=B+1 JNC :LOOP ;LOOP UNTIL HL < DE ;SET NUMTRK DEC B ;B = NUMBER OF TRACKS IN ONE BLOCK MOV A,B STO A,NUMTRK ;SET NUMTRK RET PAGE SNUMBLK: ;SET NUMBER OF BLOCKS PER DRIVE ;ENTRY ;NUMTRK = NUMBER OF TRACKS PER BLOCK ;EXIT ;NONE PROC LD A,NUMTRK ;GET NUMBER OF TRACKS PER BLOCK MOV B,A ;SAVE LDK A,MTRK ;GET NUMBER OF TRACKS PER DRIVE LDK C,0 ;ZERO COUNTER :LOOP: SUB B ; - ONE BLOCK JZ :1 ;IF EVEN DON'T INC INC C ;C=C+1 JNC :LOOP ;LOOP TILL A 0 IF FORMATS DON'T MATCH ;ZBIT RESET IF FORMATS DON'T MATCH PROC  ;CHECK FOR OSBORNE FORMAT LD A,OSBFMT ORA A RZ ;RETURN OK IF OSBORNE ;PRINT NOT OSBORNE MESSAGE LDK HL,NOTOSB CALL PRINT CALL GVCHR ;CHECK DESTINATION DISK LD A,SAVTYP MOV D,A PUSH DE ;SAVE SOURCE SAVTYP LD A,SOURCE ;SOURCE DISK XRI 0000_0001B ;OTHER DISK STO A,SDISK CALL SENDEN ;SENSE DESTINATION DENSITY POP DE ;RESTORE D = SOURCE SAVTYP LD A,NMSEC ;SOURCE SECTORS/TRACK CMP B ;DESTINATION SECTORS/TRACK RNZ ;RETURN ERROR IF SECTORS/TRACK DON'T MATCH LD A,SAVTYP ;DESTINATION SAVTYP CMP D ;SOURCE SAVTYP RNZ ;RETURN ERROR IF SAVTYPs DON'T MATCH ;RESTORE SAVTYP AND SDISK TO SOURCE MOV A,D STO A,SAVTYP ;RESTORE SOURCE SAVTYP LD A,SOURCE STO A,SDISK ;RESTORE SOURCE SDISK XRA A RET ;GOOD RETURN PAGE ; FORMAT: ;FORMAT ONE DISK ; ; If disk is to be ssdd, both sides are formatted, but ; side 1 is formatted so that side byte in sector header ; says side 0. This is done so SENDEN routine in ROM can ; Adiscriminate between a dsdd disk reformatted to ssdd ; and a dsdd disk. ; ;ENTRY ; FDENS set 1 if disk should be formatted dsdd, else 0 for ssdd ;EXIT ;A = 0 IF NO ERRORS ; OFFH IF ERROR ; 'C'-40H IF ABORT LDK HL,PFORMAT ;FORMAT MESSAGE CALL STRCON LDK A,1 STO A,SAVSEC ;SET SECTOR CALL RHOME ;HOME DRIVE JNZ :ERR ;ERROR RETURN ;FORMAT AND VERIFY ENTIRE DISK LDK HL,CRLF5S CALL PRINT XRA A ;START WITH TRACK 0 STO A,FMTERR ;NO ERRORS YET ;TRACK LOOP :TLOOP: STO A,SAVTRK ;UPDATE TRACK NUMBER XOR A ;Start with physical 841005 STO A,:SIDE ;side 0 841005 STO A,:LSIDE ;and logical side 0 841005 LD A,SAVTYP ;Set side 0 in SAVTYP 841005 AND 1111_1101B STO A,SAVTYP :SLOOP: ;Top of side loop 841005 CALL FMTINT ;INITIALIZE FORMAT BUFFER(BUFF) LD A,:LSIDE ;Load logical side MOV C,A ;Pass it in C CALL STRK ;SET NEW TRACK and logical side ;INTO DATA IF NOT FMT_FIX LDK BC,BUFF  ;POINT TO FWA OF BUFFER CALL RFORMAT ;FORMAT ONE TRACK ENDIF IF FMT_FIX LK HL,BUFF ;Point at buffer STO HL,DMADR ;save as DMA address IN SYS_DTA ;Get bank mask for TPA STO A,DMA_BANK ;and save as DMA bank CALL RFORMAT ;Format the track ENDIF JNZ :1 ;IF ERROR ; ; Skip verify if physical side 1 and logical side 0 ; LD A,:LSIDE ;Verify if logical side 1 OR A ; JNZ :VER ; ; LD A,:SIDE ;Don't verify if physical side OR A ;1 JNZ :NOVER ; ; :VER: CALL VERIFY JNZ :1 ;If error :NOVER: LDK A,'*' JMP :2 ;IF GOOD :1: LDK A,'E' STO A,FMTERR ;SET ERROR FLAG :2: CALL CONOUT ;OUTPUT INDICATOR LK A,'H' - 040h ;Backspace 841005 CALL CONOUT ; 841005 CALL CKABORT RZ ;RETURN IF ABORT LD A,:SIDE ;Is this not side 0? 841005 OR A ; 841005 JNZ :NXTTRK ;Yes... 841005 ; INC A ;No. Bump side indicator841005 STO A,:SIDE ; 841005 LD A,FDENS ;Are we formatting dsdd? OR A ; JRZ :SS ;No, leave logical sied at 0 ; STO A,:LSIDE ;Yes, set logical side to 1 :SS: LD A,SAVTYP ;Toggle side bit in 841005 XOR 0000_0010B ;SAVTYP to change 841005 STO A,SAVTYP ;physical side 841005 JMP :SLOOP ;And do side 1 841005 :NXTTRK: LK A,'L' - 040H ;Advance to next space 841005 CALL CONOUT ; 841005 LD A,SAVTRK INC A CMP MTRK JNZ :TLOOP ;CONTINUE TILL ALL TRACKS ;FINAL CHECK LD A,FMTERR ORA A JRNZ :ERR ;IF ERROR ; CALL STPODRV ;VERIFY ALL TRACKS RET ;RETURN A=0 IF NO ERROR, A=0FFH IF ERROR :ERR: ORI 0FFH RET ;RETURN ERROR :SIDE: DB 0 ; 841005 :LSIDE: DB 0 ;Logical side PAGE VERIFY: ;VERIFY 0E5H ON ONE TRACK ;USES BUFF FOR VERIFICATION ;ENTRY ;SDISK = DRIVE TO VERIFY ;SAVTRK = TRACK TO VERIFY ;EXIT ;ZBIT = RESET IF ERROR PROC LDK BC,BUFF STO BC,DMADR ;SET DMA STO BC,LBUFF1 ;SET DMA FOR CNDATA IN SYS_DTA ;Get TPA bank from PIA STO A,DMA_BANK ;and make it the DMA bank ;READ ONE TRACK LD A,NMSEC ;SECTORS/TRACK MOV B,A CALL RREAD ;READ ONE TRACK RNZ CALL CNDATA ;CHECK FOR ALL E5H'S RET PAGE COPY: ;COPY DISKETTE ;ENTRY ;SOURCE = DRIVE TO COPY FROM ;EXIT ;A = 0 IF NO ERROR ; 0FFH IF ERROR ; 'C'-40H IF ABORT ;B IS DESTROYED PROC XOR A ;Clear read error flag STO A,R_ERR_FLAG LD A,SAVTYP ;Set physical side for FDC to 0 841006 CBIT 1,A ; 841006 STO A,SAVTYP ; 841006 LK HL,ABT_MSG CALL STRCON LDK A,1 STO A,SAVSEC ;SET SECTOR *BLOCK LOOP (0-3 SINGLE DENSITY) (0-7 DOUBLE DENSITY) XRA A :BLOOP: STO A,BLOCK CALL RDMBLK ;READ MASTER LDK HL,RDERR JNZ :F_R_ERR ;Fatal read error (such as no disk in source ;drive)... ; CMP 'Q' ;Check for abort char RZ ;Return if aborted... CALL WRTBLK ;WRITE BLOCK TO OBJECT LDK HL,WTERR JNZ :ERR CMP 'Q' ;Check for abort char RZ ;Return if aborted... *FINISHED? LD A,NUMBLK ;GET NUMBER OF BLOCKS MOV B,A LD A,BLOCK ;CURRENT BLOCK INC A CMP B JNZ :BLOOP ;LOOP ; CALL STPODRV ;VERIFY ALL TRACKS LD A,R_ERR_FLG ;Check for read error OR A RZ ;No error. ; LK HL,RD_ERR_WARN ;Point at warning messg JMP :ERR ;and handle error ; :F_R_ERR: ;Fatal read error occurred LK HL,F_RD_ERR JMP :ERR :ERR: CALL PRINT ;Print err messg CALL GET_ESC ;Wait for user to enter ESC CALL CLR_W_2 ;Clear err messg OR 0FFH ;Return error message RET PAGE RDMBLK: ;READ ONE BLOCK FROM THE MASTER ;ENTRY ;EXIT ;ZBIT = RESET IF ERROR PROC LD A,SOURCE STO A,SDISK ;SET DRIVE ;FIND HEAD POSITION AND SET D.TRKR CALL SENDEN ;SENCE DENSITY RNZ LD A,SAVTYP ;Start on side 0 841008 AND 1111_1101B ;Clear bit 1 841008 STO A,SAVTYP ; 841008 XRA A ;ZERO A STO A,TRACK ; 841006 :TLOOP: CALL SETSAVTRK ;SET SAVTRK 841006 LD A,SAVTRK ;GET SAVTRK CMP MTRK RZ ;IF SAVTRK = 40 STOP CALL CKABORT ;Check for user abort request RZ ;RAeturn if aborted... CALL SETLBUFF1 ;SET LBUFF1 CALL RDMTRK ;READ MASTER JZ :NO_ERR ;No error... ;Read error occurred LK A,0FFH ;Flag the error STO A,R_ERR_FLAG LD A,SAVTRK ;Patch track # into error message MOV L,A ; LK H,0 ; LK DE,RD_ERR_P ; CALL CBD2 ; LK HL,RD_ERR ;Point at error message CALL PRINT ;and print it. It asks user if she wants to ;continue (Y/N) CALL Y_N ;Wait for user to enter Y or N PUSH AF ;Save response CALL CLR_W_2 ;Clear message POP AF ;restore Y or N response CMP 'Y' ;Is it Y (for continue)? JZ :ERR_OK ;Yes, proceed ; XOR A ;Clear Z flag LK A,'Q' ;No. Return and indicate user aborted. RET ; :ERR_OK: :NO_ERR: LD A,NSIDES ;Is this dsdd? 841006 OR A ; 841006 JZ :NXTTRK ;No, next trk 841006 ; LD A,SAVTYP ;Change FDC physical side 841006 XOR SSMASK ; 841006 STO A,SAVTYP ; 841006 BIT 1,A ; JNZ :TLOOP ;If new side is side 1, stay on same 841008 ;track :NXTTRK:  LDK HL,NUMTRK ;# OF TRACKS/BLOCK LD A,TRACK INC A CMP [HL] ;DONE? RZ ;Yes... 841006 ; STO A,TRACK ;Save new track # 841006 JMP :TLOOP ;Do next logical track 841006 ; ; Local storage for read error flagging and track recording: ; R_ERR_FLAG: ;Read error flag DB 0 R_ERR_TRK: ;Last track where read error occurred DW 0 PAGE RDMTRK: ;READ ONE TRACK OFF MASTER ;ENTRY ;LBUFF1 = DMA ADDRESS ;EXIT ;ZBIT = RESET IF ERROR PROC LD HL,SAVTRK ;Put decimal track # in message to print LK DE,RCOPYN CALL CBD2 LDK HL,RCOPY CALL STRCON ;OUTPUT MESSAGE LD HL,LBUFF1 STO HL,DMADR ;SET DMA TO "LBUFF1" IN SYS_DTA ;Get TPA bank from PIA STO A,DMA_BANK ;and make it the DMA bank LD A,NMSEC MOV B,A CALL RREAD ;READ RET PAGE WRTBLK: ;WRITE ONE BLOCK ON OBJECT DRIVE ;ENTRY ;EXIT ;ZBIT = RESET IF ERROR PROC ;SELECT DRIVE LD A,SOURCE XRI 0000_0001B ;OTHER DRIVE STO A,SDISK ;SET DRIVE ;FIND HEAD POSITION AND SET D.TRKR LD A,BLOCK ORA A JNZ :1 ;If "BLOCK" is not zero skip home ;HOME DRIVE IF ON TRACK ZERO CALL RHOME ;HOME DRIVE RNZ ;RETURN IF ERROR JR :2 ;IF GOOD SKIP SENDEN :1: CALL SENDEN RNZ ;RETURN IF ERROR :2: LD A,SAVTYP ;Start on side 0 841008 AND 1111_1101B ;Clear bit 1 841008 STO A,SAVTYP ; 841008 XRA A STO A,TRACK ;TRACK LOOP :TLOOP: CALL SETSAVTRK ;SET SAVTRK LD A,SAVTRK ;GET SAVTRK CMP MTRK RZ ;IF SAVTRK = 40 STOP CALL CKABORT ;Check for user abort request RZ ;Return if aborted... CALL SETLBUFF1 ;SET LBUFF1 CALL WRTTRK ;WRITE TRACK RNZ LD A,NSIDES ;Is this dsdd? 841006 OR A ; 841006 JZ :NXTTRK ;No, next trk 841006 ; LD A,SAVTYP ;Change FDC physical side 841006 XOR SSMASK ; 841006 STO A,SAVTYP ; 841006 BIT 1,A ; JNZ :TLOOP ;If new side is side 1, stay on same 841008 ;track :NXTTRK: LDK HL,NUMTRK ;# OF TRACKS/BLOCK LD A,TRACK INC A CMP [HL] ;DONE? RZ ;Yes... 841006 ; STO A,TRACK ;Save new track # 841006 JMP :TLOOP ;Do next track 841006 PAGE WRTTRK: ;WRITE FORMAT AND DATA ON TRACK ;ENTRY ;SAVTRK = TRACK TO COPY ;BUFF = FORMAT INFO ;LBUFF1 = INFO TO COPY ;"LBUFF1" holds the fba address of the buffer ;EXIT ;ZBIT = RESET IF ERROR PROC LD HL,SAVTRK ;Put decimal track # in message LK DE,WCOPYN CALL CBD2 LDK HL,WCOPY CALL STRCON ;OUTPUT MESSAGE ;FORMAT ;If ssdd, format side 1 to look like side 0 LD A,NSIDES ; 841006 OR A ; 841006 JNZ :GOFMT ;Not ssdd... 841006 ; LD A,SAVTYP ;Set FDC side to 1 841006 SBIT 1,A ; 841006 STO A,SAVTYP ; 841006 CALL WRTFMT ;Leave logical side at 0 841006 LD A,SAVTYP ;Set FDC side to 0 841006 CBIT 1,A ; 841006 STO A,SAVTYP ; 841006 :GOFMT: CALL WRTFMT RNZ ;IF ERROR MOV A,B ORA A ;SET FLAGS RZ ;IF ALL E5's, NO NEED TO WRITE ;WRITE A TRACK LDK A,2 STO A,ERCOUNT ;RETRY ONCE FOR WRITE COMPARE ERRORS :1: LD HL,LBUFF1 STO HL,DMADR ;SET DMA IN SYS_DTA ;Get TPA bank from PIA STO A,DMA_BANK ;and make it the DMA bank LD A,NMSEC ;SECTORS/TRACK MOV B,A CALL RWRITE RNZ ;READ A TRACK LDK HL,BUFF STO HL,DMADR ;SET DMA IN SYS_DTA ;Get TPA bank from PIA STO A,DMA_BANK ;and make it the DMA bank LD A,NMSEC MOV B,A CALL RREAD ;READ RNZ ;COMPARE BUFFERS LD BC,PTRKLEN ;Compare physical track length of data 841006 LDK DE,BUFF LD HL,LBUFF1 CALL COMPSEG ;VERIFY THE "TRACK" RZ ;RETURN IF OK LD A,ERCOUNT DEC A JNZ :1 ;IF MORE RETRIES ORI 0FFH ;INDICATE PERMANENT ERROR RET PAGE WRTFMT: ;WRITES FORMAT ON TRACK IF OSBORNE FORMAT ;ENTRY ;NONE ;EXIT ;B = 0 IF ALL E5'S ON OSBORNE FORMAT ;A = 0 IF NO ERRORS ;ZBIT SET PROC LD A,OSBFMT ORA A JNZ :1 ;SKIP FORMAT IF NOT OSBORNE ;FORMAT OSBORNE DISKS ;SET UP FORMAT BUFFER CALL SAVBUFF ;SAVE THE INFO ABOVE BUFF CALL FMTINT ;INITIALIZE FORMAT BUFFER(BUFF) LD A,NSIDES ;If ssdd, aAlways make "logical" side 841013 OR A ;0 841013 JZ :STRK ;(Obviously, A = 0...) 841013 LD A,SAVTYP ;DSDD, set "logical" side same as 841009 AND 0000_0010B ;physical side 841009 RR A ;Shift side indicator to bit 0 841009 :STRK: MOV C,A ;to pass to STRK 841006 CALL STRK ;SET TRACK NUMBER and side # IN BUFF 841006 ;FORMAT TRACK IF NOT FMT_FIX LDK BC,BUFF ;POINT TO FWA OF BUFFER CALL RFORMAT ;FORMAT ONE TRACK ENDIF IF FMT_FIX LK HL,BUFF ;Point at buffer STO HL,DMADR ;save as DMA address IN SYS_DTA ;Get bank mask for TPA STO A,DMA_BANK ;and save as DMA bank CALL RFORMAT ;Format the track ENDIF RNZ ;RETURN TO STOP IF ERROR IN COPY ;CHECK TRACK FOR NO INFORMATION(ALL 0E5H'S) CALL RSTBUFF ;RESTORE THE INFO ABOVE BUFF ;Don't verify if formatting ssdd and physical side = 1. LD A,NSIDES ;Load # sides 841013 OR A ; 841013 JNZ :CO ;DSDD...verify 841013 ; LD A,SAVTYP ;Check physical side 841013 BIT 1,A ; 841013 RNZ ;Return if on side 1 841013 ; :CO: CALL CNDATA JRNZ :1 ;IF NOT ALL E5H'S ;VERIFY E5'S ON THIS TRACK CALL SAVBUFF ;SAVE THE INFO ABOVE BUFF CALL VERIFY ;VERIFY ALL E5H'S ON DESTINATION DRIVE PUSH AF ;SAVE FLAGS CALL RSTBUFF ;RESTORE THE INFO ABOVE BUFF POP AF RNZ ;IF ERROR XRA A MOV B,A ;ALL E5's RET ;GOOD RETURN :1: LDK B,0FFH ;NOT ALL E5's XRA A RET ;GOOD RETURN PAGE SETSAVTRK: ;COMPUTE & SET THE VALUE OF "SAVTRK" ;Value = ("BLOCK" * #TRACKS/BLOCK)+ "TRACK" ;ENTRY ;NONE ;EXIT ;NONE PROC ;"BLOCK" TIMES TRACKS/BLOCK LD A,NUMTRKS DEC A MOV B,A ;B = TRACKS/BLOCK - 1 LD A,BLOCK MOV C,A ;A = "BLOCK" :LOOP: ADD C ; + "BLOCK" * (TRACKS/BLOCK - 1) DJNZ :LOOP ;ADD "TRACK" MOV B,A LD A,TRACK ADD B STO A,SAVTRK RET PAGE SETLBUFF1: ;COMPUTE & SET THE VALUE OF "LBUFF1" ;"LBUFF1" MUST BE ABOVE 4000H ;Value = ("BYTES/TRACK" * ("TRACK" + Logical side)) + "BUFF1" ;ENTRY ;NONE ;EXIT ;NONE PROC ;("BYTES/TRACK" TIMES "TRACK") + Physical side LDK HL,0 LD DE,TRKLEN LD A,TRACK ORA A JZ :2 ;IF TRACK = 0 MOV B,A :1: ADD HL,DE DJNZ :1 ;+ "BUFF1" :2: LDK DE,BUFF1 ADD HL,DE LD A,SAVTYP ;If side 1, offset to middle of logical 841009 AND 0000_0010B ;track buffer 841009 OR A ; 841009 JZ :SIDE0 ; 841009 ; LD DE,PTRKLEN ;PTRKLEN = TRKLEN/2 (middle of buffer) 841009 ADD HL,DE ; 841009 :SIDE0: STO HL,LBUFF1 RET PAGE CNDATA: ;CHECK "LBUFF1" FOR ALL 0E5H'S. IF ALL 0E5'S SET ZBIT AND RETURN ;ENTRY ;NONE ;EXIT ;ZBIT = SET IF ALL E5H'S PROC LD BC,PTRKLEN ;NUMBER OF BYTES IN ONE TRACK 841006 LD HL,LBUFF1 ;FBA OF BUFFER LDK A,FMTCHR :LOOP: ; CPI ;DEC BC : INC HL : CMP [HL] : Z if good compare : P if BC=0 DB 0EDH,0A1H JPO :1 ;IF BC=0 JZ :LOOP ;IF GOOD CMP CONTINUE RET ;ALL VALUES NOT 0E5H'S :1: XRA A ;ALL VALUES WERE E5H'S RET PAGE ;STPODRV: ;STEP THROUGH ALL TRACKS BACK TO ZERO ;ENTRY ;DRIVE MUST BE SELECTED AND READY ;EXIT ;A = 0 IF NO ERROR ; 0FFH IF ERROR ;ZBIT = RESET IF ERROR ;SAVTRK NOT CORRECT IF ERROR PROC ; LDK A,39 ; STO A,SAVTRK ; CALL RSETTRK ;SET TRACK REG ; ; LD A,SEKDEL ; ORI 0001_0100B ;UPDATE AND VERIFY ; STO A,SEKDEL ;SET UP SEKDEL ; ; LDK A,38 ; STO A,SAVTRK ;SET TRACK ; ; CALL RSDRV ;SELECT DRIVE ; JC :ERR ;IF ERROR ; ; CALL RSTEPOUT ;STEP OUT ; JC :ERR ;IF ERROR ; ; LDK A,37 ;START WITH TRACK 37 ;:LOOP: STO A,SAVTRK ;SET TRACK ; ; CALL RSDRV ;SELECT DRIVE ; JC :ERR ;IF ERROR ; ; CALL RSTEP ;STEP ; JC :ERR ;IF ERROR ; ; LD A,SAVTRK ; DEC A ; CMP -1 ; JNZ :LOOP ;IF NOT TRACK 0 ; ; XRA A ; JR :1 ;IF GOOD ; ;:ERR: ORI 0FFH ;INDICATE ERROR ; ;:1: PUSH AF ;SAVE FLAGS ; LD A,SEKDEL ; ANI 0000_0011B ;ONLY SPEAD LEFT ; STO A,SEKDEL ;RESET SEKDEL ; POP AF ;RESTORE ; ; RET PAGE FMTINT: ;MOVE FORMAT DATA TO HIGH RAM BUFFER ;SET BUFFER TO BE: ;0,1 = LENTH OF BUFFER ;2->END = BUFFER ;ENTRY ;NONE  ;EXIT ;NONE PROC ;COPY 1ST SECTOR LDK DE,BUFF+2 ;FWA FOR DATA LD HL,FORDAT ;FWA OF DATA LD BC,LIFMT ;NUMBER OF BYTES LDIR ;MOVE LDK A,1 STO A,SECTOR ;SET SECTOR LD A,NMSEC ;SECTORS/TRACK DEC A MOV B,A ;COPY REMAINING SECTORS :LOOP: PUSH BC PUSH DE POP IY ;IY = FWA OF THIS SECTOR ;MAKE ONE SECTOR LD HL,FMTSD LD BC,LISEC LDIR ;MOVE ;SET SECTOR NUMBER LDK HL,SECTOR ;INC SECTOR INC [HL] ;CHECK FOR DENSITY LD A,SAVTYP CMP SDTYP ;SINGLE DENSITY? LD A,[HL] ;A = SECTOR JZ :S ;IF SINGLE STO A,[IY+(DFSECN-DFMTSD)] ;DOUBLE JR :1 :S: STO A,[IY+(SFSECN-SFMTSD)] ;SINGLE :1: POP BC DJNZ :LOOP ;IF MORE SECTORS ;SET LENTH OF BUFFER IN BUFFER EX DE,HL LDK BC,BUFF+2 SBC HL,BC ;GET LENGTH STO HL,BUFF ;SET LENGTH INTO BUFFER RET PAGE STRK: ;SET TRACK NUMBERS AND SIDE INTO DATA 841005 ;ENTRY ; C = Logical side ; ;EXIT ;NONE PROC LDK HL,BUFF+1 LD DE,TRKOFS ADD HL,DE LD A,NMSEC MOV B,A ;AB = # OF SECTORS LD DE,LISEC LD A,SAVTRK :2: STO A,[HL] ;UPDATE TRACK CELL INC HL ;Point to SIDE CELL 841005 STO C,[HL] ;Store side byte in side cell 841005 DEC HL ;Point back at TRACK CELL 841005 ADD HL,DE ;POINT TO NEXT DJNZ :2 ;IF NOT DONE RET TITLE 'CALLS TO ROM RESIDENT ROUTINES' GOROM: ;UTILITY IN CBIOS IS JUMPED TO THAT MOVES THE STACK AND SWITCHES IN THE ROM ;ENTRY ;DE = THE ADDRESS TO CALL IN THE ROM ;EXIT *NOTE* ; The exit conditions in the rom determine what the regesters will be PROC LD A,2 MOV H,A ;HIGH ORDER BYTE OF BIOS LDK L,5AH ;LOW ORDER BYTE FOR ROM JUMP ROUTINE JMP [HL] RHOME: ;HOME THE DISK DRIVE ;ENTRY ;NONE ;EXIT ;A = 0 IF NO ERROR ;ZBIT = RESET IF ERROR PROC LDK DE,RHM_RTN CALL GOROM RET SENDEN: ;SENCE THE DENSITY, SECTOR SIZE, AND NUMBER OF SECTORS ON ONE TRACK ;ENTRY ;NONE ;EXIT ;ZBIT = SET IF GOOD ;B = NUMBER OF SECTORS PER TRACK ;SAVTYP = SECTOR SIZE AND DENSITY PROC LDK DE,SEN_RTN CALL GOROM RET RREAD: ;READ SECTOR ;ENTRY ;B = NUMBER OF SECTORS ;SDISK = DRIVE ;DMADR = DMA ADRESS ;SAVTRK = TRACK ;SAVSEC = SECTOR ;SAVTYP = DENSITY AND SECTOR SIZE ;EXIT ;HL = NEXT DMA ADDR IF GOOD TRANSFER PROC LDK DE,RD_RTN CALL GOROM RET RWRITE: ;WRITE SECTOR ;ENTRY ;B = NUMBER OF SECTORS ;SDISK = DRIVE ;DMADR = DMA ADRESS ;SAVTRK = TRACK ;SAVSEC = SECTOR ;SAVTYP = DENSITY AND SECTOR SIZE ;EXIT ;HL = NEXT DMA ADDR IF GOOD TRANSFER ;A = 0 IF NO ERROR ;ZBIT = RESET IF ERROR PROC LDK DE,WRT_RTN CALL GOROM RET RFORMAT: ;FORMAT TRACK ;ENTRY ;NONE ;EXIT ;A = 0 IF NO ERROR ;ZBIT = RESET IF ERROR PROC LDK A,2 ;RETRY ONCE FOR FORMAT ERROR STO A,ERCOUNT :LOOP: LDK DE,FMT_RTN CALL GOROM RZ ;RETURN IF NO ERROR LK HL,ERCOUNT DEC [HL] JNZ :LOOP ;RETRY ORI 0FFH ;INDICATE ERROR RET RSETTRK: ;SET THE TRACK REGESTER TO SAVTRK ;ENTRY ;SAVTRK = TRACK NUMBER ;EXIT ;NONE ; Routine no longer implemented in ROM PROC ; LDK DE,184H ; CALL GOROM RET RSDRV: ;SELECT THE DRIVE IN SDISK ;ENTRY ;SDISK = DRIVE TO SELECT ;EXIT ;NONE PROC LDK DE,SDRV_RTN CALL GOROM RET RSTEPOUT: ;STEP HEAD OUT ONE TRACK ;ENTRY ;NONE ;EXIT ;NONE PROC LDK DE,STP_O_RTN CALL GOROM RET RSTEP: ;STEP HEAD ONE TRACK IN DIRECTION LAST STEPPED ;ENTRY ;NONE ;EXIT ;NONE PROC LDK DE,STP_RTN CALL GOROM RET TITLE 'USEFUL PROC"S' SAVBUFF: ;SAVE THE VALUE OF 7000 BYTES FROM BUFF IN BUFFS ;ENTRY ;NONE ;EXIT ;NONE PROC LDK BC,7000 LDK DE,BUFFS ;DESTINATION LDK HL,BUFF ;SOURCE LDIR ;MOVE RET PAGE RSTBUFF: ;RESTORE THE VALUE OF 7000 BYTES FROM BUFFS IN BUFF ;ENTRY ;NONE ;EXIT ;NONE PROC LDK BC,7000 LDK DE,BUFF ;DESTINATION LDK HL,BUFFS ;SOURCE LDIR ;MOVE RET PAGE COMPSEG: ;COMPARE THE DATA IN THE TWO BUFFERS. ;ENTRY ;BC = NUMBER OF BYTES ;DE = FIRST BUFFER ;HL = SECOND BUFFER ;EXIT ;A = 0 IF NO ERRORS ;ZBIT RESET IF ERROR PROC PUSHAL :1: MOV A,B ;CHECK BC FOR ZERO ORA C JZ :2 ;GOOD RETURN LD A,[DE] CMP [HL] PUSH AF INC DE INC HL DEC BC POP AF JZ :1 ORI 0FFH ;INDICATE ERROR :2: POPALL RET PAGE CKABORT: ;CHECK IF ABORT CHARACTER HAS BEEN PRESSED ;ENTRY ;NONE ;EXIT ;A = CHARACTER ;ZBIT = SET IF ABORT CHARACTER PRESSED PROC CALL CIN ;CHECK FOR CHARACTER ANI 5FH ;MAKE UPPER CASE CPI 'Q' RET PAGE CONOUT: ;OUTPUT CHARACTER TO CONSOLE ;ENTRY ;A = CHARACTER PROC PUSHAL MOV E,A MVI C,2 CALL SYS POPALL RET PAGE STRCON: ;OUTPUT MESSAGE TO CONSOLE ;ENTRY ;HL = FWA OF MESSAGE ;EXIT ;NONE PROC PUSHAL EX DE,HL ;VALUE TO DE LDK C,9 ;STRING CALL SYS ;BDOS POPALL RET PAGE CBD5: ;CONVERT BINARY NUMBER TO ASCII DECIMAL ;WITH LEADING ZERO SUPRESSION. ;ENTRY ;HL = VALUE TO CONVERT ;DE = FWA TO STORE CONVERSION ;EXIT ;NONE ;CHANGES ALL REGESTERS PROC LDK BC,-10000 CALL CBO ;CONVERT TEN-THOUSANDS DIGIT CALL CLZ CBD4: LDK BC,-1000 CALL CBO ;CONVERT THOUSAODS!DIGIT CALL CLZ ;CHECK LEADING ZEROS CBD3: LDK BC,-100 CALL CBO CALL CLZ CBD2: LDK BC,-10 CALL CBO CALL CLZ MOV A,L ADI '0' STAX D LDK A,'0' STO A,CLZA ;RESET TO IGNORE LEADING ZEROS! RET PAGE CBO: ;CONVERT ONE DIGIT TO DECIMAL HEX ;ENTRY ;A = NUMBER ;EXIT ;NONE PROC LDK A,'0' PUSH DE :LOOP: MOV E,L MOV D,H INR A ADD HL,BC JC :LOOP ;IF NOT DONE DCR A MOV L,E MOV H,D POP DE RET PAGE CLZ: ;CHECK FOR LEADING ZEROS AND IF FOUND CHANGE TO LEADING SPACES. ;ENTRY ;A = NUMBER ;EXIT ;NONE PROC MOV B,A LDA CLZA CMP B JNZ :1 ;IF 1ST LEADING DIGIT FOUND LDK A,' ' STAX D INC DE ;PLUG WITH RET IF NO LEADING SPACES RET :1: MOV A,B STAX D INC DE LDK A,0FFH STO A,CLZA ;SET TO IGNORE LEADING ZERO RET CLZA: DB '0' WBOOT: LDK A,'Z'-40H CALL COUT JMP WBOOTE PRINT: LD A,[HL] ORA A RZ PUSH HL CAALL COUT POP HL INC HL JR PRINT GVCHR: ; Read a char: allow only carriage return. ; CALL C1 ;Get a char CMP CR ;Is it Carriage return? JNZ GVCHR ;No, get another ; RET ;Yes, return GET_ESC: ; Wait for user to enter ESC ; :GE: CALL C1 CMP ESC JNZ :GE ; RET C1: CALL CIN ORA A JRZ C1 RET COUT: MOV E,A JR F6 CIN: LDK E,0FFH F6: LDK C,06H JMP SYS TITLE 'CONSTANTS' ;DOUBLE DENSITY PARAMETERS DDPARM: DW DLIFMT ;LIFMT FOR DOUBLE DENSITY DW DOUBTO ;TRKOFS FOR DD DW DFORDAT ;FORDAT FOR DD DB 0 ;OSBORNE FORMAT ;SINGLE DENSITY PARAMETERS SDPARM: DW SLIFMT ;LIFMT FOR SINGLE DENSITY DW SINGTO ;TRKOFS FOR SD DW SFORDAT ;FORDAT FOR SD DB 0 ;OSBORNE FORMAT ;PARAMETERS STORED HERE PARM: LISEC: ;LISEC = LIFMT LIFMT: DS 2 TRKOFS: DS 2 FMTSD: ;FMTSD = FORDAT FORDAT: DS 2 OSBFMT: DS 1 ;OSBFMT = 0 IF OSBORNE FORMAT, OTHERWISE 0FFH NMSEC: DS 1 ;# OF SECTORS/TRACK TRKLEN: DS 2 ;# OF BYTES/TRACK NUMTRK: DS 1  ;# OF TRACKS/BLOCK NUMBLK: DS 1 ;# OF BLOCKS/DISK PTRKLEN: DS 2 ; 841006 NSIDES: DS 1 ; 841006 OVRD_FLAG: DS 1 ;True if check for formatted destination disk ;should be overridden PAGE ; Data and all message constants AMB_FCB: ;Ambiguous FCB to search for files in the ;directory of a disk DB 0 DB '????????','???','?' DB 0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0 ;***** SYSTEM MESSAGES OS_BAD_MSG: db 'COPY requires CP/M 3.X or greater.',cr,lf DB 'Copyright ' DB ESC,VSGH,CP_RG_CH,ESC,VEGH ;Set graphics mode, show ;copyright char and clr ;graphics DB ' 1983 Osborne Computer Corporation,',cr,lf DB '26538 Danti Court, Hayward, CA 94545.',cr,lf,0 SCR_TOP: DB ESC,'s','0','Z'-040h,ESC,'=',32,32 DB ' Disk Utility Program' D cr,lf D Osborn EXECUTIV Compute System' DB CR,LF DB ' V1.2' DB 0 COPYR_MSG: DACT I 808x Copyright SORCIM Corp. 1981 S/N- 007,Version 3.5EEV SorcALL ASMFilenameHEXFilenamePRNτ?1;͟4199!42 ͣ'6 #6 #6͎ 4!:f'*:;'*:;'F<*99>T29>2a$o*9|LH&*9*9*9(%b;'*9*9(%! ͩ"e:U&*:;'!HHF*|ʧ&!"F*e:|:9!B6 29!l$ Last error occurred on Page 123 Total LOST references were !?="9*9"929go"9*9&"9>s2K2:2:͎ 2929292929292929292Q:go"9!e:"^:"9*9":"9:92:5:9=29>2929>T29> 2K*9196:94H*:"9*9"9*9X!.X:9͓*9 "9:9:9*9}eG:9=__ͻ$#D> 24d"`:~G&vG!.#%fh"c:2e:*9"nx(:9¶ x= :9:9x(=:c:G 6)!K="9! B629>22>22J! :9ĭ!B ESC,'s2',CLR_SCR DB ' ' DB ESC,VSGH,CP_RG_CH,ESC,VEGH ;Set graphics mode, show ;copyright char and clr ;graphics DB ' 1983 Osborne Computer Corporation, 26538 Danti Court, ' DB 'Hayward, CA 94545',cr,lf DB ' ' DB ESC,VSGH,CP_RG_CH,ESC,VEGH ;Set graphics mode, show ;copyright char and clr ;graphics DB ' 1984 Future Systems, 828 Nob Hill Avenue, ' DB 'Pinole CA 94564',0 NO_OPT_1: = 3 IF TVI950 MAIN1: DW MAIN_1_L DB ESC,'s','1','Z'-040h,ESC,'=',32,32 MN_1_A: DB ' ',ESC,'G0 Copy Diskettes ',ESC,'G0',0,CR,LF MN_1_B: DB ' ',ESC,'G0 Format Diskettes ',ESC,'G0',0,CR,LF MN_1_C: DB ' ',ESC,'G0 RETURN TO CP/M ',ESC,'G0',0,CR,LF DB CR,LF D '$' ENDIF IF TVI912 MAIN1: DW MAIN_1_L DB ESC,'s','1','Z'-040h,ESC,'=',32,32 MN_1_A: DB ' ',ESC,'k Copy Diskettes ',ESC,'k',0,CR,LF MN_1_B: DB ' ',ESC,'k Format Diskettes ',ESC,'k',0,CR,LF MN_1_C: DB ' ',ESC,'k RETURN TO CP/M ',ESC,'k',0,CR,LF DB CR,LF D '$' ENDIF MAIN_1_L: DW MN_1_A DW MN_1_B DW MN_1_C NO_OPT_2: = 4 IF TVI950 MAIN2: DW MAIN_2_L DB ESC,'s','1','Z'-040h,ESC,'=',32,32 MN_2_A: DB ' ',ESC,'G0 Copy from Drive A to Drive B ',ESC,'G0',0,CR,LF MN_2_B: DB ' ',ESC,'G0 Copy from Drive B to Drive A ',ESC,'G0',0,CR,LF MN_2_C: DB ' ',ESC,'G0 Return to the Main Menu ',ESC,'G0',0,CR,LF MN_2_D: DB ' ',ESC,'G0 Return to CP/M ',ESC,'G0',0,CR,LF DB CR,LF DB '$' ENDIF IF TVI912 MAIN2: DW MAIN_2_L DB ESC,'s','1','Z'-040h,ESC,'=',32,32 MN_2_A: DB ' ',ESC,'k Copy from Drive A to Drive B ',ESC,'k',0,CR,LF MN_2_B: DB ' ',ESC,'k Copy from Drive B to Drive A ',ESC,'k',0,CR,LF MN_2_C: DB ' ',ESC,'k Return to the Main Menu ',ESC,'k',0,CR,LF MN_2_D: DB ' ',ESC,'k Return to CP/M ',ESC,'k',0,CR,LF DB CR,LF DB '$' ENDIF MAIN_2_L: DW MN_2_A DW MN_2_B DW MN_2_C DW MN_2_D NO_OPT_3: = 5 IF TVI950 MAIN3: DW MAIN_3_L DB ESC,'s','1','Z'-040h,ESC,'=',32,32 MN_3_A: DB ' ',ESC,'G0 Format Diskette in ADrive A ',ESC,'G0',0,CR,LF MN_3_B: DB ' ',ESC,'G0 Format Diskette in Drive B ',ESC,'G0',0,CR,LF MN_3_C: DB ' ',ESC,'G0 Return to the Main Menu ',ESC,'G0',0,CR,LF MN_3_D: DB ' ',ESC,'G0 Return to CP/M ',ESC,'G0',0,CR,LF DB CR,LF DB '$' ENDIF IF TVI912 MAIN3: DW MAIN_3_L DB ESC,'s','1','Z'-040h,ESC,'=',32,32 MN_3_A: DB ' ',ESC,'k Format Diskette in Drive A ',ESC,'k',0,CR,LF MN_3_B: DB ' ',ESC,'k Format Diskette in Drive B ',ESC,'k',0,CR,LF MN_3_C: DB ' ',ESC,'k Change format density to SINGLE sided ',ESC,'k',0,CR,LF MN_3_D: DB ' ',ESC,'k Return to the Main Menu ',ESC,'k',0,CR,LF MN_3_E: DB ' ',ESC,'k Return to CP/M ',ESC,'k',0,CR,LF DB CR,LF DB '$' ENDIF MAIN_3_L: DW MN_3_A DW MN_3_B DW MN_3_C DW MN_3_D DW MN_3_E NO_OPT_4: = 5 MAIN4 DW MAIN_4_L DB ESC,'s','1','Z'-040h,ESC,'=',32,32 MN_4_A: DB ' ',ESC,'k Format Diskette in Drive A ',ESC,'k',0,CR,LF MN_4_B: DB ' ',ESC,'k Format Diskette in Drive B ',ESC,'k',0,CR,LF MN_4_C: DB ' ',ESC,'k Change format density to DOUBLE sided ',ESC,'k',0,CR,LF MN_4_D: DB ' ',ESC,'k Return to the Main Menu ',ESC,'k',0,CR,LF MN_4_E: DB ' ',ESC,'k Return to CP/M ',ESC,'k',0,CR,LF DB CR,LF DB '$' MAIN_4_L: DW MN_4_A DW MN_4_B DW MN_4_C DW MN_4_D DW MN_4_E DIR_MSG: db ESC,'s5','Z'-40h db ' Use the ARROW keys to position the',cr,lf db ' cursor next to the desired choice',cr,lf db ' or',0 SEL_COPY: db 0 db ESC,'s6','Z'-40h db ' Press RETURN to select a COPY option$' SEL_FMT: db 0 db ESC,'s6','Z'-40h db ' Press RETURN to select a FORMAT option$' RET_CPM: db 0 db ESC,'s6','Z'-40h db ' Press RETURN to Return to CP/M$' FM_DK_DS: db 0 db ESC,'s6','Z'-40h db ' Insert a Diskette in selected drive and',cr,lf db ' Press RETURN to start formatting DOUBLE sided$' FM_DK_SS: db 0 db ESC,'s6','Z'-40h db ' Insert a Diskette in selected drive and',cr,lf db ' Press RETURN to start formatting SINGLE sided$' DS_CH_MSG: db 0 db ESC,'s6','Z'-40h db ' Press RETURN to change formatting density to DOUBLE SIDED$' SS_CH_MSG: db 0 db ESC,'s6','Z'-40h db ' Press RETURN to change formatting density to SINGLE SIDED$' RET_MN: db 0 db ESC,'s6','Z'-40h db ' Press RETURN to return to the Main Menu$' CPY_DSK: db 0 db ESC,'s6','Z'-40h db ' Insert Diskettes and',cr,lf db ' Press RETURN to Start COPY$' PAGE NUM_OPTIONS DB 0 ;# OF OPTIONS in current ;main menu SIDE: DB 0 ;0-LEFT MENU, 1- RIGHT PUT_CURSOR: DB ESC,'s','1',ESC,'=' ;MAIN MENU CURSOR POSITION Y_COORD: DB 32 X_COORD: DB 32 DB 0 PUT_SUB_CURSOR: DB ESC,'s','2',ESC,'=' ;MAIN MENU CURSOR POSITION Y_SUB_COORD: DB 32 X_SUB_COORD: DB 32 vk Copyright gG 1983 Osborne Computer Corporation, 26538 Danti Court, Hayward, CA 94545. V1.2!rs01? |‰}0Ғ!{ -! ! [*7?RS :͗! >> hh b! !3z1$4+pz24 7pz3- 3pz5* 0pz6- 0ps0fz4&4/p!:y(!~ (=w:͗!:y(!:G~(  :xG~(2y> 2:y( >2y(~#_!:y(!z: o&[^#V*>7?R=S>2 !: o&[^#V2 !: o&[^#V[*7?R@s5292; *^#V_^#V6j!66k292; *^#V_^#V!6 s0e$!"!"!;">2x> 2!"!"!">2x> 2!"!"!9">2x>!2>2!"!"!">2x>!22t   22~ 4 +: jH$>Aͮ$$>Bͮ$>AD0$>BD0$!>(Hj!+s322xA2Px22V K>2V s:V v:PHv!=h!P sN:͔ͩy Q!(!?( !  s  s22xA22P2V >2V s ;:Q>2U ͩD!1:V :H!= !P sN@ Q!(!  s!  sG2P jx<2W W !z s2( _YʎN/ Sʡ> 2Q>2Q x2N 2M :Q x!9  x !@ G /:N g.,:Q??G)"S :U )"O ɯ*TR[O R#x2Q :Q G>(? 7y2R :M !  :QW:2P :N :Qz2Q:2P!͢ >2M ! 2W#2N2"2#:Q2Qͮ :#O !@"K2J1 :#:"$>*>E2W#͕ >͕ ͍ :" <2":(2#:Q2Qæ> ͕ :N<(”:W# @CKCT#2J:N G# ͚ ɯ2 :Qˏ2Q!͢ >2M2͜!HŠQ8 !TQ:R G:2 :No&y !H sY>Q:U  :Q2QAO²!Q :<2ò*NU !$͢ *T#"K2J:N G# :2P:M   :Q2Q2] :N(͍ r ͔ :U ʅ :Q2QO] !Q :<2] *N ![͢ :U ½ :Q2Q :Qˏ2Q x>2S#*T#"K2J:N G* !@"K2J:N G# KS @*T#u :S#= :M Y ] ͮ :U " :QO !@"K2J1 i :U E :QO͚ ] $i G:Q =G:OG:2N![O :ʄ GT:Qʖ [S "T#KS *T#> ʣ ɯ@*K KG >2:N =G*K KG !4:Q~ wvw@B"@!@[I :N G[G :Nw#q+:g.ZW ` Z ] >2S#c !S#56 f l i XX#!@X@!X#xʉ # x 2 _Q_     }0>02 >0]T< =kbG: > x>2 0>/ ~/ #(  (  2 (_u0????????????COPY requires CP/M 3.X or greater. Copyright gG 1983 Osborne Computer Corporation, 26538 Danti Court, Hayward, CA 94545. s0= Disk Utility Program Osborne EXECUTIVE Computer System V1.2s2 gG 1983 Osborne Computer Corporation, 26538 Danti Court, Hayward, CA 94545 gG 1984 Future Systems, 828 Nob Hill Avenue, Pinole CA 94564s1= k Copy Diskettes k k Format Diskettes k k RETURN TO CP/M k $E^y1s1= k Copy from Drive A to Drive B k k Copy from Drive B to Drive A k k Return to the Main Menu k k Return to CP/M k $s1= k Format Diskette in Drive A k k Format Diskette in Drive B k k Change format density to SINGLE sided k k Return to the Main Menu k k Return to CP/M k $Chs1= k Format Diskette in Drive A k k Format Diskette in Drive B k k Change format density to DOUBLE sided k k Return to the Main Menu k k Return to CP/M k $4Ys5 Use the ARROW keys to position the cursor next to the desired choice ors6 Press RETURN to select a COPY option$s6 Press RETURN to select a FORMAT option$s6 Press RETURN to Return to CP/M$s6 Insert a Diskette in selected drive and Press RETURN to start formatting DOUBLE sided$s6 Insert a Diskette in selected drive and Press RETURN to start formatting SINGLE sided$s6 Press RETURN to change formatting density to DOUBLE SIDED$s6 Press RETURN to change formatting density to SINGLE SIDED$s6 Press RETURN to return to the Main Menu$s6 Insert Diskettes and Press RETURN to Start COPY$s1= s2= s2s1$s3 s5 Press and Hold Q to Quit Formattings3  Track Formatted: 0 1 2 3 0123456789012345678901234567890123456789 * Indicates Good Format E Indicates Format Error $s5 Press and Hold Q to Quit Copying$s3 Reading Track XX $s3 Writing Track XX $s2 Fatal read error occurred. Make sure source disk is in place and try again. Press ESC to continue.s2 Read error occurred on track XX. Continue (Y/N)? Read error occurred on track XX. Continue (Y/N)? s2 COPY completed with READ errors. Destination disk MAY contain bad data. Press ESC to continue.s2 Write error occurred. Retry with a different destination disk. Press ESC to continue.s2 Diskette in Drive X contains information. Is it OK to overwrite it (y/n)? s2 Diskette in Drive X MAY contain information. Is it OK to overwrite it (y/n)? s2 COPY completed successfully. Press RETURN to continue.s2 COPY ERROR. Press ESC to continue.s2 COPY ABORTED. Press RETURN to continue.s2 Source diskette is not formatted with a standard Osborne format. Press RETURN to continue.s2 Source and destination diskettes don't have matching formats. Press RETURN to continue.s2 FORMAT completed successfully. Press RETURN to continue.s2 FORMAT ERROR. A Press ESC to continue.s2 FORMAT ABORTED. Press RETURN to continue.NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN Generation procedure for Executive COPY V1.2 DAB 10/14/84 T generat objec cod fo COP th followin file ar needed: COPY.ASM, SYSS1.AST, RAMS10.ASM, ACT.COM and HEXCOM.COM. All of these files are on disk 1 of the COPY release diskette. COPY is generated with the command lines: ACT COPY S=SYSS1 HEXCOM COPY If a listing is desired, enter the following command line: ACT COPY S=SYSS1 R=F L $:9ĭFUnterminated IF nest. IUnterminated MACRO definition. !.~O#%~wy<#%J*9*9 ~w# œ~?ʜp ^#V#N#F r+s 9'n!ͭ~24#W$OToo many PROCs in program. *9?9' "9*9 "9yx  !e: f':d:_ :9¶!"f:":>(=*9"n!%4:c:#%^#V>SE>E24\*^:}!e:"^:2d::9 e::d: !9>wd:G::ʁ!4 W † :9 ͓!9~wÁn>-24>O>Y>S>E>A24*n|c~c=ͅ"::s2:ͨ :9ʽ:9>Y:9>F24292929͗!T.:9>P?*9~24 ͒ | >P24 R::9pͬ% ͬ/ƒͺ:9Ҿp %ҭ!f'!9~G?2:>N*nͻ,#!94:9ʤ>Ov ͼ ðv":"9:s2:2:> 2:Dv"9:s2:G::’*:9'> ʔ>#2:!4wðv:rG:e:N:9*:°>L24ð!e:~"^:*92~c!e:~"^:2*92ͬc!e:"^:v | } >W24>2[:\> ͒"\:, ::*^:w\>S24\*9e:':9 b *9?9'>O "9 *n~*!99ʽ f'ͬ-™ ͬ+ ͭ>UN!9{_~wͬ,ʋ N'*n#~T L@ C D F G M R͒:9@S ͒U͍f:9@͍^!9F6:96 I :9@I ͍!9~w*9~>S## C>E>S~29*9#N# f'! f'! W$Unknown CPU: '' ͓!46'#*9ͩ Of' ;' !) ͍'!4>!O$͓' 2929v}29| :9ͤ=D !94:e:- *9?>L͇ "9< ####>*9##"9'!:͡':92:*9:*9 f'"9x #"95%*9~w##s#r*9##h'%0+  3 Ƃ~ G >@w!:͆>w :9ē*9#"9 *c3 ~ ʪ(~w##^#V*9ʠ w#Ò ͤO:9= y*9#%N#Fx w# Ò *9"9|~ : # !"96!A DB 0 NUM_SUB_CMDS: DS 1 ;# OF COMMANDS IN SUB MENU NUL_MSG: M_EXIT: DB 0 DB ESC,'s','2','Z'-040h DB ESC,'s','1' DB '$' PAGE CRLF5S: DB ESC,'s3',cr,lf,lf,lf DB ' ',0 PFORMAT: DB ESC,'s5','Z'-40h DB cr,lf DB ' Press and Hold Q to Quit Formatting' DB ESC,'s','3','Z'-040h DB ' Track Formatted:',cr,lf DB ' 0 1 2 3 ' DB CR,LF DB ' 0123456789012345678901234567890123456789',cr,lf DB cr,lf DB ' * Indicates Good Format E Indicates Format Error',cr,lf DB '$' ABT_MSG: DB ESC,'s5','Z'-40h DB cr,lf DB ' Press and Hold Q to Quit Copying' DB '$' RCOPY: DB ESC,'s','3' DB ' Reading Track ' RCOPYN: DB 'XX ' ;Filled in by RDMTRK DB '$' WCOPY: DB ESC,'s','3' DB ' Writing Track ' WCOPYN: DB 'XX ' ;Filled in by WRTTRK DB '$' SECTOR: DB 0 ;FOR FORMAT SOURCE: DB 0 ;SOURCE DRIVE FOR COPY TRACK: DB 0 ;ACTIVE LOGICAL TRACK BLOCK: DB 0 ;ACTIVE BLOCK NUMBER ;BETA TEST ONLY F_RD_ERR: DB ESC,'s2',CLR_SCR DB ' Fatal read error occurred. Make sure',cr,lf DB ' source disk is in place and try again.',cr,lf DB ' Press ESC to continue.',0 RDERR: DB ESC,'s2','Z'-40h DB ' Read error occurred on track ' RD_ERR_P: DB 'XX. Continue (Y/N)? ',0 DB ' Read error occurred on track XX. Continue (Y/N)? RD_ERR_WARN: DB ESC,'s2',CLR_SCR DB ' COPY completed with READ errors. Destination disk MAY contain bad data.',cr,lf DB ' Press ESC to continue.',0 WTERR: DB ESC,'s2','Z'-40h DB ' Write error occurred. Retry with a different destination disk.',cr,lf DB ' Press ESC to continue.',0 DSK_FMT: DB ESC,'s2','Z'-40h DB ' Diskette in Drive ' D_FMT_D: DB 'X' ;Filled in by FMAT or KOPY DB ' contains information.',cr,lf DB ' Is it OK to overwrite it (y/n)? ',0 DK_MB_FMT: DB ESC,'s2','Z'-40h DB ' Diskette in Drive ' D_FMT_D2: DB 'X' ;Filled in by FMAT or KOPY DB ' MAY contain information.',cr,lf DB ' Is it OK to overwrite it (y/n)? ',0 END: DB CR,LF,LF DB 0 GMES: DB ESC,'s','2','Z'-040h DB ' COPY completed successfully.',cr,lf DB ' Press RETURN to continue.' DB 0 BMES: DB ESC,'s','2','Z'-040h DB ' COPY ERROR.',cr,lf DB ' Press ESC to continue.' DB 0 ABTCPY: DB ESC,'s','2','Z'-040h DB ' COPY ABORTED.',cr,lf DB ' Press RETURN to continue.' DB 0 NOTOSB: DB ESC,'s','2','Z'-040h DB ' Source diskette is not formatted',cr,lf DB ' with a standard Osborne format.',cr,lf DB ' Press RETURN to continue.' DB 0 BADDEN: DB ESC,'s','2','Z'-040h DB ' Source and destination diskettes don''t have matching formats.',cr,lf DB ' Press RETURN to continue.' DB 0 GDFMT: DB ESC,'s','2','Z'-040h DB ' FORMAT completed successfully.',cr,lf DB ' Press RETURN to continue.' DB 0 BDFMT: DB ESC,'s','2','Z'-040h DB ' FORMAT ERROR.',cr,lf DB ' Press ESC to continue.' DB 0 ABTFMT: DB ESC,'s','2','Z'-040h DB ' FORMAT ABORTED.',cr,lf DB ' Press RETURN to continue.' DB 0 PAGE SFORDAT: ;FORMAT DATA FOR IBM 3740. *NOTE* ;NO INDEX MARK IS USED ; **** GAP 1 **** SFMTSD: ECHO 17 ! DB 0FFH ENDM ECHO 6 ! DB 0 ENDM DB 0FEH ;ID ADDRESS MARK SFTRKN: DB 0 ;TRACK SINGTO = *-SFORDAT DB 0 ;SIDE SFSECN: DB 1 ;SECTOR DB 1 DB 0F7H ;CRC ; **** GAP 2 **** ECHO 11 ! DB 0FFH ENDM ECHO 6 ! DB 0 ENDM SFDAM: DB 0FBH ;DATA ADDRESS MARK ; **** DATA **** ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM SFCRC2: DB 0F7H ;CRC SFMTEND = * SLIFMT = *-SFORDAT SLISEC = *-SFMTSD PAGE DFORDAT: ;DOUBLE DENSITY FORMAT DATA FOR IBM 3740. *NOTE* ;NO INDEX MARK IS USED ; **** GAP 1 **** DFMTSD: ECHO 100 ! DB 04EH ENDM ECHO 12 ! DB 0 ENDM DB 0F5H,0F5H,0F5H DB 0FEH ;ID ADDRESS MARK DFTRKN: DB 0 ;TRACK DOUBTO = *-DFORDAT DB 0 ;SIDE DFSECN: DB 1 ;SECTOR DB 3 ;SECTOR LENTH DB 0F7H ;CRC ; **** GAP 2 **** ECHO 22 ! DB 04EH ENDM ECHO 12 ! DB 0 ENDM DB 0F5H,0F5H,0F5H DB 0FBH ;DATA ADDRESS MARK ; **** DATA **** ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 A"9*9"9!9"9*9;'*9!9f'*9zV  6 s#r#Z ,;  >P ) s#r#"9x29O:9Gʃ ˆ =29} :9¶29>F:9ʴ ¶} :e:b !94:9¶vz°n:9ē:929*9"9*:":Y*9"9*9"9>L >S24!::9w:9 {: :9Ox~ :92*:*:":":͙ x (::2:>*9G:92:":!"9*9|? *n~}:} 1"9F::O@°yw*:#::w#s#rx ʴx@´>w:9x>D :9>:9:[:O::G!d:yO4Q Jx2::[:*\: lMW͛%O::_G͆%!:w{=@~6*^:w#"^:!d:4 ::W{2:[: !46^#þ':9M*9##(%"f:!46=##þ' ͩʝV=ʝ#^=ʝ>V24*^:s#r+y *^:>A+w¬ͩOGx!46V*n+6:d:2d:*^::9y#% Aw# "^:*n+~#:9(=*9"n*94;'::;>~;7ʧ*7ʧ 7ʧ:9¡ ڧ'.!_ʚ;Œ:9¯> #„òaژ{Ҙ #V#Ҟ#:9ʲ*9"9 ʵ>!;?~   7ȷy#:9ʲ*9ͤõ#N f'V>#"'#~'"# x)+pV9 B#0+> !"9"9"9!9!;~ p ~# f}| fO!~ʌ#7y,+-*/()><=^&[] : \(%*9*99'+~ y¹*99'"929*9.:9g"9"9:9 *9*99' "9>a*<<4:9W~#29  F  Rf> z > : "<<> `i"9!429z29 >=9'ҁͪ> !\#!7\\\ END Statement Missing !><\#6y  !W$ACT stopped by user. *99'"9"9\ f'ͻ#$!Ve%!VC f'>2a$!C͂$f$!>="<<6 Pass 1 - Reading D:FILENAME.EXT ;}; ͒:r >Uá*9"n|’7*nͩڤ?>E247go!"t."r!9"jz>Sͼ2l K*h};9'+~ffbMb*h};9' *f;9';A:@2s"tb*h9'+~H"h> 2l!z#%9'F#N   de~# ʼ+"n>2l!;"f!};"h6>2q>E*j24!"tt>2s7ͬ0 :Q:zzB~G#4V#^6Z6T]#%>2rxß*n+ͭ"n#~G:l x+~!9Oʃ!:Pʃ!9Lʃ>2r^#V#F>ßG> x,\]/*$+^^^&()=<> <= >= < > ~-ANDDEFEQGT GE HIGHLE LOWLT MODNE NOTORREVSHLSHRXOR+%>N>2r>#ß:px2p%x2pU+ͭڒ{ڒ#~"n*n+:s*n2s"n,> *n|ͻ#"n#~ ʺ*n+~ȷ+"n*f;9'>O+~2r+~+^+V"f:r2r2s=#%~+fo>>2s&:s*f<;9'>Sr#s#w#:rw#"fG*h;9'>Sp#"h>2q*h};9'+"h~!#%9nu d)0<D {ozg) {oz {oz#!)#!)##?##? 9'l3>2q}l:rG>2rx x> 24 ) ) 5%)5%) ͭ%) E=%) ͩ)z|5%ڻ PY ͩ)):*9 f':9="9$"9 !W$  Memory OVERFLOW Stopped ACT!/q#p# *9(%:9"9:~%"n::::`:97͆`i?ځ'ځ!d3r+s+7!`3Fx!.H!d0R!2Ͱ2b:!?GN#xy_y_ѯ°#7# y÷y?>E2:2:1>w##^#VO:9#y2r>U724*9*98*9*9:9'b! =# cSh= :|:9 ^= :~ w “9'ʺ# µ¥þÐ7!6> oD# 9'7ȷ0 :?[$b#b.b~J%# ~#,4J%~#o$4f'HO$:9@Õ!9~w*9z^:4 |.> 24.5:9 :4!?怰G:9W:9O@:9ʺyzz>@GzGG&z>+24*94~# !4> #6 #6#2*9#"9!4O$H> 245!4:G~=> w# 56 #6:9@!4\!94:9l$*9:9Gʅw#xl͜lx29"9*9:9q<•!z8$Ҹ:9@29!W$G29!"9List file write error. *9}J%: !f'*&*9"2<29*9#"9&!\! \4>2$:9>B>20:0294:OJ%>$!4".%~*.>  ʄ>sw#UҚDښڛnpf'*99'ڼA6m#6a#6c#6 ###".6:9o:9=29bH:9!0*.6 #C*9!?~: ~ ~w 9'*9DM !?~Ex1}1Fd] d#KT]f 6 ^#VogʉNs#FrYP+y>!4".29|^#V#~/#oy&&".:9=29•5>Ë:9H#^*.&O:9:9:9:::?:92@/7N#F:@+w:9+w+p+qr+s*9#"9~#foþ' no ERRORs, 1234 Labels, h bytes not used. Program LWA = h. *Error page 999SYMBOL TABLE *Error page 999 SORCIM 808x Assembler ver 3.5E mm/dd/yy hh:mm Page 999 ~':9*:9'":Oi`) ))6 2:2:͎ *:"9p : f'::p : f'*:^ ͙ ~ *: ^ "::9:9w"*O::Q:#%9'!!*:"O:G_ :9:9<"#"A" >!y2Q:&!!y2Q::Q: Q:G!!:"""#"z P!:N:'6 #6  :r!*O::Q:#%"O:2Q:2N:!):*@5w#}B!|6!!!B5u!"@5:9:9·"!!>12':*:"O: (!*@5B5!!B5V$!:929!!W$Hex file write error.  9'!p#9' "O:N:2N:yW :Q:O!):#%:9:9—"*O:x#%"O:!:~#f" #Oog5#o"_j#I"::O*O:9'Š":M:y2M:> "O:">\#!]#> *6"> *6"::O>*:":Y:"X:r!*@5B5!!"\#5#>>?:Z:y2Z:>\#yp ~ ###t#^#r# &#y?H#"N#_Pt#r#\r#@_t#\j#t#zK͛%O:Y:_G͆%!X:w{=#r!2X::Y:W{2Y:bzWu# Y w# ##7! wD$ѷ$ #7D$ѷ$ $D$7:k$`$l$f$>2k$>b$:k$O$2a$2k$O ͻ$~# ¡$Ù$ ͻ$x“$> _xUү$ͻ$Ä$|ͻ$ ͻ$ ~Oʹ#!$`$$ ?? OPEN error - l$!;6#e%!;l$:9%V:9͍zɅo$MDy_xW{z/W{/_xzW{_=%>  L%~ J%J%# S% As%@O:q#p#f'>.f'xy%%ɷ”%!%#%~?BK!xʾ% ô%BJ~0%:%A%[% #%+FyR&:p &x &Bʯ&N&Ql&Hʆ& :pBʯ&Ql&Hʆ&yG&A&;&5&'V&V&dV& V&V&7N&~0Q& Q&# =e&~0R&R&_ #M&)))l&~0R&:&AR&GR&_# M&))))Æ&~0R&R&)o# ²&M&&'&'&'&'}0>02'>0]T< &=kbG:''> x>2'0~0~0#y'z{x7# A'9'h' +~ x['x~# h'x~aڅ'{҅'# u'~#Í'7#Ö'zq#ã'O:'=@I±' ®'V|'}'Ɛ'@'ɯ2(#~:+:\'~@8(##(ͬ#<~>:7:(.$(~.#$(y^(!S:( ^(:(7x7~i(#.^(*V(>?a(~# :(G>  a(x!8(|8(;8(=8(:8(@ʖ(#ʖ(*ʖ(?›(2(a({ w!d:6͹-2e:>I24\..(>.c3]-Cͥ-M..c-3͓-c>d.cle3͓-cm( (me3͓-(-3͓-͒"f:cme3͓-g-à,..͒Xx.c>I*͹-..e3M-M.>!.c3-ڰ)ͥ-*-3>)O- M."-.c3-ڰ)͹-3-- M.>!.cs-e3l- *n+~)͹-M.cs-3@-C*n"9e3\-)ͥ-M..cs-͹-g-3-*ͥ-3-(s-e3\-)ͥ-M..J,3-j*:-ʉ**3 *--"-ڰ*ͥ-.cs-3 -*3-a* \s-s-3-ڃ*:-ƒ*3-a*Ã*s-s-3-ڃ*3-ڃ*:-ƒ*a*s-s-3@-ڃ*͹-..c>H2+3@-++3 *n-+͹-M.cs-~[.+"nÝ,s-s-3-M+3-M+͹-(s-3-^+,s-3)-ڀ+͹-M.>!.͒"g:cs-e3:+O-ڧ+M.e3-Cͥ-.c:+>s-͒"f:́.Ó+H͹->!.c3-+:- ͹-(s-+>d.,Ce3\-Cͥ-M.>!..c3=-*,ͥ-M.͒"f:G,s-e3I-Cͥ-M.͒"f:́..>c3=-l,ͥ-M..cs-e3]-Cͥ-M..c3-ښ,ͥ-.cs-͹-͒"f:c3@-,3-,͹-M.>!.cs-3-,͹-M.>!.3@-Ccs-3 --3-Cͥ-.cs-e3m-;-M.e3l-;-͹-M.cs-3->:->3%->͹-M.>.8,͒"f:́.c!b:55>*9"n*`:##"`:~2d:#~2e:-CM.ͥ-.-ʹ-!d:4-4:9 *nͭ"ny_b#V"-|-͒x.}2-]Cͬ,=-@!.!g:Fw#p*f:"g:*d:o"e::9>C >$24:9>C >#:.*-}o|-^.!e:w͒د†.z†.[.}|†.|<:4 >V24ASMHEX080808085Z80 =+CADD ADICADCJACIANA#ANDANIASEG.ASSERT6BIT@CALLCBITCCCLCCMA/CMC?#CMPCMCNZCNCCPECPOCPDRCPDCPIRCPI#CPICPU3CPCSEG.CZDAA'DAD DA&DBE%DB%DCE%DCRDCX DC%@#DEC DIDJNZDSEG.DS!DW&ECHO5EIEJECT:ELSE=ENDM<endm<ENDIF=END(ENTRY,EQU+ERR;EXT-EXXBEXHLTvIDENT0IF=IM0FIM1VIM2^#INCINDRINDINIRINIINRINXIN,C@IN#JMPJNZJMJCJNCJPEJPOJPJZJRC8JRNC0JRNZ JRZ(JRLDAX LDA:LDDRLDDLDIRLDI#LDKrLD :*KFLHLD*LINK2LIST8"LKLOC#LXIMACRO5MVISMOVWG@(MSG9NEGDNOPORG"ORAORI"OROTDROTIROT,CAOUTDOUTIOUTPAGE:PCHLPOPPROC$PUSHRALRARRCREPT5RETIMRETNERETRIM RLC#RLCRLDo"RLRMRNCRNZRPERPORPRRC#RRCRRDgRRRSTRZSBBCSBCBSBITSBISET+@SHLD"SIM0SLA SPACE7SPHLSRA(SRL8STAXSTA2STC7sSTO2"Cp63SUBSUITITLE1USE/VFD)XCHG#XORXRAXRIXTHL'*M%6[HL]6[IX[IYB C D E H $L -AA?IR AFA6PSWA6SP!6IX$IYdBC B DE D HL$H$AFA6SP!6IX$IYdBC DE HL$[SP]!6[IX]$[IY]d[BC] [DE] [HL]$(((() )%)-))0)3)+G)(((+++*B),U,(,`))*!*8*,6Kl#([ uX" F a T E w  2ͮ8>2k$!"R:ͬ#<@27a5:2$:29͈8*9!\ f'"9"9:94!Vͪ5:95!zͪA5!Af'!~6!l$2!T l$!.7:9f$6!=5$h'*ABS *CODE *DATA !"5!~ 8#O 65͹8!?="9l9 8}6:929l96ͭ8^#VPY##$!\ ?'\!5$ ?? Hex or Prn file name same as Input = 5@R6H=06H=6LO7L=06L=CON:6L=LP:6L=6L6O7PS(7SLA7S=_7S\7R=07R=S7R=F7R7!.7\'8\V!.7z! 77:929Ô5!.V7Ô5>29!RE".>L2.P!:͡'Ô5Í5:9ï6>`2i$:9ï6! 7z7:9ï6PRN;729Ô5;7"9Ô5:;7d!x8872Ô5P;72`i+~=7#%8{7':!d8$YPf'7Sf'!8l$!288!R88!d88Command input errorNO source file specified, ABORTMal-formed numberIll-formed filenamePS > 99SL < 60/!'> :!'!8f' Page *%"9"9OD9T9 .9}|:k99~ 9 9, 9; 9|.9 .9.9a 9{ 9 w#86#8:k9(9~ .9.9#96#86go~<9ѯx~ O9 S9#D9~'d9"d92k96#2k95~#ʇ9<+w#_^#Vѯ7TTTTTTTTTTTTTTTTT=99hhhh?=???99?=?9 :9999990099 ?\:e:`: prompt/command response JMP X30D2 ; end  ',*E5E5E5E5E5E5E5E5E5E557 :101E3B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E547 :101E4B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E537 :101E5B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E527 :101E6B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E517 :101E7B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E507 :101E8B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5F7 :101E9B00E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E7 :101EAB00E5E5E5E5E5E5E5F74E4E4E4E4E4E4E4E7D :101EBB004E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E37 :101ECB004E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E27 :101EDB004E4E4E4E4E4E4E4E4E4E4E4E4E4E4or STO HL,COM_TABLE ;format menu LK HL,MAIN4 ;Point to format menu data STO HL,MAIN ;structure. Lˠ A,NO_OPT_4 ;Se option fo format menu STO A,NUM_OPTIONS LK A,33 ;Make FORMAT B the default ;selection. STO A,Y_COORD XOR A ;Set flag for ssdd STO A,FDENS RET ;and return ; FDENS: DB 1 ;Set double sided as default PAGE ;------------------------------------------------------------------------------ ; Menu command description and routine tables follow: ; MENU1: ;Table for main menu DW SEL_COPY DW SEL_FMT DW RET_CPM COM1: DW M_COPY ;Table for main menu DW M_FORMAT DW EXIT MENU2: DW CPY_DSK ;Table for COPY menu DW CPY_DSK DW RET_MN DW RET_CPM COM2: DW COPY_A_B ;Table for COPY menu DW COPY_B_A DW EX_MAIN DW EXIT MENU3: DW FM_DK_DS ;Table for FORMAT DW FM_DK_DS DW SS_CH_MSG DW RET_MN DW RET_CPM COM3: DW FMT_A ;Table for FORMAT DW FMT_B DW CHG_DNS DW EX_MAIN DW EXIT MENU4: DW FM_DK_SS ;Table for FORMAT DW FM_DK_SS DW DS_CH_MSG DW RET_MN DW RET_CPM COM4: DW FMT_A ;Table for FORMAT DW FMT_B DW CHG_DNS DW EX_MAIN DW EXIT PAGE ;------------------------------------------------------------------------------ ; Command routines called when user requests action. Routine ; called depends on what the current selection is. DO_COMMAND ; determines the address of the routine to execute (which ; depends on the current menu and the current selection in that ; menu). M_COPY: ; Copy selected from main menu. Set current menu to copy menu. ; CALL SETM2 RET M_FORMAT: ; Format selected from main menu. Set current menu to format menu. ; Sets DS menu (3) if FDENS = 1, else set SS menu (4). ; PROC LD A,FDENS OR A JRNZ :S3 ; CALL SETM4 RET ; :S3: CALL SETM3 RET PAGE COPY_A_B: ; Copy from A to B selected from copy menu. ; Do copy. ; CALL CLR_W_3 ;Clear window used for status LK A,'A' ;Specify A as source disk  CALL KOPY ;Copy disks CALL CLR_W_3 ;Clear window used for status RET COPY_B_A: ; Copy from A to B selected from copy menu. ; Do copy. ; CALL CLR_W_3 ;Clear window used for status LK A,'B' ;Specify B as source CALL KOPY ;Copy disks CALL CLR_W_3 ;Clear window used for status RET PAGE FMT_A: ; Format, drive A selected. ; Do format. ; LK A,'A' ;Specify drive A LK B,'D' ;Specify double-density CALL FMAT ;Format the disk CALL CLR_W_3 ;Erase message window RET FMT_B: ; Format, drive B selected. ; Do format. ; LK A,'B' ;Specify drive B LK B,'D' ;Specify double-density CALL FMAT ;Format the disk CALL CLR_W_3 ;Erase message window RET PAGE CHG_DNS: ; Change from ssdd format to dsdd or vice versa. ; PROC LK HL,FDENS ;Point at current density flag LK A,1 ;Set low order bit of A XOR [HL] ;Change state of flag JRZ :S4 ;New state is ssdd, set current menu to 4 ; CALL SETM3 ;New state is dsdd, set current menAu to 3 RET ;Return ; :S4: CALL SETM4 ;Set menu 4 RET ;and return PAGE EX_MAIN: ; Return to main menu requested. Set current menu to main ; menu. ; CALL SETM1 RET PAGE CLR_W_3: ; Routine to clear window 3. Window 3 is used for execution ; status while performing an operation. ; LK HL,:CLR_3_STR ;Point at string to clear window CALL OUT_STRING ;and send to console. RET ; :CLR_3_STR: ; String to clear window 3. Selects window 3 and sends clear screen ; character. ; DB ESC,'s3',CLR_SCR,0 PAGE FMAT: ; Disk format routine ;ENTRY ; A = Disk to format ('A' or 'B') ; B = Density in which to format ('S' or 'D') ;EXIT ;NONE PROC :LOOP: STO A,D_FMT_D STO A,D_FMT_D2 SUI 'A' STO A,SDISK MOV A,B STO A,TMP_DEN ;Save density until after we check ;for info on disk. ; CMP ESC ;Check for disk not empty check ;override ; JZ :OVR ; XOR A ;Don't override... STO A,OVRD_FLAG JMP :CO ; :OVR: LK A,0FFH STO A,OVRD_FLAG :CO: CALL CLR_W_2 LD A,OVRD_FLAG ;Check for blank disk check override OR A JNZ :OVRD ; LD A,SDISK ;See if destination disk contains info CALL CK_INFO JZ :BLK_DSK ;No...format it ; LK HL,DSK_FMT ;Assume it does DEC A ;Does it (i.e., is A = 1) ? JZ :ASK ;It does, ask user if it should be ;overwritten ; LK HL,DK_MB_FMT ;Disk MAY have info. Ask user if it ;should be overwritten. :ASK: CALL PRINT CALL Y_N PUSH AF ;Save response CALL CLR_W_2 ;Clear question POP AF ;Restore response CMP 'N' ;No, RZ ;Don't format ; ;Yes, format disk :OVRD: :BLK_DSK: LD A,TMP_DEN ;Restore density specification CALL STSAVTYP ;SET DENSITY CALL SETPARM ;SET PARAMITERS CALL FORMAT ;FORMAT DISKETTES PUSH AF ;Save return code from FORMAT LK C,0DH ;so the disk system can be reset. CALL SYS ;The disk system must be reset since ;the disk has effectively been changed ;by formatting it. POP AF ;Restore return code from FORMAT CPI 'Q' LDK HL,ABTFMT ;FORMAT aborted JRZ :DONE ;If aborted ORA A LDK HL,GDFMT ;FORMAT completed successfully JRZ :DONE ;IF NO ERRORS :BAD: LDK HL,BDFMT ;ERROR IN FORMAT CALL PRINT CALL GET_ESC CALL CLR_W_2 RET ; :DONE: CALL PRINT CALL GVCHR CALL CLR_W_2 RET ; TMP_DEN DB 0 ;Local temporary storage for density spec PAGE KOPY: ; Disk copy routine ;ENTRY ; A = Source diskette ('A' or 'B') ;EXIT ;NONE PROC :LOOP: PUSH AF ;Save disk # XRI 03H ;Compute destination drive letter STO A,D_FMT_D ;Save in message STO A,D_FMT_D2 POP AF ;Restore disk # SUI 'A' STO A,SOURCE ;SET SOURCE STO A,SDISK ;SET DISK ; CMP ESC ;Check for disk not empty check ;override ; JZ :OVR ; XOR A ;Don't override... STO A,OVRD_FLAG JMP :CO ; :OVR: LK A,0FFH STO A,OVRD_FLAG :CO: CALL CLR_W_2 CALL SENDEN ;GET DENSITY JNZ :1 ;IF ERROR LD A,SAVTYP ;Set NSIDES = 1 if dsdd, else 0 841006 CPI DSTYP ; 841006 JNZ :SSD ;  841006 ; LK A,1 ; 841006 JR :DSD ; 841006 ; :SSD: XOR A ;NSIDES = 0 841006 :DSD: STO A,NSIDES ; 841006 CALL SETPARM ;SET PARAMETERS CALL MATCHFMT ;MAKE SURE SOURCE AND DESTINATION ;IF NOT OSBORNE FORMAT LDK HL,BADDEN JNZ :DONE ;IF FORMATS DON'T MATCH LD A,OVRD_FLAG ;Check for blank disk check override OR A JNZ :OVRD ; LD A,SOURCE ;Get source drive XRI 0000_0001B ;Convert to destination drive CALL CK_INFO ;See if destination disk has info JZ :BLK_DSK ;No...format it ; LK HL,DSK_FMT ;Assume it does DEC A ;Does it (i.e., is A = 1) ? JZ :ASK ;It does, ask user if it should be ;overwritten ; LK HL,DK_MB_FMT ;Disk MAY have info. Ask user if it ;should be overwritten. :ASK: CALL PRINT CALL Y_N PUSH AF ;Save response CALL CLR_W_2 ;Clear question POP AF ;Restore response CMP 'N' ;No, RZ ;Don't copy ; ;Yes, copy disk :OVRD: :BLK_DSK: CALL COPY ;COPY A DISKETTE PUSH AF ;Save return code from COPY LK C,0DH ;so the disk system can be reset. CALL SYS ;The disk system must be reset since ;the disk has effectively been changed ;by copying to it. POP AF ;Restore return code from COPY. CPI 'Q' ;See if user aborted. LDK HL,ABTCPY ;COPY aborted JRZ :DONE OR A ;User did not abort. See if COPY good. RNZ ;Not good, COPY routine displayed ;err already, so return ; LDK HL,GMES ;COPY completed successfully :DONE: CALL PRINT ;Display message pointed to by HL CALL GVCHR ;Wait for user to enter RETURN CALL CLR_W_2 ;Clear message window. RET ; :1: LK HL,F_RD_ERR ;Fatal read error in COPY CALL PRINT CALL GET_ESC CALL CLR_W_2 RET PAGE CK_INFO: ; Checks to see if there is info on disk. Calls sense density routine ; to see if the disk is formatted. If it is not formatted, there is no ; info. ; If disk is formatted, checks for files in directory. ; ; ENTRY: ; A = # of disk on which to check for info ; 0 meaAns drive A, ; 1 means drive B. ; ; EXIT: ; A = 0 if disk has no info, ; A = 1 if disk has info and ; A = 2 if disk MAY HAVE info (i.e., can't be determined). ; Additionally: ; Z flag set if disk has no info ; Z flag clear if disk has or may have info. ; ; SIDE EFFECT: ; SDISK set to disk # (whatever A is on entry) ; PROC MOV B,A ;Save drive spec in B PUSH BC ;Save on stk STO A,SDISK ;Select disk for SENDEN CALL SENDEN ;Check for unformatted disk. Z is clear ;if disk no formatted. POP BC ;Restore disk # JNZ :NO_INFO ;Return code indicating no info ; MOV A,B ;Restore disk # to A INC A ;Make disk # relative-one per BDOS STO A,AMB_FCB ;Put drive spec in FCB for search for first LK DE,AMB_FCB ;Point at ambiguous FCB to check for any files. LK C,SRC_FIRST ;Tell BDOS to do search-for-first. CALL SYS ;Returns A = 0FFh if no files or if error INC A ;A = 0FFH? JNZ :INFO_FOUND ;No... ; XOR A ;Check for error. OR H ;Is H = 0? JNZ :CANT_TELL ;No, err ;RAMS10.ASM TITLE 'Monitor RAM Storage.' ; Used to assemble ROM resident and CBIOS ORG MRAM ; Disk operation temps and control DMABANK DS 1 ;Bank for read/write disk DMADR DS 2 ;Address for read/write disk ; Note order of xxxSEC,xxxTRK,xxxDSK must be maintained ; along with length (1,2,1). SAVSEC DS 1 ;last sector requested SAVTRK DS 2 ;last track requested SDISK DS 1 ;selected disk drive (0,1) SAVTYP DS 1 ;SELECTED TYPE (sector size) IE_ADR: DS 1 CURPOS: DS 2 ;Current cursor position ; VARIABLES FOR HIGH RAM ROUTINES TEMSAV DS 1 ;Used by jump bank routine SRCBANK DS 1 ;Source bank for block move DESTBANK DS 1 ;Destination bank for block move ;JMPSPOT and JMPADDR must stay next to each other JMPSPOT DS 1 ;To be filled in with a JMP instruction by the ROM JMPADDR DS 2 ;Address to jump to for BANKJMP and BANKCALL JMPBANK DS 1 ;Bank to jump to for BANKJMP and BANKCALL EMRAM = * ; INTERRUPT VARIABLES USR_BNK DS 1 ;User's bank on interrupt bank switch DS 2 I_POL_BANK: DS 1 I_POL_ADR: DS 2 USR_STK: DS 2 ;save current stk ptr ; Interrupt stack DS 30*2 ISTK: DS 0 ; ROM and BIOS stack DS 30*2 BIOSTK: ROMSTK: DS 0 HIBUFF: DS 100H qpppp(p:pÈpÙpqKK7p+pCf+L;LMp@p#D*Pv:6O~`opyL`opop Zp~~wyL`…pDM2v6P[jKKDhËp:pv*g5iڳp*k5+++͓lڶp*i5"g52pv!vͭj1)*6"6!6Þ!dp!d"6>26!"6:6*v:vpviK2q!vj*vK2qqf!vv͉d>267ɯ2v{͹qq6q{͹q*q7?Cqͧq{xq͹qͶqʆqͧq>2v͹qͶqsqE7:v7͹qSʝqD q͹q-7+vM"v#{ʿq2'K? ܔ ڿq7*qɾ#45qs6RqhqwqÑq&rSrqqqqrrërrqq r9s{IQ0 ENTER space OR NEW LINE SPACING (1-9): LEFT MARGIN COLUMN NUMBERumn)? (ESCAPE for cursor col RIGHT For decimal tab stop enter "#" and decimal point column  SEor occurred. ; :NO_INFO: ;No error, no info. XOR A ;Clear A and set Z flag RET ; :INFO_FOUND: ;Info on disk XOR A ;Return Z clear and A = 1 INC A RET :CANT_TELL: ;May be info. LK A,2 ;Return A = 2 and Z clear OR A RET PAGE CLR_W_2: PROC LK HL,:CLR_2_STR CALL PRINT RET ; :CLR_2_STR: DB ESC,'s2','Z'-40h,0 PAGE Y_N: PROC :YNLP: CALL C1 AND 5FH CMP 'Y' JZ :ECHO ; CMP 'N' JNZ :YNLP ; :ECHO: PUSH AF CALL COUT POP AF RET PAGE STSAVTYP: ;SET SAVTYP FOR FORMAT ;ENTRY ;A = 'S' FOR SINGLE DENSITY ;EXIT ;B = # OF SECTORS/TRACK PROC CPI 'S' JZ :SING ;IF SINGLE DENSITY ;DOUBLE DENSITY LDK A,DDTYP STO A,SAVTYP LDK B,5 ;SECTORS/TRACK RET ;SINGLE DENSITY :SING: LDK A,SDTYP STO A,SAVTYP LDK B,10 ;SECTORS/TRACK RET PAGE SETPARM: ;SET UP PARAMETERS THAT DEPEND ON DENSITY ;ENTRY ;B = # OF SECTORS/TRACK ;SAVTYP = SET ;EXIT ;PARAMETERS SET PROC MOV A,B STO A,NMSEC ;SECTORS/TRACK ORI 0FFH STO A,OSBFMT ;INITIALIZE TO NON-OSBORNE FORMAT ;CHECK FOR STANDARD OSBORNE DENSITIES LD A,SAVTYP CPI SDTYP JZ :SING ;IF SINGLE DENSITY SAVTYP ;DOUBLE DENSITY CPI DDTYP JZ :DD ;IF DOUBLE DENSITY SAVTYP 841006 ; CPI DSTYP ;DSDD uses same parameters as ssdd 841006 JNZ :2 ;Not dsdd 841006 ; :DD: MOV A,B ;VERIFY # OF SECTORS CPI DSEC JNZ :2 ;IF WRONG # OF SECTORS LDK HL,DDPARM ;DOUBLE DENSITY PARAMETERS JR :1 ;SINGLE DENSITY :SING: MOV A,B ;VERIFY SECTORS/TRACK CPI SSEC JNZ :2 ;IF NOT STANDARD SINGLE DENSITY LDK HL,SDPARM ;SINGLE DENSITY PARAMETERS ;MOVE OSBORNE PARAMETERS TO PARM :1: LDK DE,PARM LDK BC,7 LDIR ;SET UP REMAINING PARAMETERS :2: CALL STRKLEN ;SET NUMBER OF BYTES PER TRACK CALL SNUMTRK ;SET NUMBER OF TRACKS PER BLOCK CALL SNUMBLK ;SET NUMBER OF BLOCKS PER DRIVE RET PAGE STRKLEN: ;SET NUMBER OF BYTES PER 'Physical' and 'Logical' TRACK ; Logical track length (TRKLEN) is used to compute # tracks peA r 841006 ; block; physical track len (PTRKLEN) is used for verifying data 841006 ; on read/write. ;ENTRY ;NMSEC = SECTORS/TRACK ;SAVTYP SET ;EXIT ;TRKLEN = BYTES/TRACK PROC ;SET HL = SECTORS/TRACK * 128 LD A,NMSEC MOV H,A LDK L,0 ;HL = NMSEC * 256 SRA H RR L ;HL = NMSEC * 128 ;GET BYTES/SECTOR LD A,SAVTYP SRL A SRL A ANI 0000_0011B ;GET SECTOR LENGTH ;(00 = 128, 01 = 256, 10 = 512, 11 = 1024) MOV B,A JZ :2 ;DONE IF 128-BYTE SECTORS ;CALCULATE BYTES/TRACK ;HL = HL * (2**B) :1: DAD HL,HL ;HL * 2 DJNZ :1 :2: STO HL,PTRKLEN ;Save physical trk len 841006 LD A,NSIDES ;Dbl sided or single? 841006 OR A ; 841006 JZ :3 ;Single... 841006 ; ADD HL,HL ;Double; logical = 2 * physical 841006 :3: STO HL,TRKLEN RET PAGE SNUMTRK: ;SET NUMBER OF TRACKS PER BLOCK ;ENTRY ;NONE ;EXIT ;NONE PROC ;GET TOTAL BUFFER LENTH XRA A ;RESET CARRY FLAG LD HL,SYS+1 ;GET TOP OF TPA LDK DE,BUFF1 ;FBA OF BUFF1 SBC HL,DE ;HL = TOTAL SPACE AVALIBLE ;GET NUMBER OF TRACKS PER BUFFER LD DE,TRKLEN ;GET TRACK LENTH LDK B,0 ;SET COUNT TO ZERO XRA A ;RESET CARRY FLAG :LOOP: SBC HL,DE ; - ONE TRACK INC B ;B=B+1 JNC :LOOP ;LOOP UNTIL HL < DE ;SET NUMTRK DEC B ;B = NUMBER OF TRACKS IN ONE BLOCK MOV A,B STO A,NUMTRK ;SET NUMTRK RET PAGE SNUMBLK: ;SET NUMBER OF BLOCKS PER DRIVE ;ENTRY ;NUMTRK = NUMBER OF TRACKS PER BLOCK ;EXIT ;NONE PROC LD A,NUMTRK ;GET NUMBER OF TRACKS PER BLOCK MOV B,A ;SAVE LDK A,MTRK ;GET NUMBER OF TRACKS PER DRIVE LDK C,0 ;ZERO COUNTER :LOOP: SUB B ; - ONE BLOCK JZ :1 ;IF EVEN DON'T INC INC C ;C=C+1 JNC :LOOP ;LOOP TILL A 0 IF FORMATS DON'T MATCH ;ZBIT RESET IF FORMATS DON'T MATCH PROC  ;CHECK FOR OSBORNE FORMAT LD A,OSBFMT ORA A RZ ;RETURN OK IF OSBORNE ;PRINT NOT OSBORNE MESSAGE LDK HL,NOTOSB CALL PRINT CALL GVCHR ;CHECK DESTINATION DISK LD A,SAVTYP MOV D,A PUSH DE ;SAVE SOURCE SAVTYP LD A,SOURCE ;SOURCE DISK XRI 0000_0001B ;OTHER DISK STO A,SDISK CALL SENDEN ;SENSE DESTINATION DENSITY POP DE ;RESTORE D = SOURCE SAVTYP LD A,NMSEC ;SOURCE SECTORS/TRACK CMP B ;DESTINATION SECTORS/TRACK RNZ ;RETURN ERROR IF SECTORS/TRACK DON'T MATCH LD A,SAVTYP ;DESTINATION SAVTYP CMP D ;SOURCE SAVTYP RNZ ;RETURN ERROR IF SAVTYPs DON'T MATCH ;RESTORE SAVTYP AND SDISK TO SOURCE MOV A,D STO A,SAVTYP ;RESTORE SOURCE SAVTYP LD A,SOURCE STO A,SDISK ;RESTORE SOURCE SDISK XRA A RET ;GOOD RETURN PAGE ; FORMAT: ;FORMAT ONE DISK ; ; If disk is to be ssdd, both sides are formatted, but ; side 1 is formatted so that side byte in sector header ; says side 0. This is done so SENDEN routine in ROM can ; DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM DFCRC2: DB 0F7H ;CRC DFMTEND = * DLIFMT = *-DFORDAT DLISEC = *-DFMTSD ERCOUNT: DB 0 ;ERROR COUNTER LBUFF1: DW 0 ;HOLD FBA IN BUFF1 MACHTYPE: DB 0 ;MACHINE DENSITY ; 0 = Undefined ; 1 = Single ; 2 = Double FMTERR: DB 0 ;FORMAT ERROR FLAG BUFFS: DS 7000 ;SAVE BUFFER DS 40*2 STACK: DS 0 ;STACK HERE ; END  ECHO 100 ! DB 04EH ENDM ECHO 12 ! DB 0 ENDM DB 0F5H,0F5H,0F5H DB 0FEH ;ID ADDRESS MARK DFTRKN: DB 0 ;TRACK DOUBTO = *-DFORDAT DB 0 ;SIDE DFSECN: DB 1 ;SECTOR DB 3 ;SECTOR LENTH DB 0F7H ;CRC ; **** GAP 2 **** ECHO 22 ! DB 04EH ENDM ECHO 12 ! DB 0 ENDM DB 0F5H,0F5H,0F5H DB 0FBH ;DATA ADDRESS MARK ; **** DATA **** ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 | | ; X16 Clock Mode 0 1 | | | | | | ; X32 Clock Mode 1 0 | | | | | | ; X64 Clock Mode 1 1 | | | | | | ;SYNC MODE: (not used) | | | | | | ; 8 Bit Sync char 0 0 | | | | ; 16 Bit Sync char 0 1 | | | | ; SDLC Mode 1 0 | | | | ; Ext Sync mode 1 1 | | | | ;STOP BITS: | | | | ; SYNC Mode Enable 0 0 | | ; 1 Stop Bit/Char 0 1 | | ; 1.5 Stop Bits/Char 1 0 | | ; 2 Stop Bits/Char 1 1 | | ;PARITY: | | ; Parity Even/Odd <--------------------------------+ | ; Parity Enable <------------------------------------+ PAGE ;WRITE REG 5: +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | A! | | ;DTR <---------------------------+ | | | | | | | ;Tx BITS/CHARACTER: | | | | | | | ; 5 Bits 0 0 | | | | | ; 6 Bits 0 1 | | | | | ; 7 Bits 1 0 | | | | | ; 8 Bits 1 1 | | | | | ;Send Break <--------------------------------+ | | | | ;Tx Enable <------------------------------------+ | | | ;CRC Type (not used) <-------------------------------+ | | ;RTS <---------------------------------------------------+ | ;Tx CRC Enable <---------------------------------------------+ ;WRITE REG 6: +---+---+---+---+---+---+---+---+ ; (not used) | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ; | | | | | | | | ;Transmit Sync char <------------+---+---+---+---+---+---+---+ ;WRITE REG 7: +---+---+---+---+---+---+---+---+ ; (not used) | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ; | | | | | | | | ;Receive Sync char <------------+---+---+---+---+---+---+---+ PAGE ;SIO READ REGISTERS ;READ REG 0: +---+---+---+---+---+---+---+--+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0| ; +---+---+---+---+---+---+---+--+ ; | | | | | | | | ;Break/Abort <----------------+ | | | | | | | ;Tx Underrun/EOM <--------------------+ | | | | | | ;CTS <------------------------+ | | | | | ;Sync/Hunt <----------------------------+ | | | | ;DCD <--------------------------------+ | | | ;Tx Buffer Empty <------------------------------------+ | | ;Int Pending (Chan A only) <-----------------------------+ | ;Rx Character Available <------------------------------------+ ;READ REG 1: +---+---+---+---+---+---+---+--+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0| ; +---+---+---+---+---+---+---+--+ ; | | | | | | | | ;End of Frame <-----------------+ | | | | | | | ;CRC/Framing Error <-----------------+ | | | | | | ;Rx Overrun Error <---------------------+ | | | | | ;Parity Error <-----------------------------+ | | | | ;Residue codes (not used) <----------------------+---+---+  | ;All Sent <---------------------------------------------+ ;READ REG 2: +---+---+---+---+---+---+---+--+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0| ; +---+---+---+---+---+---+---+--+ ; | | | | | | | | ;Interrupt vector <--------------+---+---+---+---+---+---+---+ PAGE ;SIO Control constants REG0 = 0000_0000B ;Select register 0 REG1 = 0000_0001B ;Select register 1 REG2 = 0000_0010B ;Select register 2 REG3 = 0000_0011B ;Select register 3 REG4 = 0000_0100B ;Select register 4 REG5 = 0000_0101B ;Select register 5 REG6 = 0000_0110B ;Select register 6 REG7 = 0000_0111B ;Select register 7 INT_CNL = 0000_0000B ;Interrupt control (Reg 1) ; no interrupts RCV_CNL = 1110_0001B ;Logic control (Reg 3) ; 8 Bits/char, Auto enables on, Rx enable, ; Sync char hunt inhibit disabled BAS_CNL = 0100_0100B ;Basic control values (Reg 4) ; X16 Clock, 1 Stop bit, No parity TX_CNL_A = 1110_1000B ;Transmit control for (Reg 5) ; Channel A: DTR on, 8 Bits/char, RTS off TX_CNL_B = 1110_1010B ;Transmit control for (Reg 5) ; Channel B: DTR on, 8 Bits/char, RTS on SIO_I_IN = 000_10_111B ;Command to write to SIO WR1 to set: ; Interrupt on all Rx chars (parity ; affects vector) ; Status affects vector ; Tx Int. Enable ; External Int. Enable ;Masks SI.RRDY = 0000_0001B ;Receive char ready (Read Reg 0) SI.TRDY = 0000_0100B ;Transmit buffer empty (Read Reg 0) PAGE ;8253 TIMER ;CONTROL REG: +---+---+---+---+---+---+---+---+ ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; +---+---+---+---+---+---+---+---+ ; | | | | | | | | ;Select Counter <----------------+---+ | | | | | | ;READ/LOAD: | | | | | | ; !A" Counter Latching 0 0 | | | | ; R/L Most Significant Byte only 0 1 | | | | ; R/L Least Significant Byte only 1 0 | | | | ; R/L Both Bytes 1 1 | | | | ;MODE <------------------------------------------+---+---+ | ;BCD <------------------------------------------------------+ ;Control COUNTA = 0011_0110B ;Select counter 0, 2 bytes, Mode 3 COUNTB = 0111_0110B ;Select counter 1, 2 bytes, Mode 3 ;SETBAUD Codes ; (Code is a table offset. Table entries are 8253 count values neccessary to produce the desired baud rate) BD1200 = 8 ;Code for 1200 baud PAGE ;PARALLEL PORT CONSTANTS ;port ctl register constants. PA.CDR = 00101010b ;to address port a direction PA.CDT = 00101110b ;to address port a data and set ;port a in input program handshake mode. PB.CDR = 00000000b ;to address port b direction PB.CDT = 00000100b ;to address port b data ;direction register constants PA.DRO = 0FFh ;port a output mode PA.DRI = 00h ;port a input mode PB.DR = 0BFh ;port b direction PB.DTO = 00000010b ;port b data for output PB.DTI = 00001011b ;port b data for input PP.ORDY = 01000000b ;output rdy bit in pib PP.IRDY = 10000000b ;input rdy bit in pia ctl reg STRB = 00100000b ;strobe bit in port b ;port modes PP.OUT = 1 PP.IN = 2 ;IEEE control codes IE_TALK = 40h ;make talker IE_UTLK = 5Fh ;make untalk IE_LSTN = 20h ;make listener IE_ULST = 3Fh ;make unlisten PAGE ;VIDEO CONSTANTS FWAVM = 0C000h ;LVMEM = 128*23 + 80 ;Length of video memory ;VIDEND = FWAVM+LVMEM-1 ;End of video memory VMROWS = 24 ;24 Rows VMCOLS = 80 ;80 Columns RESERVED = 0 ;Window 0 is reserved (always set to full screen) ;NVDL = 24 ;LVDIS = 128*NVDL ;Length of Display memory ;VFLO = -22 ;First line video offset VLL = 128 ;Length of one video line ;VLDL = 64 ;Length of displayed char/line ;FWASM = FWAVM+VLDL ;Status info ;NLINE = 24 ;Number of lines MODEMSK = 0F0H ;Mask video mode bits MODEOFF = 1000H ;Offset from video character address to mode address ;MASKS REVMODE = 1000_0000B ;Reverse bit = high bit of character HAFMODE = 1000_0000B ;Half intensity bit = high bit of mode address UNDMODE = 0100_0000B ;Underline bit BLMODE = 0010_0000B ;Blink bit ALTMODE = 0001_0000B ;Alternate character set bit REV_CUR = 1000_0000B ;Reverse video (block) cursor UND_CUR = 0100_0000B ;Underline cursor INV_CUR = 0000_0000B ;Invisible cursor BLK_CUR = 0010_0000B ;Blinking cursor PAGE RTC_OFL = 18H ;RTC overflow counter port SIXTY_HZ = 60 ;Decimal 60 Hz (ticks/sec) FIFTY_HZ = 50 ;50 Hz (ticks/sec) SEC_MIN = 60H ;BCD seconds/minute MIN_HR = 60H ;minutes/hr HR_DAY = 24H ;Hours/day PAGE ;KEYBOARD CONSTANTS KL_LEN = 3 ;KEY LIST LENTH KLE_LEN = 2 ;KEY LIST ENTRY LENTH KL_USED = 7 ;KEYLIST ENTRY USED KY_SRVD = 6 ;KEY SERVICED ONCE KROW_M = 38H ;ROW NUMBER MASK KCOL_M = 7H ;COL NUMBER MASK RPTCTR = 1 ;REPEAT COUNT ROW0_M = 81H ;MASK FOR ADDRESSING ROW 0 DB_CT = 1 ;DEBOUNCE COUNT IRPTCT = 24 ;INITIAL REPEAT COUNT (400MS) SRPTCT = 3 ;SECOND REPEAT COUNT (100MS) DAB9/17 ;Reduced to half original value to ;speed repeat. TOT_ROW = 8 ;TOTAL ROWS TOT_COL = 8 CTL_KY = 2 ;COLUMN NUMBER OF CTL,ALPHA AND SHIFT KEYS ALPH_KY = 3 SHFT_KY = 4 PAGE ;BUFFER HANDLING EQUATES MX_CH_BF = 10H ;Max number of chars in a buffer BF_OV_HD = 4 ;No. bytes overhead in buffer D_RT_LEN = 6 ;No of bytes in Device List Root data structure NO_DEVS = 5 ;Number of devices NO_BUFS = 40 ;Number of buffers THR_HOLD = 4 ;Number of buffers to reserve for high priority ;devices HI_PRIOR = 80H ;High priority bit to indicate ;high priority buffers can be used PAGE ;CONTROL CHARACTERS CR = 0Dh ;^M, CR = Carriage Return LF = 0Ah ;^J, LF = Line Feed CRLF = '_'-40H ;^_, CR and LF BKS = 08h ;^H, Backspace CBELL: = 'G'-40h ;Ring the Bell MCUP: = 'K'-40h ;Move cursor up MCRIGH: = 'L'-40h ;Move cursor right VDWN: = 'V'-40H ;Move cursor down VLIN: = '_'-40H ;New line (CR,LF) VCLRS: = 'Z'-40h ;Clear and home cursor VHOME: = '^'-40h ;Home Cursor ETX = 'C' - 40h ;ASCII ETX char ACK = 'F' - 40h ;ASCII ACK char XON = 'Q' - 40h ;ASCII XON (DC1) char XOFF = 'S' - 40h ;ASCII XOFF (DC3) char ;ESCAPE SEQUENCE CHARACTERS ESC = 1Bh ;^[, ESC = Escape VLOCK: = '#' ;Lock Keyboard VUNLK: = '"' ;Unlock Keyboard VCAD: = '=' ;Cursor Addressing VSAD: = 'S' ;Screen Addressing VINC: = 'Q' ;Insert Char VDELC: = 'W' ;Delete char VINL: = 'E' ;Insert line VDELL: = 'R' ;Delete line VCEOL: = 'T' ;Clear to end of line VCEOS: = 'Y' ;Clear to end of screen (window) VSAL: = 'a' ;Start alternate character set VEAL: = 'A' ;End VSHI: = ')' ;Start half intensity VEHI: = '(' ;End VSGH: = 'g' ;Start graphics VEGH: = 'G' ;End VRON: = 'b' ;Set "A#reverse video background (black on white) VROFF: = 'd' ;Clear reverse video background (set to white on black) VCTYP: = '.' ;Cursor type define VSRV: = 'j' ;Start reverse video VERV: = 'k' ;End reverse video VSUL: = 'l' ;Start underline VEUL: = 'm' ;End underline VSBL: = '^' ;Start Blink VEBL: = 'q' ;End blink EKC: = '>' ;Enable key click DKC: = '<' ;Disable key click EFKT: = 'e' ;Enable function key translate DFKT: = 'f' ;Disable Function key translate VWDEF: = 'z' ;Window define VWSET: = 's' ;Window set VOFF: = 'o' ;Define X-Y offset VBACK: = 'x' ;Define background attributes UNDBIT: = 0000_1000B ;Underline bit ALTBIT: = 0001_0000B ; REVBIT: = 0000_0100B ;Reverse video bit BLKBIT: = 0000_0010B ;Blink bit HAFBIT: = 0000_0001B ;Half intensity bit PAGE ;BOOT CONSTANTS BOOTADDR: = 4000H ;Boot load address for P-System BIOSBANK = 0000_0000B ;BIOS bank BOOTBANK = 0000_0000B ;Boot strap loader bank TEMPBUF = 0CC00H ;Temporary buffer in video bank  ; used for DMA address when booting system PROD_CODE = 2 ;Shelly product code written on boot sector PAGE ;INTERRUPT CONSTANTS SIO_I_TBL = 0FFE0H ;Location in RAM of SIO interrupt vector ;Must be in high RAM and end in 0 INTVEC = 0FFFEH ;Other interrupt's vector ;Interrupt Device Numbers KBD_DEV = 0 ;Keyboard device number S_CH_A_I = 1 ;Device number for Serial channel A input S_CH_B_I = 2 ;Device number for Serial channel B input S_CH_A_O = 3 ;Device number for Serial channel A output S_CH_B_O = 4 ;Device number for Serial channel B output PAGE ;ROM's RAM VALUES ;Flags for console and function key table flags SYS_TBL: = 0 ;Use system table APP_TBL: = 1 ;Use application table NO_TBL: = 2 ;Don't use translation table (function key only) PAGE ;TABLE DEFINITION LOCATIONS ;SYSTEM TRACK LOCATIONS KCTRK = 2 ;Track for keyboard and character font definitions KEYSEC = 17 ;Sector for keyboard definition CHARSEC = 20 ;Sector for character font definition ALTSEC = 30 ;Sector for alternate character font definition ;RAM LOCATIONS RAMTBL = 2000H ;Keyboard and console table pointers CHRFONT = 0000H ;Character font RAM location ALTFONT = 800H ;Alternate character font RAM location PAGE ; CP/M DEFINITIONS SVER = 14 ERSIZE = 64 ; default = 64k version CVER = 22 ;CPM version number CBIOSV = SVER ;cbios version NDSKS = 2 K = 1024 ABTC = 'C'-40h ;Abort character ;DRIVE DEFINITIONS LSECB = 256 ;Length of a sector MTRK = 40 ;Maximum tracks MSEC = 10 ;Maximum Sectors FMTCHR = 0E5h ;Data format char ; Set CP/M symbols. IOBYTE = 3 CDISK = 4 ;Current logged-in CPM disk SYS = 5 ;CPM Monitor call address SYSL = SYS+1 ;(lwa of CP/m) TIMPTR = 40h ;points to where time kept DBUF = 80h ;Default disk buffer OM#LRAM = SYSL SYSR = 0 ;return to system SYSDSK = CDISK ;Contains current system disk # SYSDAT = 10h ;Date in ddmmyy SYSTIM = SYSDAT+3 ;Time in hhmmss ORGP = 100h ;Transient program origin ;EOL ;does not exist in CP/M EOM = '$' ;End of Message (for system function) EOF = 'Z'-40h ;End of File L$PRU = 128 ;Bytes per floppy sector FCB = 5Ch ;SYSTEM DEFAULT FILE CONTROL BLOCK FCB_NR = FCB+32 ;Next Record = LRN F_EX = 12 ;Extend field F_S2 = 14 ;CPM system usage **used with 2.0 SIZ funct** F_RC = 15 ;Record count (0 to 128) F_NR = 32 ;Next record ordinal in FCB F_RRF = 33 ;r0,r1,r2 (random field) in FCB L_FILEN = 8 ;length of File name L_FILEX = 3 ;length of filename suffix L_FCB = 36 ;length of entire FCB (comp with 2.0) DMA = 80h ;WHERE SECTORS ARE READ TBUFF = DMA ;where CCP puts command line PAGE ; FIRMWARE RAM DEFINITIONS ;TEMPBUF: = HSTBUF ;* TEMPBUF WILL BE THE SAME AREA AS THE SPACE ; RESERVED FOR KEYBOARD AND CONSOLE TABLES -- ; IT CAN ONLY BE USED BEFORE THESE AREAS ARE INITIALIZED PAGE ; True/False definitions FALSE = 0 TRUE = not FALSE ; Defined function codes ROMVEC = 100h ;Start of rom vector MONRAM = 2000H COMJMP = 0FD40H ;Common memory jump vectors (BANKJMP,BANKMOVE,BANKCALL,DMA READ and WRITE) MRAM = 0FD4Ah ;High memory area for variables used by ROM and BIOS HI_ROUT = 0FEF0H ;High memory routines moved from ROM TAB = 09h ;TAB ERC = 7FH ;Illegal key @FREQ = 4000 ;freq of processor SCLFRE = @FREQ/22 ;for DELAY routine Bad = 0FFH ;Entry in keybd table if key is invalid BADKEY = Bad ; TOG_ALT_SET = 0FEh ;Entry in keybd table if key is used to ;toggle alternate char set KEYTBL: = 2800H-140H ;Key code location ROMVER: = 0FEH ;ROM version number location ;Cold Boot Masks SP_KEY = 0000_0100b ;Load keyboard translation code from disk SP_CHAR = 0000_0010B ;Load character font from disk SP_ALT = 0000_0001B ;Load alternate character font from disk PAGE ;MACROS ; ALIGN Set origin to even boundary. ALIGN MACRO SIZ,O DS (*%2+(%1)-1)/(%1)*(%1)-*%2 #A$ ENDM PUSHAL MACRO PUSH BC PUSH DE PUSH HL ENDM POPALL MACRO POP HL POP DE POP BC ENDM ; Endx SYSTEXT PAGE PRINT: LD A,[HL] ORA A RZ PUSH HL CALL COUT POP HL INC HL JR PRINT GVCHR: ; Read a char: allow only carriage return. ; CALL C1 ;Get a char CMP CR ;Is it Carriage return? JNZ GVCHR ;No, get another ; RET ;Yes, return GET_ESC: ; Wait for user to enter ESC ; :GE: CALL C1 CMP ESC JNZ :GE ; RET C1: CALL CIN ORA A JRZ C1 RET COUT: MOV E,A JR F6 CIN: LDK E,0FFH F6: LDK C,06H JMP SYS TITLE 'CONSTANTS' ;DOUBLE DENSITY PARAMETERS DDPARM: DW DLIFMT ;LIFMT FOR DOUBLE DENSITY DW DOUBTO ;TRKOFS FOR DD DW DFORDAT ;FORDAT FOR DD DB 0 ;OSBORNE FORMAT ;SINGLE DENSITY PARAMETERS SDPARM: DW SLIFMT ;LIFMT FOR SINGLE DENSITY DW SINGTO ;TRKOFS FOR SD DW SFORDAT ;FORDATVEGH ;Set graphics mode, show ;copyright char and clr ;graphics DB ' 1983 Osborne Computer Corporation,',cr,lf DB ' 26538 Danti Court, Hayward, CA 94545.',cr,lf,0 NO_OPT_1: = 3 IF TVI950 MAIN1: DW MAIN_1_L DB ESC,'s','1','Z'-040h,ESC,'=',32,32 MN_1_A: DB ' ',ESC,'G0 Copy Diskettes ',ESC,'G0',0,CR,LF MN_1_B: DB ' ',ESC,'G0 Format Diskettes ',ESC,'G0',0,CR,LF MN_1_C: DB ' ',ESC,'G0 RETURN TO CP/M ',ESC,'G0',0,CR,LF DB CR,LF D '$' ENDIF IF TVI912 MAIN1: DW MAIN_1_L DB ESC,'s','1','Z'-040h,ESC,'=',32,32 MN_1_A: DB ' ',ESC,'k Copy Diskettes ',ESC,'k',0,CR,LF MN_1_B: DB ' ',ESC,'k Format Diskettes ',ESC,'k',0,CR,LF MN_1_C: DB ' ',ESC,'k RETURN TO CP/M ',ESC,'k',0,CR,LF DB CR,LF D '$' ENDIF MAIN_1_L: DW MN_1_A DW MN_1_B DW MN_1_C NO_OPT_2: = 4 IF TVI950 MAIN2: DW MAIN_2_L DB ESC,'s','1','Z'-040h,ESC,'=',32,32 MN_2_A: DB ' ',ESC,'G0 Copy from Drive A to Drive B ',ESC,'G0',0,CR,LF MN_2_B: DB ' ',ESC,'G0 Copy from Drive B to Drive A ',ESC,'G0',0,CR,LF MN_2_C: DB ' ',ESC,'G0 Return to the Main Menu ',ESC,'G0',0,CR,LF MN_2_D: DB ' ',ESC,'G0 Return to CP/M ',ESC,'G0',0,CR,LF DB CR,LF DB '$' ENDIF IF TVI912 MAIN2: DW MAIN_2_L DB ESC,'s','1','Z'-040h,ESC,'=',32,32 MN_2_A: DB ' ',ESC,'k Copy from Drive A to Drive B ',ESC,'k',0,CR,LF MN_2_B: DB ' ',ESC,'k Copy from Drive B to Drive A ',ESC,'k',0,CR,LF MN_2_C: DB ' ',ESC,'k Return to the Main Menu ',ESC,'k',0,CR,LF MN_2_D: DB ' ',ESC,'k Return to CP/M ',ESC,'k',0,CR,LF DB CR,LF DB '$' ENDIF MAIN_2_L: DW MN_2_A DW MN_2_B DW MN_2_C DW MN_2_D NO_OPT_3: = 5 IF TVI950 MAIN3: DW MAIN_3_L DB ESC,'s','1','Z'-040h,ESC,'=',32,32 MN_3_A: DB ' ',ESC,'G0 Format Diskette in Drive A ',ESC,'G0',0,CR,LF MN_3_B: DB ' ',ESC,'G0 Format Diskette in Drive B ',ESC,'G0',0,CR,LF MN_3_C: DB ' ',ESC,'G0 Return to the Main Menu ',ESC,'G0',0,CR,LF MN_3_D: DB ' ',ESC,'G0 Return to CP/M ',ESC,'G0',0,CR,LF  DB CR,LF DB '$' ENDIF IF TVI912 MAIN3: DW MAIN_3_L DB ESC,'s','1','Z'-040h,ESC,'=',32,32 MN_3_A: DB ' ',ESC,'k Format Diskette in Drive A ',ESC,'k',0,CR,LF MN_3_B: DB ' ',ESC,'k Format Diskette in Drive B ',ESC,'k',0,CR,LF MN_3_C: DB ' ',ESC,'k Change format density to SINGLE sided ',ESC,'k',0,CR,LF MN_3_D: DB ' ',ESC,'k Return to the Main Menu ',ESC,'k',0,CR,LF MN_3_E: DB ' ',ESC,'k Return to CP/M ',ESC,'k',0,CR,LF DB CR,LF DB '$' ENDIF MAIN_3_L: DW MN_3_A DW MN_3_B DW MN_3_C DW MN_3_D DW MN_3_E NO_OPT_4: = 5 MAIN4 DW MAIN_4_L DB ESC,'s','1','Z'-040h,ESC,'=',32,32 MN_4_A: DB ' ',ESC,'k Format Diskette in Drive A ',ESC,'k',0,CR,LF MN_4_B: DB ' ',ESC,'k Format Diskette in Drive B ',ESC,'k',0,CR,LF MN_4_C: DB ' ',ESC,'k Change format density to DOUBLE sided ',ESC,'k',0,CR,LF MN_4_D: DB ' ',ESC,'k Return to the Main Menu ',ESC,'k',0,CR,LF MN_4_E: DB ' ',ESC,'k Return to CP/M ',ESC,'k',0,CR,LF DB CR,LF DB '$' MAIN_4_L: DW MN_4_A DW MN_4_B DW MN_4_C DW MN_4_D DW MN_4_E DIR_MSG: db ESC,'s5','Z'-40h db ' Use the ARROW keys to position the',cr,lf db ' cursor next to the desired choice',cr,lf db ' or',0 SEL_COPY: db 0 db ESC,'s6','Z'-40h db ' Press RETURN to select a COPY option$' SEL_FMT: db 0 db ESC,'s6','Z'-40h db ' Press RETURN to select a FORMAT option$' RET_CPM: db 0 db ESC,'s6','Z'-40h db ' Press RETURN to Return to CP/M$' FM_DK_DS: db 0 db ESC,'s6','Z'-40h db ' Insert a Diskette in selected drive and',cr,lf db ' Press RETURN to start formatting DOUBLE sided$' FM_DK_SS: db 0 db ESC,'s6','Z'-40h db ' Insert a Diskette in selected drive and',cr,lf db ' Press RETURN to start formatting SINGLE sided$' DS_CH_MSG: db 0 db ESC,'s6','Z'-40h $A% db ' Press RETURN to change formatting density to DOUBLE SIDED$' SS_CH_MSG: db 0 db ESC,'s6','Z'-40h db ' Press RETURN to change formatting density to SINGLE SIDED$' RET_MN: db 0 db ESC,'s6','Z'-40h db ' Press RETURN to return to the Main Menu$' CPY_DSK: db 0 db ESC,'s6','Z'-40h db ' Insert Diskettes and',cr,lf db ' Press RETURN to Start COPY$' PAGE NUM_OPTIONS DB 0 ;# OF OPTIONS in current ;main menu SIDE: DB 0 ;0-LEFT MENU, 1- RIGHT PUT_CURSOR: DB ESC,'s','1',ESC,'=' ;MAIN MENU CURSOR POSITION Y_COORD: DB 32 X_COORD: DB 32 DB 0 PUT_SUB_CURSOR: DB ESC,'s','2',ESC,'=' ;MAIN MENU CURSOR POSITION Y_SUB_COORD: DB 32 X_SUB_COORD: DB 32 DB 0 NUM_SUB_CMDS: DS 1 ;# OF COMMANDS IN SUB MENU NUL_MSG: M_EXIT: DB 0 DB ESC,'s','2','Z'-040h DB ESC,'s','1' DB '$' PAGE CRLF5S: DB ESC,'s3',cr,lf,lf,lf DB ' ',0 PFORMAT: DB ESC,'s5','Z'-40h DB cr,lf DB ' Press and Hold Q to Quit Formatting' DB ESC,'s','3','Z'-040h DB ' Track Formatted:',cr,lf DB ' 0 1 2 3 ' DB CR,LF DB ' 0123456789012345678901234567890123456789',cr,lf DB cr,lf DB ' * Indicates Good Format E Indicates Format Error',cr,lf DB '$' ABT_MSG: DB ESC,'s5','Z'-40h DB cr,lf DB ' Press and Hold Q to Quit Copying' DB '$' RCOPY: DB ESC,'s','3' DB ' Reading Track ' RCOPYN: DB 'XX ' ;Filled in by RDMTRK DB '$' WCOPY: DB ESC,'s','3' DB ' Writing Track ' WCOPYN: DB 'XX ' ;Filled in by WRTTRK DB '$' SECTOR: DB 0 ;FOR FORMAT SOURCE: DB 0 ;SOURCE DRIVE FOR COPY TRACK: DB 0 ;ACTIVE LOGICAL TRACK BLOCK: DB 0 ;ACTIVE BLOCK NUMBER ;BETA TEST ONLY F_RD_ERR: DB ESC,'s2',CLR_SCR DB '  Fatal read error occurred. Make sure',cr,lf DB ' source disk is in place and try again.',cr,lf DB ' Press ESC to continue.',0 RDERR: DB ESC,'s2','Z'-40h DB ' Read error occurred on track ' RD_ERR_P: DB 'XX. Continue (Y/N)? ',0 DB ' Read error occurred on track XX. Continue (Y/N)? RD_ERR_WARN: DB ESC,'s2',CLR_SCR DB ' COPY completed with READ errors. Destination disk MAY contain bad data.',cr,lf DB ' Press ESC to continue.',0 WTERR: DB ESC,'s2','Z'-40h DB ' Write error occurred. Retry with a different destination disk.',cr,lf DB ' Press ESC to continue.',0 DSK_FMT: DB ESC,'s2','Z'-40h DB ' Diskette in Drive ' D_FMT_D: DB 'X' ;Filled in by FMAT or KOPY DB ' contains information.',cr,lf DB ' Is it OK to overwrite it (y/n)? ',0 DK_MB_FMT: DB ESC,'s2','Z'-40h DB ' Diskette in Drive ' D_FMT_D2: DB 'X' ;Filled in by FMAT or KOPY DB ' MAY contain information.',cr,lf DB ' Is it OK to overwrite it (y/n)? ',0 END: DB CR,LF,LF DB 0 GMES: DB ESC,'s','2','Z'-040h DB ' COPY completed successfully.',cr,lf DB ' Press RETURN to continue.' DB 0 BMES: DB ESC,'s','2','Z'-040h DB ' COPY ERROR.',cr,lf DB ' Press ESC to continue.' DB 0 ABTCPY: DB ESC,'s','2','Z'-040h DB ' COPY ABORTED.',cr,lf DB ' Press RETURN to continue.' DB 0 NOTOSB: DB ESC,'s','2','Z'-040h DB ' Source diskette is not formatted',cr,lf DB ' with a standard Osborne format.',cr,lf DB ' Press RETURN to continue.' DB 0 BADDEN: DB ESC,'s','2','Z'-040h DB ' Source and destination diskettes don''t have matching formats.',cr,lf DB ' Press RETURN to continue.' DB 0 GDFMT: DB ESC,'s','2','Z'-040h DB ' FORMAT completed successfully.',cr,lf DB ' Press RETURN to continue.' DB 0 BDFMT: DB ESC,'s','2','Z'-040h DB ' FORMAT ERROR.',cr,lf DB ' Press ESC to continue.' DB 0 ABTFMT: DB ESC,'s','2','Z'-040h DB ' FORMAT ABORTED.',cr,lf DB ' Press RETURN to continue.' DB 0 PAGE SFORDAT: ;FORMAT DATA FOR IBM 3740. *NOTE* ;NO INDEX MARK IS USED ; **** GAP 1 **** SFMTSD: ECHO 17 ! DB 0FFH ENDM ECHO 6 ! DB 0 ENDM DB 0FEH ;ID ADDRESS MARK SFTRKN: DB 0 ;TRACK SINGTO = *-SFORDAT DB 0 ;SIDE SFSECN: DB 1 ;SECTOR DB 1 DB 0F7H ;CRC ; **** GAP 2 **** ECHO 11 ! DB 0FFH ENDM ECHO 6 ! DB 0 ENDM SFDAM: DB 0FBH ;DATA ADDRESS MARK %A&; **** DATA **** ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM SFCRC2: DB 0F7H ;CRC SFMTEND = * SLIFMT = *-SFORDAT SLISEC = *-SFMTSD PAGE DFORDAT: ;DOUBLE DENSITY FORMAT DATA FOR IBM 3740. *NOTE* ;NO INDEX MARK IS USED ; **** GAP 1 **** DFMTSD: ECHO 100 ! DB 04EH ENDM ECHO 12 ! DB 0 ENDM DB 0F5H,0F5H,0F5H DB 0FEH ;ID ADDRESS MARK DFTRKN: DB 0 ;TRACK DOUBTO = *-DFORDAT DB 0 ;SIDE DFSECN: DB 1 ;SECTOR DB 3 ;SECTOR LENTH DB 0F7H ;CRC ; **** GAP 2 **** ECHO 22 ! DB 04EH ENDM ECHO 12 ! DB 0 ENDM DB 0F5H,0F5H,0F5H DB 0FBH ;DATA ADDRESS MARK ; **** DATA **** ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM DFCRC2: DB 0F7H ;CRC DFMTEND = * DLIFMT = *-DFORDAT DLISEC = *-DFMTSD ERCOUNT: DB 0 ;ERROR COUNTER LBUFF1: DW 0 ;HOLD FBA IN BUFF1 MACHTYPE: DB 0 ;MACHINE DENSITY ; 0 = Undefined ; 1 = Single ; 2 = Double FMTERR: DB 0 ;FORMAT ERROR FLAG BUFFS: DS 7000 ;SAVE BUFFER DS 40*2 STACK: DS 0 ;STACK HERE ; END  **** GAP 1 **** DFMTSD: ECHO 100 ! DB 04EH ENDM ECHO 12 ! DB 0 ENDM DB 0F5H,0F5H,0F5H DB 0FEH ;ID ADDRESS MARK DFTRKN: DB 0 ;TRACK DOUBTO = *-DFORDAT DB 0 ;SIDE DFSECN: DB 1 ;SECTOR DB 3 ;SECTOR LENTH DB 0F7H ;CRC ; **** GAP 2 **** ECHO 22 ! DB 04EH ENDM ECHO 12 ! DB 0 ENDM DB 0F5H,0F5H,0F5H DB 0FBH ;DATA ADDRESS MARK ; **** DATA **** ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM ECHO 128 DB FMTCHR ENDM DFCRC2: DB 0F7H ;CRC DFMTEND = * DLIFMT = *-DFORDAT DLISEC = *-DFMTSD ERCOUNT: DB 0 ;ERROR COUNTER LBUFF1discriminate between a dsdd disk reformatted to ssdd ; and a dsdd disk. ; ;ENTRY ; FDENS set 1 if disk should be formatted dsdd, else 0 for ssdd ;EXIT ;A = 0 IF NO ERRORS ; OFFH IF ERROR ; 'C'-40H IF ABORT LDK HL,PFORMAT ;FORMAT MESSAGE CALL STRCON LDK A,1 STO A,SAVSEC ;SET SECTOR CALL RHOME ;HOME DRIVE JNZ :ERR ;ERROR RETURN ;FORMAT AND VERIFY ENTIRE DISK LDK HL,CRLF5S CALL PRINT XRA A ;START WITH TRACK 0 STO A,FMTERR ;NO ERRORS YET ;TRACK LOOP :TLOOP: STO A,SAVTRK ;UPDATE TRACK NUMBER XOR A ;Start with physical 841005 STO A,:SIDE ;side 0 841005 STO A,:LSIDE ;and logical side 0 841005 LD A,SAVTYP ;Set side 0 in SAVTYP 841005 AND 1111_1101B STO A,SAVTYP :SLOOP: ;Top of side loop 841005 CALL FMTINT ;INITIALIZE FORMAT BUFFER(BUFF) LD A,:LSIDE ;Load logical side MOV C,A ;Pass it in C CALL STRK ;SET NEW TRACK and logical side ;INTO DATA IF NOT FMT_FIX LDK BC,BUFF  ;POINT TO FWA OF BUFFER CALL RFORMAT ;FORMAT ONE TRACK ENDIF IF FMT_FIX LK HL,BUFF ;Point at buffer STO HL,DMADR ;save as DMA address IN SYS_DTA ;Get bank mask for TPA STO A,DMA_BANK ;and save as DMA bank CALL RFORMAT ;Format the track ENDIF JNZ :1 ;IF ERROR ; ; Skip verify if physical side 1 and logical side 0 ; LD A,:LSIDE ;Verify if logical side 1 OR A ; JNZ :VER ; ; LD A,:SIDE ;Don't verify if physical side OR A ;1 JNZ :NOVER ; ; :VER: CALL VERIFY JNZ :1 ;If error :NOVER: LDK A,'*' JMP :2 ;IF GOOD :1: LDK A,'E' STO A,FMTERR ;SET ERROR FLAG :2: CALL CONOUT ;OUTPUT INDICATOR LK A,'H' - 040h ;Backspace 841005 CALL CONOUT ; 841005 CALL CKABORT RZ ;RETURN IF ABORT LD A,:SIDE ;Is this not side 0? 841005 OR A ; 841005 JNZ :NXTTRK ;Yes... 841005 ; INC A ;No. Bump side indicator841005 STO A,:SIDE ; 841005 LD A,FDENS ;Are we formatting dsdd? OR A ; JRZ :SS ;No, leave logical sied at 0 ; STO A,:LSIDE ;Yes, set logical side to 1 :SS: LD A,SAVTYP ;Toggle side bit in 841005 XOR 0000_0010B ;SAVTYP to change 841005 STO A,SAVTYP ;physical side 841005 JMP :SLOOP ;And do side 1 841005 :NXTTRK: LK A,'L' - 040H ;Advance to next space 841005 CALL CONOUT ; 841005 LD A,SAVTRK INC A CMP MTRK JNZ :TLOOP ;CONTINUE TILL ALL TRACKS ;FINAL CHECK LD A,FMTERR ORA A JRNZ :ERR ;IF ERROR ; CALL STPODRV ;VERIFY ALL TRACKS RET ;RETURN A=0 IF NO ERROR, A=0FFH IF ERROR :ERR: ORI 0FFH RET ;RETURN ERROR :SIDE: DB 0 ; 841005 :LSIDE: DB 0 ;Logical side PAGE VERIFY: ;VERIFY 0E5H ON ONE TRACK ;USES BUFF FOR VERIFICATION ;ENTRY ;SDISK = DRIVE TO VERIFY ;SAVTRK = TRACK TO VERIFY ;EXIT ;ZBIT = RESET IF ERROR PROC LDK BC,BUFF STO BC,DMADR ;SET DMA STO BC,LBUFF1 ;SET DMA FOR CNDATA IN SYS_DTA ;Get TPA bank from PIA STO A,DMA_BANK ;and make it the DMA b&A'ank ;READ ONE TRACK LD A,NMSEC ;SECTORS/TRACK MOV B,A CALL RREAD ;READ ONE TRACK RNZ CALL CNDATA ;CHECK FOR ALL E5H'S RET PAGE COPY: ;COPY DISKETTE ;ENTRY ;SOURCE = DRIVE TO COPY FROM ;EXIT ;A = 0 IF NO ERROR ; 0FFH IF ERROR ; 'C'-40H IF ABORT ;B IS DESTROYED PROC XOR A ;Clear read error flag STO A,R_ERR_FLAG LD A,SAVTYP ;Set physical side for FDC to 0 841006 CBIT 1,A ; 841006 STO A,SAVTYP ; 841006 LK HL,ABT_MSG CALL STRCON LDK A,1 STO A,SAVSEC ;SET SECTOR *BLOCK LOOP (0-3 SINGLE DENSITY) (0-7 DOUBLE DENSITY) XRA A :BLOOP: STO A,BLOCK CALL RDMBLK ;READ MASTER LDK HL,RDERR JNZ :F_R_ERR ;Fatal read error (such as no disk in source ;drive)... ; CMP 'Q' ;Check for abort char RZ ;Return if aborted... CALL WRTBLK ;WRITE BLOCK TO OBJECT LDK HL,WTERR JNZ :ERR CMP 'Q' ;Check for abort char RZ ;Return if aborted... *FINISHED? LD A,NUMBLK ;GET NUMBER OF BLOCKS MOV B,A LD A,BLOCK ;CURRENT BLOCK INC A CMP B JNZ :BLOOP ;LOOP ; CALL STPODRV ;VERIFY ALL TRACKS LD A,R_ERR_FLG ;Check for read error OR A RZ ;No error. ; LK HL,RD_ERR_WARN ;Point at warning messg JMP :ERR ;and handle error ; :F_R_ERR: ;Fatal read error occurred LK HL,F_RD_ERR JMP :ERR :ERR: CALL PRINT ;Print err messg CALL GET_ESC ;Wait for user to enter ESC CALL CLR_W_2 ;Clear err messg OR 0FFH ;Return error message RET PAGE RDMBLK: ;READ ONE BLOCK FROM THE MASTER ;ENTRY ;EXIT ;ZBIT = RESET IF ERROR PROC LD A,SOURCE STO A,SDISK ;SET DRIVE ;FIND HEAD POSITION AND SET D.TRKR CALL SENDEN ;SENCE DENSITY RNZ LD A,SAVTYP ;Start on side 0 841008 AND 1111_1101B ;Clear bit 1 841008 STO A,SAVTYP ; 841008 XRA A ;ZERO A STO A,TRACK ; 841006 :TLOOP: CALL SETSAVTRK ;SET SAVTRK 841006 LD A,SAVTRK ;GET SAVTRK CMP MTRK RZ ;IF SAVTRK = 40 STOP CALL CKABORT ;Check for user abort request RZ ;Return if aborted... CALL SETLBUFF1 ;SET LBUFF1 CALL RDMTRK ;READ MASTER JZ :NO_ERR ;No error... ;Read error occurred LK A,0FFH ;Flag the error STO A,R_ERR_FLAG LD A,SAVTRK ;Patch track # into error message MOV L,A ; LK H,0 ; LK DE,RD_ERR_P ; CALL CBD2 ; LK HL,RD_ERR ;Point at error message CALL PRINT ;and print it. It asks user if she wants to ;continue (Y/N) CALL Y_N ;Wait for user to enter Y or N PUSH AF ;Save response CALL CLR_W_2 ;Clear message POP AF ;restore Y or N response CMP 'Y' ;Is it Y (for continue)? JZ :ERR_OK ;Yes, proceed ; XOR A ;Clear Z flag LK A,'Q' ;No. Return and indicate user aborted. RET ; :ERR_OK: :NO_ERR: LD A,NSIDES ;Is this dsdd? 841006 OR A ; 841006 JZ :NXTTRK ;No, next trk 841006 ; LD A,SAVTYP ;Change FDC physical side 841006 XOR SSMASK ; 841006 STO A,SAVTYP ; 841006 BIT 1,A ; JNZ :TLOOP ;If new side is side 1, stay on same 841008 ;track :NXTTRK:  LDK HL,NUMTRK ;# OF TRACKS/BLOCK LD A,TRACK INC A CMP [HL] ;DONE? RZ ;Yes... 841006 ; STO A,TRACK ;Save new track # 841006 JMP :TLOOP ;Do next logical track 841006 ; ; Local storage for read error flagging and track recording: ; R_ERR_FLAG: ;Read error flag DB 0 R_ERR_TRK: ;Last track where read error occurred DW 0 PAGE RDMTRK: ;READ ONE TRACK OFF MASTER ;ENTRY ;LBUFF1 = DMA ADDRESS ;EXIT ;ZBIT = RESET IF ERROR PROC LD HL,SAVTRK ;Put decimal track # in message to print LK DE,RCOPYN CALL CBD2 LDK HL,RCOPY CALL STRCON ;OUTPUT MESSAGE LD HL,LBUFF1 STO HL,DMADR ;SET DMA TO "LBUFF1" IN SYS_DTA ;Get TPA bank from PIA STO A,DMA_BANK ;and make it the DMA bank LD A,NMSEC MOV B,A CALL RREAD ;READ RET PAGE WRTBLK: ;WRITE ONE BLOCK ON OBJECT DRIVE ;ENTRY ;EXIT ;ZBIT = RESET IF ERROR PROC ;SELECT DRIVE LD A,SOURCE XRI 0000_0001B ;OTHER DRIVE STO A,SDISK ;SET DRIVE ;FIND HEAD POSITION AND SET D.TRKR LD A,BLOCK ORA A JNZ :1 ;If "BLOCK" is not zero skip home ;HOME DRIVE IF ON TRACK ZERO CALL RHOME ;HOME DRIVE RNZ ;RETURN IF ERROR JR :2 ;IF GOOD SKIP SENDEN :1: CALL SENDEN RNZ ;RETURN IF ERROR :2: LD A,SAVTYP ;Start on side 0 841008 AND 1111_1101B ;Clear bit 1 841008 STO A,SAVTYP ; 841008 XRA A STO A,TRACK ;TRACK LOOP :TLOOP: CALL SETSAVTRK ;SET SAVTRK LD A,SAVTRK ;GET SAVTRK CMP MTRK RZ ;IF SAVTRK = 40 STOP CALL CKABORT ;Check for user abort request RZ ;Return if aborted... CALL SETLBUFF1 ;SET LBUFF1 CALL WRTTRK ;WRITE TRACK RNZ LD A,NSIDES ;Is this dsdd? 841006 OR A ; 841006 JZ :NXTTRK ;No, next trk 841006 ; LD A,SAVTYP ;Change FDC physical side 841006 XOR SSMASK ; 841006 STO A,SAVTYP ; 841006 BIT 1,A ; JNZ :TLOOP ;If new side is side 1, stay on same 841008 ;track :NXTTRK: LDK HL,NUMTRK ;# OF TRACKS/BLOCK LD A,TRACK INC A CMP [HL] ;DONE? RZ ;Yes... 8'A