Permalink
Cannot retrieve contributors at this time
F000:0000 ; | |
F000:0000 ; ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» | |
F000:0000 ; º This file is generated by The Interactive Disassembler (IDA) º | |
F000:0000 ; º Copyright (c) 2010 by Hex-Rays SA, <support@hex-rays.com> º | |
F000:0000 ; º Licensed to: Freeware version º | |
F000:0000 ; ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ | |
F000:0000 ; | |
F000:0000 ; Input MD5 : C66B49CD7082D1B81442FB2704542401 | |
F000:0000 ; File Name : Z:\Users\riq\progs\ibm_pcjr-bios\rom\bios-f0000-fffff.bin | |
F000:0000 ; Format : Binary file | |
F000:0000 ; Base Address: F000h Range: F0000h - 100000h Loaded length: 10000h | |
F000:0000 .8086 | |
F000:0000 .model small | |
F000:0000 ; ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ | |
F000:0000 ; Segment type: Pure code | |
F000:0000 F000 segment byte public 'CODE' | |
F000:0000 a1504036Copr_Ibm19811 db '1504036 COPR. IBM 1981,1983' | |
F000:001B z1 dw offset l12 ; return pointers for rtns called before stack is initialized | |
F000:001D dw offset l14 | |
F000:001F dw offset l16 | |
F000:0021 dw offset l19 | |
F000:0023 dw offset l24 | |
F000:0025 f3b db ' KB' ; DATA XREF: q35+36o | |
F000:0028 ex_0 dw offset eb0 ; DATA XREF: e_msg+83o | |
F000:002A dw offset eb0 | |
F000:002C dw offset totlpt0 | |
F000:002E ex1 dw offset mo1 ; DATA XREF: e_msg+BFo | |
F000:0030 ;---------------------------------------------------- | |
F000:0030 ; message area for post | |
F000:0030 ;---------------------------------------------------- | |
F000:0030 error_err db 'ERROR' ; DATA XREF: e_msg+25o | |
F000:0035 mem_err db 'A' | |
F000:0036 key_err db 'B' ; DATA XREF: key_scan_save+16o | |
F000:0037 cass_err db 'C' | |
F000:0038 com1_err db 'D' | |
F000:0039 com2_err db 'E' | |
F000:003A rom_err db 'F' | |
F000:003B cart_err db 'G' | |
F000:003C disk_err db 'H' ; DATA XREF: F000:086Fo | |
F000:003D f4 dw 378h ; DATA XREF: F000:f15co | |
F000:003D ; print source table | |
F000:003F dw 278h | |
F000:0041 imasks dw 0F7EFh ; DATA XREF: uart:at1o | |
F000:0041 ; interrupt masks for 8259 interrupt controllers | |
F000:0043 ;---------------------------------------------------- | |
F000:0043 ; setup | |
F000:0043 ; disable nmi, maskable ints. | |
F000:0043 ; sound chip, and video. | |
F000:0043 ; turn drive 0 motor off | |
F000:0043 ;---------------------------------------------------- | |
F000:0043 ; START OF FUNCTION CHUNK FOR kb_int | |
F000:0043 reset: ; CODE XREF: F000:f19_0j | |
F000:0043 ; kb_int+10Dj kb_int+11Aj | |
F000:0043 ; F000:E05Bj F000:loc_FFFF0J | |
F000:0043 mov al, 0 | |
F000:0045 out 0A0h, al ; disables nmi | |
F000:0047 dec al ; send ff to mfg_tester | |
F000:0049 out 10h, al | |
F000:004B in al, 0A0h ; reset nmi f/f | |
F000:004D cli ; disable maskable interrupts | |
F000:004D ; disable attenuation in sound chip | |
F000:004E mov ax, 108Fh ; reg address in ah, attenuator in off | |
F000:004E ; in al | |
F000:0051 mov dx, 0C0h ; 'À' ; address of sound chip | |
F000:0054 mov cx, 4 ; 4 attenuators to disable | |
F000:0057 l1: ; CODE XREF: kb_int-1504j | |
F000:0057 or al, ah ; combine reg address and data | |
F000:0059 out dx, al | |
F000:005A add ah, 20h ; ' ' ; point to next reg | |
F000:005D loop l1 | |
F000:005F mov al, 0A0h ; ' ' ; turn drive 0 motor off, enable timer | |
F000:0061 out 0F2h, al | |
F000:0063 mov dx, 3DAh ; video gate array control | |
F000:0066 in al, dx ; sync vga to accept reg | |
F000:0067 mov al, 4 ; set vga reset reg | |
F000:0069 out dx, al ; select it | |
F000:006A mov al, 1 ; set async reset | |
F000:006C out dx, al ; reset video gate array | |
F000:006D ;---------------------------------------------------- | |
F000:006D ; test 1 | |
F000:006D ; 8088 processor test | |
F000:006D ; description | |
F000:006D ; verify 8088 flags, registers | |
F000:006D ; and conditional jumps | |
F000:006D ; | |
F000:006D ; mfg. error code 0001h | |
F000:006D ;---------------------------------------------------- | |
F000:006D mov ah, 0D5h ; 'Õ' | |
F000:006F sahf | |
F000:0070 loc_F0070: ; DATA XREF: diag_bios_break+5r | |
F000:0070 jnb short l4 | |
F000:0072 jnz short l4 | |
F000:0074 jnp short l4 | |
F000:0076 jns short l4 | |
F000:0078 lahf | |
F000:0079 mov cl, 5 | |
F000:007B shr ah, cl | |
F000:007D jnb short l4 | |
F000:007F loc_F007F: ; DATA XREF: timer_int+38o | |
F000:007F mov al, 40h ; '@' | |
F000:0081 shl al, 1 | |
F000:0083 loc_F0083: ; DATA XREF: sub_F5DB5+Cw | |
F000:0083 ; sub_F5DB5+25r | |
F000:0083 jno short l4 | |
F000:0085 xor ah, ah | |
F000:0087 sahf | |
F000:0088 jbe short l4 | |
F000:008A js short l4 | |
F000:008C jp short l4 | |
F000:008E lahf | |
F000:008F mov cl, 5 | |
F000:0091 shr ah, cl | |
F000:0093 jb short l4 | |
F000:0095 shl ah, 1 | |
F000:0097 jo short l4 | |
F000:0099 ;----- read/write the 8088 general and segmentation registers | |
F000:0099 ; with all one's and zeroes's | |
F000:0099 mov ax, 0FFFFh | |
F000:009C stc | |
F000:009D l2: ; CODE XREF: kb_int-14A9j | |
F000:009D mov ds, ax | |
F000:009F mov bx, ds | |
F000:00A1 mov es, bx | |
F000:00A3 mov cx, es | |
F000:00A5 mov ss, cx | |
F000:00A7 mov dx, ss | |
F000:00A9 mov sp, dx | |
F000:00AB mov bp, sp | |
F000:00AD mov si, bp | |
F000:00AF mov di, si | |
F000:00B1 jnb short l3 | |
F000:00B3 xor ax, di | |
F000:00B5 jnz short l4 | |
F000:00B7 clc | |
F000:00B8 jmp short l2 | |
F000:00BA l3: ; CODE XREF: kb_int-14B0j | |
F000:00BA or ax, di | |
F000:00BC jz short l5 | |
F000:00BE l4: ; CODE XREF: kb_int:loc_F0070j | |
F000:00BE ; kb_int-14EFj kb_int-14EDj | |
F000:00BE ; kb_int-14EBj kb_int-14E4j | |
F000:00BE ; kb_int:loc_F0083j ... | |
F000:00BE mov dx, 10h | |
F000:00C1 mov al, 0 | |
F000:00C3 out dx, al | |
F000:00C4 inc dx | |
F000:00C5 out dx, al | |
F000:00C6 inc al | |
F000:00C8 out dx, al | |
F000:00C9 hlt | |
F000:00CA ;---------------------------------------------------- | |
F000:00CA ; test 2 | |
F000:00CA ; 8522 initialization and test | |
F000:00CA ; description | |
F000:00CA ; first initialize 8255 prog. | |
F000:00CA ; peripheral interface. ports a&b | |
F000:00CA ; are latched output | |
F000:00CA ; buffers. c is input. | |
F000:00CA ; | |
F000:00CA ; mfg. err. code =0002h | |
F000:00CA ;---------------------------------------------------- | |
F000:00CA l5: ; CODE XREF: kb_int-14A5j | |
F000:00CA mov al, 0FEh ; 'þ' | |
F000:00CC out 10h, al ; send fe to mfg | |
F000:00CE mov al, 10001001b | |
F000:00D0 out 63h, al ; configures i/o ports (63h = cmd_port) | |
F000:00D2 sub ax, ax ; test pattern seed = 0000 | |
F000:00D4 l6: ; CODE XREF: kb_int-147Dj | |
F000:00D4 mov al, ah | |
F000:00D6 out 60h, al ; write pattern port port a | |
F000:00D8 in al, 60h ; read pattern from port a | |
F000:00DA out 61h, al ; write pattern to port b | |
F000:00DC in al, 61h ; read output port | |
F000:00DE cmp al, ah ; data as expected? | |
F000:00E0 jnz short l7 ; if not, something is wrong | |
F000:00E2 inc ah ; make new data pattern | |
F000:00E4 jnz short l6 ; loop till 255 data patterns done | |
F000:00E6 jmp short l8 ; continue if done | |
F000:00E8 l7: ; CODE XREF: kb_int-1481j | |
F000:00E8 mov bl, 2 | |
F000:00EA jmp e_msg | |
F000:00ED l8: ; CODE XREF: kb_int-147Bj | |
F000:00ED xor al, al | |
F000:00EF out 60h, al ; clear kb port | |
F000:00F1 in al, 62h | |
F000:00F3 and al, 8 ; 64k card present? | |
F000:00F5 mov al, 1Bh ; port setting for 64k sys | |
F000:00F7 jnz short l9 | |
F000:00F9 mov al, 3Fh ; '?' ; port setting for 128k sys | |
F000:00FB l9: ; CODE XREF: kb_int-146Aj | |
F000:00FB mov dx, 3DFh | |
F000:00FE out dx, al | |
F000:00FF mov al, 1101b ; initialize output ports | |
F000:0101 out 61h, al | |
F000:0103 ;---------------------------------------------------- | |
F000:0103 ; Part 3 | |
F000:0103 ; set up video gate array and 6845 to get memory working | |
F000:0103 ; | |
F000:0103 ;---------------------------------------------------- | |
F000:0103 mov al, 0FDh ; 'ý' | |
F000:0105 out 10h, al | |
F000:0107 mov dx, 3D4h ; set address of 6845 | |
F000:010A mov bx, offset video_parms ; point to 6845 parms | |
F000:010D mov cx, 10h ; set parm len | |
F000:0110 nop | |
F000:0111 xor ah, ah ; ah is reg # | |
F000:0113 l10: ; CODE XREF: kb_int-1442j | |
F000:0113 mov al, ah ; get 6845 reg # | |
F000:0115 out dx, al | |
F000:0116 inc dx ; point to data port | |
F000:0117 inc ah ; next reg value | |
F000:0119 mov al, cs:[bx] ; get table value | |
F000:011C out dx, al ; out to chip | |
F000:011D inc bx ; next in table | |
F000:011E dec dx ; back to pointer reg | |
F000:011F loop l10 | |
F000:0121 mov dx, 3DAh ; set address of vga | |
F000:0124 in al, dx ; be sure addr/data flag is in the proper state | |
F000:0125 mov cx, 5 ; # of registers | |
F000:0128 xor ah, ah ; ah is reg counter | |
F000:012A l11: ; CODE XREF: kb_int-142Fj | |
F000:012A mov al, ah ; get reg # | |
F000:012C out dx, al ; select it | |
F000:012D xor al, al ; set zero for data | |
F000:012F out dx, al | |
F000:0130 inc ah ; next reg | |
F000:0132 loop l11 | |
F000:0134 ;---------------------------------------------------- | |
F000:0134 ; test 4 | |
F000:0134 ; planar board ros checksum test | |
F000:0134 ; description | |
F000:0134 ; a checksum test is done for each ros | |
F000:0134 ; module on the planar board to. | |
F000:0134 ; mfg error code =0003h module at address | |
F000:0134 ; f000:0000 error | |
F000:0134 ; 0004h module at address | |
F000:0134 ; f800:0000 error | |
F000:0134 ;---------------------------------------------------- | |
F000:0134 mov al, 0FCh ; 'ü' | |
F000:0136 out 10h, al ; mfg out = fc | |
F000:0138 ; check module at f000:0 (lenght 32k) | |
F000:0138 xor si, si | |
F000:013A mov ax, cs | |
F000:013C mov ss, ax | |
F000:013E mov ds, ax | |
F000:0140 mov cx, 8000h | |
F000:0143 mov sp, 1Bh | |
F000:0146 jmp ros_checksum | |
F000:0146 ; END OF FUNCTION CHUNK FOR kb_int | |
F000:0149 l12: ; DATA XREF: F000:z1o | |
F000:0149 jz short l13 | |
F000:014B mov bx, 3 | |
F000:014E jmp e_msg | |
F000:0151 l13: ; CODE XREF: F000:l12j | |
F000:0151 mov cx, 8000h | |
F000:0154 jmp ros_checksum | |
F000:0157 l14: ; DATA XREF: F000:001Do | |
F000:0157 jz short l15 | |
F000:0159 mov bx, 4 ; indicate error | |
F000:015C jmp e_msg | |
F000:015F ;---------------------------------------------------- | |
F000:015F ; test 5 | |
F000:015F ; base 2k read/write storage test | |
F000:015F ; description | |
F000:015F ; write/read/verify data patterns | |
F000:015F ; aa,55 and 00 to 1st 2k of storage | |
F000:015F ; and the 2k just below 64k (crt buffer) | |
F000:015F ; verify storage addressability. | |
F000:015F ; on exit set crt page to 3. set | |
F000:015F ; temporary stack also. | |
F000:015F ; mfg. error code 04xx for system board mem. | |
F000:015F ; 05xx for 64k attrib. cd. mem | |
F000:015F ; 06xx for error in both | |
F000:015F ; (xx= error bits) | |
F000:015F ;---------------------------------------------------- | |
F000:015F l15: ; CODE XREF: F000:l14j | |
F000:015F mov al, 0FBh ; 'û' | |
F000:0161 out 10h, al ; set mfg flag = fb | |
F000:0163 mov cx, 400h | |
F000:0166 xor ax, ax | |
F000:0168 mov es, ax ; load es with 0000 segment | |
F000:016A jmp podstg | |
F000:016D l16: ; DATA XREF: F000:001Fo | |
F000:016D jnz short l20 ; bad storage found | |
F000:016F mov al, 0FAh ; 'ú' ; mfg out = fa | |
F000:0171 out 10h, al | |
F000:0173 mov cx, 400h ; 1024 words to be tested in the regen buffer | |
F000:0176 in al, 60h ; where is the regen buffer? | |
F000:0178 cmp al, 1Bh ; top of 64k? | |
F000:017A mov ax, 0F80h ; set pointer to there if it is (0xf800) | |
F000:017D jz short l18 | |
F000:017F mov ah, 1Fh ; or set pointer to top of 128k (0x1f800) | |
F000:0181 l18: ; CODE XREF: F000:017Dj | |
F000:0181 mov es, ax | |
F000:0183 jmp podstg | |
F000:0186 l19: ; DATA XREF: F000:0021o | |
F000:0186 jz short l23 | |
F000:0188 l20: ; CODE XREF: F000:l16j | |
F000:0188 mov bh, 4 ; error 04 | |
F000:018A in al, 62h ; get config bits | |
F000:018C and al, 8 ; test for attrib card present | |
F000:018E jz short l21 ; worry about odd/even if it is | |
F000:0190 mov bl, cl | |
F000:0192 or bl, ch ; cobine error bits if it isn't | |
F000:0194 jmp short l22 | |
F000:0196 l21: ; CODE XREF: F000:018Ej | |
F000:0196 cmp ah, 2 ; even byte error? err 04xx | |
F000:0199 mov bl, cl | |
F000:019B jz short l22 | |
F000:019D inc bh ; make into 05xx err | |
F000:019F or bl, ch ; move and possible combine error bits | |
F000:01A1 cmp ah, 1 ; odd byte error | |
F000:01A4 jz short l22 | |
F000:01A6 inc bh ; must have been both - make into 06hh | |
F000:01A8 l22: ; CODE XREF: F000:0194j | |
F000:01A8 ; F000:019Bj F000:01A4j | |
F000:01A8 jmp e_msg ; jump to error output routine | |
F000:01AB ; retest high 2k using b8000 address path | |
F000:01AB l23: ; CODE XREF: F000:l19j | |
F000:01AB mov al, 0F9h ; 'ù' ; mfg out=f9 | |
F000:01AD out 10h, al | |
F000:01AF mov cx, 400h ; 1k words | |
F000:01B2 mov ax, 0BB80h ; point to area just tested with direct addressing | |
F000:01B5 mov es, ax | |
F000:01B7 jmp podstg | |
F000:01BA l24: ; DATA XREF: F000:0023o | |
F000:01BA jz short l25 | |
F000:01BC mov bx, 5 | |
F000:01BF jmp e_msg | |
F000:01C2 l25: ; CODE XREF: F000:l24j | |
F000:01C2 mov ax, 30h ; '0' | |
F000:01C5 mov ss, ax | |
F000:01C7 mov sp, 100h | |
F000:01CA xor ax, ax | |
F000:01CC mov ds, ax | |
F000:01CE ;----- setup crt page | |
F000:01CE mov word ptr ds:462h, 7 ; 40:62 (active page) | |
F000:01D4 ;----- set preliminary memory size word | |
F000:01D4 mov bx, 64 | |
F000:01D7 in al, 62h | |
F000:01D9 and al, 8 ; 64k card present? | |
F000:01DB mov al, 1Bh ; port system for 64k system | |
F000:01DD jnz short l26 | |
F000:01DF add bx, 64 ; else set for 128k | |
F000:01E2 mov al, 3Fh ; '?' ; port setting for 128k system | |
F000:01E4 l26: ; CODE XREF: F000:01DDj | |
F000:01E4 mov ds:415h, bx ; 40:15 (true_mem) | |
F000:01E8 mov ds:48Ah, al ; 40:8a (pagdat) | |
F000:01EB ;---------------------------------------------------- | |
F000:01EB ; part 6 | |
F000:01EB ; interrupts | |
F000:01EB ; description | |
F000:01EB ; 32 interrupts are initialized to point to a | |
F000:01EB ; dummy handler. the bios interrupts are loaded. | |
F000:01EB ; diagnostics interrupts are loaded | |
F000:01EB ; system configuration word is put in memory. | |
F000:01EB ; the dummy interrupt handler resides here. | |
F000:01EB ;---------------------------------------------------- | |
F000:01EB mov ax, 50h ; 'P' | |
F000:01EE mov ds, ax | |
F000:01F0 mov byte ptr ds:seg50.mfg_tst, 0F8h ; 'ø' ; set up mfg checkpoint from this point | |
F000:01F5 call mfg_up ; update mfg checkpoint | |
F000:01F8 mov word ptr ds:seg50.mfg_rtn, offset mfg_out | |
F000:01FE mov ax, cs | |
F000:0200 mov ds:seg50.mfg_ret_s, ax ; set doubleword pointer to mfg. | |
F000:0200 ; error output routine so diags | |
F000:0200 ; don't have to duplicate code | |
F000:0203 mov ax, 0 | |
F000:0206 mov ds, ax | |
F000:0208 ;----- set up the interrupt vectors to temp interrupt | |
F000:0208 mov cx, 0FFh ; first all interrupts | |
F000:020B sub di, di ; first interrupt location is 0000 | |
F000:020D mov es, di ; set es=0000 also | |
F000:020F d3: ; CODE XREF: F000:0216j | |
F000:020F mov ax, offset d11 ; move addr of intr proc seg | |
F000:0212 stosw | |
F000:0213 mov ax, cs ; get addr of intr proc seg | |
F000:0215 stosw | |
F000:0216 loop d3 ; vectbl0 | |
F000:0218 mov word ptr ds:124h, offset extab ; set up ekt. scan table (int 0x49) | |
F000:021E ;----- set up bios interrupts | |
F000:021E mov di, 40h ; '@' ; set up video int (int 0x10) | |
F000:0221 push cs | |
F000:0222 pop ds ; place cs in ds | |
F000:0223 mov si, offset vector_table_16 | |
F000:0226 mov cx, 16 ; 16 entries | |
F000:0229 d4: ; CODE XREF: F000:022Cj | |
F000:0229 movsw ; move interrupt vector to low memory | |
F000:022A inc di | |
F000:022B inc di ; point to next vector entry | |
F000:022C loop d4 ; repeat for all 16 bios interrupts | |
F000:022E ;----- set up diagnostics interrupts | |
F000:022E mov di, 200h ; start with int 80h | |
F000:0231 mov si, offset diag_table_ptr ; point to entry point table | |
F000:0234 mov cx, 16 ; 16 entries | |
F000:0237 d5: ; CODE XREF: F000:023Aj | |
F000:0237 movsw ; move interrupt vector to low memory | |
F000:0238 inc di | |
F000:0239 inc di ; point to next vector entry | |
F000:023A loop d5 ; repeat for all 16 bios interrupts | |
F000:023C mov ds, cx ; set ds to zero | |
F000:023E mov word ptr ds:204h, offset locate_1_int_81 ; int 0x81 | |
F000:0244 mov word ptr ds:208h, offset prtn3_int_82 ; int 0x82 | |
F000:024A mov word ptr ds:224h, offset int_89_diag_joystick ; int 0x89 | |
F000:0250 ;----- set up default equipment determination word | |
F000:0250 ; bit 15,14 = number of printers attached | |
F000:0250 ; bit 13 = 1 = serial printer present | |
F000:0250 ; bit 12 = game i/o attached | |
F000:0250 ; bit 11,10,9 = number of rs232 cards attached | |
F000:0250 ; bit 8 = dma (0=dma present, 1=no dma on system) | |
F000:0250 ; bit 7,6 = number of diskette drives | |
F000:0250 ; 00=1, 01=2, 10=3, 11=4 only if bit 0 = 1 | |
F000:0250 ; bit 5,4 = initial video mode | |
F000:0250 ; 00 - unused | |
F000:0250 ; 01 - 40x25 bw using color card | |
F000:0250 ; 10 - 80x25 bw using color card | |
F000:0250 ; 11 - 80x25 bw using bw card | |
F000:0250 ; bit 3,2 = planar ram size (10=48k, 11=64k) | |
F000:0250 ; bit 1 not used | |
F000:0250 ; bit 0 = 1 (ipl diskette installed) | |
F000:0250 ;---------------------------------------------------- | |
F000:0250 mov bx, 1118h ; default gameio, 40x25, no dma, 48k on planar | |
F000:0253 in al, 62h | |
F000:0255 and al, 8 ; 64k card present | |
F000:0257 jnz short d55 ; no, jump | |
F000:0259 or bl, 4 ; set 64k on planar | |
F000:025C d55: ; CODE XREF: F000:0257j | |
F000:025C mov ds:410h, bx ; 0:410 = 40:10 = equip flag | |
F000:0260 ;---------------------------------------------------- | |
F000:0260 ; test 7 | |
F000:0260 ; initialize and test the 8259 interrupt controller chip | |
F000:0260 ; mfg err. code 07xx (xx=00, data path or internal failure, | |
F000:0260 ; xx=any other bits on=unexpected interrupts | |
F000:0260 ;---------------------------------------------------- | |
F000:0260 call mfg_up ; mfg code=f7 | |
F000:0263 mov al, 10011b ; icw1 - reset edge sense circuit, set single 8259 chip and icw4 read | |
F000:0265 out 20h, al | |
F000:0267 mov al, 8 ; icw2 - set interrupt type 8 (8-f) | |
F000:0269 out 21h, al | |
F000:026B mov al, 1001b ; icw4 - set buffered mode/slave and 8086 mode | |
F000:026D out 21h, al | |
F000:026F ;---------------------------------------------------- | |
F000:026F ; test ability to write/read the mask register | |
F000:026F ;---------------------------------------------------- | |
F000:026F mov al, 0 ; write zeroes to imr | |
F000:0271 mov bl, al ; preset error indicator | |
F000:0273 out 21h, al ; device interrupts enabled | |
F000:0275 in al, 21h ; read imr | |
F000:0277 or al, al ; imr = 0? | |
F000:0279 jnz short gerror ; no - go to error routine | |
F000:027B mov al, 0FFh ; disable device interrupts | |
F000:027D out 21h, al ; write ones to imr | |
F000:027F in al, 21h ; read imr | |
F000:0281 add al, 1 ; all imr bits on? (add should produce 0) | |
F000:0283 jnz short gerror ; no - go to error routine | |
F000:0285 ;---------------------------------------------------- | |
F000:0285 ; check for hot interrupts | |
F000:0285 ;---------------------------------------------------- | |
F000:0285 sti | |
F000:0286 mov cx, 50h ; 'P' | |
F000:0289 hot1: ; CODE XREF: F000:hot1j | |
F000:0289 loop hot1 | |
F000:028B mov bl, ds:484h ; 0:484 == 40:84 == intr_flag. did any interrupts occur? | |
F000:028F or bl, bl | |
F000:0291 jz short end_testg | |
F000:0293 gerror: ; CODE XREF: F000:0279j | |
F000:0293 ; F000:0283j | |
F000:0293 mov bh, 7 | |
F000:0295 jmp e_msg | |
F000:0298 ; fire the diskette watchdog timer | |
F000:0298 end_testg: ; CODE XREF: F000:0291j | |
F000:0298 mov al, 0E0h ; 'à' | |
F000:029A out 0F2h, al | |
F000:029C mov al, 0A0h ; ' ' | |
F000:029E out 0F2h, al | |
F000:02A0 ;----- initialize timer 1 and timer 0 for test | |
F000:02A0 call mfg_up ; mfg ckpoint=f6 | |
F000:02A3 mov ax, 176h ; set timer 1 to mode 3 binary | |
F000:02A6 mov bx, 0FFFFh ; initial count of ffff | |
F000:02A9 call init_timer ; initialize timer 1 | |
F000:02AC mov ax, 110110b ; set timer 0 to mode 3 binary | |
F000:02AF call init_timer ; initialize timer 0 | |
F000:02B2 ;---------------------------------------------------- | |
F000:02B2 ; set bit 5 of port a0 so timer 1 clock will be pulsed by the | |
F000:02B2 ; timer 0 output rather than the system clock | |
F000:02B2 ;---------------------------------------------------- | |
F000:02B2 mov al, 100000b ; (timer 0 output used as clk input for timer 1) | |
F000:02B4 out 0A0h, al | |
F000:02B6 ;---------------------------------------------------- | |
F000:02B6 ; check if all bits go on an off in timer 0 (check for stuck | |
F000:02B6 ; bits) | |
F000:02B6 ;---------------------------------------------------- | |
F000:02B6 mov ah, 0 ; timer 0 | |
F000:02B8 call bits_on_off ; let subroutine check it | |
F000:02BB jnb short timer1_nz ; no stuck bits (carry flag not set) | |
F000:02BD mov bl, 0 ; stuck bits in timer 0 | |
F000:02BF jmp timer_error | |
F000:02C2 ;---------------------------------------------------- | |
F000:02C2 ; since timer 0 has completed at least one complete cycle, | |
F000:02C2 ; timer 1 should be non-zero. check that this is the case. | |
F000:02C2 ;---------------------------------------------------- | |
F000:02C2 timer1_nz: ; CODE XREF: F000:02BBj | |
F000:02C2 in al, 41h ; read lsb of timer 1 | |
F000:02C4 mov ah, al ; save lsb | |
F000:02C6 in al, 41h ; read msb of timer 1 | |
F000:02C8 cmp ax, 0FFFFh ; still ffff? | |
F000:02CB jnz short timer0_intr ; no - timer 1 has been bumped | |
F000:02CD mov bl, 1 ; timer 1 was not bumped by timer 0 | |
F000:02CF jmp timer_error | |
F000:02D2 ;---------------------------------------------------- | |
F000:02D2 ; check for timer 0 interrupt | |
F000:02D2 ;---------------------------------------------------- | |
F000:02D2 timer0_intr: ; CODE XREF: F000:02CBj | |
F000:02D2 sti ; enable maskable ext interrupts | |
F000:02D3 in al, 21h | |
F000:02D5 and al, 0FEh ; mask all intrs except lvl 0 | |
F000:02D7 and ds:484h, al ; clear int received | |
F000:02DB out 21h, al ; write the 8259 imr | |
F000:02DD mov cx, 0FFFFh ; set loop count | |
F000:02E0 wait_intr_loop: ; CODE XREF: F000:02E7j | |
F000:02E0 test byte ptr ds:484h, 1 ; timer 0 int occur? | |
F000:02E5 jnz short reset_intrs ; yes - continue | |
F000:02E7 loop wait_intr_loop ; wait for interrupt for specified time | |
F000:02E9 mov bl, 2 ; timer 0 intr didn't occur | |
F000:02EB jmp short timer_error | |
F000:02ED ;---------------------------------------------------- | |
F000:02ED ; housekeeping for timer 0 interrupts | |
F000:02ED ;---------------------------------------------------- | |
F000:02ED reset_intrs: ; CODE XREF: F000:02E5j | |
F000:02ED cli | |
F000:02EE ; set timer int. to point to mfg. heartbeat routine if in mfg mode | |
F000:02EE mov dx, 201h | |
F000:02F1 in al, dx ; get mfg. bits | |
F000:02F2 and al, 0F0h | |
F000:02F4 cmp al, 10000b ; sys test mode? | |
F000:02F6 jz short d6 | |
F000:02F8 or al, al ; or burn-in mode | |
F000:02FA jnz short time_1 | |
F000:02FC d6: ; CODE XREF: F000:02F6j | |
F000:02FC mov word ptr ds:20h, offset mfg_tick ; set to point to mfg. (int 0x08) | |
F000:0302 mov word ptr ds:70h, offset mfg_tick ; also set user timer int for diags. use (int 0x1c) | |
F000:0308 mov al, 0FEh ; 'þ' | |
F000:030A out 21h, al ; (enable lvl 0 interrupt) | |
F000:030C sti | |
F000:030D ;---------------------------------------------------- | |
F000:030D ; reset d5 of port a0 so that the timer 1 clock will be | |
F000:030D ; pulsed by the system clock | |
F000:030D ;---------------------------------------------------- | |
F000:030D time_1: ; CODE XREF: F000:02FAj | |
F000:030D mov al, 0 ; make al = 0 | |
F000:030F out 0A0h, al | |
F000:0311 ;---------------------------------------------------- | |
F000:0311 ; check for stuck bits in timer 1 | |
F000:0311 ;---------------------------------------------------- | |
F000:0311 mov ah, 1 ; timer 1 | |
F000:0313 call bits_on_off | |
F000:0316 jnb short timer2_init ; no stuck bits | |
F000:0318 mov bl, 3 ; stuck bits in timer 1 | |
F000:031A jmp short timer_error | |
F000:031C ;---------------------------------------------------- | |
F000:031C ; initialize timer 2 | |
F000:031C ;---------------------------------------------------- | |
F000:031C timer2_init: ; CODE XREF: F000:0316j | |
F000:031C mov ax, 2B6h ; set timer 2 to mode 3 binary | |
F000:031F mov bx, 0FFFFh ; initial count | |
F000:0322 call init_timer | |
F000:0325 ;---------------------------------------------------- | |
F000:0325 ; set pb0 of port_b of 8255 (timer 2 gate) | |
F000:0325 ;---------------------------------------------------- | |
F000:0325 in al, 61h ; current status | |
F000:0327 or al, 1 ; set bit 0, others alone | |
F000:0329 out 61h, al | |
F000:032B mov ah, 2 | |
F000:032D call bits_on_off | |
F000:0330 jnb short reinit_t2 | |
F000:0332 mov bl, 5 | |
F000:0334 jmp short timer_error | |
F000:0336 reinit_t2: ; CODE XREF: F000:0330j | |
F000:0336 in al, 61h | |
F000:0338 and al, 0FEh | |
F000:033A out 61h, al | |
F000:033C mov ax, 2B0h | |
F000:033F mov bx, 0Ah | |
F000:0342 call init_timer | |
F000:0345 in al, 62h | |
F000:0347 and al, 20h | |
F000:0349 jz short ck2_on | |
F000:034B mov bl, 4 | |
F000:034D jmp short timer_error | |
F000:034F ck2_on: ; CODE XREF: F000:0349j | |
F000:034F in al, 61h | |
F000:0351 or al, 1 | |
F000:0353 out 61h, al | |
F000:0355 mov cx, 0Ah | |
F000:0358 ck2_lo: ; CODE XREF: F000:ck2_loj | |
F000:0358 loop ck2_lo | |
F000:035A in al, 62h | |
F000:035C and al, 20h | |
F000:035E jnz short pod_13_end | |
F000:0360 mov bl, 6 | |
F000:0362 timer_error: ; CODE XREF: F000:02BFj | |
F000:0362 ; F000:02CFj F000:02EBj | |
F000:0362 ; F000:031Aj F000:0334j | |
F000:0362 ; F000:034Dj | |
F000:0362 mov bh, 8 ; timer error indicator | |
F000:0364 call e_msg | |
F000:0367 jmp short pod_13_end | |
F000:0369 latches db 0 ; DATA XREF: bits_on_off+9o | |
F000:0369 ; latch mask for timer 0 | |
F000:036A db 40h ; @ ; latch mask for timer 1 | |
F000:036B db 80h ; ; latch mask for timer 2 | |
F000:036C ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:036C bits_on_off proc near ; CODE XREF: F000:02B8p | |
F000:036C ; F000:0313p F000:032Dp | |
F000:036C xor bx, bx | |
F000:036E xor si, si | |
F000:0370 mov dx, 40h ; '@' | |
F000:0373 add dl, ah | |
F000:0375 mov di, offset latches | |
F000:0378 xor al, al | |
F000:037A xchg al, ah | |
F000:037C add di, ax | |
F000:037E outer_loop: ; CODE XREF: bits_on_off+47j | |
F000:037E mov cx, 8 | |
F000:0381 inner_loop: ; CODE XREF: bits_on_off+3Ej | |
F000:0381 push cx | |
F000:0382 mov cx, 0FFFFh | |
F000:0385 tst_bits: ; CODE XREF: bits_on_off+3Bj | |
F000:0385 mov al, cs:[di] ; timer latch mask index | |
F000:0388 out 43h, al ; latch timer | |
F000:038A push ax ; pause | |
F000:038B pop ax | |
F000:038C in al, dx ; read timer lsb | |
F000:038D or si, si | |
F000:038F jnz short second ; second pass | |
F000:0391 or al, 1 | |
F000:0393 or bl, al | |
F000:0395 in al, dx | |
F000:0396 or bh, al | |
F000:0398 cmp bx, 0FFFFh | |
F000:039C jmp short tst_cmp | |
F000:039E second: ; CODE XREF: bits_on_off+23j | |
F000:039E and bl, al | |
F000:03A0 in al, dx | |
F000:03A1 and bh, al | |
F000:03A3 or bx, bx | |
F000:03A5 tst_cmp: ; CODE XREF: bits_on_off+30j | |
F000:03A5 jz short chk_end | |
F000:03A7 loop tst_bits | |
F000:03A9 pop cx | |
F000:03AA loop inner_loop | |
F000:03AC stc | |
F000:03AD retn | |
F000:03AE chk_end: ; CODE XREF: bits_on_off:tst_cmpj | |
F000:03AE pop cx | |
F000:03AF inc si | |
F000:03B0 cmp si, 2 | |
F000:03B3 jnz short outer_loop | |
F000:03B5 clc | |
F000:03B6 retn | |
F000:03B6 bits_on_off endp | |
F000:03B7 ;---------------------------------------------------- | |
F000:03B7 ; crt attachment test | |
F000:03B7 ; 1. init crt to 40x25 - bw | |
F000:03B7 ; 2. check for vertical and video enables, and check | |
F000:03B7 ; timing of same | |
F000:03B7 ; 3. check vertical interrupt | |
F000:03B7 ; 4. check red, green, blue and intensify dots | |
F000:03B7 ; 5. init to 40x25 - color | |
F000:03B7 ; mfg. error code 09xx (xx-see comments in code) | |
F000:03B7 ;---------------------------------------------------- | |
F000:03B7 pod_13_end: ; CODE XREF: F000:035Ej | |
F000:03B7 ; F000:0367j | |
F000:03B7 call mfg_up ; mfg checkpoint=f5 | |
F000:03BA cli | |
F000:03BB mov al, 1110000b ; set timer 1 to mode 0 | |
F000:03BB ; (tim 1, lsb/msb, interrupt on terminal count, binary) | |
F000:03BD out 43h, al | |
F000:03BF mov cx, 8000h | |
F000:03C2 q1: ; CODE XREF: F000:q1j | |
F000:03C2 loop q1 ; wait for mode set to "take" | |
F000:03C4 mov al, 0 | |
F000:03C6 out 41h, al ; send first byte to timer | |
F000:03C8 sub ax, ax ; set mode 40x25 bw | |
F000:03CA int 10h | |
F000:03CC mov ax, 507h ; set video page 7 | |
F000:03CF int 10h | |
F000:03D1 mov dx, 3DAh ; set addressing to video array | |
F000:03D4 sub cx, cx | |
F000:03D6 ; look for vertical | |
F000:03D6 q2: ; CODE XREF: F000:03DBj | |
F000:03D6 in al, dx ; get status | |
F000:03D7 test al, 8 ; vertical there yet? | |
F000:03D9 jnz short q3 ; continue if it is | |
F000:03DB loop q2 | |
F000:03DD mov bl, 0 | |
F000:03DF jmp short q115 ; no vertical = error 0900 | |
F000:03E1 ; got vertical - start timer | |
F000:03E1 q3: ; CODE XREF: F000:03D9j | |
F000:03E1 xor al, al | |
F000:03E3 out 41h, al ; send 2nd byte to timer to start | |
F000:03E5 sub bx, bx ; init. enable counter | |
F000:03E7 ; wait for vertical to go away | |
F000:03E7 xor cx, cx | |
F000:03E9 q4: ; CODE XREF: F000:03EEj | |
F000:03E9 in al, dx ; get status | |
F000:03EA test al, 8 ; vertical still there? | |
F000:03EC jz short q5 ; continue if it's gone | |
F000:03EE loop q4 | |
F000:03F0 mov bl, 1 ; vertical stuck on = error 0901 | |
F000:03F2 jmp short q115 | |
F000:03F4 ; now start looking for enable transitions | |
F000:03F4 q5: ; CODE XREF: F000:03ECj | |
F000:03F4 ; F000:041Fj | |
F000:03F4 sub cx, cx | |
F000:03F6 q6: ; CODE XREF: F000:03FFj | |
F000:03F6 in al, dx ; get status | |
F000:03F7 test al, 1 ; enable on yet? | |
F000:03F9 jnz short q7 ; go on if it is | |
F000:03FB test al, 8 ; vertical on again? | |
F000:03FD jnz short q11 ; continue if it is | |
F000:03FF loop q6 ; keep looking if not | |
F000:0401 mov bl, 2 | |
F000:0403 jmp short q115 ; enable stuck off = error 0902 | |
F000:0405 ; make sure vertical went off with enable going on | |
F000:0405 q7: ; CODE XREF: F000:03F9j | |
F000:0405 test al, 8 ; vertical off? | |
F000:0407 jz short q8 ; go on if it is | |
F000:0409 mov bl, 3 | |
F000:040B jmp short q115 ; vertical stuck on = error 0903 | |
F000:040D ; now wait for enable go to off | |
F000:040D q8: ; CODE XREF: F000:0407j | |
F000:040D sub cx, cx | |
F000:040F q9: ; CODE XREF: F000:0414j | |
F000:040F in al, dx ; get status | |
F000:0410 test al, 1 ; enable off yet? | |
F000:0412 jz short q10 ; proceed if it is | |
F000:0414 loop q9 ; keep looking if not yet low | |
F000:0416 mov bl, 4 | |
F000:0418 jmp short q115 | |
F000:041A ; enable has toggled , bump counter and test for next vertical | |
F000:041A q10: ; CODE XREF: F000:0412j | |
F000:041A inc bx ; bump enable counter | |
F000:041B jz short q11 ; if counter wraps, error | |
F000:041D test al, 8 ; did enable go low because of vertical? | |
F000:041F jz short q5 ; if not, look for another enable toggle | |
F000:0421 ; have had complete vertical-vertical cycle, now test results | |
F000:0421 q11: ; CODE XREF: F000:03FDj | |
F000:0421 ; F000:041Bj | |
F000:0421 mov al, 1000000b ; latch timer1 | |
F000:0421 ; (tim 1, latching, interrupt on terminal count, binary) | |
F000:0423 out 43h, al | |
F000:0425 cmp bx, 200 ; number of enables between verticals o.k.? | |
F000:0429 jz short q12 | |
F000:042B mov bl, 5 | |
F000:042D q115: ; CODE XREF: F000:03DFj | |
F000:042D ; F000:03F2j F000:0403j | |
F000:042D ; F000:040Bj F000:0418j | |
F000:042D jmp short q22 ; wrong # enables = error 0905 | |
F000:042F q12: ; CODE XREF: F000:0429j | |
F000:042F in al, 41h ; get timer value low | |
F000:0431 mov ah, al ; save it | |
F000:0433 nop | |
F000:0434 in al, 41h ; get timer high | |
F000:0436 xchg ah, al | |
F000:0438 sti ; interrupts back on | |
F000:0439 nop | |
F000:043A cmp ax, 0A0ACh ; (0xb286 * 0.9) | |
F000:043A ; there are 0x4dc8 PIT cycles per screen (262*76) | |
F000:043A ; and 0x10000-0xb286 = 0x4d7a... a few PIT cycles short... but good enough | |
F000:043D jge short q13 | |
F000:043F mov bl, 6 | |
F000:0441 jmp short q22 ; verticals too far appart | |
F000:0441 ; = error 0906 | |
F000:0443 q13: ; CODE XREF: F000:043Dj | |
F000:0443 cmp ax, 0C460h ; (0xb286 * 1.1) | |
F000:0446 jle short q14 | |
F000:0448 mov bl, 7 | |
F000:044A jmp short q22 ; verticals too close together | |
F000:044A ; = error 0907 | |
F000:044C ; timings seem o.k., now check vertical interrupt (level 5) | |
F000:044C q14: ; CODE XREF: F000:0446j | |
F000:044C sub cx, cx ; set timeout reg | |
F000:044E in al, 21h | |
F000:0450 and al, 11011111b ; unmask int. level 5 | |
F000:0452 out 21h, al | |
F000:0454 and ds:484h, al ; intr flag | |
F000:0458 sti ; enable ints | |
F000:0459 q15: ; CODE XREF: F000:0460j | |
F000:0459 test byte ptr ds:484h, 20h ; see if intr. 5 happened yet | |
F000:045E jnz short q16 ; go on if it did | |
F000:0460 loop q15 ; keep looking if it didn't | |
F000:0462 mov bl, 8 | |
F000:0464 jmp short q22 ; no vertical interrupt = error 0908 | |
F000:0466 q16: ; CODE XREF: F000:045Ej | |
F000:0466 in al, 21h ; disable interrupts for level 5 | |
F000:0468 or al, 20h | |
F000:046A out 21h, al | |
F000:046C ; see if red, green, blue and intesify dots work | |
F000:046C ; first, set a line of reverse video, intensified blanksinto video | |
F000:046C ; buffer | |
F000:046C mov ax, 9DBh ; write chars, blocks | |
F000:046F mov bx, 77Fh ; page 7, reverse video, high intensity | |
F000:0472 mov cx, 40 ; 40 characters | |
F000:0475 int 10h | |
F000:0477 xor ax, ax ; start with blue dots | |
F000:0479 q17: ; CODE XREF: F000:04A1j | |
F000:0479 sub cx, cx | |
F000:047B out dx, al ; set video array address for dots | |
F000:047C ; see if dot comes on | |
F000:047C q18: ; CODE XREF: F000:0481j | |
F000:047C in al, dx ; get status | |
F000:047D test al, 10h ; dot there? | |
F000:047F jnz short q19 ; go look for dot to turn off | |
F000:0481 loop q18 ; continue testing for dot on | |
F000:0483 mov bl, 10h | |
F000:0485 or bl, ah ; or in dot being tested | |
F000:0487 jmp short q22 ; dot not coming on = error 091x | |
F000:0487 ; ( x=0, blue; x=1, green; | |
F000:0487 ; x=2, red;, x=3, intensity) | |
F000:0489 ; see if dot comes off | |
F000:0489 q19: ; CODE XREF: F000:047Fj | |
F000:0489 sub cx, cx | |
F000:048B q20: ; CODE XREF: F000:0490j | |
F000:048B in al, dx ; get status | |
F000:048C test al, 10h ; is dot still on? | |
F000:048E jz short q21 ; go on if dot off | |
F000:0490 loop q20 ; else, keep waiting for dot to go off | |
F000:0492 mov bl, 20h ; ' ' | |
F000:0494 or bl, ah ; or in dot being tested | |
F000:0496 jmp short q22 ; dot stuck on = error 092x | |
F000:0496 ; ( x=0, blue; x=1, green; | |
F000:0496 ; x=2, red; x=3 intensity) | |
F000:0498 ; adjust to point to next dot | |
F000:0498 q21: ; CODE XREF: F000:048Ej | |
F000:0498 inc ah | |
F000:049A cmp ah, 4 ; all for dots gone? | |
F000:049D jz short q23 ; go end | |
F000:049F mov al, ah | |
F000:04A1 jmp short q17 ; go look for another dot | |
F000:04A3 q22: ; CODE XREF: F000:q115j | |
F000:04A3 ; F000:0441j F000:044Aj | |
F000:04A3 ; F000:0464j F000:0487j | |
F000:04A3 ; F000:0496j | |
F000:04A3 mov bh, 9 ; set msb of error code | |
F000:04A5 jmp e_msg | |
F000:04A8 ; done with test reset to 40x25 - color | |
F000:04A8 q23: ; CODE XREF: F000:049Dj | |
F000:04A8 call dss | |
F000:04AB mov ax, 1 ; init to 40x25 - color | |
F000:04AE int 10h | |
F000:04B0 mov ax, 507h ; set video page 7 | |
F000:04B3 int 10h | |
F000:04B5 cmp word ptr ds:seg40.reset_flag, 1234h ; warm start? | |
F000:04BB jz short q24 ; bypass putting up power-on screen | |
F000:04BD call put_logo ; put logo on screen | |
F000:04C0 q24: ; CODE XREF: F000:04BBj | |
F000:04C0 mov al, 1110110b ; re-init timer 1 | |
F000:04C0 ; (tim 1, read/load lsb/msb, square, binary) | |
F000:04C2 out 43h, al | |
F000:04C4 mov al, 0 | |
F000:04C6 out 41h, al | |
F000:04C8 nop | |
F000:04C9 nop | |
F000:04CA out 41h, al | |
F000:04CC call mfg_up ; mfg checkpoint=f4 | |
F000:04CF xor ax, ax | |
F000:04D1 mov ds, ax | |
F000:04D3 mov word ptr ds:8, offset kdbnmi ; set interrupt vector (int 0x2) | |
F000:04D9 mov word ptr ds:120h, offset key_scan_save ; set vector for pod int handler (int 0x48) | |
F000:04DF loc_F04DF: | |
F000:04DF push cs | |
F000:04E0 loc_F04E0: | |
F000:04E0 pop ax | |
F000:04E1 loc_F04E1: ; (int 0x48 segment) | |
F000:04E1 mov ds:122h, ax | |
F000:04E4 loc_F04E4: ; set data segment | |
F000:04E4 call dss | |
F000:04E7 mov si, 1Eh | |
F000:04EA mov ds:seg40.buffer_head, si | |
F000:04EE mov ds:seg40.buffer_tail, si | |
F000:04F2 mov ds:seg40.buffer_start, si | |
F000:04F6 add si, 32 ; set default buffer of 32 bytes | |
F000:04F9 mov ds:seg40.buffer_end, si | |
F000:04FD in al, 0A0h ; clear nmi f/f | |
F000:04FF mov al, 10000000b ; enable nmi | |
F000:0501 out 0A0h, al | |
F000:0503 call mfg_up ; mfg checkpoint=f3 | |
F000:0506 mov bx, 64 ; start with base 64k | |
F000:0509 in al, 62h ; get config byte | |
F000:050B test al, 8 ; see if 64k card installed | |
F000:050D jnz short q25 | |
F000:050F add bx, 64 ; add 64k | |
F000:0512 q25: ; CODE XREF: F000:050Dj | |
F000:0512 push bx ; save k count | |
F000:0513 sub bx, 16 ; substract 16k crt refresh space | |
F000:0516 mov ds:seg40.memory_size, bx ; load "contiguous memory" word | |
F000:051A pop bx | |
F000:051B mov dx, 2000h ; set pointer to just about 128k | |
F000:051E sub di, di ; set di to point to beginning | |
F000:0520 mov cx, 0AA55h ; load data pattern | |
F000:0523 q26: ; CODE XREF: F000:053Bj | |
F000:0523 mov es, dx ; set segment to point to memory space | |
F000:0525 mov es:[di], cx ; set data pattern to memory | |
F000:0528 mov al, 0Fh | |
F000:052A mov ax, es:[di] | |
F000:052D xor ax, cx ; see if data made it back | |
F000:052F jnz short q27 ; no? then end of mem has been reached | |
F000:0531 add dx, 1000h ; point to beginning of next 64k | |
F000:0535 add bx, 40h ; '@' ; adjust total mem counter | |
F000:0538 cmp dh, 0A0h ; ' ' ; past 640 yet? | |
F000:053B jnz short q26 ; check for another block if not | |
F000:053D q27: ; CODE XREF: F000:052Fj | |
F000:053D mov ds:seg40.true_mem, bx ; load "total memory" word | |
F000:0541 ; size has been determined, now test or clear all of memory | |
F000:0541 mov ax, 4 ; 4 kb known ok at this point | |
F000:0544 call q35 | |
F000:0547 mov dx, 80h ; '' ; set pointer to just about lower 2k | |
F000:054A mov cx, 7800h ; test 30k words (60k) | |
F000:054D q28: ; CODE XREF: F000:0595j | |
F000:054D mov es, dx | |
F000:054F push cx | |
F000:0550 push bx | |
F000:0551 push ax | |
F000:0552 call podstg ; test of fill mem | |
F000:0555 jz short q29 | |
F000:0557 jmp q39 ; jump if error | |
F000:055A q29: ; CODE XREF: F000:0555j | |
F000:055A pop ax | |
F000:055B pop bx | |
F000:055C pop cx ; recover | |
F000:055D cmp ch, 78h ; 'x' ; was this a 60k pass | |
F000:0560 pushf | |
F000:0561 add ax, 3Ch ; '<' ; bump good storage by 60k | |
F000:0564 popf | |
F000:0565 jz short q30 | |
F000:0567 add ax, 2 ; add 2 for a 62k pass | |
F000:056A q30: ; CODE XREF: F000:0565j | |
F000:056A call q35 | |
F000:056D cmp ax, bx ; are we done yet? | |
F000:056F jnz short q31 | |
F000:0571 jmp q43 ; all done, if so | |
F000:0574 q31: ; CODE XREF: F000:056Fj | |
F000:0574 cmp ax, 128 ; done with 1st 128k? | |
F000:0577 jz short q32 ; go finish rest of mem. | |
F000:0579 mov dx, 0F80h ; set pointer to finish 1st 64 kb | |
F000:057C mov cx, 400h | |
F000:057F mov es, dx | |
F000:0581 push ax | |
F000:0582 push bx | |
F000:0583 push dx | |
F000:0584 call podstg ; go test/fill | |
F000:0587 jnz short q39 | |
F000:0589 pop dx | |
F000:058A pop bx | |
F000:058B pop ax | |
F000:058C add ax, 2 ; update good count | |
F000:058F mov dx, 1000h ; set pointer to 2nd 64k block | |
F000:0592 mov cx, 7C00h ; 62k worth | |
F000:0595 jmp short q28 | |
F000:0597 q32: ; CODE XREF: F000:0577j | |
F000:0597 mov dx, 2000h ; point to block about 128k | |
F000:059A q33: ; CODE XREF: F000:05BAj | |
F000:059A cmp bx, ax ; compare good mem to total mem | |
F000:059C jnz short q34 | |
F000:059E jmp q43 ; exit if all done | |
F000:05A1 q34: ; CODE XREF: F000:059Cj | |
F000:05A1 mov cx, 4000h ; set for 32kb block | |
F000:05A4 mov es, dx | |
F000:05A6 push ax | |
F000:05A7 push bx | |
F000:05A8 push dx | |
F000:05A9 call podstg ; go test/fill | |
F000:05AC jnz short q39 | |
F000:05AE pop dx | |
F000:05AF pop bx | |
F000:05B0 pop ax | |
F000:05B1 add ax, 32 ; bump good memory count | |
F000:05B4 call q35 ; display current good mem | |
F000:05B7 add dh, 8 ; set pointer to next 32k | |
F000:05BA jmp short q33 ; and make another pass | |
F000:05BC ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:05BC ; subroutine for printing tested | |
F000:05BC ; memory ok msg on the crt | |
F000:05BC ; call params: ax = x of good memory | |
F000:05BC ; (in hex) | |
F000:05BC q35 proc near ; CODE XREF: F000:0544p | |
F000:05BC ; F000:q30p F000:05B4p | |
F000:05BC call dss | |
F000:05BF cmp word ptr ds:seg40.reset_flag, 1234h | |
F000:05C5 jz short q35e | |
F000:05C7 push bx | |
F000:05C8 push cx | |
F000:05C9 push dx | |
F000:05CA push ax | |
F000:05CB mov ah, 2 | |
F000:05CD mov dx, 1421h ; row 20 (row 20, col. 33) | |
F000:05D0 mov bh, 7 | |
F000:05D2 int 10h ; - VIDEO - SET CURSOR POSITION | |
F000:05D2 ; DH,DL = row, column (0,0 = upper left) | |
F000:05D2 ; BH = page number | |
F000:05D4 pop ax | |
F000:05D5 push ax | |
F000:05D6 mov bx, 0Ah | |
F000:05D9 mov cx, 3 | |
F000:05DC q36: ; CODE XREF: q35+28j | |
F000:05DC xor dx, dx | |
F000:05DE div bx | |
F000:05E0 or dl, 30h | |
F000:05E3 push dx | |
F000:05E4 loop q36 | |
F000:05E6 mov cx, 3 | |
F000:05E9 q37: ; CODE XREF: q35+31j | |
F000:05E9 pop ax | |
F000:05EA call prt_hex | |
F000:05ED loop q37 | |
F000:05EF mov cx, 3 | |
F000:05F2 mov si, offset f3b ; print " kb" | |
F000:05F5 q38: ; CODE XREF: q35+40j | |
F000:05F5 mov al, cs:[si] | |
F000:05F8 inc si | |
F000:05F9 call prt_hex | |
F000:05FC loop q38 | |
F000:05FE pop ax | |
F000:05FF pop dx | |
F000:0600 pop cx | |
F000:0601 pop bx | |
F000:0602 q35e: ; CODE XREF: q35+9j | |
F000:0602 retn | |
F000:0602 q35 endp | |
F000:0603 q39: ; CODE XREF: F000:0557j | |
F000:0603 ; F000:0587j F000:05ACj | |
F000:0603 pop dx | |
F000:0604 cmp dx, 2000h | |
F000:0608 jl short q40 | |
F000:060A mov bl, cl | |
F000:060C or bl, ch | |
F000:060E mov cl, 4 | |
F000:0610 shr dh, cl | |
F000:0612 mov bh, 10h | |
F000:0614 or bh, dh | |
F000:0616 jmp short q42 | |
F000:0618 q40: ; CODE XREF: F000:0608j | |
F000:0618 mov bh, 0Ah | |
F000:061A in al, 62h | |
F000:061C and al, 8 | |
F000:061E jz short q41 | |
F000:0620 mov bl, cl | |
F000:0622 or bl, ch | |
F000:0624 jmp short q42 | |
F000:0626 q41: ; CODE XREF: F000:061Ej | |
F000:0626 cmp ah, 2 | |
F000:0629 mov bl, cl | |
F000:062B jz short q42 | |
F000:062D inc bh | |
F000:062F or bl, ch | |
F000:0631 cmp ah, 1 | |
F000:0634 jz short q42 | |
F000:0636 inc bh | |
F000:0638 q42: ; CODE XREF: F000:0616j | |
F000:0638 ; F000:0624j F000:062Bj | |
F000:0638 ; F000:0634j | |
F000:0638 mov si, 35h ; '5' | |
F000:063B call e_msg | |
F000:063E cli | |
F000:063F hlt | |
F000:0640 ; keyboard test | |
F000:0640 q43: ; CODE XREF: F000:0571j | |
F000:0640 ; F000:059Ej | |
F000:0640 call mfg_up ; mfg code=f2 | |
F000:0643 call dss | |
F000:0646 mov bx, 1Eh | |
F000:0649 mov al, [bx] | |
F000:064B or al, al | |
F000:064D jz short f6_y | |
F000:064F mov bh, 22h ; '"' | |
F000:0651 mov bl, al | |
F000:0653 jmp short f6 | |
F000:0655 f6_y: ; CODE XREF: F000:064Dj | |
F000:0655 cmp byte ptr ds:seg40.kdb_error, 0 | |
F000:065A jz short f7 | |
F000:065C mov bx, 2000h | |
F000:065F f6: ; CODE XREF: F000:0653j | |
F000:065F ; F000:06FCj | |
F000:065F mov si, 36h ; '6' | |
F000:0662 cmp word ptr ds:seg40.reset_flag, 4321h ; warm start to diags | |
F000:0668 jz short f6_z ; do not put up message | |
F000:066A cmp word ptr ds:seg40.reset_flag, 1234h ; warm system start | |
F000:0670 jz short f6_z ; do not put up message | |
F000:0672 call e_msg ; pritn msg on screen | |
F000:0675 f6_z: ; CODE XREF: F000:0668j | |
F000:0675 ; F000:0670j | |
F000:0675 jmp f6_x | |
F000:0678 ;check link card, if present | |
F000:0678 f7: ; CODE XREF: F000:065Aj | |
F000:0678 mov dx, 201h | |
F000:067B in al, dx ; check for burn-in mode | |
F000:067C and al, 0F0h | |
F000:067E jz short f6_x ; bypass check in burn-in mode | |
F000:0680 in al, 62h ; get config port data | |
F000:0682 and al, 10000000b ; keyboard cable attached? | |
F000:0684 jz short f6_x ; bypass test if it is | |
F000:0686 in al, 61h | |
F000:0688 and al, 11111100b ; drop speaker data | |
F000:068A out 61h, al | |
F000:068C mov al, 10110110b ; mode set timer 2 | |
F000:068C ; (tim 2, read/load lsb/msb, square, binary) | |
F000:068E out 43h, al | |
F000:0690 mov al, 1000000b ; disable nmi | |
F000:0692 out 0A0h, al | |
F000:0694 mov al, 32 ; lsb to timer 2 (approx. 40khz vaue) | |
F000:0696 mov dx, 42h ; 'B' | |
F000:0699 out dx, al | |
F000:069A sub ax, ax | |
F000:069C mov cx, ax | |
F000:069E out dx, al ; msb to timer 2 (start timer) | |
F000:069F in al, 61h | |
F000:06A1 or al, 1 | |
F000:06A3 out 61h, al ; enable timer 2 | |
F000:06A5 f7_0: ; CODE XREF: F000:06ABj | |
F000:06A5 in al, 62h ; see if keyboard data active | |
F000:06A7 and al, 40h ; '@' | |
F000:06A9 jnz short f7_1 ; exit loop if data showed up | |
F000:06AB loop f7_0 | |
F000:06AD mov bl, 2 ; set no keyboard data error | |
F000:06AF jmp short f6_1 | |
F000:06B1 f7_1: ; CODE XREF: F000:06A9j | |
F000:06B1 push es ; save es | |
F000:06B2 sub ax, ax ; set up segment reg | |
F000:06B4 mov es, ax ; * | |
F000:06B6 mov word ptr es:8, offset d11 ; set up new nmi vector | |
F000:06BD mov ds:seg40.intr_flag, al ; reset intr. flag | |
F000:06C0 in al, 61h ; disable internal beeper to | |
F000:06C2 or al, 30h ; prevent error beep | |
F000:06C4 out 61h, al | |
F000:06C6 mov al, 11000000b | |
F000:06C8 out 0A0h, al ; enable nmi | |
F000:06CA mov cx, 100h | |
F000:06CD f6_0: ; CODE XREF: F000:f6_0j | |
F000:06CD loop f6_0 ; wait a bit | |
F000:06CF in al, 61h ; re-enable beeper | |
F000:06D1 and al, 0CFh | |
F000:06D3 out 61h, al | |
F000:06D5 mov al, ds:seg40.intr_flag ; get intr. flag | |
F000:06D8 or al, al ; will be non-zero if nmi happened | |
F000:06DA mov bl, 3 ; set possible error code | |
F000:06DC mov word ptr es:8, offset kdbnmi ; reset nmi vector | |
F000:06E3 pop es | |
F000:06E4 jz short f6_1 | |
F000:06E6 mov al, 0 ; disable feedback ckt | |
F000:06E8 out 0A0h, al | |
F000:06EA in al, 61h | |
F000:06EC and al, 0FEh ; drop gate to timer 2 | |
F000:06EE out 61h, al | |
F000:06F0 f6_2: ; CODE XREF: F000:06F6j | |
F000:06F0 in al, 62h ; see if keyboard data active | |
F000:06F2 and al, 40h | |
F000:06F4 jz short f6_x ; exit loop if data went low | |
F000:06F6 loop f6_2 | |
F000:06F8 mov bl, 1 | |
F000:06FA f6_1: ; CODE XREF: F000:06AFj | |
F000:06FA ; F000:06E4j | |
F000:06FA mov bh, 21h ; '!' | |
F000:06FC jmp f6 | |
F000:06FF f6_x: ; CODE XREF: F000:f6_zj | |
F000:06FF ; F000:067Ej F000:0684j | |
F000:06FF ; F000:06F4j | |
F000:06FF mov al, 0 ; disable feedback ckt | |
F000:0701 out 0A0h, al | |
F000:0703 ; cassette interface test | |
F000:0703 call mfg_up | |
F000:0706 in al, 61h | |
F000:0708 or al, 9 | |
F000:070A out 61h, al | |
F000:070C ;----- write a bit | |
F000:070C in al, 21h | |
F000:070E or al, 1 ; disable timer interrupts | |
F000:0710 out 21h, al | |
F000:0712 mov al, 10110110b ; sel tim 2, lsb, msb, md 3 | |
F000:0712 ; (tim 2, read/load lsb/msb, square, binary) | |
F000:0714 out 43h, al | |
F000:0716 mov ax, 4D2h | |
F000:0719 out 42h, al | |
F000:071B mov al, ah | |
F000:071D out 42h, al | |
F000:071F sub cx, cx | |
F000:0721 l0: ; CODE XREF: F000:l0j | |
F000:0721 loop l0 | |
F000:0723 ;----- read cassette input | |
F000:0723 in al, 62h | |
F000:0725 and al, 10h | |
F000:0727 mov ds:6Bh, al | |
F000:072A call read_half_bit | |
F000:072D call read_half_bit | |
F000:0730 jcxz short f8 | |
F000:0732 push bx | |
F000:0733 call read_half_bit | |
F000:0736 pop ax | |
F000:0737 jcxz short f8 | |
F000:0739 add ax, bx | |
F000:073B cmp ax, 0A9Ah | |
F000:073E jnb short f8 | |
F000:0740 cmp ax, 8ADh | |
F000:0743 jb short f8 | |
F000:0745 mov dx, 201h | |
F000:0748 in al, dx | |
F000:0749 and al, 0F0h ; determine mode | |
F000:074B cmp al, 10h ; mfg? | |
F000:074D jz short f9 | |
F000:074F cmp al, 1000000b ; service? | |
F000:0751 jnz short t13_end ; go to next test if not | |
F000:0753 f9: ; CODE XREF: F000:074Dj | |
F000:0753 in al, 61h | |
F000:0755 mov dl, al | |
F000:0757 and al, 0E5h | |
F000:0759 out 61h, al | |
F000:075B xor cx, cx | |
F000:075D f91: ; CODE XREF: F000:f91j | |
F000:075D loop f91 | |
F000:075F call read_half_bit | |
F000:0762 call read_half_bit | |
F000:0765 mov al, dl | |
F000:0767 out 61h, al | |
F000:0769 jcxz short t13_end | |
F000:076B mov bx, 23FFh | |
F000:076E jmp short f81 | |
F000:0770 f8: ; CODE XREF: F000:0730j | |
F000:0770 ; F000:0737j F000:073Ej | |
F000:0770 ; F000:0743j | |
F000:0770 mov bx, 2300h | |
F000:0773 f81: ; CODE XREF: F000:076Ej | |
F000:0773 mov si, 37h ; '7' | |
F000:0776 call e_msg | |
F000:0779 t13_end: ; CODE XREF: F000:0751j | |
F000:0779 ; F000:0769j | |
F000:0779 in al, 21h | |
F000:077B and al, 0FEh ; enable timer ints | |
F000:077D out 21h, al | |
F000:077F in al, 0A0h ; clear nmi flip/flop | |
F000:0781 mov al, 10000000b ; enable nmi interrupts | |
F000:0783 out 0A0h, al | |
F000:0785 call mfg_up | |
F000:0788 mov dx, 2F8h | |
F000:078B call uart | |
F000:078E jnb short tm | |
F000:0790 mov si, 38h ; '8' | |
F000:0793 call e_msg | |
F000:0796 tm: ; CODE XREF: F000:078Ej | |
F000:0796 call mfg_up | |
F000:0799 in al, 62h | |
F000:079B and al, 2 | |
F000:079D jnz short tm1 | |
F000:079F mov dx, 3F8h | |
F000:07A2 call uart | |
F000:07A5 jnb short tm1 | |
F000:07A7 mov si, 39h ; '9' | |
F000:07AA call e_msg | |
F000:07AD tm1: ; CODE XREF: F000:079Dj | |
F000:07AD ; F000:07A5j | |
F000:07AD sub ax, ax | |
F000:07AF mov es, ax | |
F000:07B1 mov cx, 8 ; get vector cnt | |
F000:07B4 push cs ; setup ds seg reg | |
F000:07B5 pop ds | |
F000:07B6 mov si, offset vector_table | |
F000:07B9 mov di, 20h ; ' ' | |
F000:07BC f7a: ; CODE XREF: F000:07BFj | |
F000:07BC movsw | |
F000:07BD inc di ; skip over segment | |
F000:07BE inc di | |
F000:07BF loop f7a | |
F000:07C1 mov ds, cx | |
F000:07C3 mov word ptr ds:14h, offset print_screen ; print screen (int 0x5) | |
F000:07C9 mov word ptr ds:120h, offset key62_int ; 62 key conversion routine (int 0x48) | |
F000:07CF mov word ptr ds:110h, offset crt_char_gen ; dot table (int 0x44) | |
F000:07D5 mov word ptr ds:60h, offset bas_ent ; cassette basic entry (int 0x18) | |
F000:07DB push cs | |
F000:07DC pop ax | |
F000:07DD mov ds:62h, ax ; code segment for cassette (int 0x18) | |
F000:07E0 mov al, 1 | |
F000:07E2 out 13h, al ; (activity signal) | |
F000:07E4 call mfg_up ; mfg routine = ee | |
F000:07E7 mov dx, 0C000h ; set beginning address | |
F000:07EA rom_scan_1: ; CODE XREF: F000:0804j | |
F000:07EA mov ds, dx | |
F000:07EC sub bx, bx | |
F000:07EE mov ax, [bx] | |
F000:07F0 push bx | |
F000:07F1 pop bx | |
F000:07F2 cmp ax, 0AA55h | |
F000:07F5 jnz short next_rom | |
F000:07F7 call rom_check | |
F000:07FA jmp short are_we_done | |
F000:07FC next_rom: ; CODE XREF: F000:07F5j | |
F000:07FC add dx, 80h ; '' | |
F000:0800 are_we_done: ; CODE XREF: F000:07FAj | |
F000:0800 cmp dx, 0F000h | |
F000:0804 jl short rom_scan_1 | |
F000:0806 ;---------------------------------------------------- | |
F000:0806 ; diskette attachment test | |
F000:0806 ; description: | |
F000:0806 ; check if ipl diskette drive is attached to system. if | |
F000:0806 ; attached, verify status of nec fdc after a reset. issue | |
F000:0806 ; a recal and seek cmd to fdc and check status. complete | |
F000:0806 ; system initialization then pass control to the boot | |
F000:0806 ; loader program | |
F000:0806 ; mfg err codes: 2601 reset to diskette controller cd. failed | |
F000:0806 ; 2602 recalibrate to diskette drive failed | |
F000:0806 ; 2603 watchdog timer failed | |
F000:0806 ;---------------------------------------------------- | |
F000:0806 call mfg_up ; mfg routine = ed | |
F000:0809 call dss ; point to data area | |
F000:080C mov al, 0FFh | |
F000:080E mov ds:seg40.track_0, al ; init diskette scratchpads | |
F000:0811 mov ds:seg40.track_1, al | |
F000:0814 mov ds:seg40.track_2, al | |
F000:0817 in al, 62h ; diskette present? | |
F000:0819 and al, 100b | |
F000:081B jz short f10_0 | |
F000:081D jmp f15 ; no, bypass diskette test | |
F000:0820 f10_0: ; CODE XREF: F000:081Bj | |
F000:0820 or byte ptr ds:seg40.equip_flag, 1 ; set ipl diskette indication in equip. flag | |
F000:0825 cmp word ptr ds:seg40.reset_flag, 0 ; running from power-on state? | |
F000:082A jnz short f10 ; bypass watchdog test | |
F000:082C mov al, 0Ah ; read int. request register cmd. | |
F000:082E out 20h, al | |
F000:0830 in al, 20h | |
F000:0832 and al, 40h ; has watchdog gone off | |
F000:0834 jnz short f10 ; proceed if it has | |
F000:0836 mov bl, 3 ; set error code | |
F000:0838 jmp short f13 | |
F000:083A f10: ; CODE XREF: F000:082Aj | |
F000:083A ; F000:0834j | |
F000:083A mov al, 80h ; '' | |
F000:083C out 0F2h, al ; disable watchdog timer | |
F000:083E mov ah, 0 ; reset nec fdc | |
F000:0840 mov dl, ah ; set for drive 0 | |
F000:0842 int 13h ; verify status after reset | |
F000:0844 test ah, 0FFh ; status ok? | |
F000:0847 mov bl, 1 ; set up possible error code | |
F000:0849 jnz short f13 ; no - fdc failed | |
F000:084B ;----- turn drive 0 motor on | |
F000:084B mov al, 81h ; '' ; turn motor on, drive 0 | |
F000:084D out 0F2h, al ; write fdc control reg | |
F000:084F sub cx, cx | |
F000:0851 f11: ; CODE XREF: F000:f11j | |
F000:0851 loop f11 ; wait for one second | |
F000:0853 f12: ; CODE XREF: F000:f12j | |
F000:0853 loop f12 | |
F000:0855 xor dx, dx ; select drive 0 | |
F000:0857 mov ch, 1 ; select track 1 | |
F000:0859 mov ds:seg40.seek_status, dl | |
F000:085D call seek ; recalibrate disk | |
F000:0860 mov bl, 2 ; error code | |
F000:0862 jb short f13 ; go to err subroutine if err | |
F000:0864 mov ch, 34 ; select track 34 | |
F000:0866 call seek ; seek to track 34 | |
F000:0869 jnb short f14 ; ok, turn motor off | |
F000:086B mov bl, 2 | |
F000:086D f13: ; CODE XREF: F000:0838j | |
F000:086D ; F000:0849j F000:0862j | |
F000:086D mov bh, 26h ; '&' ; dsk_err: (26xx) | |
F000:086F mov si, offset disk_err ; get addr of msg | |
F000:0872 call e_msg ; go print error msg | |
F000:0875 f14: ; CODE XREF: F000:0869j | |
F000:0875 mov al, 82h ; '' | |
F000:0877 out 0F2h, al | |
F000:0879 in al, 0E2h | |
F000:087B and al, 110b | |
F000:087D cmp al, 10b | |
F000:087F jnz short f14_1 | |
F000:0881 mov al, 84h ; '' | |
F000:0883 out 0F2h, al | |
F000:0885 in al, 0E2h | |
F000:0887 and al, 110b | |
F000:0889 cmp al, 100b | |
F000:088B jnz short f14_1 | |
F000:088D in al, 0E2h | |
F000:088F and al, 110000b | |
F000:0891 jz short f14_1 | |
F000:0893 cmp al, 10000b | |
F000:0895 mov ah, 40h ; '@' | |
F000:0897 jz short f14_2 | |
F000:0899 mov ah, 80h ; '' | |
F000:089B f14_2: ; CODE XREF: F000:0897j | |
F000:089B or ds:seg40.equip_flag, ah | |
F000:089F ;----- turn drive 0 motor off | |
F000:089F f14_1: ; CODE XREF: F000:087Fj | |
F000:089F ; F000:088Bj F000:0891j | |
F000:089F mov al, 80h ; '' ; turn drive 0 motor off | |
F000:08A1 out 0F2h, al | |
F000:08A3 f15: ; CODE XREF: F000:081Dj | |
F000:08A3 mov byte ptr ds:seg40.intr_flag, 0 ; set stray interrupt flag = 00 | |
F000:08A8 mov di, 78h ; 'x' ; set default prt timeout | |
F000:08AB push ds | |
F000:08AC pop es | |
F000:08AD mov ax, 1414h ; default=20 | |
F000:08B0 stosw | |
F000:08B1 stosw | |
F000:08B2 mov ax, 101h ; rs232 default=01 | |
F000:08B5 stosw | |
F000:08B6 stosw | |
F000:08B7 in al, 21h | |
F000:08B9 and al, 0FEh ; enable timer int. (lvl 0) | |
F000:08BB out 21h, al | |
F000:08BD push ds | |
F000:08BE mov ax, 50h ; 'P' | |
F000:08C1 mov ds, ax | |
F000:08C3 cmp byte ptr ds:seg50.post_err, 0 ; check for "post_err" non-zero | |
F000:08C8 pop ds | |
F000:08C9 jz short f15a_0 ; continue if no error | |
F000:08CB mov dl, 2 | |
F000:08CD call err_beep | |
F000:08D0 err_wait: ; CODE XREF: F000:08D7j | |
F000:08D0 mov ah, 0 | |
F000:08D2 int 16h ; KEYBOARD - READ CHAR FROM BUFFER, WAIT IF EMPTY | |
F000:08D2 ; Return: AH = scan code, AL = character | |
F000:08D4 cmp ah, 1Ch | |
F000:08D7 jnz short err_wait | |
F000:08D9 jmp short f15c | |
F000:08DB f15a_0: ; CODE XREF: F000:08C9j | |
F000:08DB mov dl, 1 | |
F000:08DD call err_beep | |
F000:08E0 ;----- setup printer and rs232 base addresses if device attached | |
F000:08E0 f15c: ; CODE XREF: F000:08D9j | |
F000:08E0 mov bp, offset f4 | |
F000:08E3 xor si, si | |
F000:08E5 f16: ; CODE XREF: F000:08FEj | |
F000:08E5 mov dx, cs:[bp+0] | |
F000:08E9 mov al, 0AAh ; 'ª' | |
F000:08EB out dx, al | |
F000:08EC push ds | |
F000:08ED in al, dx | |
F000:08EE pop ds | |
F000:08EF cmp al, 0AAh ; 'ª' | |
F000:08F1 jnz short f17 | |
F000:08F3 mov [si+8], dx | |
F000:08F7 inc si | |
F000:08F8 inc si | |
F000:08F9 f17: ; CODE XREF: F000:08F1j | |
F000:08F9 inc bp | |
F000:08FA inc bp | |
F000:08FB cmp bp, 41h ; 'A' | |
F000:08FE jnz short f16 | |
F000:0900 xor bx, bx | |
F000:0902 mov dx, 3FAh | |
F000:0905 in al, dx | |
F000:0906 test al, 0F8h | |
F000:0908 jnz short f18 | |
F000:090A mov word ptr [bx+0], 3F8h | |
F000:0910 inc bx | |
F000:0911 inc bx | |
F000:0912 f18: ; CODE XREF: F000:0908j | |
F000:0912 mov word ptr [bx+0], 2F8h | |
F000:0918 inc bx | |
F000:0919 inc bx | |
F000:091A mov ax, si | |
F000:091C mov cl, 3 | |
F000:091E ror al, cl | |
F000:0920 or al, bl | |
F000:0922 or ds:11h, al | |
F000:0926 mov cx, ax | |
F000:0928 mov bx, 2FEh | |
F000:092B mov dx, 2FCh | |
F000:092E sub al, al | |
F000:0930 out dx, al | |
F000:0931 jmp short $+2 | |
F000:0933 xchg dx, bx | |
F000:0935 in al, dx | |
F000:0936 jmp short $+2 | |
F000:0938 mov al, 2 | |
F000:093A xchg dx, bx | |
F000:093C out dx, al | |
F000:093D jmp short $+2 | |
F000:093F xchg dx, bx | |
F000:0941 in al, dx | |
F000:0942 test al, 8 | |
F000:0944 jz short f19_a | |
F000:0946 test al, 1 | |
F000:0948 jnz short f19_a | |
F000:094A sub al, al | |
F000:094C xchg dx, bx | |
F000:094E out dx, al | |
F000:094F jmp short $+2 | |
F000:0951 xchg dx, bx | |
F000:0953 in al, dx | |
F000:0954 and al, 8 | |
F000:0956 jz short f19_a | |
F000:0958 ; carrier detect if following rts-indicate serial printer attached | |
F000:0958 or cl, 100000b | |
F000:095B test cl, 11000000b | |
F000:095E jnz short f19_a | |
F000:0960 or cl, 1000000b | |
F000:0963 mov word ptr ds:seg40.printer_base, 2F8h | |
F000:0969 f19_a: ; CODE XREF: F000:0944j | |
F000:0969 ; F000:0948j F000:0956j | |
F000:0969 ; F000:095Ej | |
F000:0969 or ds:seg40.equip_flag+1, cl | |
F000:096D xor dx, dx | |
F000:096F test cl, 40h | |
F000:0972 jz short f19_c | |
F000:0974 cmp word ptr ds:seg40, 2F8h | |
F000:097A jz short f19_b | |
F000:097C inc dx | |
F000:097D f19_b: ; CODE XREF: F000:097Aj | |
F000:097D mov ax, 87h ; '' ; init serial printer | |
F000:0980 int 14h | |
F000:0982 test ah, 1Eh ; error? | |
F000:0985 jnz short f19_c ; yes, jump | |
F000:0987 mov ax, 118h ; send cancel command to | |
F000:098A int 14h ; ...serial printer | |
F000:098C f19_c: ; CODE XREF: F000:0972j | |
F000:098C ; F000:0985j | |
F000:098C mov dx, 201h | |
F000:098F in al, dx ; get mfg./ service mode info | |
F000:0990 and al, 0F0h ; is high order nibble = 0 ? | |
F000:0992 jnz short f19_1 ; (burn-in mode) | |
F000:0994 f19_0: ; CODE XREF: F000:0999j | |
F000:0994 jmp reset | |
F000:0997 f19_1: ; CODE XREF: F000:0992j | |
F000:0997 cmp al, 100000b ; service mode loop? | |
F000:0999 jz short f19_0 ; branch to start | |
F000:099B cmp word ptr ds:seg40.reset_flag, 4321h ; diag. control program restart | |
F000:09A1 jz short f19_3 ; no, go boot | |
F000:09A3 cmp al, 10000b ; mfg dcp run request | |
F000:09A5 jz short f19_3 | |
F000:09A7 mov word ptr ds:seg40.reset_flag, 1234h ; set warm start indicator in case of cartridge reset | |
F000:09AD int 19h ; go to boot loader | |
F000:09AF f19_3: ; CODE XREF: F000:09A1j | |
F000:09AF ; F000:09A5j | |
F000:09AF cli | |
F000:09B0 sub ax, ax | |
F000:09B2 mov ds, ax ; reset timer int. | |
F000:09B4 mov word ptr ds:20h, offset timer_int ; (int 0x08) | |
F000:09BA int 80h ; enter dcp through int. 80h | |
F000:09BC ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:09BC ; this subroutine is the general error handler for the post | |
F000:09BC ; si = offset(address) of message buffer | |
F000:09BC ; bx = error code for manufacturing or service mode | |
F000:09BC ; registers are not preserved | |
F000:09BC ; location "post_err" is set non-zero if an error occurs in | |
F000:09BC ; customer mode | |
F000:09BC ; service/manufacturing flags as follows: (high nibble of | |
F000:09BC ; port 201) | |
F000:09BC ; 0000 = manufacturing (burn-in) mode | |
F000:09BC ; 0001 = manufacturing (system test) mode | |
F000:09BC ; 0010 = service mode (loop post) | |
F000:09BC ; 0100 = service mode (system test) | |
F000:09BC e_msg proc near ; CODE XREF: kb_int-1477j | |
F000:09BC ; F000:014Ej F000:015Cj | |
F000:09BC ; F000:l22j F000:01BFj | |
F000:09BC ; F000:0295j ... | |
F000:09BC mov dx, 201h | |
F000:09BF in al, dx ; get mode bits | |
F000:09C0 and al, 0F0h ; isolate bits of interest | |
F000:09C2 jnz short em0 | |
F000:09C4 jmp mfg_out ; manufacturing mode (burn-in) | |
F000:09C7 em0: ; CODE XREF: e_msg+6j | |
F000:09C7 cmp al, 10000b | |
F000:09C9 jnz short em1 | |
F000:09CB jmp mfg_out ; mfg. mode (system test) | |
F000:09CE em1: ; CODE XREF: e_msg+Dj | |
F000:09CE mov dh, al ; save mode | |
F000:09D0 cmp bh, 0Ah ; error code above 0ah (crt started display possible?) | |
F000:09D3 jl short beeps ; do beep output if below 10 | |
F000:09D5 push bx ; save error and mode flags | |
F000:09D6 push si | |
F000:09D7 push dx | |
F000:09D8 mov ah, 2 ; set cursor | |
F000:09DA mov dx, 1521h ; row 21, col. 33 | |
F000:09DD mov bh, 7 ; page 7 | |
F000:09DF int 10h ; - VIDEO - SET CURSOR POSITION | |
F000:09DF ; DH,DL = row, column (0,0 = upper left) | |
F000:09DF ; BH = page number | |
F000:09E1 mov si, offset error_err ; "ERROR" | |
F000:09E4 mov cx, 5 | |
F000:09E7 em_0: ; CODE XREF: e_msg+32j | |
F000:09E7 mov al, cs:[si] | |
F000:09EA inc si | |
F000:09EB call prt_hex | |
F000:09EE loop em_0 | |
F000:09F0 ; look for a blank space to possibly put customer level errors (in | |
F000:09F0 ; case of multi error) | |
F000:09F0 mov dh, 16h | |
F000:09F2 em_1: ; CODE XREF: e_msg+42j | |
F000:09F2 mov ah, 2 | |
F000:09F4 int 10h ; - VIDEO - SET CURSOR POSITION | |
F000:09F4 ; DH,DL = row, column (0,0 = upper left) | |
F000:09F4 ; BH = page number | |
F000:09F6 mov ah, 8 | |
F000:09F8 int 10h ; - VIDEO - READ ATTRIBUTES/CHARACTER AT CURSOR POSITION | |
F000:09F8 ; BH = display page | |
F000:09F8 ; Return: AL = character | |
F000:09F8 ; AH = attribute of character (alpha modes) | |
F000:09FA inc dl | |
F000:09FC cmp al, 20h ; ' ' | |
F000:09FE jnz short em_1 | |
F000:0A00 pop dx | |
F000:0A01 pop si | |
F000:0A02 pop bx | |
F000:0A03 cmp dh, 100000b ; service mode ? | |
F000:0A06 jz short serv_out | |
F000:0A08 cmp dh, 1000000b | |
F000:0A0B jz short serv_out | |
F000:0A0D mov al, cs:[si] ; get error char | |
F000:0A10 call prt_hex ; display it | |
F000:0A13 cmp bh, 20h ; ' ' ; error below 20? (mem trouble?) | |
F000:0A16 jge short em_2 | |
F000:0A18 jmp totlpt0 ; halt system if so. | |
F000:0A1B em_2: ; CODE XREF: e_msg+5Aj | |
F000:0A1B push ds | |
F000:0A1C push ax | |
F000:0A1D mov ax, 50h ; 'P' | |
F000:0A20 mov ds, ax | |
F000:0A22 mov ds:seg50.post_err, bh ; set error flag to non-zero | |
F000:0A26 pop ax | |
F000:0A27 pop ds | |
F000:0A28 retn ; return to caller | |
F000:0A29 serv_out: ; CODE XREF: e_msg+4Aj | |
F000:0A29 ; e_msg+4Fj | |
F000:0A29 mov al, bh | |
F000:0A2B push bx | |
F000:0A2C call xpc_byte | |
F000:0A2F pop bx | |
F000:0A30 mov al, bl | |
F000:0A32 call xpc_byte | |
F000:0A35 jmp totlpt0 | |
F000:0A38 beeps: ; CODE XREF: e_msg+17j | |
F000:0A38 cli | |
F000:0A39 mov ax, cs | |
F000:0A3B mov ss, ax | |
F000:0A3D mov dl, 2 | |
F000:0A3F mov sp, offset ex_0 ; set dummy return (eb0) | |
F000:0A42 eb: ; CODE XREF: e_msg+8Fj | |
F000:0A42 mov bl, 1 | |
F000:0A44 jmp beep | |
F000:0A47 eb0: ; CODE XREF: e_msg:eb0j | |
F000:0A47 ; DATA XREF: F000:ex_0o | |
F000:0A47 ; F000:002Ao | |
F000:0A47 loop eb0 | |
F000:0A49 dec dl | |
F000:0A4B jnz short eb | |
F000:0A4D cmp bh, 5 | |
F000:0A50 jnz short totlpt0 | |
F000:0A52 cmp dh, 20h ; ' ' | |
F000:0A55 jz short eb1 | |
F000:0A57 cmp dh, 40h ; '@' | |
F000:0A5A jnz short totlpt0 | |
F000:0A5C eb1: ; CODE XREF: e_msg+99j | |
F000:0A5C mov bl, 1 | |
F000:0A5E jmp beep | |
F000:0A61 mfg_out: ; CODE XREF: e_msg+8j | |
F000:0A61 ; e_msg+Fj | |
F000:0A61 ; DATA XREF: F000:01F8o | |
F000:0A61 cli | |
F000:0A62 in al, 61h | |
F000:0A64 and al, 0FCh | |
F000:0A66 out 61h, al | |
F000:0A68 mov dx, 11h | |
F000:0A6B mov al, bh ; send data to addresses 11,12 | |
F000:0A6D out dx, al | |
F000:0A6E inc dx ; send high byte | |
F000:0A6F mov al, bl | |
F000:0A71 out dx, al ; send low byte | |
F000:0A72 ; init. on-board rs232 port for communications w/mfg monitor | |
F000:0A72 mov ax, 50h ; 'P' | |
F000:0A75 mov ds, ax ; point to data segment containing checkpoint # | |
F000:0A77 mov ax, cs | |
F000:0A79 mov ss, ax ; set stack for rtn | |
F000:0A7B mov sp, offset ex1 ; (points to mo1) | |
F000:0A7E mov dx, 2FBh ; line control reg. address | |
F000:0A81 jmp s8250 ; go set up for 9600, 0dd, 2 stop bits, 8 bits | |
F000:0A84 mo1: ; DATA XREF: F000:ex1o | |
F000:0A84 mov cx, dx ; dx came back with xmit reg address in it | |
F000:0A86 mov dx, 2FCh ; modem control reg | |
F000:0A89 sub al, al ; set dtr and rts low so possible wrap plug won't confuse things | |
F000:0A8B out dx, al | |
F000:0A8C mov dx, 2FEh ; modem status reg | |
F000:0A8F mo2: ; CODE XREF: e_msg+D6j | |
F000:0A8F in al, dx | |
F000:0A90 and al, 10000b ; cts up yet? | |
F000:0A92 jz short mo2 ; loop til it is | |
F000:0A94 dec dx ; set dx=2fd (line status reg) | |
F000:0A95 xchg dx, cx ; point to xmit. data reg | |
F000:0A97 mov al, ds:seg50.mfg_tst ; get mfg routine error indicator | |
F000:0A9A out dx, al ; (maybe wrong from early errors) | |
F000:0A9B jmp short $+2 ; delay | |
F000:0A9D xchg dx, cx ; point dx=2fd | |
F000:0A9F mo3: ; CODE XREF: e_msg+E8j | |
F000:0A9F in al, dx ; transmit empty? | |
F000:0AA0 and al, 100000b | |
F000:0AA2 jmp short $+2 ; delay | |
F000:0AA4 jz short mo3 ; loop til it is | |
F000:0AA6 xchg dx, cx | |
F000:0AA8 mov al, bh ; get msb of error word | |
F000:0AAA out dx, al | |
F000:0AAB jmp short $+2 ; delay | |
F000:0AAD xchg dx, cx | |
F000:0AAF mo4: ; CODE XREF: e_msg+F8j | |
F000:0AAF in al, dx ; wait for xmit empty | |
F000:0AB0 and al, 100000b | |
F000:0AB2 jmp short $+2 ; delay | |
F000:0AB4 jz short mo4 | |
F000:0AB6 mov al, bl ; get lsb of error word | |
F000:0AB8 xchg dx, cx | |
F000:0ABA out dx, al | |
F000:0ABB totlpt0: ; CODE XREF: e_msg+5Cj | |
F000:0ABB ; e_msg+79j e_msg+94j | |
F000:0ABB ; e_msg+9Ej | |
F000:0ABB ; DATA XREF: F000:002Co | |
F000:0ABB cli ; disable ints. | |
F000:0ABC sub al, al | |
F000:0ABE out 0F2h, al ; stop diskette motor | |
F000:0AC0 out 0A0h, al ; disable nmi | |
F000:0AC2 hlt ; halt | |
F000:0AC3 retn | |
F000:0AC3 e_msg endp | |
F000:0AC4 ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:0AC4 i8250 proc near ; CODE XREF: uart+Dp | |
F000:0AC4 ; uart+11Ep | |
F000:0AC4 in al, dx | |
F000:0AC5 mov bl, 2 | |
F000:0AC7 call rr2 | |
F000:0ACA and al, 0F0h | |
F000:0ACC jnz short at20 | |
F000:0ACE call rr1 | |
F000:0AD1 and al, 0F8h | |
F000:0AD3 jnz short at20 | |
F000:0AD5 inc dx | |
F000:0AD6 call rr1 | |
F000:0AD9 and al, 0E0h | |
F000:0ADB jnz short at20 | |
F000:0ADD call rr1 | |
F000:0AE0 and al, 80h | |
F000:0AE2 jnz short at20 | |
F000:0AE4 mov al, 60h ; '`' | |
F000:0AE6 out dx, al | |
F000:0AE7 jmp short $+2 | |
F000:0AE9 inc dx | |
F000:0AEA xor al, al | |
F000:0AEC out dx, al | |
F000:0AED call rr3 | |
F000:0AF0 sub dx, 6 | |
F000:0AF3 in al, dx | |
F000:0AF4 clc | |
F000:0AF5 retn | |
F000:0AF6 at20: ; CODE XREF: i8250+8j | |
F000:0AF6 ; i8250+Fj i8250+17j | |
F000:0AF6 ; i8250+1Ej | |
F000:0AF6 stc | |
F000:0AF7 retn | |
F000:0AF7 i8250 endp | |
F000:0AF8 ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:0AF8 ict proc near ; CODE XREF: uart+36p | |
F000:0AF8 ; uart+90p uart+D1p | |
F000:0AF8 in al, dx | |
F000:0AF9 jmp short $+2 | |
F000:0AFB or al, ah | |
F000:0AFD out dx, al | |
F000:0AFE sub dx, cx | |
F000:0B00 push cx | |
F000:0B01 sub cx, cx | |
F000:0B03 at21: ; CODE XREF: ict+10j | |
F000:0B03 in al, dx | |
F000:0B04 test al, 1 | |
F000:0B06 jz short at22 | |
F000:0B08 loop at21 | |
F000:0B0A at22: ; CODE XREF: ict+Ej | |
F000:0B0A pop cx | |
F000:0B0B cmp al, bh | |
F000:0B0D jnz short at23 | |
F000:0B0F or bl, bl | |
F000:0B11 jz short at24 | |
F000:0B13 add dx, cx | |
F000:0B15 in al, dx | |
F000:0B16 jmp short at24 | |
F000:0B18 at23: ; CODE XREF: ict+15j | |
F000:0B18 mov al, 0FFh | |
F000:0B1A at24: ; CODE XREF: ict+19j ict+1Ej | |
F000:0B1A retn | |
F000:0B1A ict endp | |
F000:0B1B ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:0B1B ; --- int 0x19 ------------------------------- | |
F000:0B1B ; boot strap loader | |
F000:0B1B ; | |
F000:0B1B ; track 0, sector 1 is read into the | |
F000:0B1B ; boot location (segment 0, offset 7c00) | |
F000:0B1B ; and control is transferred there | |
F000:0B1B ; | |
F000:0B1B ; if the diskette is not present or has a | |
F000:0B1B ; problem loading (e.g., not ready), and int. | |
F000:0B1B ; 18h is executed. if a cartridge has vectored | |
F000:0B1B ; int 18h to itself, control will be passed to | |
F000:0B1B ; the cartridge. | |
F000:0B1B ; -------------------------------------------- | |
F000:0B1B boot_strap proc near ; CODE XREF: F000:E6F2j | |
F000:0B1B ; DATA XREF: F000:FF15o | |
F000:0B1B sti ; enable interrupts | |
F000:0B1C sub ax, ax ; set 40x25 b&w mode on crt | |
F000:0B1E int 10h | |
F000:0B20 sub ax, ax ; establish addressing | |
F000:0B22 mov ds, ax | |
F000:0B24 ;----- see if diskette is present | |
F000:0B24 in al, 62h ; get config bits | |
F000:0B26 and al, 100b ; is diskette present? | |
F000:0B28 jnz short h3 ; no, then attempt to go to cart | |
F000:0B2A ;----- reset the disk parameter table vector | |
F000:0B2A mov word ptr ds:78h, offset disk_parms ; (int 0x1e offset) | |
F000:0B30 mov word ptr ds:7Ah, cs ; (int 0x1e segment) | |
F000:0B34 ;----- load system from diskette -- cx has retry count | |
F000:0B34 mov cx, 4 ; set retry count | |
F000:0B37 h1: ; CODE XREF: boot_strap+35j | |
F000:0B37 push cx ; save retry count | |
F000:0B38 mov ah, 0 ; reset the diskette system | |
F000:0B3A int 13h ; diskette_io | |
F000:0B3C jb short h2 ; if error, try again | |
F000:0B3E mov ax, 201h ; read in the single sector | |
F000:0B41 sub dx, dx ; to the boot location | |
F000:0B43 mov es, dx | |
F000:0B45 mov bx, 7C00h ; (boot location) | |
F000:0B48 mov cx, 1 ; drive 0, head 0, sector 1, track 0 | |
F000:0B4B int 13h ; diskette_io | |
F000:0B4D h2: ; CODE XREF: boot_strap+21j | |
F000:0B4D pop cx ; recover retry count | |
F000:0B4E jnb short h3a ; cf set by unsuccessful read | |
F000:0B50 loop h1 ; do it for retry times | |
F000:0B52 ;----- unable to ips from diskette | |
F000:0B52 h3: ; CODE XREF: boot_strap+Dj | |
F000:0B52 int 18h ; go to basic or cartridge | |
F000:0B54 ;----- ips was successful | |
F000:0B54 h3a: ; CODE XREF: boot_strap+33j | |
F000:0B54 jmp far ptr 0:7C00h ; (boot location) | |
F000:0B54 boot_strap endp | |
F000:0B59 ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:0B59 podstg proc near ; CODE XREF: F000:016Aj | |
F000:0B59 ; F000:0183j F000:01B7j | |
F000:0B59 ; F000:0552p F000:0584p | |
F000:0B59 ; F000:05A9p | |
F000:0B59 cld | |
F000:0B5A sub di, di | |
F000:0B5C sub ax, ax | |
F000:0B5E mov ds, ax | |
F000:0B60 mov bx, ds:472h ; (0:472 == 40:72 == reset flag) | |
F000:0B64 cmp bx, 1234h | |
F000:0B68 mov dx, es | |
F000:0B6A mov ds, dx | |
F000:0B6C jnz short p1 | |
F000:0B6E p12: ; CODE XREF: podstg+24j | |
F000:0B6E rep stosw ; simple fill with 0 on warm-start | |
F000:0B70 mov ds, ax | |
F000:0B72 mov ds:472h, bx ; (0:472 == 40:72 == reset flag) | |
F000:0B76 mov ds, dx | |
F000:0B78 retn | |
F000:0B79 p1: ; CODE XREF: podstg+13j | |
F000:0B79 cmp bx, 4321h ; diag. restart? | |
F000:0B7D jz short p12 ; do fill with zeroes | |
F000:0B7F p2: ; CODE XREF: podstg+35j | |
F000:0B7F mov [di], al | |
F000:0B81 mov al, [di] | |
F000:0B83 xor al, ah | |
F000:0B85 jz short py | |
F000:0B87 jmp p8 | |
F000:0B8A py: ; CODE XREF: podstg+2Cj | |
F000:0B8A inc ah | |
F000:0B8C mov al, ah | |
F000:0B8E jnz short p2 | |
F000:0B90 mov bp, cx | |
F000:0B92 mov ax, 0AAAAh | |
F000:0B95 mov bx, ax | |
F000:0B97 mov dx, 5555h | |
F000:0B9A rep stosw | |
F000:0B9C dec di | |
F000:0B9D dec di | |
F000:0B9E std | |
F000:0B9F mov si, di | |
F000:0BA1 mov cx, bp | |
F000:0BA3 p3: ; CODE XREF: podstg+52j | |
F000:0BA3 lodsw | |
F000:0BA4 xor ax, bx | |
F000:0BA6 jnz short p8 | |
F000:0BA8 mov ax, dx | |
F000:0BAA stosw | |
F000:0BAB loop p3 | |
F000:0BAD mov cx, bp | |
F000:0BAF cld | |
F000:0BB0 inc si | |
F000:0BB1 inc si | |
F000:0BB2 mov di, si | |
F000:0BB4 mov bx, dx | |
F000:0BB6 mov dx, 0FFh | |
F000:0BB9 px: ; CODE XREF: podstg+68j | |
F000:0BB9 ; podstg+77j | |
F000:0BB9 lodsw | |
F000:0BBA xor ax, bx | |
F000:0BBC jnz short p8 | |
F000:0BBE mov ax, dx | |
F000:0BC0 stosw | |
F000:0BC1 loop px | |
F000:0BC3 mov cx, bp | |
F000:0BC5 std | |
F000:0BC6 dec si | |
F000:0BC7 dec si | |
F000:0BC8 mov di, si | |
F000:0BCA mov bx, dx | |
F000:0BCC not dx | |
F000:0BCE or dl, dl | |
F000:0BD0 jz short px | |
F000:0BD2 cld | |
F000:0BD3 add si, 4 | |
F000:0BD6 not dx | |
F000:0BD8 mov di, si | |
F000:0BDA mov cx, bp | |
F000:0BDC p4: ; CODE XREF: podstg+89j | |
F000:0BDC lodsw | |
F000:0BDD xor ax, dx | |
F000:0BDF jnz short p8 | |
F000:0BE1 stosw | |
F000:0BE2 loop p4 | |
F000:0BE4 std | |
F000:0BE5 dec si | |
F000:0BE6 dec si | |
F000:0BE7 ;----- check if in service/mfg modes, if so, perform refresh check | |
F000:0BE7 mov dx, 201h | |
F000:0BEA in al, dx ; get options bits | |
F000:0BEB and al, 0F0h | |
F000:0BED cmp al, 0F0h ; 'ð' ; all bits high=normal mode (no joy buttons pressed) | |
F000:0BEF jz short p6 | |
F000:0BF1 mov cx, cs | |
F000:0BF3 mov bx, ss | |
F000:0BF5 cmp cx, bx | |
F000:0BF7 jz short p6 | |
F000:0BF9 mov al, 18h | |
F000:0BFB p5: ; CODE XREF: podstg:p5j | |
F000:0BFB ; podstg+A6j | |
F000:0BFB loop p5 | |
F000:0BFD dec al | |
F000:0BFF jnz short p5 | |
F000:0C01 p6: ; CODE XREF: podstg+96j | |
F000:0C01 ; podstg+9Ej | |
F000:0C01 mov cx, bp | |
F000:0C03 p7: ; CODE XREF: podstg+AFj | |
F000:0C03 lodsw | |
F000:0C04 or ax, ax | |
F000:0C06 jnz short p8 | |
F000:0C08 loop p7 | |
F000:0C0A jmp short p11 | |
F000:0C0C p8: ; CODE XREF: podstg+2Ej | |
F000:0C0C ; podstg+4Dj podstg+63j | |
F000:0C0C ; podstg+86j podstg+ADj | |
F000:0C0C mov cx, ax | |
F000:0C0E xor ah, ah | |
F000:0C10 or ch, ch | |
F000:0C12 jz short p9 | |
F000:0C14 inc ah | |
F000:0C16 p9: ; CODE XREF: podstg+B9j | |
F000:0C16 or cl, cl | |
F000:0C18 jz short p10 | |
F000:0C1A add ah, 2 | |
F000:0C1D p10: ; CODE XREF: podstg+BFj | |
F000:0C1D or ah, ah | |
F000:0C1F p11: ; CODE XREF: podstg+B1j | |
F000:0C1F cld | |
F000:0C20 retn | |
F000:0C20 podstg endp | |
F000:0C21 ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:0C21 put_logo proc near ; CODE XREF: F000:04BDp | |
F000:0C21 push ds | |
F000:0C22 push bp | |
F000:0C23 push ax | |
F000:0C24 push bx | |
F000:0C25 push cx | |
F000:0C26 push dx | |
F000:0C27 mov bp, offset logo | |
F000:0C2A mov dx, 8000h ; point dh dl at row column 0, 0 | |
F000:0C2D mov bl, 11111b ; attribute of characters to be written | |
F000:0C2F int 82h ; call output routine | |
F000:0C31 mov bl, 0 ; initialize attribute | |
F000:0C33 mov dl, 0 ; initialize column | |
F000:0C35 again: ; CODE XREF: put_logo+20j | |
F000:0C35 mov dh, 94h ; '' ; set line | |
F000:0C37 mov bp, offset color ; output given color bar | |
F000:0C3A int 82h ; call output routine | |
F000:0C3C inc bl ; increment attribute | |
F000:0C3E cmp dl, 32 ; is the column counter pointing past 40? | |
F000:0C41 jl short again ; if not, do it again | |
F000:0C43 pop dx | |
F000:0C44 pop cx | |
F000:0C45 pop bx | |
F000:0C46 pop ax | |
F000:0C47 pop bp ; restore bp | |
F000:0C48 pop ds ; restore ds | |
F000:0C49 retn | |
F000:0C49 put_logo endp | |
F000:0C4A logo db 3 ; DATA XREF: put_logo+6o | |
F000:0C4B db 20h ; space | |
F000:0C4C db 0DCh ; half block | |
F000:0C4D logo_e db 28h, 0FBh, 28h, 0FBh, 2, 7, 1, 9, 3, 4, 9, 4, 1, 0FBh | |
F000:0C4D db 2, 7, 1, 0Ah, 2, 5, 7, 5, 1, 0FBh, 2, 7, 1, 0Bh, 1 | |
F000:0C4D db 6, 5, 6, 1, 0FBh, 4, 3, 5, 4 dup(3), 5, 3, 5, 3, 0FBh | |
F000:0C4D db 4, 3, 5, 4 dup(3), 6, 1, 6, 3, 0FBh, 4, 3, 5, 8, 4 | |
F000:0C4D db 0Dh, 3, 0FBh, 4, 3, 5, 7, 5, 0Dh, 3, 0FBh, 4, 3, 5 | |
F000:0C4D db 8, 4, 0Dh, 3, 0FBh, 4, 3, 5, 4 dup(3), 0Dh, 3, 0FBh | |
F000:0C4D db 4, 3, 5, 5 dup(3), 1, 5, 1, 2 dup(3), 0FBh, 2, 7, 1 | |
F000:0C4D db 0Bh, 1, 5, 2, 3, 2, 5, 1, 0FBh, 2, 7, 1, 0Ah, 2, 5 | |
F000:0C4D db 3, 1, 3, 5, 1, 0FBh, 2, 7, 1, 9, 3, 5, 7, 5, 1, 0FBh | |
F000:0C4D db 28h, 0FBh, 28h, 0FCh | |
F000:0CDD color db 2 ; DATA XREF: put_logo+16o | |
F000:0CDE db 0DBh ; Û ; full block | |
F000:0CDF color_e db 2, 77h, 2, 77h, 2, 77h, 2, 77h, 2, 0FCh | |
F000:0CE9 moo10 dw offset set_mode ; DATA XREF: video_io+38r | |
F000:0CE9 ; 0x00 | |
F000:0CEB dw offset set_ctype ; 0x01 | |
F000:0CED dw offset set_cpos ; 0x02 | |
F000:0CEF dw offset read_cursor ; 0x03 | |
F000:0CF1 dw offset read_lpen ; 0x04 | |
F000:0CF3 dw offset act_disp_page ; 0x05 | |
F000:0CF5 dw offset scroll_up ; 0x06 | |
F000:0CF7 dw offset scroll_down ; 0x07 | |
F000:0CF9 dw offset read_ac_current ; 0x08 | |
F000:0CFB dw offset write_ac_current ; 0x09 | |
F000:0CFD dw offset write_c_current ; 0x0a | |
F000:0CFF dw offset set_color ; 0x0b | |
F000:0D01 dw offset write_dot ; 0x0c | |
F000:0D03 dw offset read_dot ; 0x0d | |
F000:0D05 dw offset write_tty ; 0x0e | |
F000:0D07 dw offset video_state ; 0x0f | |
F000:0D09 dw offset set_palette ; 0x10 | |
F000:0D0B ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:0D0B video_io proc far ; CODE XREF: F000:F065j | |
F000:0D0B ; DATA XREF: F000:vector_table_16o | |
F000:0D0B sti ; interrupts back on | |
F000:0D0C cld | |
F000:0D0D push es | |
F000:0D0E push ds ; save segment registers | |
F000:0D0F push dx | |
F000:0D10 push cx | |
F000:0D11 push bx | |
F000:0D12 push si | |
F000:0D13 push di | |
F000:0D14 push ax ; save ax value | |
F000:0D15 mov al, ah ; get into low byte | |
F000:0D17 xor ah, ah ; zero to high byte | |
F000:0D19 shl ax, 1 ; #2 for table lookup | |
F000:0D1B mov si, ax ; put into si for branch | |
F000:0D1D cmp ax, 22h ; '"' ; test for within range | |
F000:0D20 jb short c1 | |
F000:0D22 pop ax ; throw away the parameters | |
F000:0D23 jmp video_return ; do nothing if not in range | |
F000:0D26 c1: ; CODE XREF: video_io+15j | |
F000:0D26 call dss | |
F000:0D29 mov ax, 0B800h ; segment for color card | |
F000:0D2C cmp byte ptr ds:seg40.crt_mode, 9 ; in mode using 32k regen? | |
F000:0D31 jb short c2 ; no, jump | |
F000:0D33 mov ah, ds:seg40.pagdat ; get copy of page regs | |
F000:0D37 and ah, 111000b ; isolate cpu reg | |
F000:0D3A shr ah, 1 ; shift to make it into segment value | |
F000:0D3C c2: ; CODE XREF: video_io+26j | |
F000:0D3C mov es, ax ; set up to point at video ram area | |
F000:0D3E pop ax ; recover value | |
F000:0D3F mov ah, ds:seg40.crt_mode ; get current mode into ah | |
F000:0D43 jmp cs:moo10[si] | |
F000:0D43 video_io endp | |
F000:0D48 ; table of regen lenghts | |
F000:0D48 moo50 dw 2048 ; DATA XREF: set_mode+1B6r | |
F000:0D48 ; mode 0 40x25 bw | |
F000:0D4A dw 2048 ; mode 1 40x25 color | |
F000:0D4C dw 4096 ; mode 2 80x25 bw | |
F000:0D4E dw 4096 ; mode 3 80x25 color | |
F000:0D50 dw 16384 ; mode 4 320x200 4 color | |
F000:0D52 dw 16384 ; mode 5 320x200 4 color | |
F000:0D54 dw 16384 ; mode 6 640x200 bw | |
F000:0D56 dw 0 | |
F000:0D58 dw 16384 ; mode 8 160x200 16 color | |
F000:0D5A dw 32768 ; mode 9 320x200 16 color | |
F000:0D5C dw 32768 ; mode a 640x200 4 color | |
F000:0D5E ;------ columns | |
F000:0D5E moo60 db 40, 40, 80, 80, 40, 40, 80, 0, 20, 40, 80 | |
F000:0D5E ; DATA XREF: set_mode+1AAr | |
F000:0D5E ; columns | |
F000:0D69 ;------ table of gate array parameters for mode settings (0x03da) | |
F000:0D69 ;model control1, palette mask, border color, mode control 2 | |
F000:0D69 moo70 db 0Ch, 0Fh, 0, 2 ; DATA XREF: set_mode+9Do | |
F000:0D69 ; mode 0 40x25 bw | |
F000:0D6D moo70l db 8, 0Fh, 0, 2 ; mode 1 40x25 color | |
F000:0D71 db 0Dh, 0Fh, 0, 2 ; mode 2 80x25 bw | |
F000:0D75 db 9, 0Fh, 0, 2 ; mode 3 80x25 color | |
F000:0D79 db 0Ah, 3, 0, 0 ; mode 4 320x200 4 color | |
F000:0D7D db 0Eh, 3, 0, 0 ; mode 5 320x200 bw | |
F000:0D81 db 0Eh, 1, 0, 8 ; mode 6 640x200 bw | |
F000:0D85 db 0, 0, 0, 0 ; mode 7 invalid | |
F000:0D89 db 1Ah, 0Fh, 0, 0 ; mode 8 160x200 16 color | |
F000:0D8D db 1Bh, 0Fh, 0, 0 ; mode 9 320x200 16 color | |
F000:0D91 db 0Bh, 3, 0, 0 ; mode a 640x200 4 color | |
F000:0D95 ;---------- tables of palette colors for 2 and 4 color modes | |
F000:0D95 moo72 db 0, 0Fh, 0, 0 ; DATA XREF: set_mode+42o | |
F000:0D95 ; set_color+28o | |
F000:0D95 ; 2 color, set 0 | |
F000:0D99 moo72l db 0Fh, 0, 0, 0 ; 2 color, set 1 | |
F000:0D9D moo74 db 0, 2, 4, 6 ; DATA XREF: set_color:c32o | |
F000:0D9D ; 4 color, set 0 | |
F000:0DA1 moo75 db 0, 3, 5, 0Fh ; DATA XREF: set_mode+49o | |
F000:0DA1 ; 4 color, set 1 | |
F000:0DA5 ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:0DA5 set_mode proc far ; CODE XREF: video_io+38j | |
F000:0DA5 ; DATA XREF: F000:moo10o | |
F000:0DA5 push ax ; save input mode on stack | |
F000:0DA6 and al, 7Fh ; remove clear regen switch | |
F000:0DA8 cmp al, 7 ; check for valid modes | |
F000:0DAA jz short c3 ; mode 7 is invalid | |
F000:0DAC cmp al, 0Bh | |
F000:0DAE jb short c4 ; greater than 0xa is invalid | |
F000:0DB0 c3: ; CODE XREF: set_mode+5j | |
F000:0DB0 mov al, 0 ; default to mode 0 | |
F000:0DB2 c4: ; CODE XREF: set_mode+9j | |
F000:0DB2 cmp al, 2 ; check for modes needing 128k | |
F000:0DB4 jz short c5 | |
F000:0DB6 cmp al, 3 | |
F000:0DB8 jz short c5 | |
F000:0DBA cmp al, 9 | |
F000:0DBC jb short c6 | |
F000:0DBE c5: ; CODE XREF: set_mode+Fj | |
F000:0DBE ; set_mode+13j | |
F000:0DBE cmp word ptr ds:seg40.true_mem, 128 ; do we have 128k? | |
F000:0DC4 jnb short c6 ; yes, jump | |
F000:0DC6 mov al, 0 ; no, default to mode 0 | |
F000:0DC8 c6: ; CODE XREF: set_mode+17j | |
F000:0DC8 ; set_mode+1Fj | |
F000:0DC8 mov dx, 3D4h ; address of color card | |
F000:0DCB mov ah, al ; save mode in ah | |
F000:0DCD mov ds:seg40.crt_mode, al ; save in global variable | |
F000:0DD0 mov ds:seg40.addr_6845, dx ; save address in base | |
F000:0DD4 mov di, ax ; save mode in di | |
F000:0DD6 mov dx, 3DAh ; point to control register | |
F000:0DD9 in al, dx ; sync control reg to address | |
F000:0DDA xor al, al ; set vga reg 0 (mode control 1) | |
F000:0DDC out dx, al ; select it | |
F000:0DDD mov al, ds:seg40.crt_mode_set ; get last mode set | |
F000:0DE0 and al, 11110111b ; turn off video | |
F000:0DE2 out dx, al ; set in gate array | |
F000:0DE3 ; ----- set default palettes | |
F000:0DE3 mov ax, di ; get mode | |
F000:0DE5 mov ah, 10h ; set palette reg 0 | |
F000:0DE7 mov bx, offset moo72 ; point to table entry | |
F000:0DEA cmp al, 6 ; 2 color mode? | |
F000:0DEC jz short c7 ; yes, jump | |
F000:0DEE mov bx, offset moo75 ; point to table entry | |
F000:0DF1 cmp al, 5 ; check for 4 color mode | |
F000:0DF3 jz short c7 ; yes, jump | |
F000:0DF5 cmp al, 4 ; check for 4 color mode | |
F000:0DF7 jz short c7 ; yes, jump | |
F000:0DF9 cmp al, 0Ah ; check for 4 color mode | |
F000:0DFB jnz short c9 ; no, jump | |
F000:0DFD c7: ; CODE XREF: set_mode+47j | |
F000:0DFD ; set_mode+4Ej set_mode+52j | |
F000:0DFD mov cx, 4 ; number of regs to set | |
F000:0E00 c8: ; CODE XREF: set_mode+65j | |
F000:0E00 mov al, ah ; get reg number | |
F000:0E02 out dx, al ; select it | |
F000:0E03 mov al, cs:[bx] ; get data | |
F000:0E06 out dx, al ; set it | |
F000:0E07 inc ah ; next reg | |
F000:0E09 inc bx ; next table value | |
F000:0E0A loop c8 | |
F000:0E0C jmp short c11 | |
F000:0E0E ;----- set palettes for 16 color | |
F000:0E0E c9: ; CODE XREF: set_mode+56j | |
F000:0E0E mov cx, 10h ; number of palettes, ah is reg counter | |
F000:0E11 c10: ; CODE XREF: set_mode+72j | |
F000:0E11 mov al, ah ; get reg number | |
F000:0E13 out dx, al ; select it | |
F000:0E14 out dx, al ; set palette value | |
F000:0E15 inc ah ; next reg | |
F000:0E17 loop c10 | |
F000:0E19 ;----- setup m0 & m1 in pagreg | |
F000:0E19 c11: ; CODE XREF: set_mode+67j | |
F000:0E19 mov ax, di ; get current mode | |
F000:0E1B xor bl, bl ; set up for alpha mode | |
F000:0E1D cmp al, 4 ; in alpha mode? | |
F000:0E1F jb short c12 ; yes, jump | |
F000:0E21 mov bl, 1000000b ; set up for 16k regen (bit 6 on) | |
F000:0E23 cmp al, 9 ; mode use 16k | |
F000:0E25 jb short c12 ; yes, jump | |
F000:0E27 mov bl, 11000000b ; set up for 32k regen (bit 7,6 on) | |
F000:0E29 c12: ; CODE XREF: set_mode+7Aj | |
F000:0E29 ; set_mode+80j | |
F000:0E29 mov dx, 3DFh ; set port address of pagreg | |
F000:0E2C mov al, ds:seg40.pagdat ; get last data output | |
F000:0E2F and al, 3Fh ; '?' ; clear m0 & m1 bits | |
F000:0E31 or al, bl ; set new bits | |
F000:0E33 out dx, al ; stuff back in port (update video address mode) | |
F000:0E34 mov ds:seg40.pagdat, al ; save copy in ram | |
F000:0E37 ;----- enable video and correct port settings | |
F000:0E37 mov ax, di ; get current mode | |
F000:0E39 xor ah, ah ; into ax reg | |
F000:0E3B mov cx, 4 ; set table entry lenght (moo70l) | |
F000:0E3E mul cx ; times mode for offset into table | |
F000:0E40 mov bx, ax ; table offset in bx | |
F000:0E42 add bx, offset moo70 ; add table start to offset | |
F000:0E46 mov ah, cs:[bx] ; save mode set and palette (ah=mode control 1) | |
F000:0E49 mov al, cs:[bx+2] ; till we can put them in ram (al=border color) | |
F000:0E4D mov si, ax | |
F000:0E4F cli ; disable interrupts | |
F000:0E50 call mode_alive ; keep memory data valid | |
F000:0E53 mov al, 10000b ; disable nmi and hold request | |
F000:0E55 out 0A0h, al | |
F000:0E57 mov dx, 3DAh | |
F000:0E5A mov al, 4 ; point to reset reg | |
F000:0E5C out dx, al ; send to gate array | |
F000:0E5D mov al, 2 ; set synchronous reset | |
F000:0E5F out dx, al ; do it | |
F000:0E60 ; while the gate array is in reset state, we cannot access ram | |
F000:0E60 mov ax, si ; restore new mode set (ah=mode control 1, al=border color) | |
F000:0E62 and ah, 11110111b ; turn off video enable (bit 3: video enable) | |
F000:0E65 xor al, al ; set up to select vga reg 0 (mode control 1) | |
F000:0E67 out dx, al ; select it | |
F000:0E68 xchg ah, al ; ah is vga reg counter | |
F000:0E6A out dx, al ; set mode | |
F000:0E6B mov al, 4 ; set up to select vga reg 4 (reset) | |
F000:0E6D out dx, al ; select it | |
F000:0E6E xor al, al ; (low before changing modes) | |
F000:0E70 out dx, al ; remove reset from vga | |
F000:0E71 ; now ok to access ram again | |
F000:0E71 mov al, 80h ; '' ; enable nmi again | |
F000:0E73 out 0A0h, al ; 0xa0 = nmi_port | |
F000:0E75 call mode_alive ; keep memory data valid | |
F000:0E78 sti | |
F000:0E79 jmp short c14 | |
F000:0E7B c13: ; CODE XREF: set_mode+E0j | |
F000:0E7B mov al, ah ; get vga reg number | |
F000:0E7D out dx, al ; select reg | |
F000:0E7E mov al, cs:[bx] ; get table value | |
F000:0E81 out dx, al ; put in vga reg | |
F000:0E82 c14: ; CODE XREF: set_mode+D4j | |
F000:0E82 inc bx ; next in table | |
F000:0E83 inc ah ; next reg | |
F000:0E85 loop c13 ; do entire entry | |
F000:0E87 ;---- set up crt and cpu page regs according to mode & memory size | |
F000:0E87 mov dx, 3DFh ; set io address of pagreg | |
F000:0E8A mov al, ds:seg40.pagdat ; get last data output | |
F000:0E8D and al, 11000000b ; clear reg bits | |
F000:0E8F mov bl, 110110b ; set up for graphics mode with 32k regen | |
F000:0E91 test al, 80h ; '' ; in this mode? | |
F000:0E93 jnz short c15 ; yes, jump | |
F000:0E95 mov bl, 111111b ; set up for 16k regen and 128k memory | |
F000:0E97 cmp word ptr ds:seg40.true_mem, 128 ; do we have 128k? | |
F000:0E9D jnb short c15 ; yes, jump | |
F000:0E9F mov bl, 11011b ; set up for 16k regen and 64k memory | |
F000:0EA1 c15: ; CODE XREF: set_mode+EEj | |
F000:0EA1 ; set_mode+F8j | |
F000:0EA1 or al, bl ; combine mode bits and reg values | |
F000:0EA3 out dx, al ; set port | |
F000:0EA4 mov ds:seg40.pagdat, al ; save copy in ram | |
F000:0EA7 mov ax, si ; put mode set & palette in ram | |
F000:0EA9 mov ds:seg40.crt_mode_set, ah | |
F000:0EAD mov ds:seg40.crt_palette, al | |
F000:0EB0 in al, 61h ; get current value of 8255 port b | |
F000:0EB2 and al, 11111011b ; set up graphics mode | |
F000:0EB4 test ah, 2 ; just set alpha mode in vga? | |
F000:0EB7 jnz short c16 ; yes, jump | |
F000:0EB9 or al, 4 ; set up alpha mode | |
F000:0EBB c16: ; CODE XREF: set_mode+112j | |
F000:0EBB out 61h, al ; stuff back in 8255 | |
F000:0EBD ;----- set up 6845 | |
F000:0EBD push ds ; save data segment value | |
F000:0EBE xor ax, ax ; set up for abs0 segment | |
F000:0EC0 mov ds, ax ; establish vector table addressing | |
F000:0EC2 lds bx, ds:74h ; get pointer to video parms (int 0x1d) | |
F000:0EC6 mov ax, di ; get current mode in ax | |
F000:0EC8 mov cx, 10h ; lenghts of each row of table | |
F000:0ECB nop | |
F000:0ECC cmp ah, 2 ; determine which to use | |
F000:0ECF jb short c17 ; mode is 0 or 1 | |
F000:0ED1 add bx, cx ; move to next row of init table | |
F000:0ED3 cmp ah, 4 | |
F000:0ED6 jb short c17 ; mode is 2 or 3 | |
F000:0ED8 add bx, cx ; move to graphics row of | |
F000:0EDA cmp ah, 9 ; init_table | |
F000:0EDD jb short c17 ; mode is 4, 5, 6, 8 or 9 | |
F000:0EDF add bx, cx ; move to next graphics row of init_table | |
F000:0EE1 ;----- bx points to correct row of initialization table | |
F000:0EE1 c17: ; CODE XREF: set_mode+12Aj | |
F000:0EE1 ; set_mode+131j | |
F000:0EE1 ; set_mode+138j | |
F000:0EE1 push ax ; save mode in ah | |
F000:0EE2 mov al, [bx+2] ; get horz. sync position | |
F000:0EE5 mov di, [bx+0Ah] ; get cursor type | |
F000:0EE8 push ds | |
F000:0EE9 call dss | |
F000:0EEC mov ds:seg40.horz_pos, al ; save horz. sync position variable | |
F000:0EEF mov ds:seg40.cursor_mode, di ; save cursor mode | |
F000:0EF3 push ax | |
F000:0EF4 mov al, ds:seg40.var_delay ; set default offset | |
F000:0EF7 and al, 0Fh | |
F000:0EF9 mov ds:seg40.var_delay, al | |
F000:0EFC pop ax | |
F000:0EFD pop ds | |
F000:0EFE xor ah, ah ; ah will serve as register number during loop | |
F000:0F00 mov dx, 3D4h ; point to 6845 | |
F000:0F03 ; loop through table, outputting reg address, then value from table | |
F000:0F03 c18: ; CODE XREF: set_mode+169j | |
F000:0F03 mov al, ah ; get 6845 register number | |
F000:0F05 out dx, al | |
F000:0F06 inc dx ; point to data port | |
F000:0F07 inc ah ; next register value | |
F000:0F09 mov al, [bx] ; get table value | |
F000:0F0B out dx, al ; out to chip | |
F000:0F0C inc bx ; next in table | |
F000:0F0D dec dx ; back to pointer register | |
F000:0F0E loop c18 ; do the whole table | |
F000:0F10 pop ax ; get mode back | |
F000:0F11 pop ds ; recover segment value | |
F000:0F12 ;----- fill regen area with blank | |
F000:0F12 xor di, di ; set up pointer for regen | |
F000:0F14 mov ds:seg40.crt_start, di ; start address saved in global | |
F000:0F18 mov byte ptr ds:seg40.active_page, 0 ; set page value | |
F000:0F1D pop dx ; get original input back | |
F000:0F1E and dl, 80h ; no clear of regen? | |
F000:0F21 jnz short c21 ; skip clearing regen | |
F000:0F23 mov dx, 0B800h ; setup segment for 16k regen area | |
F000:0F26 mov cx, 8192 ; number of words to clear (16k) | |
F000:0F29 cmp al, 9 ; require 32k byte regen? | |
F000:0F2B jb short c19 ; no, jump | |
F000:0F2D shl cx, 1 ; set 16k words to clear (32k) | |
F000:0F2F mov dx, 1800h ; set up segment for 32k regen arean | |
F000:0F32 c19: ; CODE XREF: set_mode+186j | |
F000:0F32 mov es, dx ; set regen segment | |
F000:0F34 cmp al, 4 ; test for graphics | |
F000:0F36 mov ax, 0F20h ; fill char for alpha (' ' + 15*256) | |
F000:0F39 jb short c20 ; no_graphics_init | |
F000:0F3B xor ax, ax ; fill for graphics mode | |
F000:0F3D c20: ; CODE XREF: set_mode+194j | |
F000:0F3D rep stosw ; fill the regen area with blanks | |
F000:0F3F ;----- enable video | |
F000:0F3F c21: ; CODE XREF: set_mode+17Cj | |
F000:0F3F mov dx, 3DAh ; set port address of vga | |
F000:0F42 xor al, al ; (al=0 -> mode control 1) | |
F000:0F44 out dx, al ; select vga reg 0 | |
F000:0F45 mov al, ds:seg40.crt_mode_set ; get mode set value | |
F000:0F48 out dx, al ; set mode | |
F000:0F49 ;----- determine number of columns, both for entire display | |
F000:0F49 ;----- and the number to be used for tty interface | |
F000:0F49 xor bh, bh | |
F000:0F4B mov bl, ds:seg40.crt_mode | |
F000:0F4F mov al, cs:moo60[bx] | |
F000:0F54 xor ah, ah | |
F000:0F56 mov ds:seg40.crt_cols, ax ; number of columns in this screen | |
F000:0F59 ;----- set cursor positions | |
F000:0F59 shl bx, 1 ; word offset into clear length table | |
F000:0F5B mov cx, cs:moo50[bx] ; length to clear | |
F000:0F60 mov ds:seg40.crt_len, cx ; save length of crt | |
F000:0F64 mov cx, 8 ; clear all cursor positions | |
F000:0F67 mov di, seg40.cursor_posn | |
F000:0F6A push ds ; establish segment | |
F000:0F6B pop es ; addressing | |
F000:0F6C xor ax, ax ; fill with zeroes | |
F000:0F6E rep stosw | |
F000:0F70 video_return: ; CODE XREF: video_io+18j | |
F000:0F70 ; write_tty+5Ej | |
F000:0F70 ; set_ctype+11j | |
F000:0F70 ; set_cpos:loc_FE49Fj | |
F000:0F70 ; act_disp_page+25j | |
F000:0F70 ; set_color+22j ... | |
F000:0F70 pop di | |
F000:0F71 pop si | |
F000:0F72 pop bx | |
F000:0F73 c22: ; CODE XREF: act_disp_page+77j | |
F000:0F73 ; video_state+Ej | |
F000:0F73 pop cx | |
F000:0F74 pop dx | |
F000:0F75 pop ds | |
F000:0F76 pop es ; recover segments | |
F000:0F77 iret ; all done | |
F000:0F77 set_mode endp ; sp = 0Eh | |
F000:0F78 ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:0F78 ; keyboard nmi interrupt routine | |
F000:0F78 ; | |
F000:0F78 ; this routine obtains control upon an nmi interrupt, which | |
F000:0F78 ; occurs upon a keystroke from the keyboard. | |
F000:0F78 ; | |
F000:0F78 ; this routine will de-serialize the bit stream in order to | |
F000:0F78 ; get the keyboard scan code entered. it then issues int 48 | |
F000:0F78 ; passing the scan code in al to the key processor . upon return | |
F000:0F78 ; it re-enables nmi and return to system (iret) | |
F000:0F78 kdbnmi proc far ; DATA XREF: F000:04D3o | |
F000:0F78 ; F000:06DCo | |
F000:0F78 cli | |
F000:0F79 push si | |
F000:0F7A push di | |
F000:0F7B push ax ; save regs | |
F000:0F7C push bx | |
F000:0F7D push cx | |
F000:0F7E push dx | |
F000:0F7F push ds | |
F000:0F80 push es | |
F000:0F81 mov si, 8 ; set up # of data bits | |
F000:0F84 xor bl, bl ; init parity counter | |
F000:0F86 xor ah, ah | |
F000:0F88 mov cx, 5 ; set counter | |
F000:0F8B i1: ; CODE XREF: kdbnmi:i2j | |
F000:0F8B in al, 62h ; get sample | |
F000:0F8D test al, 40h ; test if 1 | |
F000:0F8F jz short i2 ; jmp if 0 | |
F000:0F91 inc ah | |
F000:0F93 i2: ; CODE XREF: kdbnmi+17j | |
F000:0F93 loop i1 | |
F000:0F95 cmp ah, 3 | |
F000:0F98 jnb short i25 | |
F000:0F9A jmp short i8 | |
F000:0F9C db 90h ; | |
F000:0F9D i25: ; CODE XREF: kdbnmi+20j | |
F000:0F9D mov cx, 32h ; '2' | |
F000:0FA0 i3: ; CODE XREF: kdbnmi+2Ej | |
F000:0FA0 in al, 62h | |
F000:0FA2 test al, 40h | |
F000:0FA4 jz short i5 | |
F000:0FA6 loop i3 | |
F000:0FA8 jmp short i8 | |
F000:0FAA db 90h ; | |
F000:0FAB i5: ; CODE XREF: kdbnmi+2Cj | |
F000:0FAB mov al, 1000000b ; read clock | |
F000:0FAB ; (tim 1, latching, interrupt on terminal count, binary) | |
F000:0FAD out 43h, al | |
F000:0FAF nop | |
F000:0FB0 nop | |
F000:0FB1 in al, 41h | |
F000:0FB3 mov ah, al | |
F000:0FB5 in al, 41h | |
F000:0FB7 xchg ah, al | |
F000:0FB9 mov di, ax ; save clock time in di | |
F000:0FBB mov cx, 4 ; set counter | |
F000:0FBE i6: ; CODE XREF: kdbnmi+4Cj | |
F000:0FBE in al, 62h ; get sample | |
F000:0FC0 test al, 40h ; test if 0 | |
F000:0FC2 jnz short i8 ; jmp if invalid transition (sync) | |
F000:0FC4 loop i6 ; keep looking for valid transition | |
F000:0FC6 mov dx, 544 ; 310 usec away (.838 us / ct) | |
F000:0FC9 i7: ; CODE XREF: kdbnmi+67j | |
F000:0FC9 call i30 | |
F000:0FCC mov dx, 526 | |
F000:0FCF push ax | |
F000:0FD0 call i30 | |
F000:0FD3 mov cl, al | |
F000:0FD5 pop ax | |
F000:0FD6 cmp cl, al | |
F000:0FD8 jz short i9 | |
F000:0FDA shr bh, 1 | |
F000:0FDC or bh, al | |
F000:0FDE dec si | |
F000:0FDF jnz short i7 | |
F000:0FE1 call i30 | |
F000:0FE4 push ax | |
F000:0FE5 call i30 | |
F000:0FE8 mov cl, al | |
F000:0FEA pop ax | |
F000:0FEB cmp cl, al | |
F000:0FED jz short i9 | |
F000:0FEF and bl, 1 ; check if odd parity | |
F000:0FF2 jz short i9 ; jmp if parity error | |
F000:0FF4 sti ; enable interrupts | |
F000:0FF5 mov al, bh ; place scan code in al | |
F000:0FF7 int 48h ; character processing (PCjr - Cordless Keyboard Translation) | |
F000:0FF9 i8: ; CODE XREF: kdbnmi+22j | |
F000:0FF9 ; kdbnmi+30j kdbnmi+4Aj | |
F000:0FF9 ; kdbnmi+92j kdbnmi+B7j | |
F000:0FF9 pop es ; restore regs | |
F000:0FFA pop ds | |
F000:0FFB pop dx | |
F000:0FFC pop cx | |
F000:0FFD pop bx | |
F000:0FFE in al, 0A0h ; enable nmi (clear nmi latch) | |
F000:1000 pop ax | |
F000:1001 pop di | |
F000:1002 pop si | |
F000:1003 iret | |
F000:1004 ;----------parity, synch or phase error. output missed key beep | |
F000:1004 i9: ; CODE XREF: kdbnmi+60j | |
F000:1004 ; kdbnmi+75j kdbnmi+7Aj | |
F000:1004 call dss ; set up addressing | |
F000:1007 cmp si, 8 ; are we on the first data bit? | |
F000:100A jz short i8 ; no audio feedback (might be a glitch) | |
F000:100C test byte ptr ds:seg40.kb_flag_1, 1 ; check if transmition errors are to be reported | |
F000:1011 jnz short i10 ; 1=do not beep, 0=beep | |
F000:1013 mov bx, 80h ; '' ; duration of error beep | |
F000:1016 mov cx, 48h ; 'H' ; frequency of error beep | |
F000:1019 call kb_noise ; audio feedback | |
F000:101C and byte ptr ds:seg40.kb_flag, 0F0h ; clear alt,ctrl,left and right shifts | |
F000:1021 and byte ptr ds:seg40.kb_flag_1, 0Fh ; clear potential break of ins,caps num and scroll shifts | |
F000:1026 and byte ptr ds:seg40.kb_flag_2, 1Fh ; clear function states | |
F000:102B i10: ; CODE XREF: kdbnmi+99j | |
F000:102B inc byte ptr ds:seg40.kdb_error ; keep track of keyboard errors | |
F000:102F jmp short i8 | |
F000:102F kdbnmi endp | |
F000:1031 ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:1031 i30 proc near ; CODE XREF: kdbnmi:i7p | |
F000:1031 ; kdbnmi+58p kdbnmi+69p | |
F000:1031 ; kdbnmi+6Dp i30+14j | |
F000:1031 mov al, 1000000b ; read clock | |
F000:1031 ; (tim 1, latching, interrupt on terminal count, binary) | |
F000:1033 out 43h, al | |
F000:1035 nop | |
F000:1036 nop | |
F000:1037 in al, 41h | |
F000:1039 mov ah, al | |
F000:103B in al, 41h | |
F000:103D xchg ah, al | |
F000:103F mov cx, di ; get last clock time | |
F000:1041 sub cx, ax ; sub current time | |
F000:1043 cmp cx, dx ; is it time to sample? | |
F000:1045 jb short i30 ; no, keep looking at it | |
F000:1047 sub cx, dx ; update # of counts off | |
F000:1049 mov di, ax ; save current time as last time | |
F000:104B add di, cx ; add difference for next time | |
F000:104D ;----- start sampling data bit (5 samples) | |
F000:104D mov cx, 5 ; set counter | |
F000:1050 ;---------------------------------------------------- | |
F000:1050 ; | |
F000:1050 ; sample line | |
F000:1050 ; | |
F000:1050 ; port_c is sampled cx times and if there are 3 or more 1"s | |
F000:1050 ; then 80h is returned in al, else 00h is returned in al. | |
F000:1050 ; parity counter is mantained in es. | |
F000:1050 ; | |
F000:1050 ;---------------------------------------------------- | |
F000:1050 xor ah, ah ; clear counter | |
F000:1052 i32: ; CODE XREF: i30:i33j | |
F000:1052 in al, 62h ; get sample | |
F000:1054 test al, 40h ; test if 1 | |
F000:1056 jz short i33 ; jump if 0 | |
F000:1058 inc ah ; keep count of 1's | |
F000:105A i33: ; CODE XREF: i30+25j | |
F000:105A loop i32 ; keep sampling | |
F000:105C cmp ah, 3 ; valid 1? | |
F000:105F jb short i34 ; jmp if not valid 1 | |
F000:1061 mov al, 80h ; '' ; return 80h in al (1) | |
F000:1063 inc bl ; increment parity counter | |
F000:1065 retn ; return to caller | |
F000:1066 i34: ; CODE XREF: i30+2Ej | |
F000:1066 xor al, al ; return 0 in al (0) | |
F000:1068 retn ; return to caller | |
F000:1068 i30 endp | |
F000:1069 ;-----table of valid scan codes | |
F000:1069 kb0 db key_b, key_q, key_e, key_p, key_s, key_n, key_up_arrow | |
F000:1069 ; DATA XREF: key62_int+174o | |
F000:1069 ; key62_int:kb10_1o | |
F000:1069 db key_down_arrow, key_left_arrow, key_right_arrow, key_minus | |
F000:1069 db key_equals | |
F000:1075 ;-----table of new scan codes (fn + kb0 = kb1) | |
F000:1075 kb1 db key_break, key_pause, key_echo, key_prt_screen, key_scroll | |
F000:1075 ; DATA XREF: key62_int+1ABr | |
F000:1075 db key_num, key_home, key_end, key_page_up, key_page_down | |
F000:1075 db key_minus_pad, key_plus_pad | |
F000:1081 ;---------------------------------------------------- | |
F000:1081 ;note: there is a one to one correspondance between | |
F000:1081 ; the size of kb0 and kb1 | |
F000:1081 ;---------------------------------------------------- | |
F000:1081 ;table of numeric keypad scan codes | |
F000:1081 ; these scan codes were numeric scan codes on | |
F000:1081 ; the 83 key keyboard. | |
F000:1081 ;---------------------------------------------------- | |
F000:1081 num_codes db 4Fh, 50h, 51h, 4Bh, 4Ch, 4Dh, 47h, 48h, 49h, 52h | |
F000:1081 ; DATA XREF: key62_int+131o | |
F000:108B ;---------------------------------------------------- | |
F000:108B ;table of simulated keystrokes | |
F000:108B ; | |
F000:108B ; this table represents a 4*2 array. each row | |
F000:108B ; consists of a sequence of scan codes which | |
F000:108B ; would have been generated on an 83 key keyboard | |
F000:108B ; to cause the following functions: | |
F000:108B ; row 1=echo crt output to the printer | |
F000:108B ; row 2=break | |
F000:108B ; the table has both make and break scan codes. | |
F000:108B ;---------------------------------------------------- | |
F000:108B scan db 1Dh, 37h, 0B7h, 9Dh ; DATA XREF: key62_int+212o | |
F000:108B ; ctrl + prtsc | |
F000:108F db 1Dh, 46h, 0C6h, 9Dh ; ctrl + scroll_lock | |
F000:1093 ;---------------------------------------------------- | |
F000:1093 ;table of valid alt shift scan codes | |
F000:1093 ; | |
F000:1093 ; this table contains scan codes for keys on the | |
F000:1093 ; 62 key keyboard. these codes are used in | |
F000:1093 ; combinations with the alt key to produce scan codes | |
F000:1093 ; for keys not found on the 62 key keyboard. | |
F000:1093 ;---------------------------------------------------- | |
F000:1093 alt_table db 35h, 28h, 34h, 1Ah, 1Bh ; DATA XREF: key62_int+B7o | |
F000:1093 ; key62_int+C1o | |
F000:1098 ;---------------------------------------------------- | |
F000:1098 ;table of translated scan codes with alt shift | |
F000:1098 ; | |
F000:1098 ; this table contains the scan codes for the | |
F000:1098 ; keys which are not in the 62 key keyboard and | |
F000:1098 ; will be translated with alt shift. there is a | |
F000:1098 ; one to one correspondence between the sizes | |
F000:1098 ; of alt_table and new_alt. | |
F000:1098 ; the following translations are made: | |
F000:1098 ; alt+ / = \ | |
F000:1098 ; alt+ ' = ` | |
F000:1098 ; alt+ [ = | | |
F000:1098 ; alt+ ] = ~ | |
F000:1098 ; alt+ . = # | |
F000:1098 ;---------------------------------------------------- | |
F000:1098 new_alt db 2Bh, 29h, 37h, 2Bh, 29h ; DATA XREF: key62_int+C6r | |
F000:109D ;----------------------------------------------------------- | |
F000:109D ; extab | |
F000:109D ; table of scan codes for mapping extended set | |
F000:109D ; of scan codes (scan codes > 85). this table | |
F000:109D ; allows other devices to use the keyboard interface. | |
F000:109D ; if the device generates a scan code > 85 this table | |
F000:109D ; can be used to map the device to the keyboard. the | |
F000:109D ; device also has the option of having a unioue scan | |
F000:109D ; code put in the keyboard buffer (instead of mapping | |
F000:109D ; to the keyboard). the extended scan code put in the | |
F000:109D ; buffer will be continuous beginning at 150. a zero | |
F000:109D ; will be used in place of an ascii code (e.g. a | |
F000:109D ; device generating scan code 86 and not mapping 86 | |
F000:109D ; to the keyboard will have a [150,0] put in the | |
F000:109D ; keyboard buffer. | |
F000:109D ; table format: | |
F000:109D ; the first byte is a length indicating the number | |
F000:109D ; of scan codes mapped to the keyboard. the remaining | |
F000:109D ; entries are words. the first byte (low byte) is a | |
F000:109D ; scan code and the second byte (high byte) is zero. | |
F000:109D ; a device generating n scan codes is assumed to generate the | |
F000:109D ; following stream 86,87,88,...,b6+(n-1). the scan code bytes | |
F000:109D ; in the table correspond to this set with the first data | |
F000:109D ; byte matching 86, the second matching 87 etc. | |
F000:109D ; notes: | |
F000:109D ; (1) if a device generates a break code, nothing is | |
F000:109D ; put in the buffer | |
F000:109D ; (2) a length of 0 indicates that zero scan codes have been | |
F000:109D ; mapped to the keyboard and all extended scan codes will | |
F000:109D ; be used | |
F000:109D ; (3) a device can map some of its scan codes to the keyboard | |
F000:109D ; and have some its scan codes in the extended set | |
F000:109D ;----------------------------------------------------------- | |
F000:109D | |
F000:109D extab db 14h ; DATA XREF: F000:0218o | |
F000:109E dw 48h, 49h, 4Dh, 51h, 50h, 4Fh, 4Bh, 47h, 39h, 1Ch, 11h | |
F000:109E dw 12h, 1Fh, 2Dh, 2Ch, 2Bh, 1Eh, 10h, 0Fh, 1 | |
F000:10C6 ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:10C6 ; ----------------------------------------------------- | |
F000:10C6 ; key62_int (int 0x48) | |
F000:10C6 ; the purpose of this routine is to translate scan codes and | |
F000:10C6 ; scan code combinations from the 62 key keyboard to their | |
F000:10C6 ; equivalents on the 83 key keyboard. the scan code is | |
F000:10C6 ; passed in al. each scan code passed either triggers one or | |
F000:10C6 ; more calls to interrupt 9 or sets flags to retain keyboard | |
F000:10C6 ; status. when interrupt 9 is called the translated scan | |
F000:10C6 ; codes are passed to it in al. the intent of this code was | |
F000:10C6 ; to keep interrupt 9 intact from its origin in the pc family. | |
F000:10C6 ; this routine is in the front end of interrupt 9 and | |
F000:10C6 ; transforms a 62 key keyboard to look as if it uere an 83 | |
F000:10C6 ; key version. | |
F000:10C6 ; it is assumed that this routine is called from the nmi | |
F000:10C6 ; deserialization routine and that all registers were saved | |
F000:10C6 ; in the calling routine. as a consequence all registers are | |
F000:10C6 ; destroyed | |
F000:10C6 ; ----------------------------------------------------- | |
F000:10C6 key62_int proc far ; DATA XREF: F000:07C9o | |
F000:10C6 sti | |
F000:10C7 cld ; forward direction | |
F000:10C8 call dss ; set up addressing | |
F000:10CB mov ah, al ; save scan code | |
F000:10CD call tpm ; adjust output for user modification | |
F000:10D0 jnb short kbx0 ; jump if ok to continue | |
F000:10D2 iret ; return from interrupt | |
F000:10D3 ;-----extended scan code check | |
F000:10D3 kbx0: ; CODE XREF: key62_int+Aj | |
F000:10D3 cmp al, 0FFh ; is this an overrun char? | |
F000:10D5 jz short kb0_1 ; pass it to interrupt 9 | |
F000:10D7 and al, 7Fh ; turn off break bit | |
F000:10D9 cmp al, 86 ; is this scan code > 86? | |
F000:10DB jl short kbx4 ; replace break bit | |
F000:10DD ;-----scan code is in extended set | |
F000:10DD push ds | |
F000:10DE xor si, si | |
F000:10E0 mov ds, si | |
F000:10E2 les di, ds:124h ; get pointer to extended set (int 0x49) | |
F000:10E6 mov cl, es:[di] ; get lenght byte | |
F000:10E9 pop ds | |
F000:10EA ;-----does scan code get mapped to keyboard or to new extended scan codes? | |
F000:10EA sub al, 86 ; convert to base to new set | |
F000:10EC dec cl ; length - 1 | |
F000:10EE cmp al, cl ; is code in table? | |
F000:10F0 jg short kbx1 ; jump if scan code not in table | |
F000:10F2 ;-----get scan code from table | |
F000:10F2 inc di ; point di past length byte | |
F000:10F3 mov bx, ax | |
F000:10F5 xor bh, bh ; preparing for adding to 16 bit register | |
F000:10F7 shl bx, 1 | |
F000:10F9 add di, bx ; offset to correct table entry | |
F000:10FB mov al, es:[di] ; translated scan code in al | |
F000:10FE cmp al, 86 ; is code in keyboard set? | |
F000:1100 jl short kbx4 ; in keyboard set, check for break | |
F000:1102 ;-----scan code gets mapped to extended scan codes | |
F000:1102 kbx1: ; CODE XREF: key62_int+2Aj | |
F000:1102 test ah, 80h ; is this a break code? | |
F000:1105 jz short kbx2 ; make code, put it in buffer | |
F000:1107 iret ; break code, return from interrupt | |
F000:1108 kbx2: ; CODE XREF: key62_int+3Fj | |
F000:1108 add ah, 64 ; extended set codes begin at 150 | |
F000:110B xor al, al ; zero out ascii value (null) | |
F000:110D mov bx, ds:seg40.buffer_tail ; get tail pointer | |
F000:1111 mov si, bx ; save pointer to tail | |
F000:1113 call k4 ; increment tail value | |
F000:1116 cmp bx, ds:seg40.buffer_head ; is buffer full? | |
F000:111A jnz short kbx3 ; put contents of ax in buffer | |
F000:111C ;-----buffer is full, beep and clear flags | |
F000:111C mov bx, 80h ; '' ; frequency of beep | |
F000:111F mov cx, 48h ; 'H' ; duration of beep | |
F000:1122 call kb_noise ; buffer full beep | |
F000:1125 and byte ptr ds:seg40.kb_flag, 0F0h ; clear alt, ctrl, left and right shift | |
F000:112A and byte ptr ds:seg40.kb_flag_1, 0Fh ; clear make of ins, caps_lock, num and scroll | |
F000:112F and byte ptr ds:seg40.kb_flag_2, 1Fh ; clear function states | |
F000:1134 iret ; done with interrupt | |
F000:1135 kbx3: ; CODE XREF: key62_int+54j | |
F000:1135 mov [si], ax ; put contents of ax in buffer | |
F000:1137 mov ds:seg40.buffer_tail, bx ; advance buffer tail | |
F000:113B iret ; return from interrupt | |
F000:113C kbx4: ; CODE XREF: key62_int+15j | |
F000:113C ; key62_int+3Aj | |
F000:113C and ah, 80h ; mask break bit on original scan | |
F000:113F or al, ah ; update new scan code | |
F000:1141 mov ah, al ; save al in ah again | |
F000:1143 ;------83 key keyboard functions shift+prtsc and ctrl+numlock | |
F000:1143 kb0_1: ; CODE XREF: key62_int+Fj | |
F000:1143 cmp al, key_num ; is this a numlock? | |
F000:1145 jnz short kb0_3 ; check for prtsc | |
F000:1147 test byte ptr ds:seg40.kb_flag, 100b ; is ctrl key being held down? | |
F000:114C jz short kb0_2 ; numlock without ctrl, continue | |
F000:114E test byte ptr ds:seg40.kb_flag, 1000b ; is alt key held currently? | |
F000:1153 jnz short kb0_2 ; pass it on | |
F000:1155 jmp kb16_1 ; put keyboard in hold state | |
F000:1158 kb0_2: ; CODE XREF: key62_int+86j | |
F000:1158 ; key62_int+8Dj | |
F000:1158 ; key62_int+9Ej | |
F000:1158 ; key62_int+A5j | |
F000:1158 jmp cont_int ; continue with interrupt 0x48 | |
F000:115B ;-----check for prtsc | |
F000:115B kb0_3: ; CODE XREF: key62_int+7Fj | |
F000:115B cmp al, 55 ; is this prtsc key? | |
F000:115D jnz short kb1_1 ; not a prtsc key | |
F000:115F test byte ptr ds:seg40.kb_flag, 11b ; either shift active? | |
F000:1164 jz short kb0_2 ; process scan in int9 | |
F000:1166 test byte ptr ds:seg40.kb_flag, 100b ; is ctrl key pressed? | |
F000:116B jnz short kb0_2 ; not a valid prtsc (pc compatible) | |
F000:116D jmp prtsc ; handle the print screen function | |
F000:1170 ;-----alternate shift translations | |
F000:1170 kb1_1: ; CODE XREF: key62_int+97j | |
F000:1170 mov ah, al ; save character | |
F000:1172 and al, 7Fh ; mask break bit | |
F000:1174 test byte ptr ds:seg40.kb_flag, 1000b ; is this a potential translation? | |
F000:1179 jz short kb2 | |
F000:117B ;-----table lookup | |
F000:117B push cs | |
F000:117C pop es ; initialize segment for table lookup | |
F000:117D mov di, offset alt_table | |
F000:1180 mov cx, 5 ; get ready for table lookup | |
F000:1183 repne scasb ; search table | |
F000:1185 jnz short kb2 ; jump if match is not found | |
F000:1187 mov cx, (offset alt_table+1) | |
F000:118A sub di, cx ; update di to index scan code | |
F000:118C mov al, cs:new_alt[di] ; translate scan code | |
F000:1191 ;-----check for break code | |
F000:1191 mov bl, ds:seg40.kb_flag ; save kb_flag status | |
F000:1195 xor byte ptr ds:seg40.kb_flag, 1000b ; mask off alt shift | |
F000:119A test ah, 80h ; is this a break character | |
F000:119D jz short kb1_2 ; jump if scan is a make | |
F000:119F or al, 80h ; set break bit | |
F000:11A1 ;-----make code, check for shift sequence | |
F000:11A1 kb1_2: ; CODE XREF: key62_int+D7j | |
F000:11A1 cmp di, 3 ; is this a shift sequence | |
F000:11A4 jl short kb1_3 ; jump if not a shift sequence | |
F000:11A6 or byte ptr ds:seg40.kb_flag, 10b ; turn on shift flag | |
F000:11AB kb1_3: ; CODE XREF: key62_int+DEj | |
F000:11AB out 60h, al | |
F000:11AD int 9 ; issue int to process scan code | |
F000:11AF mov ds:seg40.kb_flag, bl ; restore original flag states | |
F000:11B3 iret | |
F000:11B4 ;-----function key handler | |
F000:11B4 kb2: ; CODE XREF: key62_int+B3j | |
F000:11B4 ; key62_int+BFj | |
F000:11B4 cmp al, key_fn ; check for function key (fn_key) | |
F000:11B6 jnz short kb4 ; jump if not function key | |
F000:11B8 test ah, 80h ; is this a function break | |
F000:11BB jnz short kb3 ; jump if function break | |
F000:11BD and byte ptr ds:seg40.kb_flag_2, 1Fh ; clear all previous functions | |
F000:11C2 or byte ptr ds:seg40.kb_flag_2, 10100000b ; (fn_flag + fn_pending) | |
F000:11C7 iret ; return from interrupt | |
F000:11C8 ;-----function break | |
F000:11C8 kb3: ; CODE XREF: key62_int+F5j | |
F000:11C8 test byte ptr ds:seg40.kb_flag_2, 100000b ; (fn_pending) | |
F000:11CD jnz short kb3_1 ; jump if function is pending | |
F000:11CF and byte ptr ds:seg40.kb_flag_2, 1Fh ; clear all flags | |
F000:11D4 iret | |
F000:11D5 kb3_1: ; CODE XREF: key62_int+107j | |
F000:11D5 or byte ptr ds:seg40.kb_flag_2, 1000000b ; set break flag (fn_break) | |
F000:11DA kb3_2: ; CODE XREF: key62_int+117j | |
F000:11DA iret ; return from interrupt | |
F000:11DB ;-----check if function flag already set | |
F000:11DB kb4: ; CODE XREF: key62_int+F0j | |
F000:11DB cmp al, key_phk ; is this a phantom key? (phk) | |
F000:11DD jz short kb3_2 ; jump if phantom sequence | |
F000:11DF test byte ptr ds:seg40.kb_flag_2, 10010000b ; are we in function state? (fn_flag + fn_lock) | |
F000:11E4 jnz short kb5 | |
F000:11E6 ;-----check if num_state is active | |
F000:11E6 test byte ptr ds:seg40.kb_flag, 100000b ; (num_state) | |
F000:11EB jz short kb4_0 ; jump if not in num_state | |
F000:11ED cmp al, key_num_0 ; are we in numeric keypad region? | |
F000:11EF ja short kb4_0 ; jump if not in keypad | |
F000:11F1 dec al ; check lower bound of range | |
F000:11F3 jz short kb4_0 ; jump if not in range (esc key) | |
F000:11F5 ;-----translate scan code to numeric keypad | |
F000:11F5 dec al ; al is offset into table | |
F000:11F7 mov bx, offset num_codes | |
F000:11FA xlat byte ptr cs:[bx] ; new scan code is in al | |
F000:11FC and ah, 80h ; isolate break bit on original scan code | |
F000:11FF or al, ah ; update keypad scan code | |
F000:1201 jmp short cont_int ; continue with interrupt | |
F000:1203 kb4_0: ; CODE XREF: key62_int+125j | |
F000:1203 ; key62_int+129j | |
F000:1203 ; key62_int+12Dj | |
F000:1203 mov al, ah ; get back break bit if set | |
F000:1205 jmp short cont_int | |
F000:1207 ;-----check for valid function key | |
F000:1207 kb5: ; CODE XREF: key62_int+11Ej | |
F000:1207 cmp al, key_num_0 ; check for range of integers | |
F000:1209 ja short kb7 ; jump if not in range | |
F000:120B dec al ; check for esc key (=1) | |
F000:120D jnz short kb6 ; not escape key, range of integers | |
F000:120F ;-----escape key, lock keyboard in function lock | |
F000:120F test ah, 80h ; is this a break code? | |
F000:1212 jnz short kb8 ; no processing for escape break | |
F000:1214 test byte ptr ds:seg40.kb_flag_2, 80h ; toggles only when fn held concurrently (fn_flag) | |
F000:1219 jz short kb8 ; not held concurrently | |
F000:121B test byte ptr ds:seg40.kb_flag_2, 40h ; has the function key been released (fn_break) | |
F000:1220 jnz short kb8 ; continue if released. process as esc | |
F000:1222 test byte ptr ds:seg40.kb_flag, 3 ; either shift? (left_shift+right_shift) | |
F000:1227 jz short kb8 ; not held down | |
F000:1229 xor byte ptr ds:seg40.kb_flag_2, 10h ; toggle state (fn_lock) | |
F000:122E and byte ptr ds:seg40.kb_flag_2, 1Fh ; turn off other states (clear_flags) | |
F000:1233 iret ; return from interrupt | |
F000:1234 ;-----scan code in range 1 -> 0 | |
F000:1234 kb6: ; CODE XREF: key62_int+147j | |
F000:1234 add al, 58 ; generate correct scan code | |
F000:1236 jmp short kb12 ; clean-up before return to kb_int | |
F000:1238 ;-----check table for other valid scan codes | |
F000:1238 kb7: ; CODE XREF: key62_int+143j | |
F000:1238 push cs | |
F000:1239 pop es ; establish address of table | |
F000:123A mov di, offset kb0 ; base of table | |
F000:123D mov cx, 0Ch ; lenght of table | |
F000:1240 repne scasb ; search table for a match | |
F000:1242 jz short kb10 ; jump if match | |
F000:1244 ;-----illegal character | |
F000:1244 kb8: ; CODE XREF: key62_int+14Cj | |
F000:1244 ; key62_int+153j | |
F000:1244 ; key62_int+15Aj | |
F000:1244 ; key62_int+161j | |
F000:1244 ; key62_int+1A4j | |
F000:1244 test byte ptr ds:seg40.kb_flag_2, 40h | |
F000:1249 jz short kb9 | |
F000:124B test ah, 80h | |
F000:124E jnz short kb9 | |
F000:1250 kb85: ; CODE XREF: key62_int+1FCj | |
F000:1250 and byte ptr ds:seg40.kb_flag_2, 1Fh | |
F000:1255 mov byte ptr ds:seg40.cur_func, 0 | |
F000:125A ;-----function break is not set | |
F000:125A kb9: ; CODE XREF: key62_int+183j | |
F000:125A ; key62_int+188j | |
F000:125A mov al, ah ; retreive original scancode | |
F000:125C cont_int: ; CODE XREF: key62_int:kb0_2j | |
F000:125C ; key62_int+13Bj | |
F000:125C ; key62_int+13Fj | |
F000:125C ; key62_int+203j | |
F000:125C out 60h, al ; AT Keyboard controller 8042. | |
F000:125E int 9 ; issue keyboard interrupt | |
F000:1260 ret_int: ; CODE XREF: key62_int+1D0j | |
F000:1260 ; key62_int+1E1j | |
F000:1260 iret | |
F000:1261 ;-----before translation check for alt+fn+n_key as num lock | |
F000:1261 kb10: ; CODE XREF: key62_int+17Cj | |
F000:1261 cmp al, key_n ; is this a potention numlock? (n_key) | |
F000:1263 jnz short kb10_1 ; not a numkey, translate it | |
F000:1265 test byte ptr ds:seg40.kb_flag, 8 ; alt held down also? | |
F000:126A jz short kb8 ; treat as illegal combination | |
F000:126C kb10_1: ; CODE XREF: key62_int+19Dj | |
F000:126C mov cx, (offset kb0+1) ; get offset to table | |
F000:126F sub di, cx ; update index to new scancode table | |
F000:1271 mov al, cs:kb1[di] ; move new scancode into register | |
F000:1276 ;-----translated code in al or an offset to the table "scan" | |
F000:1276 kb12: ; CODE XREF: key62_int+170j | |
F000:1276 test ah, 80h ; is this a break char? | |
F000:1279 jz short kb13 ; jump if make code | |
F000:127B ;-----check for toggle key | |
F000:127B cmp al, key_num ; is this a num lock? | |
F000:127D jz short kb12_1 ; jump if toggle key | |
F000:127F cmp al, key_scroll ; is this a scroll lock? | |
F000:1281 jnz short kb12_2 ; jump if not a toggle key | |
F000:1283 kb12_1: ; CODE XREF: key62_int+1B7j | |
F000:1283 or al, 80h ; turn on break bit | |
F000:1285 out 60h, al | |
F000:1287 int 9 ; toggle state | |
F000:1289 and al, 7Fh ; turn off break bit | |
F000:128B kb12_2: ; CODE XREF: key62_int+1BBj | |
F000:128B test byte ptr ds:seg40.kb_flag_2, 40h ; has function break occured? | |
F000:1290 jz short kb12_3 ; jump if break has not occured | |
F000:1292 cmp al, ds:seg40.cur_func ; is this a break of old valid function | |
F000:1296 jnz short ret_int ; allow further current functions | |
F000:1298 and byte ptr ds:seg40.kb_flag_2, 1Fh ; (clear_flags) | |
F000:129D kb12_20: ; CODE XREF: key62_int+1E8j | |
F000:129D mov byte ptr ds:seg40.cur_func, 0 ; clear current function | |
F000:12A2 iret ; return from interrupt | |
F000:12A3 kb12_3: ; CODE XREF: key62_int+1CAj | |
F000:12A3 cmp al, ds:seg40.cur_func ; is this break of first function? | |
F000:12A7 jnz short ret_int ; ignore | |
F000:12A9 and byte ptr ds:seg40.kb_flag_2, 0DFh ; turn off pending function (and_mask-fn_pending) | |
F000:12AE jmp short kb12_20 ; clear current function and return | |
F000:12B0 ;-----valid make key has pressed | |
F000:12B0 kb13: ; CODE XREF: key62_int+1B3j | |
F000:12B0 test byte ptr ds:seg40.kb_flag_2, 40h ; check if function key has been pressed | |
F000:12B5 jz short kb14_1 ; jump if not set | |
F000:12B7 ;------function break has already occured | |
F000:12B7 cmp byte ptr ds:seg40.cur_func, 0 ; is this a new function? | |
F000:12BC jz short kb14_1 ; initialize new function | |
F000:12BE cmp ds:seg40.cur_func, al ; is this non-current function | |
F000:12C2 jnz short kb85 ; jump if no function is pending to retreive original scan code | |
F000:12C4 ;-----check for scan code generation sequence | |
F000:12C4 kb14_1: ; CODE XREF: key62_int+1EFj | |
F000:12C4 ; key62_int+1F6j | |
F000:12C4 mov ds:seg40.cur_func, al ; initialize current fn | |
F000:12C7 cmp al, key_prt_screen ; is this a simulated sequence? | |
F000:12C9 jg short cont_int ; jump if this is a simple translation | |
F000:12CB jz short prtsc ; do the print screen function | |
F000:12CD cmp al, key_pause ; is this the hold function? | |
F000:12CF jz short kb16_1 | |
F000:12D1 ;-----break or echo | |
F000:12D1 dec al ; point at base | |
F000:12D3 shl al, 1 | |
F000:12D5 shl al, 1 ; multiply by 4 | |
F000:12D7 cbw | |
F000:12D8 db 2Eh | |
F000:12D8 lea si, scan ; address sequence of simulated keystrokes | |
F000:12DD add si, ax ; update to point at correct set | |
F000:12DF mov cx, 4 ; loop counter | |
F000:12E2 generate: ; CODE XREF: key62_int+222j | |
F000:12E2 lods byte ptr cs:[si] ; get scan code from table | |
F000:12E4 out 60h, al | |
F000:12E6 int 9 ; process it | |
F000:12E8 loop generate ; get next | |
F000:12EA iret | |
F000:12EB ;-----put keyboard in hold state | |
F000:12EB kb16_1: ; CODE XREF: key62_int+8Fj | |
F000:12EB ; key62_int+209j | |
F000:12EB test byte ptr ds:seg40.kb_flag_1, 8 | |
F000:12F0 jnz short kb16_2 | |
F000:12F2 or byte ptr ds:seg40.kb_flag_1, 8 | |
F000:12F7 in al, 0A0h ; reset keyboard latch | |
F000:12F9 hold: ; CODE XREF: key62_int+238j | |
F000:12F9 test byte ptr ds:seg40.kb_flag_1, 8 | |
F000:12FE jnz short hold | |
F000:1300 kb16_2: ; CODE XREF: key62_int+22Aj | |
F000:1300 iret | |
F000:1301 ;-----print screen function | |
F000:1301 prtsc: ; CODE XREF: key62_int+A7j | |
F000:1301 ; key62_int+205j | |
F000:1301 test byte ptr ds:seg40.kb_flag_1, 8 ; is hold state in progress | |
F000:1306 jz short kb16_3 ; ok to continue with prtsc | |
F000:1308 and byte ptr ds:seg40.kb_flag_1, 0F7h ; turn off flag | |
F000:130D iret | |
F000:130E kb16_3: ; CODE XREF: key62_int+240j | |
F000:130E add sp, 6 ; get rid of call to interrupt 48h | |
F000:1311 pop es ; pop registers that aren't modified in int5 | |
F000:1312 pop ds | |
F000:1313 pop dx | |
F000:1314 pop cx | |
F000:1315 pop bx | |
F000:1316 in al, 0A0h ; reset keyboard latch | |
F000:1318 int 5 ; issue interrupt | |
F000:131A pop ax | |
F000:131B pop di | |
F000:131C pop si ; pop the rest | |
F000:131D iret | |
F000:131D key62_int endp ; sp = 16h | |
F000:131E ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:131E ; ----------------------------------------------------- | |
F000:131E ; typamatic | |
F000:131E ; this routine will check keyboard status bits in kb_flag_2 | |
F000:131E ; and determine what state the keyboard is in. appropriate | |
F000:131E ; action will be taken. | |
F000:131E ; input | |
F000:131E ; al= scan code of key which triggered non-maskable interrupt | |
F000:131E ; output | |
F000:131E ; carry bit = 1 if no action is to be taken | |
F000:131E ; carry bit = 0 means scan code in al should be processed | |
F000:131E ; further | |
F000:131E ; modifications to the variables cur_char and var_delay are | |
F000:131E ; made. also the putchar bit in kb_flag_2 is toggled when | |
F000:131E ; the keyboard is in half rate mode | |
F000:131E ; ----------------------------------------------------- | |
F000:131E tpm proc near ; CODE XREF: key62_int+7p | |
F000:131E push bx | |
F000:131F cmp ds:seg40.cur_char, al ; is this a new char? | |
F000:1323 jz short tp2 ; jump if same character | |
F000:1325 ;-----new character check for break sequences | |
F000:1325 test al, 80h ; is the new key a break key? | |
F000:1327 jz short tp0 ; jump if not a break key | |
F000:1329 and al, 7Fh ; clear break bit | |
F000:132B cmp ds:seg40.cur_char, al ; is the new character the break of the last make? | |
F000:132F mov al, ah ; retreive original character | |
F000:1331 jnz short tp ; jump if not the same character | |
F000:1333 mov byte ptr ds:seg40.cur_char, 0 ; clear current character | |
F000:1338 tp: ; CODE XREF: tpm+13j tpm+2Fj | |
F000:1338 ; tpm+36j tpm+5Cj tpm+68j | |
F000:1338 clc ; clear carry bit | |
F000:1339 pop bx | |
F000:133A retn ; return | |
F000:133B ;-----initialize new character | |
F000:133B tp0: ; CODE XREF: tpm+9j | |
F000:133B mov ds:seg40.cur_char, al ; save new character | |
F000:133E and byte ptr ds:seg40.var_delay, 0F0h ; clear variable delay | |
F000:1343 and byte ptr ds:seg40.kb_flag_2, 0FEh ; initial putchar bit as zero | |
F000:1348 test byte ptr ds:seg40.kb_flag_2, 2 ; are we increasing the initial delay? | |
F000:134D jz short tp ; default delay | |
F000:134F or byte ptr ds:seg40.var_delay, 0Fh ; increase the delay by 2x | |
F000:1354 jmp short tp | |
F000:1356 ;-----check if we are in typamatic mode and if delay is over | |
F000:1356 tp2: ; CODE XREF: tpm+5j | |
F000:1356 test byte ptr ds:seg40.kb_flag_2, 8 ; if typamatic turned off? | |
F000:135B jnz short tp4 ; jump if typamatic turned off | |
F000:135D mov bl, ds:seg40.var_delay ; get var_delay | |
F000:1361 and bl, 0Fh ; mask off high order (screen range) | |
F000:1364 or bl, bl ; is initial delay over? | |
F000:1366 jz short tp3 ; jump if delay is over | |
F000:1368 dec bl ; decrease delay wait by another character | |
F000:136A and byte ptr ds:seg40.var_delay, 0F0h | |
F000:136F or ds:seg40.var_delay, bl | |
F000:1373 jmp short tp4 | |
F000:1375 ;-----check if time to output char | |
F000:1375 tp3: ; CODE XREF: tpm+48j | |
F000:1375 test byte ptr ds:seg40.kb_flag_2, 4 ; are we in half rate mode? | |
F000:137A jz short tp ; jump if we are in normal mode | |
F000:137C xor byte ptr ds:seg40.kb_flag_2, 1 ; toggle bit | |
F000:1381 test byte ptr ds:seg40.kb_flag_2, 1 ; is it time to put out a char | |
F000:1386 jnz short tp ; not time to output character | |
F000:1388 tp4: ; CODE XREF: tpm+3Dj tpm+55j | |
F000:1388 stc ; skip this character. set carry flag | |
F000:1389 pop bx | |
F000:138A retn | |
F000:138A tpm endp | |
F000:138B ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:138B dss proc near ; CODE XREF: F000:q23p | |
F000:138B ; F000:loc_F04E4p q35p | |
F000:138B ; F000:0643p F000:0809p | |
F000:138B ; video_io:c1p ... | |
F000:138B push ax | |
F000:138C mov ax, 40h ; '@' | |
F000:138F mov ds, ax | |
F000:1391 pop ax | |
F000:1392 retn | |
F000:1392 dss endp | |
F000:1393 ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:1393 ; --- int 0x1a ---------------------------------------- | |
F000:1393 ; time_of_day/sound source select | |
F000:1393 ; this routine allows the clock to be set/read | |
F000:1393 ; an interface for setting the multiplexer for | |
F000:1393 ; audio source is also provided | |
F000:1393 ; | |
F000:1393 ; input | |
F000:1393 ; (ah) = 0 read the current clock setting | |
F000:1393 ; return cx = high portion of count | |
F000:1393 ; dx = low portion of count | |
F000:1393 ; al = 0 if timer has not passed 24 hours | |
F000:1393 ; since last read. <> 0 if on another day | |
F000:1393 ; (ah) = 1 set current clock | |
F000:1393 ; cx = high portion of count | |
F000:1393 ; dx = low portion of count | |
F000:1393 ; (ah) = 80h set up sound multiplexer | |
F000:1393 ; al =(source of sound) --> "audio out" or rf modulator | |
F000:1393 ; 00 = 8253 channel 2 | |
F000:1393 ; 01 = cassette input | |
F000:1393 ; 02 = "audio in" line on i/o channel | |
F000:1393 ; 03 = complex sound generator chip | |
F000:1393 ; | |
F000:1393 ; note: counts occur at the rate of 1193180/65536 counts/sec | |
F000:1393 ; (out about 18.2 per second -- see equates below) | |
F000:1393 ; ----------------------------------------------------- | |
F000:1393 time_of_day proc far ; CODE XREF: F000:FE6Ej | |
F000:1393 ; DATA XREF: F000:FF17o | |
F000:1393 sti ; interrupts back on | |
F000:1394 push ds ; save segment | |
F000:1395 call dss | |
F000:1398 cmp ah, 80h ; '' ; ah=80? | |
F000:139B jz short t4a ; mux_set-up | |
F000:139D or ah, ah ; ah=0? | |
F000:139F jz short t2 ; read_time | |
F000:13A1 dec ah ; ah=1? | |
F000:13A3 jz short t3 ; set_time | |
F000:13A5 t1: ; CODE XREF: time_of_day+26j | |
F000:13A5 ; time_of_day+36j | |
F000:13A5 ; time_of_day+48j | |
F000:13A5 sti ; interrupts back on | |
F000:13A6 pop ds ; recover segment | |
F000:13A7 iret ; return to caller | |
F000:13A8 t2: ; CODE XREF: time_of_day+Cj | |
F000:13A8 cli ; no timer interrupts while reading | |
F000:13A9 mov al, ds:seg40.timer_ofl | |
F000:13AC mov byte ptr ds:seg40.timer_ofl, 0 ; get overflow, and reset flag | |
F000:13B1 mov cx, ds:seg40.timer_high | |
F000:13B5 mov dx, ds:seg40.timer_low | |
F000:13B9 jmp short t1 ; tod_return | |
F000:13BB t3: ; CODE XREF: time_of_day+10j | |
F000:13BB cli ; no interrupts while writing | |
F000:13BC mov ds:seg40.timer_low, dx | |
F000:13C0 mov ds:seg40.timer_high, cx ; set the time | |
F000:13C4 mov byte ptr ds:seg40.timer_ofl, 0 ; reset overflow | |
F000:13C9 jmp short t1 ; tod_return | |
F000:13CB t4a: ; CODE XREF: time_of_day+8j | |
F000:13CB push cx | |
F000:13CC mov cl, 5 | |
F000:13CE shl al, cl ; shift parm bits left 5 positions | |
F000:13D0 xchg al, ah ; save parm | |
F000:13D2 in al, 61h ; get current port settings | |
F000:13D4 and al, 10011111b ; isolate mux bits | |
F000:13D6 or al, ah ; combine port bits/parm bits | |
F000:13D8 out 61h, al ; set port to new value | |
F000:13DA pop cx | |
F000:13DB jmp short t1 ; tod_return | |
F000:13DB time_of_day endp | |
F000:13DD ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:13DD ; --- int 0x16 ---------------------------------------- | |
F000:13DD ; keyboard i/o | |
F000:13DD ; these routines provide keyboard support | |
F000:13DD ; input | |
F000:13DD ; (ah)=0 read the next ascii character struck from the | |
F000:13DD ; keyboard, return the result in (al), scan code in | |
F000:13DD ; (ah) | |
F000:13DD ; (ah)=1 set the z flag to indicate if an ascii character is | |
F000:13DD ; available to be read. | |
F000:13DD ; (zf)=1 -- no code available | |
F000:13DD ; (zf)=0 -- code is available | |
F000:13DD ; (ah)=2 return the current shift status in al register | |
F000:13DD ; the bit settings for this code are indicated in | |
F000:13DD ; the equates for kb_flag | |
F000:13DD ; (ah)=3 set typematic rates. the typematic rate can be | |
F000:13DD ; changed using the following functions: | |
F000:13DD ; (al)=0 return to default. restores original | |
F000:13DD ; state. i.e. typematic on, normal initial | |
F000:13DD ; delay, and normal typematic rate | |
F000:13DD ; (al)=1 increase initial delay. this is the | |
F000:13DD ; delay between the first characters | |
F000:13DD ; by one half. | |
F000:13DD ; (al)=2 half_rate. slows typematic character | |
F000:13DD ; by one half. | |
F000:13DD ; (al)=3 combines al=1 and al=2. increases | |
F000:13DD ; initial delay and slows typematic | |
F000:13DD ; characters by one half. | |
F000:13DD ; (al)=4 turn off typematic characters. only the | |
F000:13DD ; first character is honored. all others | |
F000:13DD ; are ignored. | |
F000:13DD ; al is range checked. if al<0 or al>4 the state | |
F000:13DD ; remains the same. | |
F000:13DD ; ***note*** each time the typematic rates are | |
F000:13DD ; changed all previous states are removed. i.e. if | |
F000:13DD ; the keyboard is in the half rate mode and you want | |
F000:13DD ; to add an increase in typematic delay, you must | |
F000:13DD ; call this routine with ah=3 and al=3 | |
F000:13DD ; (ah)=4 adjust keyboard by the value in al as follows: | |
F000:13DD ; (al)=0 turn off keyboard click. | |
F000:13DD ; (al)=1 turn on keyboard click. | |
F000:13DD ; al is range checked. the state is unaltered if | |
F000:13DD ; al <> 1,0. | |
F000:13DD ; output | |
F000:13DD ; as noted above, only ax and flags changed | |
F000:13DD ; all registers retained | |
F000:13DD ; ----------------------------------------------------- | |
F000:13DD keyboard_io proc far ; CODE XREF: F000:E82Ej | |
F000:13DD ; DATA XREF: F000:FF0Fo | |
F000:13DD sti | |
F000:13DE push ds | |
F000:13DF push bx | |
F000:13E0 call dss | |
F000:13E3 or ah, ah ; ah=0 | |
F000:13E5 jz short k1 ; ascii_read | |
F000:13E7 dec ah ; ah=1 | |
F000:13E9 jz short k2 ; ascii_status | |
F000:13EB dec ah ; ah=2 | |
F000:13ED jz short k3 ; shift_status | |
F000:13EF jmp short k3_1 | |
F000:13F1 k1: ; CODE XREF: keyboard_io+8j | |
F000:13F1 ; keyboard_io+1Fj | |
F000:13F1 sti | |
F000:13F2 nop | |
F000:13F3 cli | |
F000:13F4 mov bx, ds:seg40.buffer_head | |
F000:13F8 cmp bx, ds:seg40.buffer_tail | |
F000:13FC jz short k1 | |
F000:13FE mov ax, [bx] | |
F000:1400 call k4 | |
F000:1403 mov ds:seg40.buffer_head, bx | |
F000:1407 jmp short ret_int_16 | |
F000:1409 k2: ; CODE XREF: keyboard_io+Cj | |
F000:1409 cli | |
F000:140A mov bx, ds:seg40.buffer_head | |
F000:140E cmp bx, ds:seg40.buffer_tail | |
F000:1412 mov ax, [bx] | |
F000:1414 sti | |
F000:1415 pop bx | |
F000:1416 pop ds | |
F000:1417 retf 2 | |
F000:141A k3: ; CODE XREF: keyboard_io+10j | |
F000:141A mov al, ds:seg40.kb_flag | |
F000:141D jmp short ret_int_16 | |
F000:141F k3_1: ; CODE XREF: keyboard_io+12j | |
F000:141F dec ah | |
F000:1421 jz short k3_3 ; ah=3, adjust typematic | |
F000:1423 dec ah ; range check for ah=4 | |
F000:1425 jnz short ret_int_16 ; illegal function call | |
F000:1427 or al, al ; turn off keyboard click? | |
F000:1429 jnz short k3_2 ; jump for range check | |
F000:142B and byte ptr ds:seg40.kb_flag_1, 0FBh ; turn off click | |
F000:1430 jmp short ret_int_16 | |
F000:1432 k3_2: ; CODE XREF: keyboard_io+4Cj | |
F000:1432 cmp al, 1 | |
F000:1434 jnz short ret_int_16 | |
F000:1436 or byte ptr ds:seg40.kb_flag_1, 4 ; turn on keyboard click | |
F000:143B jmp short ret_int_16 | |
F000:143D k3_3: ; CODE XREF: keyboard_io+44j | |
F000:143D cmp al, 4 | |
F000:143F jg short ret_int_16 | |
F000:1441 and byte ptr ds:seg40.kb_flag_2, 0F1h ; mask off any old typematic states | |
F000:1446 shl al, 1 ; shift to proper position | |
F000:1448 or ds:seg40.kb_flag_2, al | |
F000:144C ret_int_16: ; CODE XREF: keyboard_io+2Aj | |
F000:144C ; keyboard_io+40j | |
F000:144C ; keyboard_io+48j | |
F000:144C ; keyboard_io+53j | |
F000:144C ; keyboard_io+57j | |
F000:144C ; keyboard_io+5Ej ... | |
F000:144C pop bx | |
F000:144D pop ds | |
F000:144E iret | |
F000:144E keyboard_io endp | |
F000:144F ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:144F ; ----- increment a buffer pointer | |
F000:144F k4 proc near ; CODE XREF: key62_int+4Dp | |
F000:144F ; keyboard_io+23p | |
F000:144F ; kb_int+202p kb_int+2C1p | |
F000:144F inc bx ; move to next word in list | |
F000:1450 inc bx | |
F000:1451 cmp bx, ds:seg40.buffer_end ; at the end of buffer? | |
F000:1455 jnz short k5 ; no, continue | |
F000:1457 mov bx, ds:seg40.buffer_start ; yes, reset to buffer beginning | |
F000:145B k5: ; CODE XREF: k4+6j | |
F000:145B retn | |
F000:145B k4 endp | |
F000:145C ;---- table of shift keys and mask values | |
F000:145C k6 db 52h, 3Ah, 45h, 46h, 38h, 1Dh, 2Ah, 36h ; DATA XREF: kb_int+32o | |
F000:145C ; kb_int:k17o | |
F000:1464 ;---- shift_mask table | |
F000:1464 k7 db 80h, 40h, 20h, 10h, 8, 4, 2, 1 ; DATA XREF: kb_int+45r | |
F000:146C ;---- scan code tables | |
F000:146C k8 db 1Bh, 0FFh, 0, 3 dup(0FFh), 1Eh, 4 dup(0FFh), 1Fh, 0FFh | |
F000:146C ; DATA XREF: kb_int:k42o | |
F000:146C db 7Fh, 0FFh, 11h, 17h, 5, 12h, 14h, 19h, 15h, 9, 0Fh | |
F000:146C db 10h, 1Bh, 1Dh, 0Ah, 0FFh, 1, 13h, 4, 6, 7, 8, 0Ah, 0Bh | |
F000:146C db 0Ch, 4 dup(0FFh), 1Ch, 1Ah, 18h, 3, 16h, 2, 0Eh, 0Dh | |
F000:146C db 6 dup(0FFh), 20h, 0FFh | |
F000:14A6 ;---- ctl table scan | |
F000:14A6 k9 db 5Eh, 5Fh, 60h, 61h, 62h, 63h, 64h, 65h, 66h, 67h, 2 dup(0FFh) | |
F000:14A6 ; DATA XREF: kb_int+21Do | |
F000:14A6 db 77h, 0FFh, 84h, 0FFh, 73h, 0FFh, 74h, 0FFh, 75h, 0FFh | |
F000:14A6 db 76h, 2 dup(0FFh) | |
F000:14BF ;---- lc table | |
F000:14BF k10 db 1Bh, 31h, 32h, 33h, 34h, 35h, 36h, 37h, 38h, 39h, 30h | |
F000:14BF ; DATA XREF: kb_int:k55o | |
F000:14BF db 2Dh, 3Dh, 8, 9, 71h, 77h, 65h, 72h, 74h, 79h, 75h, 69h | |
F000:14BF db 6Fh, 70h, 5Bh, 5Dh, 0Dh, 0FFh, 61h, 73h, 64h, 66h, 67h | |
F000:14BF db 68h, 6Ah, 6Bh, 6Ch, 3Bh, 27h, 60h, 0FFh, 5Ch, 7Ah, 78h | |
F000:14BF db 63h, 76h, 62h, 6Eh, 6Dh, 2Ch, 2Eh, 2Fh, 0FFh, 2Ah, 0FFh | |
F000:14BF db 20h, 0FFh | |
F000:14F9 ;---- vc table | |
F000:14F9 k11 db 1Bh, 21h, 40h, 23h, 24h, 25h, 5Eh, 26h, 2Ah, 28h, 29h | |
F000:14F9 ; DATA XREF: kb_int:k47o | |
F000:14F9 db 5Fh, 2Bh, 8, 0, 51h, 57h, 45h, 52h, 54h, 59h, 55h, 49h | |
F000:14F9 db 4Fh, 50h, 7Bh, 7Dh, 0Dh, 0FFh, 41h, 53h, 44h, 46h, 47h | |
F000:14F9 db 48h, 4Ah, 4Bh, 4Ch, 3Ah, 22h, 7Eh, 0FFh, 7Ch, 5Ah, 58h | |
F000:14F9 db 43h, 56h, 42h, 4Eh, 4Dh, 3Ch, 3Eh, 3Fh, 0FFh, 0, 0FFh | |
F000:14F9 db 20h, 0FFh | |
F000:1533 ;---- uc table scan | |
F000:1533 k12 db 54h, 55h, 56h, 57h, 58h, 59h, 5Ah, 5Bh, 5Ch, 5Dh | |
F000:1533 ; DATA XREF: kb_int+23Bo | |
F000:153D ;---- alt table scan | |
F000:153D k13 db 68h, 69h, 6Ah, 6Bh, 6Ch, 6Dh, 6Eh, 6Fh, 70h, 71h | |
F000:1547 ;---- num state table | |
F000:1547 k14 db 37h, 38h, 39h, 2Dh, 34h, 35h, 36h, 2Bh, 31h, 32h, 33h | |
F000:1547 ; DATA XREF: kb_int+277o | |
F000:1547 db 30h, 2Eh | |
F000:1554 ;---- base case table | |
F000:1554 k15 db 47h, 48h, 49h, 0FFh, 4Bh, 0FFh, 4Dh, 0FFh, 4Fh, 50h | |
F000:1554 ; DATA XREF: kb_int+25Eo | |
F000:1554 db 51h, 52h, 53h | |
F000:1561 ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:1561 ; int 0x09 handler | |
F000:1561 ; keyboard interrupt routine | |
F000:1561 kb_int proc far ; CODE XREF: F000:E987j | |
F000:1561 ; DATA XREF: real_vector_setup+Ao | |
F000:1561 ; F000:FEF5o | |
F000:1561 ; FUNCTION CHUNK AT F000:0043 SIZE 00000106 BYTES | |
F000:1561 sti ; allow further interrupts | |
F000:1562 push ax | |
F000:1563 push bx | |
F000:1564 push cx | |
F000:1565 push dx | |
F000:1566 push si | |
F000:1567 push di | |
F000:1568 push ds | |
F000:1569 push es | |
F000:156A cld ; forward direction | |
F000:156B call dss | |
F000:156E mov ah, al ; move scan code in ah | |
F000:1570 ;----- test for overrun scan code from keyboard | |
F000:1570 cmp al, 0FFh ; is this an overrun char? | |
F000:1572 jnz short k16 ; no, test for shift key | |
F000:1574 mov bx, 80h ; '' ; duration of error beep | |
F000:1577 mov cx, 48h ; 'H' ; frequency of tone | |
F000:157A call kb_noise ; buffer full beep | |
F000:157D and byte ptr ds:seg40.kb_flag, 0F0h | |
F000:1582 and byte ptr ds:seg40.kb_flag_1, 0Fh | |
F000:1587 and byte ptr ds:seg40.kb_flag_2, 1Fh | |
F000:158C jmp k26 | |
F000:158F ;----- test for shift keys | |
F000:158F k16: ; CODE XREF: kb_int+11j | |
F000:158F and al, 7Fh ; test shift | |
F000:158F ; turn off the break bit | |
F000:1591 push cs | |
F000:1592 pop es | |
F000:1593 mov di, offset k6 | |
F000:1596 mov cx, 8 | |
F000:1599 repne scasb | |
F000:159B mov al, ah | |
F000:159D jz short k17 | |
F000:159F jmp k25 | |
F000:15A2 ;----- shift key found | |
F000:15A2 k17: ; CODE XREF: kb_int+3Cj | |
F000:15A2 sub di, (offset k6+1) | |
F000:15A6 mov ah, cs:k7[di] | |
F000:15AB test al, 80h | |
F000:15AD jnz short k23 | |
F000:15AF ;----- shift make found, determine set or toggle | |
F000:15AF cmp ah, 10h | |
F000:15B2 jnb short k18 | |
F000:15B4 ;----- plain shift key, set shift on | |
F000:15B4 or ds:seg40.kb_flag, ah | |
F000:15B8 jmp k26 | |
F000:15BB ;----- toggled shift key, test for 1st make or not | |
F000:15BB k18: ; CODE XREF: kb_int+51j | |
F000:15BB test byte ptr ds:seg40.kb_flag, 4 | |
F000:15C0 jnz short k25 | |
F000:15C2 cmp al, 52h ; 'R' | |
F000:15C4 jnz short k22 | |
F000:15C6 test byte ptr ds:seg40.kb_flag, 8 | |
F000:15CB jnz short k25 | |
F000:15CD test byte ptr ds:seg40.kb_flag, 20h | |
F000:15D2 jnz short k21 | |
F000:15D4 test byte ptr ds:seg40.kb_flag, 3 | |
F000:15D9 jz short k22 | |
F000:15DB k20: ; CODE XREF: kb_int+85j | |
F000:15DB mov ax, 5230h ; put out an ascii zero | |
F000:15DE jmp k57 | |
F000:15E1 k21: ; CODE XREF: kb_int+71j | |
F000:15E1 test byte ptr ds:seg40.kb_flag, 3 | |
F000:15E6 jz short k20 | |
F000:15E8 k22: ; CODE XREF: kb_int+63j | |
F000:15E8 ; kb_int+78j | |
F000:15E8 test ds:seg40.kb_flag_1, ah | |
F000:15EC jnz short k26 | |
F000:15EE or ds:seg40.kb_flag_1, ah | |
F000:15F2 xor ds:seg40.kb_flag, ah | |
F000:15F6 cmp al, 52h ; 'R' | |
F000:15F8 jnz short k26 | |
F000:15FA mov ax, 5200h | |
F000:15FD jmp k57 ; put into output buffer | |
F000:1600 ;----- break shift found | |
F000:1600 k23: ; CODE XREF: kb_int+4Cj | |
F000:1600 cmp ah, 10h | |
F000:1603 jnb short k24 | |
F000:1605 not ah | |
F000:1607 and ds:seg40.kb_flag, ah | |
F000:160B cmp al, 0B8h ; '¸' | |
F000:160D jnz short k26 | |
F000:160F ;----- alternate shift key released, get the value into buffer | |
F000:160F mov al, ds:seg40.alt_input | |
F000:1612 xor ah, ah | |
F000:1614 mov ds:seg40.alt_input, ah | |
F000:1618 or al, al | |
F000:161A jz short k26 | |
F000:161C jmp k58 | |
F000:161F k24: ; CODE XREF: kb_int+A2j | |
F000:161F cmp al, 0BAh ; 'º' | |
F000:1621 jnz short k24_1 | |
F000:1623 test byte ptr ds:seg40.kb_flag_1, 2 | |
F000:1628 jz short k24_1 | |
F000:162A and byte ptr ds:seg40.kb_flag_1, 0FDh | |
F000:162F jmp short k26 | |
F000:1631 db 90h ; | |
F000:1632 ;----- break or normal toggle | |
F000:1632 k24_1: ; CODE XREF: kb_int+C0j | |
F000:1632 ; kb_int+C7j | |
F000:1632 not ah | |
F000:1634 and ds:seg40.kb_flag_1, ah | |
F000:1638 jmp short k26 | |
F000:163A ;----- test for hold state | |
F000:163A k25: ; CODE XREF: kb_int+3Ej | |
F000:163A ; kb_int+5Fj kb_int+6Aj | |
F000:163A cmp al, 80h ; '' | |
F000:163C jnb short k26 | |
F000:163E test byte ptr ds:seg40.kb_flag_1, 8 | |
F000:1643 jz short k28 | |
F000:1645 and byte ptr ds:seg40.kb_flag_1, 0F7h | |
F000:164A k26: ; CODE XREF: kb_int+2Bj | |
F000:164A ; kb_int+57j kb_int+8Bj | |
F000:164A ; kb_int+97j kb_int+ACj | |
F000:164A ; kb_int+B9j ... | |
F000:164A pop es | |
F000:164B pop ds | |
F000:164C pop di | |
F000:164D pop si | |
F000:164E pop dx | |
F000:164F pop cx | |
F000:1650 pop bx | |
F000:1651 pop ax | |
F000:1652 iret | |
F000:1653 ;----- not in hold state, test for special chars | |
F000:1653 k28: ; CODE XREF: kb_int+E2j | |
F000:1653 test byte ptr ds:seg40.kb_flag, 8 | |
F000:1658 jnz short k29 | |
F000:165A jmp k38 | |
F000:165D ;----- test for alt+ctrl key sequences | |
F000:165D k29: ; CODE XREF: kb_int+F7j | |
F000:165D test byte ptr ds:seg40.kb_flag, 4 ; test-reset | |
F000:165D ; are we in control shift also | |
F000:1662 jz short k31 ; no reset | |
F000:1664 cmp al, key_del ; shift state is there, test key | |
F000:1666 jnz short k29_1 ; no_reset | |
F000:1668 ;----- ctl-alt-del has been found, do i/o cleanup | |
F000:1668 mov word ptr ds:seg40.reset_flag, 1234h ; set flag for reset function | |
F000:166E jmp reset ; jump to power on diagnostics | |
F000:1671 k29_1: ; CODE XREF: kb_int+105j | |
F000:1671 cmp al, key_ins ; check for reset with diagnostics (ins_key) | |
F000:1673 jnz short k29_2 ; check for other alt-ctrl-sequences | |
F000:1675 ;----- alt-ctrl-ins has been found | |
F000:1675 mov word ptr ds:seg40.reset_flag, 4321h ; set flag for diagnostics | |
F000:167B jmp reset ; level 1 diagnostics | |
F000:167E k29_2: ; CODE XREF: kb_int+112j | |
F000:167E cmp al, key_caps ; check for keyboard click toggle (caps_key) | |
F000:1680 jnz short k29_3 ; check for screen adjustment | |
F000:1682 ;----- alt+ctrl+capslock has been found | |
F000:1682 test byte ptr ds:seg40.kb_flag_1, 2 | |
F000:1687 jnz short k26 | |
F000:1689 xor byte ptr ds:seg40.kb_flag_1, 4 ; toogle key for audio keystroke feedback | |
F000:168E or byte ptr ds:seg40.kb_flag_1, 2 ; set click_sequence state | |
F000:1693 jmp short k26 ; interrupt is over | |
F000:1695 k29_3: ; CODE XREF: kb_int+11Fj | |
F000:1695 cmp al, key_right_arrow ; adjust screen to the right? (right_arrow) | |
F000:1697 jnz short k29_4 ; look for right adjustment | |
F000:1699 call get_pos ; get the # of positions the screen is shifted | |
F000:169C cmp al, 0FCh ; 'ü' ; is the screen shifted as far as possible? | |
F000:169E jl short k26 ; out of range | |
F000:16A0 dec byte ptr ds:seg40.horz_pos ; shift value to the right | |
F000:16A4 dec al ; decrease range value | |
F000:16A6 call put_pos ; restore storage location | |
F000:16A9 jmp short k29_5 ; adjust | |
F000:16AB k29_4: ; CODE XREF: kb_int+136j | |
F000:16AB cmp al, key_left_arrow ; adjust screen to the left (left_arrow) | |
F000:16AD jnz short k31 ; not an alt_ctrl sequence | |
F000:16AF call get_pos ; get number of positions the screen is shifted | |
F000:16B2 cmp al, 4 ; is screen shifted as far as possible? | |
F000:16B4 jg short k26 | |
F000:16B6 inc byte ptr ds:seg40.horz_pos ; shift screen to the left | |
F000:16BA inc al ; increase number of positions screen is shifted | |
F000:16BC call put_pos ; put position back in storage | |
F000:16BF k29_5: ; CODE XREF: kb_int+148j | |
F000:16BF mov al, 2 ; adjust | |
F000:16C1 mov dx, 3D4h ; address to crt controller | |
F000:16C4 out dx, al | |
F000:16C5 mov al, ds:seg40.horz_pos ; column position | |
F000:16C8 inc dx ; point at data register | |
F000:16C9 out dx, al ; mov position | |
F000:16CA jmp k26 | |
F000:16CD ;----- in alternate shift, reset not found | |
F000:16CD k31: ; CODE XREF: kb_int+101j | |
F000:16CD ; kb_int+14Cj | |
F000:16CD cmp al, 57 ; no-reset | |
F000:16CD ; test for space key | |
F000:16CF jnz short k32 ; not there | |
F000:16D1 mov al, 20h ; ' ' ; set space char | |
F000:16D3 jmp k57 ; buffer_fill | |
F000:16D6 ;---- alt input table | |
F000:16D6 k30 db 52h, 4Fh, 50h, 51h, 4Bh, 4Ch, 4Dh, 47h, 48h, 49h | |
F000:16D6 ; DATA XREF: kb_int:k32o | |
F000:16D6 ; kb_int+1A3o | |
F000:16E0 ;---- super-shift-table | |
F000:16E0 db 10h, 11h, 12h, 13h, 14h, 15h, 16h, 17h, 18h, 19h, 1Eh | |
F000:16E0 db 1Fh, 20h, 21h, 22h, 23h, 24h, 25h, 26h, 2Ch, 2Dh, 2Eh | |
F000:16E0 db 2Fh, 30h, 31h, 32h | |
F000:16FA k32: ; CODE XREF: kb_int+16Ej | |
F000:16FA mov di, offset k30 | |
F000:16FD mov cx, 0Ah | |
F000:1700 repne scasb | |
F000:1702 jnz short k33 | |
F000:1704 sub di, (offset k30+1) | |
F000:1708 mov al, ds:seg40.alt_input | |
F000:170B mov ah, 0Ah | |
F000:170D mul ah | |
F000:170F add ax, di | |
F000:1711 mov ds:seg40.alt_input, al | |
F000:1714 jmp k26 | |
F000:1717 k33: ; CODE XREF: kb_int+1A1j | |
F000:1717 mov byte ptr ds:seg40.alt_input, 0 | |
F000:171C mov cx, 1Ah | |
F000:171F repne scasb | |
F000:1721 jnz short k34 | |
F000:1723 xor al, al | |
F000:1725 jmp k57 | |
F000:1728 k34: ; CODE XREF: kb_int+1C0j | |
F000:1728 cmp al, 2 | |
F000:172A jb short k35 | |
F000:172C cmp al, 0Eh | |
F000:172E jnb short k35 | |
F000:1730 add ah, 76h ; 'v' | |
F000:1733 xor al, al | |
F000:1735 jmp k57 | |
F000:1738 k35: ; CODE XREF: kb_int+1C9j | |
F000:1738 ; kb_int+1CDj | |
F000:1738 cmp al, 3Bh ; ';' | |
F000:173A jnb short k37 | |
F000:173C k36: ; CODE XREF: kb_int+1E0j | |
F000:173C jmp k26 | |
F000:173F k37: ; CODE XREF: kb_int+1D9j | |
F000:173F cmp al, 47h ; 'G' | |
F000:1741 jnb short k36 | |
F000:1743 mov bx, 153Dh | |
F000:1746 jmp k63 | |
F000:1749 k38: ; CODE XREF: kb_int+F9j | |
F000:1749 test byte ptr ds:seg40.kb_flag, 4 | |
F000:174E jz short k44 | |
F000:1750 cmp al, 46h ; 'F' | |
F000:1752 jnz short k41 | |
F000:1754 mov bx, ds:seg40.buffer_head | |
F000:1758 mov byte ptr ds:seg40.bios_break, 80h ; '' | |
F000:175D int 1Bh ; CTRL-BREAK KEY | |
F000:175F sub ax, ax | |
F000:1761 mov [bx], ax | |
F000:1763 call k4 | |
F000:1766 mov ds:seg40.buffer_tail, bx | |
F000:176A jmp k26 | |
F000:176D k41: ; CODE XREF: kb_int+1F1j | |
F000:176D cmp al, 37h ; '7' | |
F000:176F jnz short k42 | |
F000:1771 mov ax, 7200h | |
F000:1774 jmp short k57 | |
F000:1776 db 90h ; | |
F000:1777 k42: ; CODE XREF: kb_int+20Ej | |
F000:1777 mov bx, offset k8 | |
F000:177A cmp al, 3Bh ; ';' | |
F000:177C jb short k56 | |
F000:177E mov bx, offset k9 | |
F000:1781 jmp k63 | |
F000:1784 k44: ; CODE XREF: kb_int+1EDj | |
F000:1784 cmp al, 47h ; 'G' | |
F000:1786 jnb short k48 | |
F000:1788 test byte ptr ds:seg40.kb_flag, 3 | |
F000:178D jz short k54 | |
F000:178F cmp al, 0Fh | |
F000:1791 jnz short k46 | |
F000:1793 mov ax, 0F00h | |
F000:1796 jmp short k57 | |
F000:1798 k46: ; CODE XREF: kb_int+230j | |
F000:1798 cmp al, 3Bh ; ';' | |
F000:179A jb short k47 | |
F000:179C mov bx, offset k12 | |
F000:179F jmp k63 | |
F000:17A2 k47: ; CODE XREF: kb_int+239j | |
F000:17A2 mov bx, offset k11 | |
F000:17A5 jmp short k56 | |
F000:17A7 k48: ; CODE XREF: kb_int+225j | |
F000:17A7 test byte ptr ds:seg40.kb_flag, 20h | |
F000:17AC jnz short k52 | |
F000:17AE test byte ptr ds:seg40.kb_flag, 3 | |
F000:17B3 jnz short k53 | |
F000:17B5 k49: ; CODE XREF: kb_int+273j | |
F000:17B5 cmp al, 4Ah ; 'J' | |
F000:17B7 jz short k50 | |
F000:17B9 cmp al, 4Eh ; 'N' | |
F000:17BB jz short k51 | |
F000:17BD sub al, 47h ; 'G' | |
F000:17BF mov bx, offset k15 | |
F000:17C2 jmp k64 | |
F000:17C5 k50: ; CODE XREF: kb_int+256j | |
F000:17C5 mov ax, 4A2Dh | |
F000:17C8 jmp short k57 | |
F000:17CA k51: ; CODE XREF: kb_int+25Aj | |
F000:17CA mov ax, 4E2Bh | |
F000:17CD jmp short k57 | |
F000:17CF k52: ; CODE XREF: kb_int+24Bj | |
F000:17CF test byte ptr ds:seg40.kb_flag, 3 | |
F000:17D4 jnz short k49 | |
F000:17D6 k53: ; CODE XREF: kb_int+252j | |
F000:17D6 sub al, 46h ; 'F' | |
F000:17D8 mov bx, offset k14 | |
F000:17DB jmp short k56 | |
F000:17DD k54: ; CODE XREF: kb_int+22Cj | |
F000:17DD cmp al, 3Bh ; ';' | |
F000:17DF jb short k55 | |
F000:17E1 xor al, al | |
F000:17E3 jmp short k57 | |
F000:17E5 k55: ; CODE XREF: kb_int+27Ej | |
F000:17E5 mov bx, offset k10 | |
F000:17E8 k56: ; CODE XREF: kb_int+21Bj | |
F000:17E8 ; kb_int+244j kb_int+27Aj | |
F000:17E8 dec al | |
F000:17EA xlat byte ptr cs:[bx] | |
F000:17EC ;----- put character into buffer | |
F000:17EC k57: ; CODE XREF: kb_int+7Dj | |
F000:17EC ; kb_int+9Cj kb_int+172j | |
F000:17EC ; kb_int+1C4j kb_int+1D4j | |
F000:17EC ; kb_int+213j ... | |
F000:17EC cmp al, 0FFh ; buffer fill | |
F000:17EC ; is this an ignore char? | |
F000:17EE jz short k59 ; yes, do nothing with it | |
F000:17F0 cmp ah, 0FFh ; look for -1 pseudo scan | |
F000:17F3 jz short k59 ; near interrupt return | |
F000:17F5 k58: ; CODE XREF: kb_int+BBj | |
F000:17F5 test byte ptr ds:seg40.kb_flag, 40h | |
F000:17FA jz short k61 | |
F000:17FC test byte ptr ds:seg40.kb_flag, 3 | |
F000:1801 jz short k60 | |
F000:1803 cmp al, 41h ; 'A' | |
F000:1805 jb short k61 | |
F000:1807 cmp al, 5Ah ; 'Z' | |
F000:1809 ja short k61 | |
F000:180B add al, 20h ; ' ' | |
F000:180D jmp short k61 | |
F000:180F k59: ; CODE XREF: kb_int+28Dj | |
F000:180F ; kb_int+292j | |
F000:180F jmp k26 | |
F000:1812 ;----- convert any lower case to upper case | |
F000:1812 k60: ; CODE XREF: kb_int+2A0j | |
F000:1812 cmp al, 61h ; 'a' ; lower-to-upper | |
F000:1812 ; find out if alphabetic | |
F000:1814 jb short k61 ; not_caps_state | |
F000:1816 cmp al, 7Ah ; 'z' | |
F000:1818 ja short k61 ; not_caps_state | |
F000:181A sub al, 20h ; ' ' ; convert to uppper case ('a' - 'A') | |
F000:181C k61: ; CODE XREF: kb_int+299j | |
F000:181C ; kb_int+2A4j kb_int+2A8j | |
F000:181C ; kb_int+2ACj kb_int+2B3j | |
F000:181C ; kb_int+2B7j | |
F000:181C mov bx, ds:seg40.buffer_tail ; not_caps_state | |
F000:181C ; get the end pointer to the buffer | |
F000:1820 mov si, bx ; save the value | |
F000:1822 call k4 ; advance the tail | |
F000:1825 cmp bx, ds:seg40.buffer_head ; has the buffer wrapped around | |
F000:1829 jnz short k61_1 ; buffer_full_beep | |
F000:182B push bx ; save buffer tail | |
F000:182C mov bx, 80h ; '' ; duration of error beep | |
F000:182F mov cx, 48h ; 'H' ; frequency of error beep half tone | |
F000:1832 call kb_noise ; output noise | |
F000:1835 and byte ptr ds:seg40.kb_flag, 0F0h ; clear alt,clrl,left and right shifts | |
F000:183A and byte ptr ds:seg40.kb_flag_1, 0Fh ; clear potential break of ins,caps,num and scroll shift | |
F000:183F and byte ptr ds:seg40.kb_flag_2, 1Fh ; clear function states | |
F000:1844 pop bx ; retreive buffer tail | |
F000:1845 jmp k26 ; return from interrupt | |
F000:1848 k61_1: ; CODE XREF: kb_int+2C8j | |
F000:1848 test byte ptr ds:seg40.kb_flag_1, 4 ; is audio feedback enabled? | |
F000:184D jz short k61_2 ; no, just put in buffer | |
F000:184F push bx ; save buffer tail value | |
F000:1850 mov bx, 1 ; duration of click | |
F000:1853 mov cx, 10h ; frequency of click | |
F000:1856 call kb_noise ; output audio feedback of key stroke | |
F000:1859 pop bx ; retreive buffer_tail value | |
F000:185A k61_2: ; CODE XREF: kb_int+2ECj | |
F000:185A mov [si], ax ; store the value | |
F000:185C mov ds:seg40.buffer_tail, bx ; move the pointer up | |
F000:1860 jmp k26 ; interrupt_return | |
F000:1863 ;----- translate scan for pseudo scan codes | |
F000:1863 k63: ; CODE XREF: kb_int+1E5j | |
F000:1863 ; kb_int+220j kb_int+23Ej | |
F000:1863 sub al, 59 ; translate-scan | |
F000:1863 ; convert origin to function keys | |
F000:1865 k64: ; CODE XREF: kb_int+261j | |
F000:1865 xlat byte ptr cs:[bx] ; translate-scan-orgd | |
F000:1865 ; ctl table scan | |
F000:1867 mov ah, al ; put value into ah | |
F000:1869 xor al, al ; zero ascii code | |
F000:186B jmp k57 ; put it into the buffer | |
F000:186B kb_int endp | |
F000:186E ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:186E get_pos proc near ; CODE XREF: kb_int+138p | |
F000:186E ; kb_int+14Ep | |
F000:186E push cx | |
F000:186F mov al, ds:seg40.var_delay | |
F000:1872 and al, 0F0h ; mask off low nibble | |
F000:1874 mov cl, 4 | |
F000:1876 sar al, cl | |
F000:1878 pop cx | |
F000:1879 retn | |
F000:1879 get_pos endp | |
F000:187A ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:187A put_pos proc near ; CODE XREF: kb_int+145p | |
F000:187A ; kb_int+15Bp | |
F000:187A push cx | |
F000:187B mov cl, 4 | |
F000:187D shl al, cl | |
F000:187F mov cl, ds:seg40.var_delay | |
F000:1883 and cl, 0Fh | |
F000:1886 or al, cl | |
F000:1888 mov ds:seg40.var_delay, al | |
F000:188B pop cx | |
F000:188C retn | |
F000:188C put_pos endp | |
F000:188D ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:188D ; ----------------------------------------------------- | |
F000:188D ; manufactoring activity signal routine - invoked through the timer | |
F000:188D ; tick routine during manufacturing activities. (accessed through | |
F000:188D ; int 1ch) | |
F000:188D ; ----------------------------------------------------- | |
F000:188D mfg_tick proc far ; DATA XREF: F000:d6o | |
F000:188D ; F000:0302o | |
F000:188D push ax | |
F000:188E sub ax, ax ; send a 00 to port 13 as a | |
F000:1890 out 13h, al ; activity signal | |
F000:1892 in al, 61h ; flip speaker data to opposite sense | |
F000:1894 mov ah, al ; save orig setting | |
F000:1896 and ah, 10011101b ; make sure mux is -> right and isolate speaker bit | |
F000:1899 not al ; flip all bits | |
F000:189B and al, 10b ; isolate speaker data bit (now in opposite sense) | |
F000:189D or al, ah ; combine with orig. data form port b | |
F000:189F or al, 10000b ; and disable internal speaker | |
F000:18A1 out 61h, al | |
F000:18A3 mov al, 20h ; ' ' ; eoi to intr. chip | |
F000:18A5 out 20h, al | |
F000:18A7 pop ax | |
F000:18A8 iret | |
F000:18A8 mfg_tick endp | |
F000:18A9 ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:18A9 ; ----------------------------------------------------- | |
F000:18A9 ; convert and print ascii code | |
F000:18A9 ; | |
F000:18A9 ; al must contain number to be converted. | |
F000:18A9 ; ax and bx destroyed. | |
F000:18A9 ; ----------------------------------------------------- | |
F000:18A9 xpc_byte proc near ; CODE XREF: e_msg+70p | |
F000:18A9 ; e_msg+76p rom_check+33p | |
F000:18A9 push ax | |
F000:18AA mov cl, 4 | |
F000:18AC shr al, cl | |
F000:18AE call xlat_pr | |
F000:18B1 pop ax | |
F000:18B2 and al, 0Fh | |
F000:18B2 xpc_byte endp | |
F000:18B4 ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:18B4 xlat_pr proc near ; CODE XREF: xpc_byte+5p | |
F000:18B4 add al, 90h ; '' | |
F000:18B6 daa | |
F000:18B7 adc al, 40h ; '@' | |
F000:18B9 daa | |
F000:18B9 xlat_pr endp | |
F000:18BA ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:18BA prt_hex proc near ; CODE XREF: q35+2Ep q35+3Dp | |
F000:18BA ; e_msg+2Fp e_msg+54p | |
F000:18BA ; p_msg+5p | |
F000:18BA push bx | |
F000:18BB mov ah, 0Eh | |
F000:18BD mov bh, 0 | |
F000:18BF int 10h | |
F000:18C1 pop bx | |
F000:18C2 retn | |
F000:18C2 prt_hex endp | |
F000:18C3 ; START OF FUNCTION CHUNK FOR printer_io | |
F000:18C3 reprint: ; CODE XREF: printer_io+1Cj | |
F000:18C3 sub dx, dx | |
F000:18C5 test ch, 4 | |
F000:18C8 jz short loc_F18CB | |
F000:18CA inc dx | |
F000:18CB loc_F18CB: ; CODE XREF: printer_io-D70Aj | |
F000:18CB or ah, ah | |
F000:18CD jz short loc_F1910 | |
F000:18CF dec ah | |
F000:18D1 jz short loc_F18F0 | |
F000:18D3 dec ah | |
F000:18D5 jnz short loc_F18ED | |
F000:18D7 push ax | |
F000:18D8 mov ah, 3 | |
F000:18DA int 14h ; SERIAL I/O - GET USART STATUS | |
F000:18DA ; DX = port number (0-3) | |
F000:18DA ; Return: AX = port status code | |
F000:18DC call fake | |
F000:18DF pop ax | |
F000:18E0 or dh, dh | |
F000:18E2 jz short loc_F18EB | |
F000:18E4 mov ah, dh | |
F000:18E6 and ah, 0FEh | |
F000:18E9 jmp short loc_F18ED | |
F000:18EB loc_F18EB: ; CODE XREF: printer_io-D6F0j | |
F000:18EB mov ah, 90h ; '' | |
F000:18ED loc_F18ED: ; CODE XREF: printer_io-D6FDj | |
F000:18ED ; printer_io-D6E9j | |
F000:18ED ; printer_io-D6C8j | |
F000:18ED ; printer_io-D6C4j | |
F000:18ED ; printer_io-D6B3j | |
F000:18ED ; printer_io-D6AFj | |
F000:18ED jmp loc_FF00D | |
F000:18F0 loc_F18F0: ; CODE XREF: printer_io-D701j | |
F000:18F0 mov si, dx | |
F000:18F2 mov al, ds:78h | |
F000:18F5 add al, 0Ah | |
F000:18F7 mov [si+7Ch], al | |
F000:18FB push ax | |
F000:18FC mov al, 87h ; '' | |
F000:18FE sub ah, ah | |
F000:1900 int 14h ; SERIAL I/O - INITIALIZE USART | |
F000:1900 ; AL = initializing parameters, DX = port number (0-3) | |
F000:1900 ; Return: AH = RS-232 status code bits, AL = modem status bits | |
F000:1902 call fake | |
F000:1905 pop ax | |
F000:1906 mov ah, dh | |
F000:1908 or ah, ah | |
F000:190A jz short loc_F18ED | |
F000:190C mov ah, 0A8h ; '¨' | |
F000:190E jmp short loc_F18ED | |
F000:1910 loc_F1910: ; CODE XREF: printer_io-D705j | |
F000:1910 push ax | |
F000:1911 mov ah, 1 | |
F000:1913 int 14h ; SERIAL I/O - TRANSMIT CHARACTER | |
F000:1913 ; AL = character, DX = port number (0-3) | |
F000:1913 ; Return: AH = RS-232 status code bits, AL = modem status bits | |
F000:1915 call fake | |
F000:1918 pop ax | |
F000:1919 or dh, dh | |
F000:191B jz short loc_F1921 | |
F000:191D mov ah, dh | |
F000:191F jmp short loc_F18ED | |
F000:1921 loc_F1921: ; CODE XREF: printer_io-D6B7j | |
F000:1921 mov ah, 10h | |
F000:1923 jmp short loc_F18ED | |
F000:1923 ; END OF FUNCTION CHUNK FOR printer_io | |
F000:1925 ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:1925 fake proc near ; CODE XREF: printer_io-D6F6p | |
F000:1925 ; printer_io-D6D0p | |
F000:1925 ; printer_io-D6BDp | |
F000:1925 xor dh, dh | |
F000:1927 test ah, 1Eh | |
F000:192A jz short b13_1 | |
F000:192C mov dh, 8 | |
F000:192E retn | |
F000:192F b13_1: ; CODE XREF: fake+5j | |
F000:192F test ah, 80h | |
F000:1932 jz short b13_2 | |
F000:1934 mov dh, 9 | |
F000:1936 b13_2: ; CODE XREF: fake+Dj | |
F000:1936 retn | |
F000:1936 fake endp | |
F000:1937 ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:1937 ; ----------------------------------------------------- | |
F000:1937 ; new_int9 | |
F000:1937 ; this routine is the interrupt 9 handler when the machine is | |
F000:1937 ; first powered on and cassette basic is given control. it | |
F000:1937 ; handles the first keystrokes entered from the keyboard and | |
F000:1937 ; performs "special" actions as follows: | |
F000:1937 ; if esc is the first key enetered mini-welcome is | |
F000:1937 ; executed | |
F000:1937 ; if ctrl-esc is the first sequence "load cas1",r" is | |
F000:1937 ; executed giving the user the ability to boot | |
F000:1937 ; from cassette | |
F000:1937 ; after these keystrokes or after any other keystrokes the | |
F000:1937 ; interrupt 9 vector is changed to point at the real | |
F000:1937 ; interrupt 9 routine. | |
F000:1937 ; ----------------------------------------------------- | |
F000:1937 new_int_9 proc far ; DATA XREF: bas_ent+4o | |
F000:1937 cmp al, 1 ; is this an escape key? | |
F000:1939 jz short esc_key ; jump if al=esc key | |
F000:193B cmp al, key_ctl ; else, is this a control key? | |
F000:193D jz short ctrl_key ; jump if al=ctrl key | |
F000:193F call real_vector_setup ; otherwise initialize real int 9 vector | |
F000:1942 int 9 ; pass the scan code in al | |
F000:1944 iret ; return to interrupt 0x48 | |
F000:1945 ctrl_key: ; CODE XREF: new_int_9+6j | |
F000:1945 or byte ptr ds:seg40.kb_flag, 4 ; turn on ctrl shift in kb_flag | |
F000:194A iret ; return to interrupt | |
F000:194B esc_key: ; CODE XREF: new_int_9+2j | |
F000:194B test byte ptr ds:seg40.kb_flag, 4 ; has control shift occured? | |
F000:1950 jz short esc_only ; no. escape only | |
F000:1952 ;control escape has occured, put message in buffer for cassette | |
F000:1952 ;load | |
F000:1952 mov byte ptr ds:seg40.kb_flag, 0 ; zero out control state | |
F000:1957 push ds | |
F000:1958 pop es ; initialize es for bios data | |
F000:1959 push ds ; save old ds | |
F000:195A push cs ; point ds at code segment | |
F000:195B pop ds | |
F000:195C mov si, offset cas_load ; get message | |
F000:195F mov di, 1Eh ; point at keyboard buffer | |
F000:1962 mov cx, 0Fh ; lenght of cassette message | |
F000:1965 nop | |
F000:1966 t_loop: ; CODE XREF: new_int_9+31j | |
F000:1966 lodsb ; get ascii character from message | |
F000:1967 stosw ; put in keyboard buffer | |
F000:1968 loop t_loop | |
F000:196A pop ds ; retreive bios data segment | |
F000:196B ;-----initialize queue so message will be removed from buffer | |
F000:196B mov word ptr ds:seg40.buffer_head, 1Eh ; (kb_buffer) | |
F000:1971 mov word ptr ds:seg40.buffer_tail, 3Ch ; '<' ; (kb_buffer+cas_lenght*2) | |
F000:1977 ;---------------------------------------------------- | |
F000:1977 ;***note*** | |
F000:1977 ; it is assumed that the lenght of the cassette message is | |
F000:1977 ; less than or equal to the lenght of the buffer. if this is | |
F000:1977 ; not the case the buffer will eventually consume memory. | |
F000:1977 ;---------------------------------------------------- | |
F000:1977 call real_vector_setup | |
F000:197A iret | |
F000:197B esc_only: ; CODE XREF: new_int_9+19j | |
F000:197B call real_vector_setup | |
F000:197E mov cx, offset mini | |
F000:1981 jmp cx ; enter the world of keyboard caper | |
F000:1981 new_int_9 endp | |
F000:1983 ;-----message for output when control-escape is entered as first | |
F000:1983 ; key sequence | |
F000:1983 cas_load db 'LOAD "CAS1:",R',0Dh ; DATA XREF: new_int_9+25o | |
F000:1992 ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:1992 write_tty proc far ; CODE XREF: video_io+38j | |
F000:1992 ; DATA XREF: F000:0D05o | |
F000:1992 push ax | |
F000:1993 push ax | |
F000:1994 mov bh, ds:seg40.active_page | |
F000:1998 push bx | |
F000:1999 mov bl, bh | |
F000:199B xor bh, bh | |
F000:199D shl bx, 1 | |
F000:199F mov dx, [bx+50h] | |
F000:19A3 pop bx | |
F000:19A4 pop ax | |
F000:19A5 cmp al, 8 | |
F000:19A7 jz short loc_F19F9 | |
F000:19A9 cmp al, 0Dh | |
F000:19AB jz short loc_F1A01 | |
F000:19AD cmp al, 0Ah | |
F000:19AF jz short loc_F19C6 | |
F000:19B1 cmp al, 7 | |
F000:19B3 jz short loc_F1A05 | |
F000:19B5 mov ah, 0Ah | |
F000:19B7 mov cx, 1 | |
F000:19BA int 10h ; - VIDEO - WRITE CHARACTERS ONLY AT CURSOR POSITION | |
F000:19BA ; AL = character, BH = display page - alpha mode | |
F000:19BA ; BL = color of character (graphics mode, PCjr only) | |
F000:19BA ; CX = number of times to write character | |
F000:19BC inc dl | |
F000:19BE cmp dl, ds:seg40.crt_cols | |
F000:19C2 jnz short loc_F19F5 | |
F000:19C4 xor dl, dl | |
F000:19C6 loc_F19C6: ; CODE XREF: write_tty+1Dj | |
F000:19C6 cmp dh, 18h | |
F000:19C9 jnz short loc_F19F3 | |
F000:19CB mov ah, 2 | |
F000:19CD int 10h ; - VIDEO - SET CURSOR POSITION | |
F000:19CD ; DH,DL = row, column (0,0 = upper left) | |
F000:19CD ; BH = page number | |
F000:19CF mov al, ds:seg40.crt_mode | |
F000:19D2 cmp al, 4 | |
F000:19D4 jb short loc_F19DA | |
F000:19D6 xor bh, bh | |
F000:19D8 jmp short loc_F19E0 | |
F000:19DA loc_F19DA: ; CODE XREF: write_tty+42j | |
F000:19DA mov ah, 8 | |
F000:19DC int 10h ; - VIDEO - READ ATTRIBUTES/CHARACTER AT CURSOR POSITION | |
F000:19DC ; BH = display page | |
F000:19DC ; Return: AL = character | |
F000:19DC ; AH = attribute of character (alpha modes) | |
F000:19DE mov bh, ah | |
F000:19E0 loc_F19E0: ; CODE XREF: write_tty+46j | |
F000:19E0 mov ax, 601h | |
F000:19E3 sub cx, cx | |
F000:19E5 mov dh, 18h | |
F000:19E7 mov dl, ds:seg40.crt_cols | |
F000:19EB dec dl | |
F000:19ED loc_F19ED: ; CODE XREF: write_tty+65j | |
F000:19ED int 10h ; - VIDEO - SCROLL PAGE UP | |
F000:19ED ; AL = number of lines to scroll window (0 = blank whole window) | |
F000:19ED ; BH = attributes to be used on blanked lines | |
F000:19ED ; CH,CL = row,column of upper left corner of window to scroll | |
F000:19ED ; DH,DL = row,column of lower right corner of window | |
F000:19EF loc_F19EF: ; CODE XREF: write_tty+78j | |
F000:19EF pop ax | |
F000:19F0 jmp video_return | |
F000:19F3 loc_F19F3: ; CODE XREF: write_tty+37j | |
F000:19F3 inc dh | |
F000:19F5 loc_F19F5: ; CODE XREF: write_tty+30j | |
F000:19F5 ; write_tty+69j | |
F000:19F5 ; write_tty+6Dj | |
F000:19F5 ; write_tty+71j | |
F000:19F5 mov ah, 2 | |
F000:19F7 jmp short loc_F19ED | |
F000:19F9 loc_F19F9: ; CODE XREF: write_tty+15j | |
F000:19F9 or dl, dl | |
F000:19FB jz short loc_F19F5 | |
F000:19FD dec dl | |
F000:19FF jmp short loc_F19F5 | |
F000:1A01 loc_F1A01: ; CODE XREF: write_tty+19j | |
F000:1A01 xor dl, dl | |
F000:1A03 jmp short loc_F19F5 | |
F000:1A05 loc_F1A05: ; CODE XREF: write_tty+21j | |
F000:1A05 mov bl, 2 | |
F000:1A07 call beep | |
F000:1A0A jmp short loc_F19EF | |
F000:1A0A write_tty endp | |
F000:1A0C ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:1A0C ; dl = number of times to beep | |
F000:1A0C err_beep proc near ; CODE XREF: F000:08CDp | |
F000:1A0C ; F000:08DDp | |
F000:1A0C pushf | |
F000:1A0D push bx | |
F000:1A0E cli | |
F000:1A0F g3: ; CODE XREF: err_beep+Cj | |
F000:1A0F mov bl, 1 | |
F000:1A11 call beep | |
F000:1A14 g4: ; CODE XREF: err_beep:g4j | |
F000:1A14 loop g4 | |
F000:1A16 dec dl | |
F000:1A18 jnz short g3 | |
F000:1A1A g5: ; CODE XREF: err_beep:g5j | |
F000:1A1A loop g5 | |
F000:1A1C g6: ; CODE XREF: err_beep:g6j | |
F000:1A1C loop g6 | |
F000:1A1E pop bx | |
F000:1A1F popf | |
F000:1A20 retn | |
F000:1A20 err_beep endp | |
F000:1A21 ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:1A21 video_set_cursor_pos proc near ; CODE XREF: prtn3_int_82:set_cur_pos_and_printp | |
F000:1A21 ; prtn3_int_82:set_cur_pos_and_exitp | |
F000:1A21 mov ah, 2 | |
F000:1A23 push di | |
F000:1A24 push si | |
F000:1A25 int 10h ; - VIDEO - SET CURSOR POSITION | |
F000:1A25 ; DH,DL = row, column (0,0 = upper left) | |
F000:1A25 ; BH = page number | |
F000:1A27 pop si | |
F000:1A28 pop di | |
F000:1A29 retn | |
F000:1A29 video_set_cursor_pos endp | |
F000:1A2A ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ | |
F000:1A2A ; print something using basic strings | |
F000:1A2A ; bp = pointer to bas string | |
F000:1A2A ; dh = row bit7 bit6 special meaning | |
F000:1A2A ; dl = col | |
F000:1A2A ; bl = char attribute | |
F000:1A2A ; Attributes: bp-based frame | |
F000:1A2A prtn3_int_82 proc far ; DATA XREF: F000:0244o | |
F000:1A2A push ax | |
F000:1A2B push es | |
F000:1A2C push bp | |
F000:1A2D mov bp, sp | |
F000:1A2F mov ax, [bp+8] | |
F000:1A32 mov es, ax | |
F000:1A34 pop bp | |
F000:1A35 push bx | |
F000:1A36 push cx | |
F000:1A37 push bp | |
F000:1A38 push si | |
F000:1A39 push di | |
F000:1A3A push ds | |
F000:1A3B push dx | |
F000:1A3C call dss | |
F000:1A3F mov bh, ds:seg40.active_page | |
F000:1A43 xor cx, cx | |
F000:1A45 start_again: ; CODE XREF: prtn3_int_82+70j | |
F000:1A45 ; prtn3_int_82+102j | |
F000:1A45 mov di, 1 ; offset to pattern | |
F000:1A48 mov al, es:[bp+0] ; pattern len | |
F000:1A4C xor ah, ah | |
F000:1A4E mov si, ax ; pattern len in si | |
F000:1A50 test dh, 80h ; '' ; bit 7 = on -> use custom attrib | |
F000:1A53 jnz short skip_attrib | |
F000:1A55 mov bl, 111b ; attrib 7 = white | |
F000:1A57 skip_attrib: ; CODE XREF: prtn3_int_82+29j | |
F000:1A57 test dh, 40h ; bit 6 = off -> regural version | |
F000:1A5A jz short do_reg_version | |
F000:1A5C inc si ; len + 1 | |
F000:1A5D and dx, 1F7Fh ; row = 0-31. col=0-127 | |
F000:1A61 l1: ; CODE XREF: prtn3_int_82+8Aj | |
F000:1A61 inc cl ; total read +1 | |
F000:1A63 dec di ; attrib offset = 0 (?) | |
F000:1A64 not si ; len is in not'ed. re-not it. | |
F000:1A66 add si, 2 | |
F000:1A69 next_char: ; CODE XREF: prtn3_int_82+4Fj | |
F000:1A69 ; prtn3_int_82+57j | |
F000:1A69 ; prtn3_int_82+66j | |
F000:1A69 ; prtn3_int_82+CAj | |
F000:1A69 inc di ; offset + 1 | |
F000:1A6A inc si ; len-1 | |
F000:1A6B jz short _set_cur_pos_and_exit | |
F000:1A6D mov al, es:[bp+di] ; al = char from user buffer | |
F000:1A70 cmp al, 0Dh ; carriage return? | |
F000:1A72 jnz short not_cr | |
F000:1A74 add dh, 1 ; dh = row++ | |
F000:1A74 ; dl = col = 0 | |
F000:1A77 mov dl, 0 | |
F000:1A79 jmp short next_char | |
F000:1A7B not_cr: ; CODE XREF: prtn3_int_82+48j | |
F000:1A7B cmp al, 0Ah ; line feed? | |
F000:1A7D jnz short not_linefeed | |
F000:1A7F inc dh ; row ++ | |
F000:1A81 jmp short next_char | |
F000:1A83 not_linefeed: ; CODE XREF: prtn3_int_82+53j | |
F000:1A83 cmp al, 0Bh ; vertical tab? | |
F000:1A85 jnz short not_vt | |
F000:1A87 inc dh ; row ++ | |
F000:1A89 inc si ; next char | |
F000:1A8A inc di | |
F000:1A8B mov al, es:[bp+di] | |
F000:1A8E add dl, al ; col += char from buffer | |
F000:1A90 jmp short next_char | |
F000:1A92 not_vt: ; CODE XREF: prtn3_int_82+5Bj | |
F000:1A92 cmp al, 0Ch ; form feed? | |
F000:1A94 jnz short set_cur_pos_and_print | |
F000:1A96 inc di | |
F000:1A97 inc di | |
F000:1A98 add bp, di ; bp += 2 | |
F000:1A9A jmp short start_again | |
F000:1A9C do_reg_version: ; CODE XREF: prtn3_int_82+30j | |
F000:1A9C and dx, 1F7Fh ; row = 0-31. col=0-127 | |
F000:1AA0 reg_version_loop: ; CODE XREF: prtn3_int_82+D6j | |
F000:1AA0 ; prtn3_int_82+E1j | |
F000:1AA0 ; prtn3_int_82+EAj | |
F000:1AA0 ; prtn3_int_82+FDj | |
F000:1AA0 mov cl, es:[bp+si] ; cl = control code | |
F000:1AA3 inc si ; si = offset + 1 | |
F000:1AA4 cmp cl, 0 ; cl == 0 ? | |
F000:1AA7 jz short ctl_is_0 | |
F000:1AA9 jl short ctl_is_g_than_128 | |
F000:1AAB cmp cl, 51h ; 'Q' | |
F000:1AAE jl short set_cur_pos_and_print | |
F000:1AB0 jmp short check_more_ctrl_codes | |
F000:1AB2 ctl_is_g_than_128: ; CODE XREF: prtn3_int_82+7Fj | |
F000:1AB2 inc cl | |
F000:1AB4 jz short l1 ; cl = 0xff ? | |
F000:1AB6 inc cl | |
F000:1AB8 jz short reset_pattern_offset ; cl = 0xfe ? | |
F000:1ABA inc cl | |
F000:1ABC jz short update_row ; cl = 0xfd ? | |
F000:1ABE inc cl | |
F000:1AC0 jz short _set_cur_pos_and_exit ; cl = 0xfc ? | |
F000:1AC2 inc cl | |
F000:1AC4 jz short new_row ; cl = 0xfb ? | |
F000:1AC6 inc cl | |
F000:1AC8 jz short start_new_pattern ; cl = 0xfa | |
F000:1ACA sub cx, 6 ; restore orignal cx value (before the inc's) | |
F000:1ACD check_more_ctrl_codes: ; CODE XREF: prtn3_int_82+86j | |
F000:1ACD sub cl, 51h ; 'Q' | |
F000:1AD0 cmp cl, 50h ; 'P' | |
F000:1AD3 jl short update_col | |
F000:1AD5 sub cl, 50h ; 'P' | |
F000:1AD8 cmp cl, 51h ; 'Q' | |
F000:1ADB jl short update_attrib_and_print | |
F000:1ADD _set_cur_pos_and_exit: ; CODE XREF: prtn3_int_82+41j | |
F000:1ADD ; prtn3_int_82+96j | |
F000:1ADD jmp short set_cur_pos_and_exit | |
F000:1ADF set_cur_pos_and_print: ; CODE XREF: prtn3_int_82+6Aj | |
F000:1ADF ; prtn3_int_82+84j | |
F000:1ADF ; prtn3_int_82+F2j | |
F000:1ADF call video_set_cursor_pos | |
F000:1AE2 push di | |
F000:1AE3 push si | |
F000:1AE4 mov ah, 9 | |
F000:1AE6 mov al, es:[bp+di] ; al = char to print (pattern) | |
F000:1AE9 add dl, cl ; update column w/times char is written | |
F000:1AEB int 10h ; - VIDEO - WRITE ATTRIBUTES/CHARACTERS AT CURSOR POSITION | |
F000:1AEB ; AL = character, BH = display page | |
F000:1AEB ; BL = attributes of character (alpha modes) or color (graphics modes) | |
F000:1AEB ; CX = number of times to write character | |
F000:1AED pop si | |
F000:1AEE pop di | |
F000:1AEF ctl_is_0: ; CODE XREF: prtn3_int_82+7Dj | |
F000:1AEF ; prtn3_int_82+F0j | |
F000:1AEF cmp si, 0 | |
F000:1AF2 jge short check_pattern | |
F000:1AF4 jmp next_char | |
F000:1AF7 check_pattern: ; CODE XREF: prtn3_int_82+C8j | |
F000:1AF7 mov al, es:[bp+0] ; fetch pattern len | |
F000:1AFB xor ah, ah | |
F000:1AFD inc di ; pattern offset ++ | |
F000:1AFE cmp ax, di ; end of pattern? | |
F000:1B00 jg short reg_version_loop | |
F000:1B02 jmp short reset_pattern_offset | |
F000:1B04 new_row: ; CODE XREF: prtn3_int_82+9Aj | |
F000:1B04 mov dl, 0 ; col = 0 | |
F000:1B06 inc dh ; next row | |
F000:1B08 reset_pattern_offset: ; CODE XREF: prtn3_int_82+8Ej | |
F000:1B08 ; prtn3_int_82+D8j | |
F000:1B08 mov di, 1 ; reset pattern offset | |
F000:1B0B jmp short reg_version_loop | |
F000:1B0D update_col: ; CODE XREF: prtn3_int_82+A9j | |
F000:1B0D sub cl, 40 | |
F000:1B10 add dl, cl ; update col | |
F000:1B12 inc dh ; row++ | |
F000:1B14 jmp short reg_version_loop | |
F000:1B16 update_attrib_and_print: ; CODE XREF: prtn3_int_82+B1j | |
F000:1B16 mov bl, es:[bp+di] ; get attrib value | |
F000:1B19 inc di ; pattern offset++ | |
F000:1B1A jz short ctl_is_0 ; is it 0? (overflow?) | |
F000:1B1C jmp short set_cur_pos_and_print | |
F000:1B1E update_row: ; CODE XREF: prtn3_int_82+92j | |
F000:1B1E mov ah, es:[bp+si] ; ah = ctrl from buffer | |
F000:1B21 inc si ; ctl offset++ | |
F000:1B22 sub ah, 40 | |
F000:1B25 add dh, ah ; row += ah | |
F000:1B27 jmp reg_version_loop | |
F000:1B2A start_new_pattern: ; CODE XREF: prtn3_int_82+9Ej | |
F000:1B2A add bp, si | |
F000:1B2C jmp start_again | |
F000:1B2F set_cur_pos_and_exit: ; CODE XREF: prtn3_int_82:_set_cur_pos_and_exitj | |
F000:1B2F call video_set_cursor_pos | |
F000:1B32 pop bx | |
F000:1B33 push bx | |
F000:1B34 test bh, 20h | |
F000:1B37 jz short read_char_y_n | |
F000:1B39 test bh, 80h | |
F000:1B3C jz short beep_1 | |
F000:1B3E mov bl, 3 ; long beep | |
F000:1B40 call beep | |
F000:1B43 jmp short read_char_y_n | |
F000:1B45 beep_1: ; CODE XREF: prtn3_int_82+112j | |
F000:1B45 mov bl, 1 ; short beep | |
F000:1B47 call beep | |
F000:1B4A read_char_y_n: ; CODE XREF: prtn3_int_82+10Dj | |
F000:1B4A ; prtn3_int_82+119j | |
F000:1B4A pop bx | |
F000:1B4B test bl, 80h | |
F000:1B4E jz short exit | |
F000:1B50 mov ah, 0 | |
F000:1B52 int 16h ; KEYBOARD - READ CHAR FROM BUFFER, WAIT IF EMPTY | |
F000:1B52 ; Return: AH = scan code, AL = character | |
F000:1B54 cmp al, 59h ; 'Y' | |
F000:1B56 clc | |
F000:1B57 jn |