; JRCONFIG.SYS v3.10 ; This version looks at its own extension for .dsk to enable ; ramdisk the RAM disk or not. MEMORY_FILL_PATTERN EQU 5aa5h ; String macros BEL EQU 7 TAB EQU 9 LF EQU 10 CR EQU 13 ESC EQU 27 ; BIOS Data Area (BDA) offsets BDA_COM2_PORT EQU 02h BDA_BIOS_DATA_SEG EQU 0eh BDA_EQUIP_BITS EQU 10h BDA_MEM_SIZE_KB EQU 13h BDA_ADAP_MEM_SIZE EQU 15h BDA_KBD_SHIFT_FLAG EQU 17h BDA_ACTIVE_MODE EQU 49h BDA_VIDEO_FLAGS EQU 89h BDA_VIDEO_FLAGS2 EQU 8ah ; I/O Ports PORT_KEYBOARD_STORAGE EQU 0060h ; 8255 Port A PORT_NMI_MASK EQU 00a0h ; Bit 7 PORT_CRT_ADDRESS EQU 03d4h ; 6845 CRT controller PORT_CRT_DATA EQU 03d5h ; 6845 CRT controller PORT_VIDEO_PAGE EQU 03dfh ; b0-2: CRT, b3-5 CPU, b6-7 address mode _TEXT segment word public use16 'CODE' public _entry assume cs:_TEXT, ds:_TEXT, es:nothing org 0 public _sys_header _sys_header: dd -1 ; Link to next driver in chain (filled in by DOS) _sys_flags: dw 8000h ; Char dev, no-output-until-busy support dw _strategy_entry dw _commands_entry _sys_name: db 'JRCONSYS' ; Char dev only: Device name _sys_table: dw _cmd0_driver_init ; [CB] Initialization dw _cmd1_media_check ; [ B] Media Check dw _cmd2_build_bios_param_block ; [ B] Build BPB dw _cmd3_ioctl_read ; [CB] IOCTL Read dw _cmd4_read ; [CB] Read dw _cmdn_completed ; [C ] Non-Destructive Read dw _cmdn_completed ; [C ] Input Status dw _cmdn_completed ; [C ] Flush Input Buffers dw _cmd5_write ; [CB] Write dw _cmd5_write ; [ B] Write w/ Verify dw _cmdn_completed ; [C ] Output Status dw _cmdn_completed ; [C ] Flush Output Buffers dw _cmdn_completed ; [CB] IOCTL Write _table_20: db 000h ; 002c db 000h ; 002d db 000h ; 002e db 'JRCONFIG' ; 002f _bios_param_block: _bpb_bytes_per_sector dw 128 _bpb_sec_per_unit db 1 _bpb_reserved_sectors dw 1 _bpb_fat_tables db 1 _bpb_rootdisk_entries dw 00010h _bpb_total_sectors dw 0 _bpb_media_desc_byte db 0f8h _bpb_secs_per_fat dw 0 _bpb_secs_per_track dw 0 ; DOS 3.x only _bpb_head_count dw 0 ; DOS 3.x only _bpb_hidden_sectors dw 0 ; DOS 3.x only _bpb_pointer dw offset _bios_param_block _prev_int09h dd 0 _prev_int10h_a dd 0 _prev_int10h_b dd 0 _prev_int10h_c dd 0 _prev_int20h dd 0 _prev_int21h dd 0 _prev_int27h dd 0 _sys_request dw 0 ; Saved DOS transaction pointer _sys_request_seg dw 0 _break_min dw 0 ; Top of resident program (segment) _video_start dw 0 ; Start of frame (segment) _video_end dw 0 ; End of frame (segment) _break_end dw 0 ; End of allocation (segment) _video_size dw 0400h ; In paragraphs (segment offset) _video_page db 7 ; A17-14 page translation _video_kb db 010h ; Video frame size in KB _displaymaster db 0 ; From prescence pattern check _combocart_off dw 0 _combocart_seg dw 0 _unknown_table_2: db 64 dup(0) ; 007d _ramdisk_sized db 0 ; ---------------------------------------------------------- ; FUNC: _strategy_entry ; ; DESC: Entry point from DOS used to store the request block ; for all command requests to the device driver processed ; during _command_entry below. ; ; INPUTS: es:bx - Pointer to driver specific command block ; ; OUTPUTS: none ; ; CLOBBERS: none _strategy_entry proc far public mov cs:_sys_request_seg, es mov cs:_sys_request, bx retf _strategy_entry endp ; ---------------------------------------------------------- ; FUNC: _commands_entry ; ; DESC: Entry point from DOS used to process specific driver ; requests. This is done through a dispatch table ; above. Supporting dispatch functions are setup with ; the following entry registers: ; ; dx:cx - Far pointer to driver command line ; ds:bx - Command request block ; es:di - Break address of driver memory ; ; Dispatch functions are expected to re-enter this ; code via a short jump to _cmdn_completed. ; ; INPUTS: none - All information is command specific and ; passed via the _sys_request block ; ; OUTPUTS: none - All information is command specific and ; passed via the _sys_request block ; ; CLOBBERS: none _commands_entry proc far public push si push ax push cx push dx push di push bp push ds push es push bx lds bx, cs:_sys_request mov cx, word ptr ds:[bx + 012h] ; Command line offset mov dx, word ptr ds:[bx + 014h] ; Command line segment mov al, byte ptr ds:[bx + 2] ; Command code cbw mov si, _sys_table add si, ax add si, ax cmp al, 11 ja _command_unknown les di, ds:[bx + 00eh] ; First free address above driver push cs pop ds cld jmp ds:[si] _command_unknown: mov ax, 08103h ; Unknown error status jmp _command_exit _cmdn_completed: mov ax, 0100h ; Driver done - no error _command_exit: lds bx, cs:_sys_request mov word ptr ds:[bx + 3], ax ; Return status call _spin_status pop bx pop es pop ds pop bp pop di pop dx pop cx pop ax pop si retf _commands_entry endp _cmd3_ioctl_read: mov al, 080h mov ah, ds:_video_page stosw mov al, ds:_video_kb stosb _cmdn_io_completed: clc jmp _cmdn_completed _cmd1_media_check: lds bx, ds:_sys_request mov byte ptr ds:[bx + 00eh], 1 ; Block device not changed jmp _cmdn_completed _cmd2_build_bios_param_block: lds bx, ds:_sys_request mov word ptr ds:[bx + 012h], _bios_param_block mov word ptr ds:[bx + 014h], cs jmp _cmdn_completed ; On I/O entry: ; cx = bytes/sector count ; dx = starting sector number ; Memory map looks like this: ; [resident ][ region 1 ][ video frame ][ region 2 ] _cmd4_read: xor ax, ax ; copy direction: 0 = read jmp _cmd_io_setup _cmd5_write: mov al, 1 ; copy direction: 1 = write _cmd_io_setup: shl dx, 1 ; start sector * 128 (7 left shift minus shl dx, 1 ; 4 right shift for paragraph adjust shl dx, 1 add dx, ds:_break_min mov bx, dx ; bx = dx = starting paragraph shl cx, 1 ; sector count * 128 (7 left shift minus shl cx, 1 ; 4 right shift for paragraph adjust shl cx, 1 add bx, cx ; bx = ending paragraph ; If we're above the start of video frame, add size to start loc cmp dx, ds:_video_start jae _adjust_copy_offset ; If we're in lower region and not spilling into video frame, go cmp bx, ds:_video_start jbe _cmd_io_go ; Overlapping video frame, break into two transfers doing lower first mov cx, ds:_video_start sub cx, dx call _copy_io_block push cs ; Block copy may trample ds pop ds mov cx, bx sub cx, ds:_video_start xor dx, dx jmp _adjust_for_region_two _adjust_copy_offset: sub dx, ds:_video_start _adjust_for_region_two: add dx, ds:_video_end _cmd_io_go: call _copy_io_block jmp _cmdn_io_completed ; ---------------------------------------------------------- ; FUNC: _copy_io_block ; ; DESC: Copy a ram region specified in paragraphs/segment offsets ; with optional reversal of src/dst ; ; INPUTS: dx - starting source segment/paragraph ; es:di - Target byte pointer for copy ; cx - Number of paragraphs to copy ; ax - 1 reverse direction, 0 no reversal ; ; OUTPUTS: es:di - Advanced past copy length ; ; CLOBBERS: cx, dx, ds, si _copy_io_block proc near public shl cx, 1 ; cx = paragraphs w/ word movement = * 8 shl cx, 1 shl cx, 1 xor si, si mov ds, dx or ax, ax jz _copy_io_block_go _copy_io_block_swap_ptrs: push es pop ds mov es, dx xchg di, si _copy_io_block_go: rep movsw or ax, ax jz _copy_io_block_done _copy_io_block_swap_ptrs_back: push ds pop es mov di, si _copy_io_block_done: ret _copy_io_block endp ; ---------------------------------------------------------- ; FUNC: _int09h_handler ; ; DESC: Traps keyboard IRQ handler _int09h_handler proc far public in al, PORT_KEYBOARD_STORAGE jmp dword ptr cs:_prev_int09h _int09h_handler endp _vram_req: db 5 ; Mode 0: Text - 40x25 B/W db 5 ; Mode 1: Text - 40x25 Color db 5 ; Mode 2: Text - 80x25 B/W db 5 ; Mode 3: Text - 80x25 Color db 16 ; Mode 4: Graphics - 320x200 4 Color db 16 ; Mode 5: Graphics - 320x200 B/W 4 Shades db 16 ; Mode 6: Graphics - 640x200 B/W 2 Shades db 0 ; Mode 7: Not Valid db 16 ; Mode 8: Enhanced Graphics - 160x200 16 Color db 32 ; Mode 9: Enhanced Graphics - 320x200 16 Color db 32 ; Mode 10: Enhanced Graphics - 640x200 4 Color db 32 ; Mode 11: ? _int10h_handler_a proc far public push bp cmp ah, 0 jnz _loc_11 cmp byte ptr cs:_video_kb, 0 jz _loc_11 mov bp, ax ; and bp, 0fh ; fixup - open watcom encodes this more efficiently (w/ 1 byte arg) db 81h, 0e5h, 0fh, 00h push ax mov al, byte ptr cs:[bp + _vram_req] cmp byte ptr cs:_video_kb, al pop ax jnb _loc_12 xor ax, ax pop bp iret _loc_11: cmp byte ptr cs:_video_kb, 0 jnz _loc_12 cmp byte ptr cs:_video_kb, 0 jnz _loc_12 cmp ah, 0 jnz _loc_41 cmp al, 9 jb _loc_12 cmp al, 0ah ja _loc_12 push es push di push dx push cx push ax pushf mov dx, 03dah in al, dx mov al, 0 ; Mode control 1 register out dx, al mov al, 12h ; Value: 16-color graphics? out dx, al mov ax, 0040h mov es, ax mov al, es:BDA_VIDEO_FLAGS2 and al, 0f6h mov es:BDA_VIDEO_FLAGS2, al mov dx, PORT_VIDEO_PAGE out dx, al cld mov ax, 0b800h mov es, ax xor ax, ax mov di, ax mov cx, 4000h rep stosw popf pop ax pop cx pop dx pop di pop es or al, 080h _loc_12: pushf call dword ptr cs:_prev_int10h_a _loc_13: pop bp iret _loc_41: push ds push ax mov ax, 0040h mov ds, ax cmp byte ptr ds:BDA_ACTIVE_MODE, 9 pop ax pop ds jb _loc_12 pushf push cs mov bp, _loc_13 push bp sti cld push es push ds push dx push cx push bx push si push di push ax mov al, ah xor ah, ah shl ax, 1 mov si, ax ; cmp ax, 22h ; fixup db 3dh, 22h, 00h jb _loc_45 pop ax jmp far ptr 0f000h, 00f70h _loc_45: push ax mov ax, 0040h mov ds, ax pop ax mov ax, 0b800h jmp far ptr 0f000h, 00d3ch _int10h_handler_a endp ; ---------------------------------------------------------- ; FUNC: _int10h_handler_b ; ; DESC: Traps for set video mode (ah=0) and chains the previous ; handler with bit 7 of the mode set to one. After, it ; clears the active video page ; ; A video frame size validity check is also performed _int10h_handler_b proc far public or ah, ah jz _int10h_b_check_mode jmp dword ptr cs:_prev_int10h_b _int10h_b_check_mode: push bp push ax mov bp, ax ; and bp, 0fh ; fixup db 81h, 0e5h, 0fh, 00h mov al, byte ptr cs:[bp + _vram_req] cmp byte ptr cs:_video_kb, al pop ax pop bp jnb _int10h_b_set_mode xor ax, ax iret _int10h_b_set_mode: push ax or al, 080h pushf call dword ptr cs:_prev_int10h_b call _reset_video_page pop ax test al, 080h jnz _int10h_b_done push ax push cx push di push es mov ch, cs:_screen_color mov cl, ' ' cmp al, 7 jz _int10h_b_cleanup cmp al, 4 jb _int10h_b_cleanup xor cx, cx _int10h_b_cleanup: call _memset_vpage pop es pop di pop cx pop ax _int10h_b_done: iret _int10h_handler_b endp _screen_color db 7 ; ---------------------------------------------------------- ; FUNC: _int10h_handler_c ; ; DESC: Installed by the '-n' option, this handler traps for ; set video mode (ah=0) and translates color modes (1 & 3) ; to black and white modes (0 & 2) respectively _int10h_handler_c proc far public or ah, ah jnz _int10h_c_done cmp al, 1 jne _int10h_c_check_three ; Mode 1 (40x25 Color) -> Mode 0 (40x25 BW) mov al, 0 jmp _int10h_c_done _int10h_c_check_three: cmp al, 3 jne _int10h_c_done ; Mode 3 (80x25 Color) -> Mode 1 (80x25 BW) mov al, 2 _int10h_c_done: jmp dword ptr cs:_prev_int10h_c _int10h_handler_c endp ; ---------------------------------------------------------- ; FUNC: _int12h_handler ; ; DESC: Traps BIOS get memory size call being made ; cartridge BASIC and limits the reported RAM ; size to 240KB. _int12h_handler proc far public sti push bp mov bp, sp mov bp, [bp + 4] mov ax, 00f0h cmp bp, 0e800h je _int12h_done push ds mov ax, 0040h mov ds, ax mov ax, ds:BDA_MEM_SIZE_KB pop ds _int12h_done: pop bp iret _int12h_handler endp ; ---------------------------------------------------------- ; FUNC: _int27h_handler ; ; DESC: Traps DOS calls to int 27 - DOS 1 terminate ; and stay resident ; ; The active video page is reset before the DOS ; program terminates. ; ; This handler is only installed when the video ; frame is not located at the top of 128KB (!=7) _int27h_handler proc far public call _reset_video_page jmp dword ptr cs:_prev_int27h _int27h_handler endp ; ---------------------------------------------------------- ; FUNC: _int20h_handler ; ; DESC: Traps DOS calls to int 20 - DOS 1 terminate program ; ; The active video page is reset before the DOS ; program terminates. ; ; This handler is only installed when the video ; frame is not located at the top of 128KB (!=7) _int20h_handler proc far public call _reset_video_page jmp dword ptr cs:_prev_int20h _int20h_handler endp ; ---------------------------------------------------------- ; FUNC: _int21h_handler ; ; DESC: Traps DOS calls to: ; ; Func 00h -> Terminate program ; Func 31h -> Terminate and Stay Resident ; Func 4ch -> Terminate with Return code ; ; The active video page is reset before the DOS ; program terminates. ; ; This handler is only installed when the video ; frame is not located at the top of 128KB (!=7) _int21h_handler proc far public cmp ah, 0 je _int21h_clear cmp ah, 31h je _int21h_clear cmp ah, 4ch jne _int21h_chain _int21h_clear: call _reset_video_page _int21h_chain: jmp dword ptr cs:_prev_int21h _int21h_handler endp ; ---------------------------------------------------------- ; FUNC: _int60h_handler ; ; DESC: Traps DOS multiplex interrupt to provide info ; to support utilities. _int60h_handler proc far public cmp ah, 0 jne _int60h_func1 _int60h_func0: mov cs:_sys_request, bx mov cs:_sys_request_seg, cx mov ax, _strategy_entry mov bx, _commands_entry mov cx, cs mov dx, offset _bpb_pointer mov bp, cs:_bpb_total_sectors cmp word ptr cs:_sys_flags, 6000h jne _int60h_done mov bp, -1 jmp _int60h_done _int60h_func1: cmp ah, 1 jne _int60h_done cmp word ptr cs:_spinchar_offset, -1 jz _int60h_done mov cs:_spinchar_offset, bx _int60h_done: iret _int60h_handler endp ; ---------------------------------------------------------- ; FUNC: _default_video_page ; ; DESC: This ensures the default video page of 7 is set in ; both the CRT and CPU page registers by calling ; the original Jr BIOS. Unlike _reset_video_page, ; this function always sets the page to 7 instead ; of the _video_page variable. ; ; INPUTS: none ; ; OUTPUTS: none ; ; CLOBBERS: none _default_video_page proc near public push ax push bx mov bx, 0707h jmp _reset_video_page_go _default_video_page endp ; ---------------------------------------------------------- ; FUNC: _reset_video_page ; ; DESC: This ensures the desired video page is set in ; both the CRT and CPU page registers by calling ; the original Jr BIOS. ; ; INPUTS: none ; ; OUTPUTS: none ; ; CLOBBERS: none _reset_video_page proc near public push ax push bx mov bl, cs:_video_page mov bh, bl ; bh=CRT page reg, bl=CPU page reg _reset_video_page_go: mov ax, 0583h ; Set CRT/CPU page reg pushf call dword ptr cs:_prev_int10h_a pop bx pop ax ret _reset_video_page endp ; ---------------------------------------------------------- ; FUNC: _memset_vpage ; ; DESC: This clears the active video frame with a specified ; character ; ; INPUTS: cx - Character/attribute to set in page ; ; OUTPUTS: none ; ; CLOBBERS: ax, es, di _memset_vpage proc near public mov ax, cx mov cx, cs:_video_size cmp cx, 0800h jb _memset_vpage_go mov cx, 0800h _memset_vpage_go: shl cx, 1 ; cx = paragraphs w/ word movement = * 8 shl cx, 1 shl cx, 1 mov es, cs:_video_start xor di, di pushf cld rep stosw popf ret _memset_vpage endp _cmd0_finalize: rep stosw pop di pop si pop cx rep movsw push cs pop ds cmp byte ptr cs:_displaymaster, 0 jnz _loc_79 cmp byte ptr cs:_video_kb, 0 jnz _loc_80 call _default_video_page jmp _loc_79 nop _loc_80: mov ch, cs:_screen_color mov cl, ' ' call _memset_vpage call _reset_video_page _loc_79: mov dx, _str_version mov ah, 9 int 21h mov dx, _str_6 mov ah, 9 int 21h mov dx, _str_9 cmp word ptr cs:_break_end, 2000h ja _loc_96 cmp byte ptr cs:_ramdisk_sized, 0 jnz _loc_96 mov dx, _str_8 _loc_96: mov ah, 9 int 21h cmp byte ptr cs:_video_kb, 0 jz _loc_97 mov dx, _str_10 mov ah, 9 int 21h _loc_97: cmp byte ptr cs:_video_kb, 0 jnz _loc_98 mov dx, _str_12 cmp byte ptr cs:_displaymaster, 0 jnz _loc_99 mov dx, _str_11 _loc_99: mov ah, 9 int 21h _loc_98: mov dx, _data_34 mov ah, 9 int 21h mov dx, _data_47 mov ah, 9 int 21h mov ax, 5502h call _combocart_rpc cmp word ptr cs:_combocart_off, 0ff8h jz _loc_100 cmp word ptr cs:_combocart_off, 0 jz _loc_101 mov dx, _str_16 jmp _loc_102 _loc_101: mov dx, _str_15 _loc_102: mov ah, 9 int 21h _loc_100: mov dx, _str_17 mov ah, 9 int 21h mov dx, _str_18 mov ah, 9 int 21h mov dx, _str_20 mov ah, 9 int 21h test byte ptr cs:_cmdline_error, 40h jz _loc_111 mov dx, _str_21a mov ah, 9 int 21h _loc_111: test byte ptr cs:_cmdline_error, 1 jz _loc_112 mov dx, _str_23b mov ah, 9 int 21h _loc_112: test byte ptr cs:_cmdline_error, 41h jz _loc_113 test byte ptr cs:_cmdline_error, 080h jnz _loc_113 mov dx, _str_26 mov ah, 9 int 21h _loc_114: xor ax, ax int 16h cmp al, ESC jnz _loc_114 _loc_113: mov dx, _str_27 mov ah, 9 int 21h _cmd0_normal_exit: mov cx, ds:_break_end lds bx, ds:_sys_request mov byte ptr ds:[bx + 00dh], 1 ; Units installed mov word ptr ds:[bx + 00eh], 0 ; Top of memory offset mov word ptr ds:[bx + 010h], cx ; Top of memory segment mov word ptr ds:[bx + 012h], offset _bpb_pointer mov word ptr ds:[bx + 014h], cs jmp _cmdn_completed _spinchar_index dw 0 _spinchar_table: db '|' db '/' db '-' db '\' _spinchar_offset dw -1 ; ---------------------------------------------------------- ; FUNC: _spin_status ; ; DESC: If enabled, update a spinning character at a ; configurable location on the top row of the ; screen. The character updates/spins on each ; call to the driver which is usually disk access. ; ; INPUTS: ds:bx - Driver request block ; ; OUTPUTS: none ; ; CLOBBERS: ax, bx, ds _spin_status proc near public test word ptr cs:_spinchar_offset, 08000h jnz _spin_done mov ax, 0b800h mov ds, ax mov ax, cs:_spinchar_index inc ax ; cmp ax, 4 ; fixup - open watcom encodes this more efficiently (w/ 1 byte arg) db 3dh, 04h, 00h jb _spin_draw mov ax, 0 _spin_draw: mov cs:_spinchar_index, ax mov bx, _spinchar_table add bx, ax mov al, cs:[bx] mov bx, cs:_spinchar_offset mov ds:[bx], al _spin_done: ret _spin_status endp _combocart_rpc proc near public cmp word ptr cs:_combocart_off, 0ff8h jnz _combocart_rpc_done push ds push bx push ax push cs pop ds ; mov bx, _combocart_off ; fixup db 0bbh dw _combocart_off call dword ptr cs:_combocart_off pop ax pop bx pop ds _combocart_rpc_done: ret _combocart_rpc endp _ramdisk_root: _root_filename db 'JRCONFIG' _root_extension db ' ' _root_attributes db 08h _root_reserved db 10 dup(0) _root_time dw 0c000h _root_date dw 00d81h _root_start_cluster dw 0 _root_size dd 0 _str_version: db 'JRCONFIG Version 3.10', CR, LF _str_copyright: db 'Copyright (C) 1991-1992 PC Enterprises', CR, LF db 'Copyright (C) 1986-1988, 1991 Larry Newcomb', CR, LF, LF _str_4: db 'SYSTEM INFORMATION:', CR, LF _str_5: db '128KB of conventional memory recognized', CR, LF, '$' STR_RAM_SIZE EQU (_str_5) _str_6: db ' 0KB of slow memory available' _data_38: db CR, LF _data_39: db '$' _str_7: db 'se a larger /S value to improve performance)', CR, LF, '$' _str_8: db ' ?KB of slow memory allocated for a RAM disk (use /S option to recover)', CR, LF, '$' _str_9: db ' ?KB of memory allocated for a RAM disk ', CR, LF, '$' _str_10: db ' ' _data_41: db ' ?KB of PCjr video memory located at segment ????h', CR, LF, '$' STR_VIDEO_KB EQU (_data_41 + 1) STR_VIDEO_SEG EQU (_data_41 + 44) _str_11: db 'PC Enterprises', 27h, ' jrExcellerator PC Memory Mode detected', CR, LF, '$' _str_12: db 'PC Enterprises', 27h, ' Display Master Memory Mode detected', CR, LF, '$' _data_34: db '$' _str_13: db 'emory above 640KB detected (use /L to utilize as conventional memory)', CR, LF _data_47: db '$' _str_14: db 'RSYNC installed', CR, LF, '$' _str_15: db 'PC Enterprises', 27h, ' Compatibility Cartridge not found', CR, LF, '$' _str_16: db 'PC Enterprises', 27h, ' Compatibility Cartridge not installed', CR, LF, '$' _str_17: db 'Floppy drives controlled by DOS = 1', CR, LF, '$' STR_FLOPPY_COUNT EQU (_str_17 + 34) _str_18: db 'System board ROM BIOS release date = ' _str_18_date: db '06/01/' _data_35: db '83' _data_36: db CR, LF _data_37: db '$' _str_19: db 'his is an uncommon ROM BIOS)', CR, LF, '$' _str_20: db 'System board ROM BIOS ID byte = ??', CR, LF, '$' STR_BOARD_ID EQU (_str_20 + 32) _cmdline_error db 0 _str_21a: db LF _str_21b: db 'JRCONFIG WARNING:', BEL _str_22: db ' Unsupported pass parameter(s) in CONFIG.SYS', CR, LF _str_23: db 'Data Integrity problems may occur', CR, LF, '$' _str_23b: db LF _str_24: db 'JRCONFIG ERROR:', BEL, ' Illegal pass parameter(s) in CONFIG.SYS', CR, LF _str_25: db 'Illegal pass parameters are ignored', CR, LF, '$' _str_26: db 'Press ', 27h, 'Esc', 27h, ' to continue' _str_27: db CR, LF, '$' _end_resident_portion_min: _stack_temp: db 512 dup(0) _stack_top dw 0 _saved_sp dw 0 _saved_ss dw 0 _saved_ax dw 0 _saved_bx dw 0 _int10h_handler_dos2x proc far public pushf cmp ah, 12h jnz _loc_2 cmp bl, 38h jb _loc_2 call dword ptr cs:_prev_int10h_a iret _loc_2: popf mov cs:_saved_sp, sp mov cs:_saved_ss, ss mov cs:_saved_ax, ax mov cs:_saved_bx, bx mov ax, cs mov bx, offset _stack_top mov ss, ax mov sp, bx mov ax, cs:_saved_ax mov bx, cs:_saved_bx pushf call dword ptr cs:_prev_int10h_a mov cs:_saved_ax, ax mov cs:_saved_bx, bx mov ax, cs:_saved_ss mov bx, cs:_saved_sp mov ss, ax mov sp, bx mov ax, cs:_saved_ax mov bx, cs:_saved_bx iret _int10h_handler_dos2x endp _cmd0_error_lowmem: mov dx, _str_error_mem jmp _cmd0_error_exit ; ********************************************************** ; ********************************************************** ; Marker for minimum part of device driver to remain in memory ; after driver exit. Also serves as starting location for any ; potential RAM disk. _end_resident_portion: ; ********************************************************** ; ********************************************************** _cmd0_driver_init proc near public call _combocart_find mov ax, 5500h call _combocart_rpc mov ax, 0040h mov es, ax mov ax, es:BDA_ADAP_MEM_SIZE cmp ax, 0100h jb _cmd0_error_lowmem _video_frame_check: push ds mov ax, 1c00h ; Page 7 frame mov es, ax mov ax, 0b800h ; CGA video window mov ds, ax mov cx, word ptr ds:[3ff0h] cmp cx, word ptr es:[3ff0h] jnz _video_frame_notfound not word ptr ds:[3ff0h] mov ax, ds:[3ff0h] cmp ax, es:[3ff0h] mov ds:[3ff0h], cx jz _bios_check _video_frame_notfound: mov byte ptr cs:_video_kb, 0 _bios_check: mov ax, 0f000h mov es, ax cmp word ptr es:[03b7h], 1ee8h jz _memory_pattern_check mov cs:_displaymaster, 1 _memory_pattern_check: pop ds mov ax, 2000h mov es, ax cmp word ptr es:[0200h], MEMORY_FILL_PATTERN mov ax, 0040h mov es, ax jz _jrconfig_init ; Progression for initial boot pass only call _proc_command_line add sp, 10h ; Fixup ram size for next load mov ax, es:BDA_ADAP_MEM_SIZE mov es:BDA_MEM_SIZE_KB, ax ; Mask all interrupts but IRQ0 (timer clock) mov al, 0feh out 21h, al ; Get current video mode: al=mode, bh=active page mov ah, 0fh int 10h ; Clear video by scrolling entire screen up xor cx, cx mov dh, 24 dec ah mov dl, ah xor al, al mov bh, 7 mov ah, 6 int 10h ; Set cursor posiiton to 0, 0 xor bx, bx mov dx, bx mov ah, 2 int 10h ; Stuff floppy count into upper 2 bits of BDA equip list mov ax, 0040h mov es, ax mov al, cs:_floppy_count mov bx, BDA_EQUIP_BITS mov cl, 6 test al, 080h jnz _verify_fill_pattern shl al, cl and byte ptr es:[bx], 3fh or byte ptr es:[bx], al _verify_fill_pattern: push es mov ax, 2000h mov es, ax mov word ptr es:[0200h], MEMORY_FILL_PATTERN pop es mov ax, 5501h call _combocart_rpc ; System Bootstrap Loader (soft re-OS load & execute) int 19h ; does not return _loc_50: jmp _cmd0_error_cleanup _jrconfig_init: mov al, 1 mov cs:_expanded_mem, al mov ax, 3509h ; IRQ1 Keyboard int 21h mov word ptr ds:_prev_int09h, bx mov word ptr ds:_prev_int09h + 2, es mov ax, 3510h ; BIOS Video Services int 21h mov word ptr ds:_prev_int10h_a, bx mov word ptr ds:_prev_int10h_a + 2, es mov ax, 3520h ; DOS Terminate Prog int 21h mov word ptr ds:_prev_int20h, bx mov word ptr ds:_prev_int20h + 2, es mov ax, 3521h ; DOS Service int 21h mov word ptr ds:_prev_int21h, bx mov word ptr ds:_prev_int21h + 2, es mov ax, 3527h ; DOS TSR Exit int 21h mov word ptr ds:_prev_int27h, bx mov word ptr ds:_prev_int27h + 2, es cmp byte ptr cs:_displaymaster, 0 jnz _loc_30 mov dx, _int10h_handler_a mov ax, 2510h int 21h jmp _loc_31 nop _loc_30: mov ax, 3000h int 21h cmp al, 3 jae _loc_31 mov byte ptr cs:_dosver_2x, 1 nop mov dx, _int10h_handler_dos2x mov ax, 2510h int 21h _loc_31: call _proc_command_line cmp byte ptr ds:_sys_name, 1 jne _loc_47 cmp word ptr cs:_ramdisk_size, 640 ja _loc_47 mov word ptr cs:_ramdisk_size, 640 _loc_47: mov cl, 6 mov bx, cs:_ramdisk_size cmp bx, -1 jz _loc_48 shr bx, cl mov al, ds:_video_kb add al, 0fh and al, 0f0h cbw sub dx, 50h sub dx, ax cmp bx, dx jbe _loc_49 jmp _loc_50 _loc_49: add ax, bx sub ax, 080h shl ax, cl add ax, word ptr ds:_break_min jle _loc_48 mov cs:_ramdisk_size_ext, ax mov ds:_break_end, ax sub word ptr cs:_ramdisk_size, ax _loc_48: mov al, ds:_video_kb cbw shl ax, cl mov ds:_video_size, ax mov ax, cs:_ramdisk_size mov bp, ax ; cmp ax, 0ffffh ; fixup - open watcom encodes this differently db 03dh, 0ffh, 0ffh jne _size_ramdisk mov bp, 2000h mov ax, ds:_video_size add ax, 03ffh and ax, 0fc00h mov dx, ax sub dx, ds:_video_size mov cs:_ramdisk_size_ext, dx mov ds:_break_end, dx sub bp, ax sub bp, ds:_break_min _size_ramdisk: ; bp = ram disk size in paragraphs mov dx, ds:_break_min mov es, dx add dx, bp cmp byte ptr cs:_video_kb, 0 jz _loc_66 add dx, 03ffh and dx, 0fc00h _loc_66: mov ds:_video_start, dx mov ax, dx ; Video page LSB is A14, paragraph is A4 mov cl, 10 ; Shift RD-end-paragraph down by 10 shr ax, cl mov ds:_video_page, al mov cl, 4 ; Get back to video page start KB shl al, cl ; Each page frame is 16KB, shift up by 2^4 add al, ds:_video_kb ; al = end video KB cmp al, 080h je _loc_67 jc _loc_68 jmp _error_allocation _loc_68: cmp byte ptr cs:_video_kb, 0 jz _loc_67 push es mov ax, 3510h int 21h mov word ptr cs:_prev_int10h_b, bx mov word ptr cs:_prev_int10h_b + 2, es mov dx, _int10h_handler_b mov ax, 2510h int 21h pop es mov dx, _int20h_handler mov ax, 2520h int 21h mov dx, _int27h_handler mov ax, 2527h int 21h mov dx, _int21h_handler mov ax, 2521h int 21h _loc_67: mov dx, _int60h_handler mov ax, 2560h int 21h mov dx, ds:_video_start mov ax, ds:_video_size add ax, dx mov ds:_video_end, ax add ds:_break_end, ax mov bx, dx sub bx, ds:_break_min add bx, cs:_ramdisk_size_ext mov cl, 3 shr bx, cl mov ds:_bpb_total_sectors, bx inc bx and bl, 0feh mov si, bx shr bx, 1 add bx, si add bx, 7fh shl bx, 1 mov byte ptr ds:_bpb_secs_per_fat, bh inc bh xor bl, bl shr bx, 1 mov di, bx mov si, _ramdisk_root mov cx, 0010h push cx push si push di call _copy_bpb mov di, 0080h mov ax, 0fff8h stosw xchg al, ah stosb xor ax, ax stosb mov cx, ds:_video_start sub cx, ds:_break_min shl cx, 1 shl cx, 1 shl cx, 1 sub cx, 42h cmp cx, 7000h jbe _loc_71 mov cx, 7000h _loc_71: call _update_video_string call _update_lowermem_string call _update_slow_disksize_string call _update_disksize_string call _update_bios_string call _update_board_string call _update_memory_string jmp _cmd0_finalize _cmd0_driver_init endp _proc_command_line proc near public ; Compute minimum program break (minus ram disk) ; Round up to nearest page and adjust for program ; load point mov ax, _end_resident_portion_min cmp byte ptr cs:_dosver_2x, 0 jz _fixup_break mov ax, _end_resident_portion _fixup_break: ; add ax, 0fh ; fixup - open watcom encodes this more efficiently (w/ 1 byte immediate) db 05h, 0fh, 00h mov cl, 4 shr ax, cl mov bx, cs add bx, ax mov ds:_break_min, bx push ds lds si, ds:_sys_request lds si, ds:[si + 012h] push di push es push ds pop es mov cx, 16 mov al, '.' repne scasb jcxz _loc_27 mov al, byte ptr ds:[di] and al, 0dfh ; toupper cmp al, 'D' ; or 'd' jnz _loc_27 mov word ptr cs:_sys_flags, 6000h mov byte ptr cs:_sys_name, 1 _loc_27: pop es pop di _proc_arg_next: ; On success, cl = arg letter (lower-case'd), bx = arg value call _get_next_arg mov al, cl or al, al jnz _proc_arg mov ax, 0040h mov ds, ax mov ax, ds:BDA_MEM_SIZE_KB call _update_ram_string call _update_floppycount_string pop ds cmp byte ptr cs:_video_mode_set, 0 jnz _proc_command_line_done mov bl, 3 call _set_video_mode _proc_command_line_done: ret _proc_arg: ; ---------------------------------------------------------- ; -d will tell DOS how many floppy drives to control and to ; assign a drive letter for each one of them use /Dn ; option, where n is 1 to 4. _proc_arg_d: cmp al, 'd' jne _proc_arg_h mov al, bl dec al and al, 3 mov cs:_floppy_count, al jmp _proc_arg_next ; ---------------------------------------------------------- ; -h Is not designed for the average user. I use it for ; testing programs I want to put outside the DOS user ; area. /Hnnn will put nnn as the top of ram, regardless ; of how much ram you actually have; ie, /H512 will set ; the top of ram to 512KB. If you don't have that much ; ram, your system will probably crash. _proc_arg_h: cmp al, 'h' jne _proc_arg_l push es mov ax, 0040h mov es, ax mov word ptr es:BDA_MEM_SIZE_KB, bx mov word ptr es:BDA_ADAP_MEM_SIZE, bx pop es jmp _proc_arg_next ; ---------------------------------------------------------- ; -l Will check for additional RAM located above 640KB and ; allow DOS to use any memory it finds as conventional ; memory. It allows for a maximum of 736KB to be ; recognized (note: the PCjr "POST" or "colorbar" screen ; will always stop testing at 640KB even if the /L option ; is used). _proc_arg_l: cmp al, 'l' jne _proc_arg_s cmp byte ptr cs:_displaymaster, 0 jnz _proc_arg_l_done call _memory_check _proc_arg_l_done: jmp _proc_arg_next ; ---------------------------------------------------------- ; -s Sets the size of the ramdisk, use -sn where n is the number ; of K bytes you want the ramdisk to be. The ramdisk size may ; be a little larger than the value you put in, because of ; video page boundaries. The default size is 91K for DOS 2.1 ; and 79K for DOS 3.1. (10K is the smallest ramdisk you can ; have, because that is how much room is left on the video ; page where IBMDOS.COM is loaded with DOS 2.1, and this space ; can not be used for anything else anyway. With DOS 3.1 you ; get about 15K, because IBMDOS.COM is larger and video ram ; must be moved to a higher video page). There is no upper ; limit on the size of the ramdisk (other than the amount of ; RAM you have in your computer). _proc_arg_s: cmp byte ptr cs:_expanded_mem, 0 jz _skip_arg_s cmp al, 's' jne _proc_arg_q mov cs:_ramdisk_sized, 1 mov cl, 6 shl bx, cl mov cs:_ramdisk_size, bx _skip_arg_s: jmp _proc_arg_next ; ---------------------------------------------------------- ; -q Re-enable legacy cartridge support _proc_arg_q: cmp al, 'q' jne _proc_arg_i or byte ptr cs:_cmdline_error, 40h push ds push si mov ax, 0e800h mov ds, ax mov si, 6 lodsw cmp ax, 4205h ; 05h 'BASIC' jne _cartbasic_notfound lodsw cmp ax, 'SA' jne _cartbasic_notfound lodsw cmp ax, 'CI' jne _cartbasic_notfound push cs pop ds mov dx, _int12h_handler mov ax, 2512h int 21h _cartbasic_notfound: pop si pop ds jmp _proc_arg_next ; ---------------------------------------------------------- ; -i Re-enable legacy keyboard supprt _proc_arg_i: cmp al, 'i' jne _proc_arg_r or byte ptr cs:_cmdline_error, 40h cmp bl, 9 jne _proc_arg_r_skip push ds push cs pop ds mov dx, _int09h_handler mov ax, 2509h int 21h pop ds _proc_arg_r_skip: jmp _proc_arg_next ; -r Assigns the next available drive letter to the memory ; set aside to be used as a ramdisk. The size of the ; ramdisk can be specified with the /S option. _proc_arg_r: cmp al, 'r' jne _proc_arg_p mov word ptr cs:_sys_flags, 6000h mov byte ptr cs:_sys_name, 1 jmp _proc_arg_next ; -p Disable pause for ESC on error _proc_arg_p: cmp al, 'p' jne _proc_arg_o and byte ptr cs:_cmdline_error, 7fh cmp bl, 0 jnz _proc_arg_p_done or byte ptr cs:_cmdline_error, 080h _proc_arg_p_done: jmp _proc_arg_next ; ---------------------------------------------------------- ; -o Will turn OFF the PC Enterprises Compatibility ; cartridge. Use /On where n is the option listed in ; your Compatibility Cartridge manual. _proc_arg_o: cmp al, 'o' jne _proc_arg_j cmp bl, 0 jnz _proc_arg_o_done mov word ptr cs:_combocart_off, 0ffffh _proc_arg_o_done: jmp _proc_arg_next ; ---------------------------------------------------------- ; -j Will put the address for the COM port on the motherboard ; into the BIOS data area for COM2. This will solve the ; problem that some communications programs have when using ; the COM port on the motherboard and an external modem. When ; you specify COM2, the program will now find it; and it will ; use the correct hardware interrupt. _proc_arg_j: cmp al, 'j' jne _proc_arg_m or byte ptr cs:_cmdline_error, 40h push ds mov ax, 0040h mov ds, ax mov word ptr ds:BDA_COM2_PORT, 02f8h pop ds jmp _proc_arg_next ; ---------------------------------------------------------- ; -m Will turn off the jr's internal speaker. If you run a ; program that turns the speaker back on, it will probably ; stay on. _proc_arg_m: cmp al, 'm' jne _proc_arg_n in al, 61h or al, 10h out 61h, al jmp _proc_arg_next ; ---------------------------------------------------------- ; -n Will prevent color modes for monochrome monitors. ; jrConfig will intercept a call to change to CO40 or ; CO80, and make a call for BW40 or BW80. It will have ; no effect on graphics modes. _proc_arg_n: cmp al, 'n' jne _proc_arg_g cmp byte ptr cs:_displaymaster, 0 jnz _proc_arg_n_done mov ax, 3510h int 21h mov word ptr cs:_prev_int10h_c, bx mov word ptr cs:_prev_int10h_c + 2, es mov dx, _int10h_handler_c push ds mov ax, cs mov ds, ax mov ax, 2510h int 21h pop ds _proc_arg_n_done: jmp _proc_arg_next ; ---------------------------------------------------------- ; -g Will read the time and date from a hardware clock ; and sets the time and date in DOS. Use /G0 for a ; jrCaptain and /G1 for the PCE jrRom-Clock. ; ; If /G0 assumes the jrCaptain clock chip is using ; address (37D hex - 893 decimal). If you have changed ; the jumper on the jrCaptain circuit board to set your ; clock chip at (27D hex 637 decimal) then use /G637. ; ; If your clock is at another address, use /Gnnn where ; nnn is the decimal address of the clock chip. If there ; is a problem reading the clock chip, jrConfig will beep ; and give the general error message about "thexoptions ; list in CONFIG.SYS". If you are sure that nothing is ; wrong with your clock chip, then it is either at ; another address or it is incompatible with jrConfig. _proc_arg_g: cmp al, 'g' jne _proc_arg_v cmp bl, 1 jne _proc_arg_g_jrc call _sub_33 jmp _proc_arg_next _proc_arg_g_jrc: cmp bl, 2 jb _proc_arg_g_go mov cs:_rtc_io_address, bx _proc_arg_g_go: call _rtc_jrc_init jmp _proc_arg_next ; ---------------------------------------------------------- ; -v Will reserve video ram, where n is 4 to 96. Normally 16K is ; set aside for video ram, you can either decrease or increase ; this amount with this option. Using -v4 will reserve 4K for ; video, giving you an extra 12K of user ram, but you must not ; use any graphics modes or a program that uses text pages ; other than the first test page. If you are concerned about ; speed, you may not want to use this option with a value less ; than 16. The extra RAM that you get this way will be in the ; video page, and that will be in the first 128K. Any other ; device drivers and COMMAND.COM will load into this area. ; Unless you have some large device drivers, the regular DOS ; programs you run will start in this low RAM. Don't be fooled ; by the size of the files on the disk. JRCONFIG is over half ; initialization code, the resident portion is less than 2K. ; Only about 3K of COMMAND.COM will load into low memory, the ; rest is the transient portion that is at the top of DOS ; memory. High values are used for reserving ram to be used ; for high-res graphics (32K) or extra video pages. _proc_arg_v: cmp al, 'v' jne _proc_arg_t cmp byte ptr cs:_video_kb, 0 jz _proc_arg_v_done cmp bl, 60h ja _proc_arg_v_error cmp bl, 5 jb _proc_arg_v_error mov cs:_video_kb, bl _proc_arg_v_done: jmp _proc_arg_next ; ---------------------------------------------------------- ; -t Will set the video display mode, use -tn where n is: ; ; Alpha Modes ; 0 for 40 X 25 B/W (Default) ; 1 for 40 X 25 Color ; 2 for 80 X 25 B/W ; 3 for 80 X 25 Color _proc_arg_t: cmp al, 't' jne _proc_arg_c mov byte ptr cs:_video_mode_set, 1 nop call _set_video_mode jmp _proc_arg_next ; ---------------------------------------------------------- ; -c Will turn on the keyboard click. _proc_arg_c: cmp al, 'c' jne _proc_arg_x mov ax, 0401h int 16h jmp _proc_arg_next ; ---------------------------------------------------------- ; -x Will set the proper step motor rate in DOS 3.x, this will ; make the disk quieter. Note: this will not take effect until ; after you see the initialization message. ; ; The default step rate for the PCjr is 13; which is the best ; rate for most 5.25 inch drives. If you want to make it some ; other value, use -xnn where nn is from 1 to 15. If you have ; a 3.5 inch drive that is noisy, using n = 14 may quiet it ; down; although it may make the 5.25 drive slightly noisier. ; You may need to experiment with different values for the ; best value for your combination of drives. If the step rate ; is set wrong for your drive it can become noisy and you may ; have read/write errors, so use this options carefully. Note, ; if you do not specify a step rate, the default value is ; used. _proc_arg_x: cmp al, 'x' jne _proc_arg_b and bl, 0fh cmp bl, 0 jz _loc_152 push ds push cx mov cl, 4 shl bl, cl mov ax, 0050h mov ds, ax mov al, ds:[22h] and al, 0fh or al, bl mov ds:[22h], al pop cx pop ds _loc_152: xor ax, ax int 13h jmp _proc_arg_next _proc_arg_v_error: jmp _proc_arg_error_jump nop ; ---------------------------------------------------------- ; -b Will move the screen n positions to the right, use -bn where ; n is from 1 to 7. ; Note: Both -a & -b MUST come after the -t option on the ; command line in CONFIG.SYS. If the -t option comes ; after either -a or -b, there effect will be cancelled. _proc_arg_b: cmp al, 'b' jne _proc_arg_a cmp byte ptr cs:_displaymaster, 0 jnz _proc_arg_ab_done push ds push dx mov ax, 0040h mov ds, ax mov al, ds:BDA_VIDEO_FLAGS ; and bx, 7 ; fixup - open watcom encodes this more efficiently (w/ 1 byte immediate) db 81h, 0e3h, 07h, 00h cmp bl, 0 jne _proc_arg_b_save inc bx _proc_arg_b_save: sub ax, bx mov ds:BDA_VIDEO_FLAGS, al jmp _proc_arg_ab_go ; ---------------------------------------------------------- ; -a Will move the screen n positions to the left, use -an where ; n is from 1 to 7. _proc_arg_a: cmp al, 'a' jne _proc_arg_k cmp byte ptr cs:_displaymaster, 0 jnz _proc_arg_ab_done push ds push dx mov ax, 0040h mov ds, ax mov al, ds:BDA_VIDEO_FLAGS ; and bx, 7 ; fixup - open watcom encodes this more efficiently (w/ 1 byte immediate) db 81h, 0e3h, 07h, 00h cmp bl, 0 jne _proc_arg_a_save inc bx _proc_arg_a_save: add ax, bx mov ds:BDA_VIDEO_FLAGS, al _proc_arg_ab_go: mov al, 2 ; Horizontal sync position mov dx, PORT_CRT_ADDRESS out dx, al mov al, ds:BDA_VIDEO_FLAGS inc dx ; Advance to data register out dx, al pop dx pop ds _proc_arg_ab_done: jmp _proc_arg_next ; ---------------------------------------------------------- ; -k Will set Caps-Lock (Note: If you have a keyboard with an ; indicator light for Caps-Lock, the light will not be turned ; on.) _proc_arg_k: cmp al, 'k' jne _proc_arg_w push es mov ax, 0040h mov es, ax mov bx, BDA_KBD_SHIFT_FLAG mov byte ptr es:[bx], 40h pop es jmp _proc_arg_next ; ---------------------------------------------------------- _proc_arg_error_jump: jmp _proc_arg_error nop ; ---------------------------------------------------------- ; -w Will put a clockwise spinning character in on the top ; row of your screen whenever the ramdisk is accessed. ; Use -wnn where nn is the column you want it to sppear ; in. _proc_arg_w: cmp al, 'w' jne _proc_arg_e cmp bl, 50h ja _proc_arg_error_jump mov bh, 0 rol bx, 1 mov cs:_spinchar_offset, bx jmp _proc_arg_next ; ---------------------------------------------------------- ; -e Will set the number of directory entries allowed on the ; ramdisk. The default is 16 entries. Use -en where: ; -e1 will allow 32 entries ; -e2 will allow 64 entries ; -e3 will allow 128 entries ; Each entry uses 32 bytes of the RAM reserved for the ; ramdisk. _proc_arg_e: cmp al, 'e' jne _proc_arg_y cmp bl, 3 ja _proc_arg_error mov ch, 16h cmp bl, 0 jz _proc_arg_e_skip mov cl, bl shl ch, cl _proc_arg_e_skip: mov byte ptr cs:_bpb_rootdisk_entries, ch jmp _proc_arg_next ; ---------------------------------------------------------- _proc_arg_error: or byte ptr cs:_cmdline_error, 1 jmp _proc_arg_next ; ---------------------------------------------------------- ; -y Will install the PCE Keyboard Buffer routines if you ; have a Keyboard Buffer or Combo cartridge. ; ; These routines, available only on cartridges, replace ; the keyboard and floppy disk routines, and allow the ; keyboard to be used while the disk drive is being ; accessed. They can also increase the usual 15 ; character keyboard buffer provided by DOS to 47 ; characters. To use the 47 character buffer you must ; reserve space for the larger buffer in the first 64KB ; of RAM. When you use jrConfig without using the /S ; option the cartridges display and "Out of Range" ; message. The reason is that jrConfig has set aside all ; the memory in the first 128KB to improve performance ; (remember: the 47-character buffer must be in the first ; 64KB). ; ; The /Y option solves this problem. It installs either ; the JRSYNC or JRSYNCNP routines, allocates space for ; the 47 character buffer, and allows jrConfig to utilize ; the first 128KB of slow memory as it normally does. To ; install the 47 character buffer after jrConfig has run ; just type JRSYNC47 (you may wish to put that line in ; your AUTOEXEC.BAT file). ; ; Use /Yn where n is: ; ; 0 for version 1.2 ; 1 PCE Keyboard Buffer (or Combo) Cartridge w/ parity check ; 2 PCE Keyboard Buffer (or Combo) Cartridge w/o parity check ; 3 David Cox's Combo Cartridge with parity check ; 4 David Cox's Combo Cartridge without parity check ; ; If you have another version you may wish to try all the ; JRSYNC options. If the initialization message that ; jrConfig prints shows up then jrConfig has found the ; cartridge. If your computer locks up, you have an ; incompatible version. _proc_arg_y: cmp al, 'y' jne _proc_arg_error cmp bl, 5 ja _proc_arg_error push ds mov ax, 0ce00h _loc_174: add ax, 0200h cmp ax, 0f000h jnb _loc_173 mov ds, ax cmp word ptr ds:[008h], 'SR' jne _loc_174 cmp word ptr ds:[00ah], 'NY' jne _loc_174 jmp _loc_175 nop _loc_173: pop ds jmp _proc_arg_next _loc_175: mov cs:_data_48, ax mov byte ptr cs:_data_47, 'J' mov byte ptr cs:_data_43, bl push es push di push si xor ax, ax mov ds, ax out PORT_NMI_MASK, al pushf cli cmp byte ptr cs:_data_43, 0 jnz _loc_176 mov word ptr ds:[008h], 02e8h mov word ptr ds:[038h], 1dafh jmp _loc_177 nop _loc_176: cmp byte ptr cs:_data_43, 2 ja _loc_180 mov word ptr ds:[008h], 04b8h mov word ptr ds:[038h], 1f91h jmp _loc_177 nop _loc_180: mov word ptr ds:[008h], 0459h mov word ptr ds:[038h], 1f32h _loc_177: mov bx, cs:_data_48 mov word ptr ds:[00ah], bx mov word ptr ds:[03ah], bx mov bx, 004eh cmp word ptr ds:[bx], 0f000h call _sub_48 mov ax, cs:_break_min mov es, ax ; add ax, 40h ; fixup - open watcom encodes this more efficiently (w/ 1 byte immediate) db 05h, 40h, 00h mov cs:_break_min, ax mov word ptr es:[060h], 0 cmp byte ptr cs:_data_43, 2 jz _loc_178 cmp byte ptr cs:_data_43, 4 jz _loc_178 mov byte ptr es:[064h], 0 jmp _loc_179 nop _loc_178: mov byte ptr es:[064h], 0ffh _loc_179: mov ax, 0040h mov ds, ax mov ds:BDA_BIOS_DATA_SEG, es mov ax, 00dah mov es, ax mov ax, cs mov ds, ax mov si, _jrsync_table sub dx, dx _loc_182: lodsb mov ah, 0 xchg ax, cx lodsw xchg ax, di mov bx, cx repe cmpsb jnz _loc_181 sub di, bx xchg bx, cx rep movsb inc dx _loc_181: add si, cx add si, bx cmp si, _jrsync_table_end jb _loc_182 popf mov al, 080h out PORT_NMI_MASK, al pop si pop di pop es pop ds jmp _proc_arg_next _proc_command_line endp ; ---------------------------------------------------------- ; FUNC: _set_video_mode ; ; DESC: Simple check for any additional memory above that ; indicated in the BDA. A word write/read/verify is ; performed every paragraph until it either fails or ; reaches the CGA video window at b8000. The memory ; is cleared as the test progresses. The final ; detected value is placed back in the BDA. ; ; This is done on the first pass before the int 19h ; warm restart so that DOS can have access to the ; full expansion memory after the warm re-start. ; ; INPUTS: bl - Video mode to set ; ; OUTPUTS: none ; ; CLOBBERS: ax, bx, cx, dx _set_video_mode proc near public cmp byte ptr cs:_displaymaster, 0 jnz _set_video_mode_done cmp bl, 2 jb _set_video_mode_noneighty cmp bl, 3 ja _set_video_mode_noneighty ; For 80 column text modes, update BDA push es mov ax, 0040h mov es, ax mov ax, es:BDA_EQUIP_BITS and al, 0cfh or al, 20h mov es:BDA_EQUIP_BITS, ax pop es _set_video_mode_noneighty: push ds push cx mov ax, 0040h mov ds, ax mov al, ds:BDA_VIDEO_FLAGS sub al, 2ch cmp al, 10h jle _set_video_mode_go sub al, 2eh _set_video_mode_go: mov cl, al mov ah, 0 mov al, bl int 10h mov al, 2 mov dx, PORT_CRT_ADDRESS out dx, al inc dx mov al, ds:BDA_VIDEO_FLAGS add al, cl mov ds:BDA_VIDEO_FLAGS, al out dx, al pop cx pop ds _set_video_mode_done: ret _set_video_mode endp ; ---------------------------------------------------------- ; FUNC: _memory_check ; ; DESC: Simple check for any additional memory above that ; indicated in the BDA. A word write/read/verify is ; performed every paragraph until it either fails or ; reaches the CGA video window at b8000. The memory ; is cleared as the test progresses. The final ; detected value is placed back in the BDA. ; ; This is done on the first pass before the int 19h ; warm restart so that DOS can have access to the ; full expansion memory after the warm re-start. ; ; INPUTS: none ; ; OUTPUTS: none ; ; CLOBBERS: ax, bx, cx, dx _memory_check proc near public push es push ds push di mov bx, 0040h mov es, bx mov ax, es:[BDA_ADAP_MEM_SIZE] mov cl, 6 ; <<10 for KB, >>4 for segment shl ax, cl _memory_check_loop: xor bx, bx cmp ax, 0b800h ; stop @ CGA window je _memory_check_done mov ds, ax ; simple word write/read mov ds:[bx], ax mov cx, ds:[bx] cmp ax, cx jne _memory_check_done mov cx, 8 ; Clear the tested paragraph mov es, ax xor ax, ax xor di, di rep stosw mov ax, ds inc ax jmp _memory_check_loop _memory_check_done: mov cl, 6 ; <<4 to get to bytes, >>10 for KB shr ax, cl mov bx, 0040h mov es, bx mov es:[BDA_ADAP_MEM_SIZE], ax pop di pop ds pop es _memory_check endp ; This routine is related to jrSyncro Cartridge _sub_48 proc near public jz _loc_105 mov bx, 0102h _loc_105: cmp byte ptr cs:_data_43, 0 jz _loc_57 cmp byte ptr cs:_data_43, 2 ja _loc_58 mov word ptr ds:[bx - 2], 07b6h jmp _loc_59 nop _loc_58: mov word ptr ds:[bx - 2], 0757h jmp _loc_59 nop _loc_57: mov word ptr ds:[bx - 2], 05e0h _loc_59: mov ax, cs:_data_48 mov ds:[bx], ax ret _sub_48 endp _data_43 db 0 _data_48 dw 0e000h _jrsync_table: db 00ah db 0d1h db 00ch db 02eh db 08bh db 026h db 0d1h db 002h db 02eh db 08eh db 016h db 0d3h db 002h db 02eh db 08eh db 016h db 0d3h db 002h db 02eh db 08bh db 026h db 0d1h db 002h db 00ah db 022h db 015h db 036h db 08bh db 026h db 0d1h db 002h db 036h db 08eh db 016h db 0d3h db 002h db 02eh db 08eh db 016h db 0d3h db 002h db 02eh db 08bh db 026h db 0d1h db 002h db 008h db 0d1h db 031h db 0bch db 0d1h db 002h db 08eh db 016h db 0d3h db 002h db 08eh db 016h db 0d3h db 002h db 0bch db 0d1h db 002h db 004h db 05fh db 032h db 08ch db 0c4h db 08eh db 0d4h db 08ch db 0c5h db 08eh _jrsync_table_end: db 0d5h _cmd0_error_cleanup: pop dx _error_allocation: mov dx, _str_error_fatal _cmd0_error_exit: mov ah, 9 int 21h lds bx, ds:_sys_request mov byte ptr ds:[bx + 00dh], 0 mov word ptr ds:[bx + 00eh], _end_resident_portion mov word ptr ds:[bx + 010h], cs ; All versions return offset of 32 for this pointer which is a ; random offset into the BPB for all versions. Since this is ; an error return, maybe it's a status? /shrug - no clue mov word ptr ds:[bx + 012h], 32h mov word ptr ds:[bx + 014h], cs jmp _cmdn_completed ; ---------------------------------------------------------- ; FUNC: _get_next_arg ; ; DESC: Processes next argument in a command line pointed to by ; ds:si consuming the next argument by incrementing si. ; Command arguments follow -L or /L. The letter ; can be upper or lower case and the optional argument must ; be a decimal number. ; ; NOTE: On invalid argument, jumps directly to _proc_arg_error ; ; INPUTS: ds:si - Next character in string ; ; OUTPUTS: al - 0 on error, lower case letter on success ; bx - optional decimal value or zero if not present ; ds:si - Advances past argument consumed ; ; CLOBBERS: cx, dx _get_next_arg proc near public xor bx, bx mov cx, bx _find_arg: lodsb cmp al, ' ' je _find_arg cmp al, TAB je _find_arg cmp al, CR je _last_arg cmp al, LF je _last_arg cmp al, '-' je _tolower_arg cmp al, '/' jne _find_arg _tolower_arg: lodsb or al, ' ' mov cl, al _todecimal_arg: lodsb sub al, '0' jb _invalid_arg cmp al, TAB ja _invalid_arg cbw xchg ax, bx mov dx, 10 mul dx add bx, ax jmp _todecimal_arg _invalid_arg: add al, '0' cmp al, ' ' jbe _last_arg cmp al, '-' jz _last_arg cmp al, '/' jz _last_arg pop ds jmp _proc_arg_error ; stack leak _last_arg: dec si ret _get_next_arg endp _expanded_mem db 0 ; 2nd pass w/ >=256KB confirmed _ramdisk_size_ext dw 0 ; Size above video frame (paragraphs) _ramdisk_size dw -1 ; Size below video frame (paragraphs) _dosver_2x db 0 _video_mode_set db 0 ; 1 if video mode set via cmd line arg _str_error_fatal: db 'FATAL ERROR: Check Parameters in CONFIG.SYS', CR, LF, '$' _str_error_mem: db 'ERROR: Not enough memory. At least 256K is needed.', CR, LF, '$' ; Lower 2 bits (only) indicate installed floppy count minus one. ; This variable is eventually stuffed into the upper two bits ; of the first byte of the BDA equipment status bits. _floppy_count db -1 ; ---------------------------------------------------------- ; FUNC: _update_ram_string ; ; DESC: Modifies the ram size string to reflect detected amount ; of conventional memory ; ; INPUTS: ax - Size of RAM in KB ; ; OUTPUTS: none ; ; CLOBBERS: none _update_ram_string proc near public push ax push bx push cx push dx xor cx, cx mov bx, 10 _update_ram_todec: xor dx, dx div bx add dx, '0' push dx inc cx or ax, ax jnz _update_ram_todec mov bx, 0 _update_ram_copy: pop dx mov byte ptr cs:[STR_RAM_SIZE][bx], dl inc bx loop _update_ram_copy pop dx pop cx pop bx pop ax ret _update_ram_string endp _copy_bpb proc near public push ds push si push di push cx push cs pop ds mov si, _table_20 xor di, di mov cx, 30 rep movsb pop cx pop di pop si pop ds ret _copy_bpb endp _update_video_string proc near public push ax push bx push cx push dx mov ax, ds:_video_size mov cl, 6 shr ax, cl xor cx, cx mov bx, 10 or ax, ax jz _loc_92 xor dx, dx div bx add dx, '0' mov byte ptr cs:STR_VIDEO_KB, dl or ax, ax jz _loc_92 xor dx, dx div bx add dx, '0' mov byte ptr cs:_data_41, dl _loc_92: mov ax, ds:_video_start mov cl, 4 mov bx, 4 _loc_94: mov dl, al and dl, 0fh add dl, 30h cmp dl, 3ah jb _loc_93 add dl, 7 _loc_93: mov byte ptr cs:[STR_VIDEO_SEG][bx], dl shr ax, cl dec bx jnz _loc_94 pop dx pop cx pop bx pop ax ret _update_video_string endp _update_lowermem_string proc near public push ax push bx push cx push dx mov cx, word ptr ds:_break_end cmp cx, 2000h jnb _update_lowermem_done mov word ptr cs:_data_38, '( ' mov byte ptr cs:_data_39, 'u' mov ax, 2000h sub ax, cx ; add ax, 3fh db 05h, 3fh, 00h mov cl, 6 shr ax, cl xor cx, cx mov bx, 10 _update_lowermem_bcd: xor dx, dx div bx add dx, '0' push dx inc cx or ax, ax jnz _update_lowermem_bcd mov bx, 3 sub bx, cx _update_lowermem_print: pop dx mov byte ptr cs:[bx + _str_6], dl inc bx loop _update_lowermem_print _update_lowermem_done: pop dx pop cx pop bx pop ax ret _update_lowermem_string endp _update_slow_disksize_string proc near public push ax push bx push cx push dx mov ax, ds:_bpb_total_sectors mov cl, 3 shr ax, cl xor cx, cx mov bx, 10 _update_slow_disksize_bcd: xor dx, dx div bx add dx, '0' push dx inc cx or ax, ax jnz _update_slow_disksize_bcd mov bx, 3 sub bx, cx _update_slow_disksize_print: pop dx mov byte ptr cs:[bx + _str_8], dl inc bx loop _update_slow_disksize_print pop dx pop cx pop bx pop ax ret _update_slow_disksize_string endp _update_disksize_string proc near public push ax push bx push cx push dx mov ax, ds:_bpb_total_sectors mov cl, 3 shr ax, cl xor cx, cx mov bx, 10 _update_disksize_bcd: xor dx, dx div bx add dx, '0' push dx inc cx or ax, ax jnz _update_disksize_bcd mov bx, 3 sub bx, cx _update_disksize_print: pop dx mov byte ptr cs:[bx + _str_9], dl inc bx loop _update_disksize_print pop dx pop cx pop bx pop ax ret _update_disksize_string endp _update_bios_string proc near public push es push ds push si push di push cx mov cx, 0f000h mov ds, cx mov si, 0fff5h push cs pop es mov di, _str_18_date mov cx, 8 repe cmpsb jz _update_bios_string_done mov si, 0fff5h mov di, _str_18_date mov cx, 8 rep movsb cmp byte ptr cs:_data_35, '8' jnz _update_bios_string_done mov word ptr cs:_data_36, '( ' mov byte ptr cs:_data_37, 't' _update_bios_string_done: pop cx pop di pop si pop ds pop es ret _update_bios_string endp _update_board_string proc near public push ds push ax mov ax, 0f000h mov ds, ax mov ah, byte ptr ds:[0fffeh] mov al, ah shr al, 1 shr al, 1 shr al, 1 shr al, 1 and ah, 0fh add ax, '77' mov word ptr cs:[STR_BOARD_ID], ax pop ax pop ds ret _update_board_string endp _update_memory_string proc near public cmp byte ptr cs:_displaymaster, 0 jnz _update_memory_done push ds push ax mov ax, 0040h mov ds, ax cmp word ptr ds:BDA_ADAP_MEM_SIZE, 640 ja _update_memory_cleanup mov ax, 0a000h mov ds, ax push word ptr ds:[000h] mov ax, MEMORY_FILL_PATTERN mov ds:[00h], ax cmp word ptr ds:[000h], ax jnz _update_memory_notfound not ax not word ptr ds:[000h] cmp word ptr ds:[000h], ax jnz _update_memory_notfound mov byte ptr cs:_data_34, 'M' _update_memory_notfound: pop word ptr ds:[000h] _update_memory_cleanup: pop ax pop ds _update_memory_done: ret _update_memory_string endp ; ---------------------------------------------------------- ; FUNC: _update_floppycount_string ; ; DESC: Modifies the detected floppy count string to reflect ; the number of floppy drives in the BDA ; ; INPUTS: none ; ; OUTPUTS: none ; ; CLOBBERS: none _update_floppycount_string proc near public push ax push bx push cx push es mov ax, 040h mov es, ax mov bx, BDA_EQUIP_BITS mov al, es:[bx] mov cl, 6 shr al, cl and al, 3 add byte ptr cs:[STR_FLOPPY_COUNT], al pop es pop cx pop bx pop ax ret _update_floppycount_string endp ; ---------------------------------------------------------- ; FUNC: _rtc_jrc_init ; ; DESC: If detected, set DOS date and time from a ; jrCaptain RTC device ; ; INPUTS: none ; ; OUTPUTS: none ; ; CLOBBERS: ax _rtc_jrc_init proc near public xor ax, ax call _rtc_jrc_detect or al, al jz _rtc_jrc_init_go _rtc_jrc_init_error: or byte ptr cs:_cmdline_error, 1 jmp _rtc_jrc_done _rtc_jrc_init_go: call _rtc_jrc_set or al, al jnz _rtc_jrc_init_error _rtc_jrc_done: ret _rtc_jrc_init endp ; ---------------------------------------------------------- ; FUNC: _rtc_jrc_set ; ; DESC: Set DOS date and time from a jrCaptain RTC device ; ; INPUTS: none ; ; OUTPUTS: none ; ; CLOBBERS: ax _rtc_jrc_set proc near public mov ah, 0ah call _rtc_io_read and al, 0c0h jnz _rtc_jrc_set_error _rtc_jrc_set_ready: mov ah, 0 call _rtc_io_read or al, al jnz _rtc_jrc_set_ready mov cx, 0 mov dx, cx mov ah, 2dh int 21h mov ah, 4 call _rtc_io_read call _to_bcd mov ch, al mov ah, 3 call _rtc_io_read call _to_bcd mov cl, al mov ah, 2 call _rtc_io_read call _to_bcd mov dh, al mov ah, 1 call _rtc_io_read call _to_bcd mov dl, al mov ah, 2dh int 21h ; set time or al, al jnz _rtc_jrc_set_error call _sub_45 call _sub_46 mov ah, 2bh int 21h ; set date or al, al jnz _rtc_jrc_set_error mov al, 0 ret _rtc_jrc_set_error: mov al, 1 ret _rtc_jrc_set endp ; ---------------------------------------------------------- ; FUNC: _to_bcd ; ; DESC: Convert value in al from hexidecimal value to binary ; coded decimal ; ; INPUTS: al - HEX value to convert ; ; OUTPUTS: al - BCD result ; ; CLOBBERS: none _to_bcd proc near public push cx mov ch, al mov cl, 4 shr al, cl mov cl, 10 mul cl and ch, 0fh add al, ch pop cx ret _to_bcd endp ; ---------------------------------------------------------- ; FUNC: _rtc_io_read ; ; DESC: Read a register value from a jrCaptain RTC ; ; INPUTS: ah - Register address to read ; ; OUTPUTS: al - Register value ; ; CLOBBERS: none _rtc_io_read proc near public push dx mov al, ah mov dx, cs:_rtc_io_address out dx, al inc dx inc dx in al, dx pop dx ret _rtc_io_read endp ; ---------------------------------------------------------- ; FUNC: _rtc_io_write ; ; DESC: Write a register value to a jrCaptain RTC ; ; INPUTS: ah - Register address to write ; al - Register value to write ; ; OUTPUTS: none ; ; CLOBBERS: none _rtc_io_write proc near public push dx xchg ah, al mov dx, cs:_rtc_io_address out dx, al inc dx inc dx mov al, ah out dx, al pop dx ret _rtc_io_write endp _sub_45 proc near public mov ah, 0fh call _rtc_io_read mov bh, al call _to_bcd mov ah, 0 mov dx, 0064h mul dx mov cx, ax mov ah, 0eh call _rtc_io_read mov bl, al call _to_bcd mov ah, 0 add cx, ax mov ah, 9 call _rtc_io_read mov dl, al mov ah, 7 call _rtc_io_read mov dh, al mov ah, 9 call _rtc_io_write cmp dl, dh jle _loc_158 inc cx mov al, 1 add al, bl daa mov bl, al mov al, 0 adc al, bh daa mov ah, 0fh call _rtc_io_write mov ah, 0eh mov al, bl call _rtc_io_write mov ax, cx ; and ax, 3 ; fixup - open watcom encodes this more efficiently (w/ 1 byte immediate) db 25h, 03h, 00h or ax, ax jnz _loc_158 mov ax, 0a01h call _rtc_io_write _loc_158: ret _sub_45 endp _sub_46 proc near public mov ah, 7 call _rtc_io_read mov bh, al call _to_bcd mov dh, al mov ah, 6 call _rtc_io_read mov bl, al call _to_bcd mov dl, al mov ah, 0ah call _rtc_io_read mov cs:_rtc_unknown, al and al, 1 jz _loc_155 cmp dx, 0301h jl _loc_155 jg _loc_156 mov al, 2 mov cs:_rtc_unknown, al jmp _loc_157 _loc_156: mov al, 0 mov cs:_rtc_unknown, al _loc_157: cmp dl, 1 jne _loc_165 dec dh mov al, bh sub al, 1 das mov bh, 0 mov bl, dh add bx, 04e7h mov bl, ds:[bx] mov bh, al mov al, bl call _to_bcd mov dl, al jmp _loc_166 _loc_165: dec dl mov al, bl sub al, 1 das mov bl, al _loc_166: mov ah, 7 mov al, bh call _rtc_io_write mov ah, 9 mov al, bh call _rtc_io_write mov ah, 6 mov al, bl call _rtc_io_write _loc_155: mov al, cs:_rtc_unknown and al, 2 jz _loc_167 cmp bx, 0228h jne _loc_168 inc dl jmp _loc_167 _loc_168: mov al, 0 mov cs:_rtc_unknown, al _loc_167: mov al, cs:_rtc_unknown mov ah, 0ah call _rtc_io_write ret _sub_46 endp ; ---------------------------------------------------------- ; FUNC: _rtc_jrc_detect ; ; DESC: I believe this attempts to detect and validate a jrCaptain ; RTC. I don't know anything about the hardware and this was ; from a disassembly. So guessing really ; ; INPUTS: none ; ; OUTPUTS: al - 1 on error, 0 on success ; ; CLOBBERS: ah _rtc_jrc_detect proc near public mov ah, 0 ; Read reg 0 -> al call _rtc_io_read mov bl, al and al, 0fh jnz _rtc_jrc_detect_fail cmp bl, 090h ja _rtc_jrc_detect_fail mov cx, 588 ; Arbitrary delay loop _rtc_jrc_detect_delay: loop _rtc_jrc_detect_delay mov ah, 0 ; Read reg 0 -> al call _rtc_io_read mov bh, al and al, 0fh jnz _rtc_jrc_detect_fail cmp bh, 090h ja _rtc_jrc_detect_fail cmp bh, bl je _rtc_jrc_detect_fail mov al, 0 ret _rtc_jrc_detect_fail: mov al, 1 ret _rtc_jrc_detect endp _rtc_unknown db 0 _rtc_io_address dw 0037dh _sub_33 proc near public push es push ds push cs pop ds mov ax, 0fe00h mov es, ax _loc_127: cli call _sub_34 call _sub_35 sti call _sub_36 jnb _loc_126 mov ax, es sub ax, 0200h mov es, ax cmp ax, 0c000h jnb _loc_127 jmp _loc_128 nop _loc_126: call _sub_39 call _sub_40 or al, al jnz _loc_128 call _sub_41 or al, al jz _loc_137 _loc_128: or byte ptr cs:_cmdline_error, 1 _loc_137: sti pop ds pop es _rtc_weird_loc: ret _sub_33 endp _rtc_storage_a: _rtc_bcd_dsec db 0 ; 18ba _rtc_bcd_sec db 0 ; 18bb _rtc_bcd_min db 0 ; 18bc _rtc_bcd_hour db 0 ; 18bd db 000h ; 18be _rtc_bcd_day db 0 ; 18bf _rtc_bcd_month db 0 ; 18c0 _rtc_bcd_year db 0 ; 18c1 _rtc_storage_b: db 000h ; 18c2 db 000h ; 18c3 db 000h ; 18c4 db 000h ; 18c5 db 000h ; 18c6 db 000h ; 18c7 db 000h ; 18c8 db 000h ; 18c9 _sub_34 proc near public xor di, di mov al, byte ptr es:[di + 4] xor bx, bx _loc_143: mov cx, 8 mov ah, byte ptr ds:[bx + _rtc_preamble] _loc_142: xor di, di shr ah, 1 rcl di, 1 mov al, byte ptr es:[di] loop _loc_142 inc bx cmp bx, 8 jl _loc_143 ret _sub_34 endp _rtc_preamble: db 0c5h db 03ah db 0a3h db 05ch db 0c5h db 03ah db 0a3h db 05ch _sub_35 proc near public xor di, di xor bx, bx _loc_141: mov cx, 8 _loc_140: mov ah, byte ptr es:[di + 4] shr ax, 1 loop _loc_140 mov byte ptr ds:[bx + _rtc_storage_a], al mov byte ptr ds:[bx + _rtc_storage_b], al inc bx cmp bx, 8 jl _loc_141 ret _sub_35 endp _sub_36 proc near public mov dx, 0ff00h mov cx, 8 _loc_138: mov bx, cx mov al, byte ptr ds:[bx + _rtc_weird_loc] or dl, al and dh, al loop _loc_138 cmp dx, -1; jz _loc_139 or dx, dx jz _loc_139 mov al, ds:_rtc_bcd_sec cmp al, 59h ja _loc_139 and al, 0fh cmp al, 9 ja _loc_139 mov al, ds:_rtc_bcd_day or al, al jz _loc_139 cmp al, 31h ja _loc_139 and al, 0fh cmp al, 9 ja _loc_139 mov al, ds:_rtc_bcd_month or al, al jz _loc_139 cmp al, 12h ja _loc_139 and al, 0fh cmp al, 9 ja _loc_139 clc ret _loc_139: stc ret _sub_36 endp _sub_39 proc near public xor bx, bx _loc_146: mov al, byte ptr ds:[bx + _rtc_bcd_dsec] xor ah, ah mov cx, 0610h div cl mul ch sub byte ptr ds:[bx + _rtc_bcd_dsec], al inc bx cmp bx, 8 jl _loc_146 ret _sub_39 endp _sub_40 proc near public mov cx, 1980 add cl, ds:_rtc_bcd_year adc ch, 0 mov dh, ds:_rtc_bcd_month mov dl, ds:_rtc_bcd_day mov ah, 2bh int 21h or al, al jz _loc_145 mov al, 1 _loc_145: ret _sub_40 endp _sub_41 proc near public mov ch, ds:_rtc_bcd_hour mov cl, ds:_rtc_bcd_min mov dh, ds:_rtc_bcd_sec mov dl, ds:_rtc_bcd_dsec mov ah, 2dh int 21h test al, al jz _loc_144 mov al, 2 _loc_144: ret _sub_41 endp _combocart_find proc near public push ds push bx push ax mov ax, 0d000h xor bx, bx _combocart_loop: mov ds, ax cmp word ptr ds:[bx + 0ff0h], 'CP' jne _combocart_notfound cmp word ptr ds:[bx + 0ff2h], 'rj' jne _combocart_notfound cmp word ptr ds:[bx + 0ff4h], 'CC' jne _combocart_notfound cmp word ptr ds:[bx + 0ff6h], '>-' jne _combocart_notfound mov word ptr cs:_combocart_off, 0ff8h mov cs:_combocart_seg, ax jmp _combocart_done nop _combocart_notfound: add ax, 0100h cmp ax, 0f000h jb _combocart_loop _combocart_done: pop ax pop bx pop ds ret _combocart_find endp _TEXT ends end