PAGE 64, 132 TITLE FELANI.ASM (c) 1989 JaMeSoft SUBTTL ZNET ROM BIOS EXTENZE PC ;***************************************************************************** ; Deklarace ;***************************************************************************** NetRamSeg equ 0cd00h NETRAM_SHIFT EQU 100H NET_BOOT_BIT EQU 01000000B ;tento bit na přepínači povoluje ;boot po síti BOOT_SEC_OFFS EQU 7C00H ;kam se čte boot sektor SIZE_BOOT_SEC EQU 512 ;a jeho velikost MAX_FRAME EQU 600 ;max. délka rámce RESET_DELAY EQU 5000 ;čekání po resetu ZNET GO_BASIC EQU 18H ;INT po neúspěšném IPL BIOS_VIDEO EQU 10H ;INT displej TTYWRITE EQU 14 ;funkce piš v TTY módu ;----------------------------------------------------------------------------- ; Chybové kódy ;----------------------------------------------------------------------------- RAM_WRITE_FAIL EQU 1 ;chyba ZNET RAM RESET_FAIL EQU 2 ;chyba ZNET reset ;***************************************************************************** ; formální segment pro flek INT basic ;***************************************************************************** INT_VECTORS SEGMENT AT 0 ORG 4 * GO_BASIC GO_BASIC_OFFS DW ? GO_BASIC_SEG DW ? ORG 4A6H LAN_2 DB ? LAN_1 DB ? INT_VECTORS ENDS ;***************************************************************************** ; formální segment pro načtení a spuštění boot sektoru po síti ;***************************************************************************** BOOT_SEC SEGMENT AT 0 ORG BOOT_SEC_OFFS BOOT_LOC PROC FAR ;sem přeneseme boot sektor a skočíme do něj DW 512 DUP (?) BOOT_LOC ENDP BOOT_SEC ENDS ;***************************************************************************** ; segment sdílené paměti ZNET ;***************************************************************************** NETRAM SEGMENT PAGE SWITCHES DB ? LOCAL_ADR DB ? CNT_COLISSION DB ? CNT_RX_ERROR DB ? TX_SEMAFOR DB ? TX_LEN DW ? ZVERS LABEL BYTE TX_BUF DB MAX_FRAME DUP (?) RX1_SEMAFOR DB ? RX1_LEN DW ? RX1_BUF DB MAX_FRAME + 2 DUP (?) RX2_SEMAFOR DB ? RX2_LEN DW ? RX2_BUF DB MAX_FRAME + 2 DUP (?) POST DW ? NETRAM ENDS ;***************************************************************************** ; segment ROM pro PC na ZNET ;***************************************************************************** NETROM SEGMENT PAGE ASSUME CS:NETROM, DS:NETRAM ;----------------------------------------------------------------------------- ; pár konstant ;----------------------------------------------------------------------------- CR EQU 13 LF EQU 10 BS EQU 8 ;############################################################################# ; makroinstrukce ;############################################################################# ; vypiš ASCIIZ string v CS WRITE MACRO STRING IFNB MOV AX, OFFSET STRING ENDIF CALL WRITE$ ENDM ;############################################################################# ; vypiš znak PUTCHAR MACRO CODE IFNB MOV AL, CODE ENDIF CALL PUTCHAR$ ENDM ;############################################################################# ; vypiš chybové hlášení a kód chyby ERROR MACRO NUMBER IFNB MOV AL, NUMBER ENDIF CALL ERROR$ ENDM ;############################################################################# ; resetuj ZNET RESET_CARD MACRO CALL RESET_CARD$ ENDM ;############################################################################# ; zpoždění n * LOOP $ DELAY MACRO COUNT IFNB MOV AX, COUNT ENDIF CALL DELAY$ ENDM ;############################################################################# ; piš hex slovo WRITEHW MACRO NUM IFNB MOV AX, NUM ENDIF CALL WRITEHW$ ENDM ;############################################################################# ; piš hex byte WRITEHB MACRO NUM IFNB MOV AL, NUM ENDIF CALL WRITEHB$ ENDM ;############################################################################# ; piš hex číslici WRITEHN MACRO NUM IFNB MOV AL, NUM ENDIF CALL WRITEHN$ ENDM .SALL ; nerozepisuj makra ;***************************************************************************** ; začátek BIOS extenze ;***************************************************************************** SETUP PROC FAR ;formální deklarace pro zjištění velikosti ROM ;***************************************************************************** ; konvence IBM, ROM SIGNATURE ;***************************************************************************** SIGNATURE LABEL BYTE DB 55H, 0AAH ;***************************************************************************** ; konvence IBM, ROM LEN mod 512 ;***************************************************************************** DB 8 ;4 kbyte ROM ;***************************************************************************** ; konvence IBM, ROM SCAN FAR CALL ENTRY POINT ; ; sem udělá ROM BIOS dlouhý call ;***************************************************************************** JMP SHORT ROM_SCAN ;skok na skutečný začátek SETUP ;***************************************************************************** ; konvence moje, doplní sumu ROM na 0 ;***************************************************************************** CHECKSUM: DB 0 ;***************************************************************************** ; otestuj ZNET, je-li nastaven přepínač net_boot, flekni INT basic ;***************************************************************************** ROM_SCAN PROC FAR PUSH DS ;pro sichr PUSH ES MOV AX, CS ADD AX, NETRAM_SHIFT MOV DS, AX ;máme assume ds : netram WRITE SIGNON ;ohlášení rom scanu RESET_CARD ;init ZNET MOV AL,SWITCHES ;přepínače na desce MOV AH,AL ;schovat XOR AL, -1 ;komplement MOV SWITCHES, AL ;zapsat CMP AL, SWITCHES ;podařilo se ? MOV AL, RAM_WRITE_FAIL ;připrav chybu JNE SCAN_DONE ;nepodařilo se, chyba RAM ;----------------------------------------------------------------------------- ; RAM snad funguje PUSH AX ;v AH původní přepínače, které jsme přepsali RESET_CARD ;init ZNET POP AX CMP AH, SWITCHES ;obnovil se stav přepínačů ? MOV AL,RESET_FAIL ;připrav chybu JNE SCAN_DONE ;ne, chyba funkce reset ;----------------------------------------------------------------------------- ; reset se povedl MOV AL, 0 ;chyba 0 je žádná chyba ; na SCAN_DONE se skáče, v AL je kód chyby, 0 je Ok SCAN_DONE: TEST AL, -1 ;byla chyba ? JNE SCAN_IVERS ;ano, nehledej verzi ROM Z80 MOV AX,POST CMP AX,'OK' JE DONE_1 ;----------------------------------------------------------------------------- CMP AX,'ER' MOV AL,-1 JNE SCAN_IVERS ;----------------------------------------------------------------------------- DONE_1: ;----------------------------------------------------------------------------- ; ZNET je Ok MOV SI, OFFSET ZVERS NEXT: MOV AL, [SI] ;znak INC SI ;index na další znak TEST AL, -1 ;kód znaku je 0 ? JE NEXT_1 ;ano, konec stringu ;----------------------------------------------------------------------------- ; v AL znak pro výpis PUTCHAR ;vypsat JMP NEXT ;a na další ;============================================================================= ; NEXT_1: PUTCHAR CR ;oddělit před verzí PC ROM PUTCHAR LF MOV AL, 0 ;žádná chyba ; tady je zase v AL příznak chyby, 0 je Ok SCAN_IVERS: PUSH AX ;schovat chybu WRITE IVERS ;vypiš verzi PC ROM POP AX ;obnovit chybu TEST AL, -1 ;Ok ? JNE SCAN_ERROR ;ne, přeskoč výpis přepínačů ;----------------------------------------------------------------------------- ; všechno proběhlo dobře WRITE ADR_MSG ;SW= MOV AL, SWITCHES ;přepínače TEST AL,80H JE SCAN_IVERS_1 ;----------------------------------------------------------------------------- ; KARTA 2 AND AL,0BFH MOV SWITCHES, AL SCAN_IVERS_1: WRITEHB ;vypsat v hexu PUTCHAR ' ' ;oddělit mezerou JMP SCAN_OK ;pokračuj větví Ok ;============================================================================= ; vypsat chybu a kód chyby SCAN_ERROR: ERROR ;ERROR XX JMP SCAN_EXIT ;víc nelze dělat ;============================================================================= ; jsme spokojeni SCAN_OK: WRITE OK_MSG ;oznam úspěch testu MOV AL, SWITCHES MOV AH, AL OR AL, 80H MOV CX, SEG INT_VECTORS MOV DS, CX ;zajisti následující assume ASSUME DS:INT_VECTORS TEST AH,80H JE SCAN_OK_0 ;----------------------------------------------------------------------------- ; KARTA 2 MOV LAN_2,AL ;připrav flag pro ROM BIOS JMP SCAN_EXIT ;NO NET BOOT FROM LANA 2 ;============================================================================= ; KARTA 1 SCAN_OK_0: MOV LAN_1,AL TEST AL, NET_BOOT_BIT ;net boot povolen ? JE SCAN_EXIT ;ne, jsem hotovi ;----------------------------------------------------------------------------- ; net boot povolen, flekni INT basic MOV AX, OFFSET NET_BOOT ;ofset část int vektoru MOV GO_BASIC_OFFS, AX MOV AX, CS ;segment část int vektoru MOV GO_BASIC_SEG, AX ;int basic půjde do NET_BOOT ;ukončení ROM_SCAN SCAN_EXIT: MOV CX,0 LOOP $ LOOP $ LOOP $ LOOP $ LOOP $ POP ES ;vrátíme segment registry POP DS RET ;zpátky do ROM_BIOS ROM_SCAN ENDP SETUP ENDP ;***************************************************************************** ; net boot zkusí zavést něco po síti ;***************************************************************************** ASSUME DS:NETRAM NET_BOOT PROC FAR ;int rutina je FAR MOV AX,CS MOV DS,AX MOV SI,0 MOV AX,SEG ROM_COPY MOV ES,AX MOV DI,0 MOV CX,NETROM_SIZE CLI CLD REP MOVSB PUSH ES MOV AX,OFFSET NET_BOOT_CONT PUSH AX RET ;============================================================================= NET_BOOT_CONT: MOV AX, NetRamSeg MOV DS, AX ;splnit assume WRITE NET_BOOT_MSG ;oznam pokus o net boot MOV RX1_SEMAFOR, 0 ;povolit příjem MOV RX2_SEMAFOR,0 MOV CX,1 ;čítač pokusů o vyslání MOV BX,0 ;čítač přijatých platných rámců NET_BOOT_1: MOV AX, NetRamSeg MOV ES, AX WRITEHW CX ;číslo vysílání PUTCHAR ' ' ;oddělit od WRITEHW BX ;čísla příjatých rámců PUSH CX ;schovat čítač TEST TX_SEMAFOR, -1 ;vysílání připraveno ? JE NETBOOT_2 ;ano, Ok ;----------------------------------------------------------------------------- ; neodvysílaná zpráva RESET_CARD ;init ZNET TEST TX_SEMAFOR, -1 ;reset Ok ? JE NETBOOT_2 ;ano, fajn ;----------------------------------------------------------------------------- ; nezdar resetu ERROR RESET_FAIL ;to se poví JMP $ ;a co teď ? ;============================================================================= ; připraveni vysílat NETBOOT_2: MOV AX, CS ;připrav vysílanou zprávu PUSH DS MOV DS, AX CLD MOV SI, OFFSET BOOT_FRAME MOV DI, OFFSET TX_BUF MOV CX, SIZE_BOOT_FRAME REP MOVSB ;šup tam s ní POP DS MOV TX_LEN,SIZE_BOOT_FRAME MOV TX_SEMAFOR, 1 ;žádej vysílání NET_BOOT_2A: MOV CX,0 LOOP $ ;----------------------------------------------------------------------------- MOV SI,OFFSET RX1_SEMAFOR TEST BYTE PTR [SI], -1 ;přijalo se něco ? JNE NET_BOOT_RX ;ano, mrkni se je-li to boot_block ;----------------------------------------------------------------------------- LOOP $ ;----------------------------------------------------------------------------- MOV SI,OFFSET RX2_SEMAFOR TEST BYTE PTR [SI], -1 JNE NET_BOOT_RX ;----------------------------------------------------------------------------- LOOP $ ;----------------------------------------------------------------------------- TEST TX_SEMAFOR, -1 ;odvysíláno ? JNE NET_BOOT_2A ;ještě ne, čekej dál ;----------------------------------------------------------------------------- ; žádost vyslána, ale nikdo nereaguje POP CX ;čítač pokusů INC CX ;++ JMP NET_BOOT_3 ;a znova ;============================================================================= ; někdo něco poslal NET_BOOT_RX: INC BX ;počet přijatých rámců MOV AX, CS MOV ES, AX CLD ADD SI,6 MOV DI, OFFSET BOOT_BLOCK MOV CX, SIZE_BOOT_BLOCK PUSH SI REPE CMPSB ;je to boot block ? POP SI POP CX JE NET_BOOT_OK ;ano ;----------------------------------------------------------------------------- ; rámec přijat, ale není to boot block MOV BYTE PTR [SI-6],0 ;povol příjem JMP NET_BOOT_3 ;a další pokus ;============================================================================= ; přijat platný boot block NET_BOOT_OK: MOV AX, SEG BOOT_LOC MOV ES, AX CLD ADD SI,7 MOV DI, OFFSET BOOT_LOC MOV CX, SIZE_BOOT_SEC REP MOVSB ;přesun do BOOT_LOC PUTCHAR ' ' WRITE OK_MSG ;ohlaš úspěch net boot POP CX MOV RX1_SEMAFOR, 0 ;povol příjem MOV RX2_SEMAFOR, 0 JMP BOOT_LOC ;začni provádět boot ;============================================================================= ; další pokus NET_BOOT_3: WRITE BS9 ;kurzor zpět před čísla JMP NET_BOOT_1 ;a znovu dokola ;............................................................................. ; rámec žádosti o boot block BOOT_FRAME: DB -1, 6 DUP (0) DW 10 DB 0 SIZE_BOOT_FRAME EQU $-BOOT_FRAME ;............................................................................. ; začátek rámce boot block BOOT_BLOCK: DB 4 DUP (0) DW 522 DB 1 SIZE_BOOT_BLOCK EQU $-BOOT_BLOCK NET_BOOT ENDP ;***************************************************************************** ; podprogramy ;***************************************************************************** ERROR$ PROC NEAR PUSH AX WRITE ERR_MSG POP AX WRITEHB WRITE CRLF RET ERROR$ ENDP ;***************************************************************************** WRITEHW$ PROC NEAR PUSH AX WRITEHB AH POP AX WRITEHB RET WRITEHW$ ENDP ;***************************************************************************** WRITEHB$ PROC NEAR PUSH CX PUSH AX MOV CL, 4 SHR AL, CL WRITEHN POP AX WRITEHN POP CX RET WRITEHB$ ENDP ;***************************************************************************** WRITEHN$ PROC NEAR CALL HDIGIT PUTCHAR RET WRITEHN$ ENDP ;***************************************************************************** HDIGIT PROC NEAR AND AL, 15 CMP AL, 9 JLE HDIGIT_1 ;----------------------------------------------------------------------------- SUB AL, 10 ADD AL, 'A' JMP HDIGIT_2 ;============================================================================= HDIGIT_1: ADD AL, '0' HDIGIT_2: RET HDIGIT ENDP ;***************************************************************************** WRITE$ PROC NEAR PUSH DS PUSH SI MOV SI, AX MOV AX, CS MOV DS, AX CLD WRITE_1: LODSB CMP AL,0 JE WRITE_2 ;----------------------------------------------------------------------------- PUTCHAR JMP WRITE_1 ;============================================================================= WRITE_2: POP SI POP DS RET WRITE$ ENDP ;***************************************************************************** PUTCHAR$ PROC NEAR PUSH BX PUSH AX MOV AH, TTYWRITE INT BIOS_VIDEO POP AX POP BX RET PUTCHAR$ ENDP ;***************************************************************************** RESET_CARD$ PROC NEAR MOV CS:SIGNATURE, 0 MOV POST,0 MOV CX,0 RESET_0: CMP POST,'OK' JE RESET_1 ;----------------------------------------------------------------------------- CMP POST,'ER' JE RESET_1 ;----------------------------------------------------------------------------- LOOP RESET_0 ;----------------------------------------------------------------------------- RESET_1: RET RESET_CARD$ ENDP ;***************************************************************************** DELAY$ PROC NEAR PUSH CX MOV CX, AX LOOP $ ;----------------------------------------------------------------------------- POP CX RET DELAY$ ENDP ;***************************************************************************** SIGNON: DB CR, LF, 'ZNET (c) Tesla ELSTROJ 1988, 1989', CR, LF, 0 IVERS: DB 'IROM (c) JaMeSoft 89-06-21 09:12', CR, LF DB 'ZNET ', 0 ERR_MSG: DB 'ERROR ', 0 NET_BOOT_MSG: DB CR, LF, 'Zkusím NET BOOT ', 0 BS9: DB 9 DUP (BS), 0 ADR_MSG: DB 'SW = ', 0 OK_MSG: DB 'Ok' CRLF: DB CR, LF, 0 NETROM_SIZE EQU $-SIGNATURE NETROM ENDS ROM_COPY SEGMENT AT 800H ROM_COPY ENDS ;***************************************************************************** TEMP SEGMENT ASSUME CS:TEMP, DS:MEM, SS:MEM ENTRY: CLI MOV AX, SEG MEM MOV SS, AX MOV DS, AX MOV AX, OFFSET TOP MOV SP, AX STI MOV AX, DS MOV ES, AX CLD MOV DI, OFFSET ROM MOV CX, 4096 MOV AL, -1 REP STOSB PUSH DS MOV AX, SEG NETROM MOV DS, AX MOV CX, NETROM_SIZE MOV SI, OFFSET SIGNATURE MOV DI, OFFSET ROM REP MOVSB POP DS MOV SI, OFFSET ROM MOV CX, 4096 MOV AL, 0 COMPUTE: ADD AL, [SI] INC SI LOOP COMPUTE ;----------------------------------------------------------------------------- XOR AL, -1 INC AL MOV NEW_SUM, AL MOV AH, 3CH MOV CX, 0 MOV DX, OFFSET FNAME INT 21H JC EXIT ;----------------------------------------------------------------------------- MOV BX, AX MOV AH, 40H MOV CX, 4096 MOV DX, OFFSET ROM PUSH BX INT 21H POP BX JC EXIT ;----------------------------------------------------------------------------- MOV AH, 3EH INT 21H JC EXIT ;----------------------------------------------------------------------------- MOV AH, 9 MOV DX, OFFSET FILE_OK_MSG INT 21H ; CALL ROM_SCAN EXIT: MOV AX,4C00H INT 21H TEMP ENDS MEM SEGMENT STACK ROM LABEL BYTE DB OFFSET CHECKSUM DUP (?) NEW_SUM LABEL BYTE DB 4096 DUP (?) FILE_OK_MSG LABEL BYTE DB CR, LF, 'FILE OK', CR, LF, '$' FNAME LABEL BYTE DB 'FELANI.ROM', 0 DW 256 DUP (?) TOP LABEL WORD MEM ENDS ;***************************************************************************** ;***************************************************************************** END ENTRY