*----------------------------------------------------------------------------- * Mini 68008 BIOS * Mike Christle 2016 *----------------------------------------------------------------------------- *----------------------------------------------------------------------------- * TERMS OF USE: MIT License *----------------------------------------------------------------------------- * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. *----------------------------------------------------------------------------- *----------------------------------------------------------------------------- * 68681 DUART Register Port Addresses *----------------------------------------------------------------------------- DUART_MR1A EQU $8000 DUART_MR2A EQU $8000 DUART_SRA EQU $8002 DUART_CSRA EQU $8002 DUART_CRA EQU $8004 DUART_RHRA EQU $8006 DUART_THRA EQU $8006 DUART_IPCR EQU $8008 DUART_ACR EQU $8008 DUART_ISR EQU $800A DUART_IMR EQU $800A DUART_IVR EQU $8018 DUART_OPCR EQU $801A DUART_SOPR EQU $801C DUART_ROPR EQU $801E *----------------------------------------------------------------------------- * 68681 Interrupt Service Register Constants *----------------------------------------------------------------------------- INPORT_INT_BIT EQU 7 BREAKB_INT_BIT EQU 6 RXRDYB_INT_BIT EQU 5 TXRDYB_INT_BIT EQU 4 CTRRDY_INT_BIT EQU 3 BREAKA_INT_BIT EQU 2 RXRDYA_INT_BIT EQU 1 TXRDYA_INT_BIT EQU 0 *----------------------------------------------------------------------------- * 68681 Command Register Constants * Bit 7 - 0 * Bit 654 - Commands * Bit 3 - Disable Transmiter * Bit 2 - Enable Transmiter * Bit 1 - Disable Receiver * Bit 0 - Enable Receiver *----------------------------------------------------------------------------- CRA_RESET_MRA EQU $10 CRA_RESET_RCVR EQU $20 CRA_RESET_XMTR EQU $30 CRA_RESER_ERROR EQU $40 CRA_RESET_BREAK EQU $50 CRA_START_BREAK EQU $60 CRA_STOP_BREAK EQU $70 CRA_DISABLE_TX EQU $08 CRA_ENABLE_TX EQU $04 CRA_DISABLE_RX EQU $02 CRA_ENABLE_RX EQU $01 ASCII_CR EQU 13 ASCII_LF EQU 10 INT_MASK EQU ~$0700 SSP_INIT EQU $17E00 APP_START EQU $10000 *-------------------------------------------------------------------------- * Register Usage * A0 Temp D0 Temp * A1 Temp D1 Temp * A2 Save D2 Temp * A3 Save D3 Temp * A4 Save D4 Save * A5 App Static Data Address D5 Save * A6 BIOS Static Data Address D6 Save * A7 Stack Pointer D7 Save *-------------------------------------------------------------------------- *-------------------------------------------------------------------------- * BIOS STATIC DATA *-------------------------------------------------------------------------- BUFR_SIZE EQU 128 BUFR_SIZE_MASK EQU BUFR_SIZE - 1 ORG 0 TXRDYA_IV DS 4 *TxRDY AInterrupt Vector RXRDYA_IV DS 4 *RxRDY A Interrupt Vector BREAKA_IV DS 4 *Delta Break A Interrupt Vector CTRRDY_IV DS 4 *Counter Ready Interrupt Vector TXRDYB_IV DS 4 *TxRDY B Interrupt Vector RXRDYB_IV DS 4 *RxRDY B Interrupt Vector BREAKB_IV DS 4 *Delta Break B Interrupt Vector INPORT_IV DS 4 *In Port Change Interrupt Vector RXBUFR DS BUFR_SIZE TXBUFR DS BUFR_SIZE CMND_BUFR DS BUFR_SIZE TXTOP DS 2 TXBOT DS 2 RXTOP DS 2 RXBOT DS 2 IMR_IMAGE DS 1 ISR_IMAGE DS 1 *-------------------------------------------------------------------------- ORG $0 *-------------------------------------------------------------------------- DL SSP_INIT *00 Reset: Initial SSP DA INIT_RESET *01 Reset: Initial PC DA ERROR_RESET *02 Bus Error DA ERROR_RESET *03 Address Error DA ERROR_RESET *04 Illegal Instruction DA ERROR_RESET *05 Zero Divide DA ERROR_RESET *06 CHK Instruction DA ERROR_RESET *07 TRAPV Instruction DA ERROR_RESET *08 Privilege Violation DA ERROR_RESET *09 Trace DA ERROR_RESET *0A Line 1010 Emulator DA ERROR_RESET *0B Line 1111 Emulator DA ERROR_RESET *0C (Unassigned, Reserved) DA ERROR_RESET *0D (Unassigned, Reserved) DA ERROR_RESET *0E (Unassigned, Reserved) DA ERROR_RESET *0F Uninitialized Interrupt Vector DA ERROR_RESET *10 (Unassigned, Reserved) DA ERROR_RESET *11 (Unassigned, Reserved) DA ERROR_RESET *12 (Unassigned, Reserved) DA ERROR_RESET *13 (Unassigned, Reserved) DA ERROR_RESET *14 (Unassigned, Reserved) DA ERROR_RESET *15 (Unassigned, Reserved) DA ERROR_RESET *16 (Unassigned, Reserved) DA ERROR_RESET *17 (Unassigned, Reserved) DA ERROR_RESET *18 Spurious Interrupt DA ERROR_RESET *19 Level 1 Interrupt Autovector DA ERROR_RESET *1A Level 2 Interrupt Autovector DA ERROR_RESET *1B Level 3 Interrupt Autovector DA ERROR_RESET *1C Level 4 Interrupt Autovector DA ERROR_RESET *1D Level 5 Interrupt Autovector DA ERROR_RESET *1E Level 6 Interrupt Autovector DA ERROR_RESET *1F Level 7 Interrupt Autovector DA BIOS_CALL *20 TRAP Instruction Vectors DA ERROR_RESET *21 TRAP Instruction Vectors DA ERROR_RESET *22 TRAP Instruction Vectors DA ERROR_RESET *23 TRAP Instruction Vectors DA ERROR_RESET *24 TRAP Instruction Vectors DA ERROR_RESET *25 TRAP Instruction Vectors DA ERROR_RESET *26 TRAP Instruction Vectors DA ERROR_RESET *27 TRAP Instruction Vectors DA ERROR_RESET *28 TRAP Instruction Vectors DA ERROR_RESET *29 TRAP Instruction Vectors DA ERROR_RESET *2A TRAP Instruction Vectors DA ERROR_RESET *2B TRAP Instruction Vectors DA ERROR_RESET *2C TRAP Instruction Vectors DA ERROR_RESET *2D TRAP Instruction Vectors DA ERROR_RESET *2E TRAP Instruction Vectors DA ERROR_RESET *2F TRAP Instruction Vectors DA ERROR_RESET *30 (Unassigned, Reserved) DA ERROR_RESET *31 (Unassigned, Reserved) DA ERROR_RESET *32 (Unassigned, Reserved) DA ERROR_RESET *33 (Unassigned, Reserved) DA ERROR_RESET *34 (Unassigned, Reserved) DA ERROR_RESET *35 (Unassigned, Reserved) DA ERROR_RESET *36 (Unassigned, Reserved) DA ERROR_RESET *37 (Unassigned, Reserved) DA ERROR_RESET *38 (Unassigned, Reserved) DA ERROR_RESET *39 (Unassigned, Reserved) DA ERROR_RESET *3A (Unassigned, Reserved) DA ERROR_RESET *3B (Unassigned, Reserved) DA ERROR_RESET *3C (Unassigned, Reserved) DA ERROR_RESET *3D (Unassigned, Reserved) DA ERROR_RESET *3E (Unassigned, Reserved) DA ERROR_RESET *3F (Unassigned, Reserved) *40–FF User Interrupt Vectors DA DUART_INT *40 68681 DUART INTERRUPT *-------------------------------------------------------------------------- ORG $400 ERROR_RESET RESET INIT_RESET MOVEA.L #SSP_INIT, A7 *System Stack Pointer MOVEA.L #SSP_INIT, A6 *BIOS Static Data Address CLR.W (TXTOP, A6) CLR.W (TXBOT, A6) CLR.W (RXTOP, A6) CLR.W (RXBOT, A6) *----------------------------------------------------------------------------- * Init Interrupt Vectors *----------------------------------------------------------------------------- MOVEA.L #$0400, A0 MOVE.L A0, (INPORT_IV, A6) MOVE.L A0, (BREAKB_IV, A6) MOVE.L A0, (RXRDYB_IV, A6) MOVE.L A0, (TXRDYB_IV, A6) MOVE.L A0, (CTRRDY_IV, A6) MOVE.L A0, (BREAKA_IV, A6) MOVE.L #RX_INT, (RXRDYA_IV, A6) MOVE.L #TX_INT, (TXRDYA_IV, A6) *----------------------------------------------------------------------------- * Reset the 68681 DUART *----------------------------------------------------------------------------- MOVE.B #CRA_RESET_RCVR, (DUART_CRA).W MOVE.B #CRA_RESET_XMTR, (DUART_CRA).W MOVE.B #CRA_RESET_MRA, (DUART_CRA).W *----------------------------------------------------------------------------- * 68681 MR1A * Bit 7 = 0 - No RTS Control * Bit 6 = 0 - RxDRY Causes Interrupt * Bit 5 = 0 - Char Error Mode * Bit 432 = 100 - No Parity * Bit 10 = 11 - 8 Data Bits *----------------------------------------------------------------------------- MOVE.B #$13, (DUART_MR1A).W *----------------------------------------------------------------------------- * 68681 MR2A * Bit 76 = 00 - Normal Mode * Bit 5 = 0 - No TxRTS Control * Bit 4 = 0 - No TxCTS Control * Bit 3210 = 0111 - 1 Stop Bit *----------------------------------------------------------------------------- MOVE.B #$07, (DUART_MR2A).W *----------------------------------------------------------------------------- * 68681 CSRA * Bit 7654 = 1011 - Receiver 9600 Baud * Bit 3210 = 1011 - Transmiter 9600 Baud *----------------------------------------------------------------------------- MOVE.B #$BB, (DUART_CSRA).W *----------------------------------------------------------------------------- * 68681 IMR * Bit 7 = 0 - In Port Change Interrupt * Bit 6 = 0 - Delta Break B Interrupt * Bit 5 = 0 - RxRDY B Interrupt * Bit 4 = 0 - TxRDY B Interrupt * Bit 3 = 0 - Counter Ready Interrupt * Bit 2 = 0 - Delta Break A Interrupt * Bit 1 = 1 - RxRDY A Interrupt * Bit 0 = 1 - TxRDY AInterrupt *----------------------------------------------------------------------------- MOVE.B #$03, (DUART_IMR).W MOVE.B #$03, (IMR_IMAGE, A6) MOVE.B #$40, (DUART_IVR).W *----------------------------------------------------------------------------- * Enable UART Receiver *----------------------------------------------------------------------------- MOVE.B #CRA_ENABLE_RX, (DUART_CRA).W MOVE.W #$2000, SR *-------------------------------------------------------------------------- * Command Loop *-------------------------------------------------------------------------- MOVEA.L #HEADER, A2 BSR PUTS COMMAND_LOOP MOVEA.L #PROMPT, A2 BSR PUTS LEA (CMND_BUFR, A6), A2 MOVE.W #BUFR_SIZE, D4 BSR GETS LEA (CMND_BUFR, A6), A2 MOVE.B (A2)+, D0 ORI.B #$20, D0 CMPI.B #'d', D0 BNE.S COMMAND_LOOP_1 BSR DUMP_MEMORY BRA.S COMMAND_LOOP COMMAND_LOOP_1 CMPI.B #'f', D0 BNE.S COMMAND_LOOP_2 BSR FILL_MEMORY BRA.S COMMAND_LOOP COMMAND_LOOP_2 CMPI.B #'s', D0 BNE.S COMMAND_LOOP_3 BSR DOWNLOAD BRA.S COMMAND_LOOP COMMAND_LOOP_3 CMPI.B #'j', D0 BNE.S COMMAND_LOOP_9 BSR JSR_TO BRA.S COMMAND_LOOP COMMAND_LOOP_9 CMPI.B #'?', D0 BNE.S COMMAND_LOOP MOVEA.W #MENU_STR, A2 BSR PUTS BRA.S COMMAND_LOOP MENU_STR DB "D ADRS COUNT - Dump Memory ", ASCII_CR DB "F ADRS VALUE COUNT - Fill Memory ", ASCII_CR DB "J ADRS - JSR To Adrs ", ASCII_CR DB "S2xxx - Download Hex Record ", ASCII_CR DB "? - Menu ", ASCII_CR, 0 HEADER DB "Mini 68008 BIOS", ASCII_CR, 0 PROMPT DB ">", 0 *-------------------------------------------------------------------------- * DUART Interrupt Service Routine *-------------------------------------------------------------------------- DUART_INT MOVEM.L D0-D1/A0, -(A7) MOVE.B (DUART_ISR).W, D0 AND.B (IMR_IMAGE, A6), D0 MOVE.B D0, (ISR_IMAGE, A6) BTST.L #CTRRDY_INT_BIT, D0 BEQ.S DUART_INT_1 MOVEA.L (CTRRDY_IV, A6), A0 JSR (A0) DUART_INT_1 BTST.B #INPORT_INT_BIT, (ISR_IMAGE, A6) BEQ.S DUART_INT_2 MOVEA.L (INPORT_IV, A6), A0 JSR (A0) DUART_INT_2 BTST.B #RXRDYA_INT_BIT, (ISR_IMAGE, A6) BEQ.S DUART_INT_3 MOVEA.L (RXRDYA_IV, A6), A0 JSR (A0) DUART_INT_3 BTST.B #RXRDYB_INT_BIT, (ISR_IMAGE, A6) BEQ.S DUART_INT_4 MOVEA.L (RXRDYB_IV, A6), A0 JSR (A0) DUART_INT_4 BTST.B #TXRDYA_INT_BIT, (ISR_IMAGE, A6) BEQ.S DUART_INT_5 MOVEA.L (TXRDYA_IV, A6), A0 JSR (A0) DUART_INT_5 BTST.B #TXRDYB_INT_BIT, (ISR_IMAGE, A6) BEQ.S DUART_INT_6 MOVEA.L (TXRDYB_IV, A6), A0 JSR (A0) DUART_INT_6 BTST.B #BREAKB_INT_BIT, (ISR_IMAGE, A6) BEQ.S DUART_INT_7 MOVEA.L (BREAKB_IV, A6), A0 JSR (A0) DUART_INT_7 BTST.B #BREAKA_INT_BIT, (ISR_IMAGE, A6) BEQ.S DUART_INT_X MOVEA.L (BREAKA_IV, A6), A0 JSR (A0) DUART_INT_X MOVEM.L (A7)+, D0-D1/A0 RTE *-------------------------------------------------------------------------- * TX_INT *-------------------------------------------------------------------------- TX_INT MOVE.W (TXBOT, A6), D0 CMP.W (TXTOP, A6), D0 BNE.S TX_INT_1 MOVE.B #CRA_DISABLE_TX, (DUART_CRA).W BRA.S TX_INT_X TX_INT_1 LEA (TXBUFR, A6), A0 MOVE.B (0, A0, D0.W), (DUART_THRA).W ADDQ.W #1, D0 ANDI.W #BUFR_SIZE_MASK, D0 MOVE.W D0, (TXBOT, A6) TX_INT_X RTS *-------------------------------------------------------------------------- * PUTC * * D2.B = Char *-------------------------------------------------------------------------- PUTC MOVE.W (TXTOP, A6), D1 MOVE.W D1, D0 ADDQ.W #1, D1 ANDI.W #BUFR_SIZE_MASK, D1 PUTC_1 CMP.W (TXBOT, A6), D1 BEQ.S PUTC_1 LEA (TXBUFR, A6), A0 MOVE.B D2, (0, A0, D0.W) MOVE.W D1, (TXTOP, A6) MOVE.B #CRA_ENABLE_TX, (DUART_CRA).W RTS *-------------------------------------------------------------------------- * PUTS * * A2 = Pointer to NULL terminated string *-------------------------------------------------------------------------- PUTS MOVE.B (A2)+, D2 BEQ.S PUTS_X BSR.S PUTC BRA.S PUTS PUTS_X RTS *-------------------------------------------------------------------------- * RX_INT *-------------------------------------------------------------------------- RX_INT MOVE.B (DUART_RHRA).W, D1 LEA (RXBUFR, A6), A0 MOVE.W (RXTOP, A6), D0 ADDA.W D0, A0 ADDQ.W #1, D0 ANDI.W #BUFR_SIZE_MASK, D0 CMP.W (RXBOT, A6), D0 BEQ.S RX_INT_X MOVE.B D1, (A0) MOVE.W D0, (RXTOP, A6) RX_INT_X RTS *-------------------------------------------------------------------------- * GETC * * D2.B = Char, 0 If Buffer Empty * Z = 1 If Buffer Empty *-------------------------------------------------------------------------- GETC CLR.L D2 MOVE.W (RXBOT, A6), D1 CMP.W (RXTOP, A6), D1 BEQ.S GETC_X LEA (RXBUFR, A6), A0 MOVE.B (0, A0, D1.W), D2 ADDQ.W #1, D1 ANDI.W #BUFR_SIZE_MASK, D1 MOVE.W D1, (RXBOT, A6) ADDQ.L #1, D1 GETC_X RTS *-------------------------------------------------------------------------- * GETS * * A2 = Pointer to buffer * D4 = Buffer size * Terminated on CR *-------------------------------------------------------------------------- GETS SUBQ.W #1, D4 BEQ.S GETS_X GETS_1 BSR.S GETC BEQ.S GETS_1 CMP.B #ASCII_CR, D2 BEQ.S GETS_X MOVE.B D2, (A2)+ BRA.S GETS GETS_X CLR.B (A2) RTS *-------------------------------------------------------------------------- * JSR To Address *-------------------------------------------------------------------------- JSR_TO LEA (CMND_BUFR + 1, A6), A2 BSR PARSE_PARM MOVEA.L D0, A0 JSR (A0) RTS *-------------------------------------------------------------------------- * DOWNLOAD S2 RECORD * * All other S-Records are ignored * D6 - Byte Counter * D7 - Checksum * A2 - Input Buffer Address * A3 - Destination Address *-------------------------------------------------------------------------- DOWNLOAD LEA (CMND_BUFR + 1, A6), A2 MOVE.B (A2)+, D0 CMP.B #'2', D0 BNE DOWNLOAD_X MOVE.W #2, D4 BSR HEX2INT *Byte count MOVE.L D0, D6 MOVE.L D0, D7 SUBQ.W #4, D6 MOVE.W #6, D4 BSR HEX2INT *Address MOVEA.L D0, A3 ADD.B D0, D7 LSR.L #8, D0 ADD.B D0, D7 LSR.L #8, D0 ADD.B D0, D7 DOWNLOAD_1 TST.W D6 BEQ.S DOWNLOAD_2 MOVE.W #2, D4 BSR HEX2INT *Data byte MOVE.B D0, (A3)+ ADD.B D0, D7 SUBQ.W #1, D6 BRA.S DOWNLOAD_1 DOWNLOAD_2 MOVE.W #2, D4 BSR HEX2INT *Checksum ADD.B D0, D7 ADDQ.B #1, D7 BEQ.S DOWNLOAD_X MOVE.B #'X', D2 BSR PUTC DOWNLOAD_X RTS *-------------------------------------------------------------------------- * HEX2INT * * A2 = Pointer to string * D4 = Max digits * D0 = Result *-------------------------------------------------------------------------- HEX2INT CLR.L D0 HEX2INT_1 MOVE.B (A2)+, D1 ORI.B #$20, D1 SUBI.B #'0', D1 BMI.S HEX2INT_X CMP.B #9, D1 BLE.S HEX2INT_2 SUBI.B #39, D1 BMI.S HEX2INT_X CMP.B #15, D1 BGT.S HEX2INT_X HEX2INT_2 LSL.L #4, D0 OR.B D1, D0 SUBQ.W #1, D4 BNE.S HEX2INT_1 HEX2INT_X RTS *-------------------------------------------------------------------------- * PARSE_PARM * A2 - Input Address * D0 - Value *-------------------------------------------------------------------------- PARSE_PARM MOVE.W #' ', D0 PARSE_PARM_1 CMP.B (A2), D0 BNE.S PARSE_PARM_2 ADDQ.L #1, A2 BRA.S PARSE_PARM_1 PARSE_PARM_2 MOVE.W #8, D4 BSR HEX2INT RTS *-------------------------------------------------------------------------- * FILL_MEMORY * F ADRS VALUE COUNT * * A3 - Address * D7 - Value * D6 - Count *-------------------------------------------------------------------------- FILL_MEMORY LEA (CMND_BUFR + 1, A6), A2 BSR PARSE_PARM MOVEA.L D0, A3 BSR PARSE_PARM MOVE.W D0, D7 BSR PARSE_PARM MOVE.W D0, D6 FILL_MEMORY_1 MOVE.B D7, (A3)+ SUBQ.W #1, D6 BNE.S FILL_MEMORY_1 RTS *-------------------------------------------------------------------------- * DUMP_MEMORY * D ADRS LINE_COUNT * * A2 - Address pointer * D7 - Line counter * D6 - Word counter *-------------------------------------------------------------------------- DUMP_MEMORY LEA (CMND_BUFR + 1, A6), A2 BSR PARSE_PARM MOVEA.L D0, A3 BSR PARSE_PARM MOVE.W D0, D7 SUBQ.W #1, D7 DUMP_MEMORY_1 MOVE.L A3, D4 MOVE.W #3, D5 BSR PRINT_HEX MOVE.W #15, D6 DUMP_MEMORY_2 MOVE.B #' ', D2 BSR PUTC MOVE.B (A3)+, D4 MOVE.W #1, D5 BSR PRINT_HEX DBF D6, DUMP_MEMORY_2 MOVE.B #ASCII_CR, D2 BSR PUTC DBF D7, DUMP_MEMORY_1 RTS *-------------------------------------------------------------------------- * PRINT_DEC * D3.L = Value to print *-------------------------------------------------------------------------- PRINT_DEC MOVEM.W D2/D4, -(A7) CLR.W D4 TST.L D3 BPL.S PRINT_DEC_1 NEG.L D3 MOVE.B #'-', D2 BSR PUTC PRINT_DEC_1 DIVU.W #10000, D3 BNE.S PRINT_DEC_2 SWAP D3 BSR.S PRINT_DEC_10 BRA.S PRINT_DEC_3 PRINT_DEC_2 SWAP D3 MOVE.L D3, -(A7) CLR.L D3 MOVE.W (A7)+, D3 BSR.S PRINT_DEC_10 CLR.L D3 MOVE.W (A7)+, D3 BSR.S PRINT_DEC_20 PRINT_DEC_3 MOVEM.W (A7)+, D2/D4 RTS *-------------------------------------------------------------------------- PRINT_DEC_10 DIVU.W #10, D3 SWAP D3 MOVE.B D3, -(A7) ADDQ.W #1, D4 CLR.W D3 SWAP D3 BNE.S PRINT_DEC_10 PRINT_DEC_11 MOVE.B (A7)+, D2 MOVE.B (DIGIT_TABLE, PC, D2.W), D2 BSR PUTC SUBQ.W #1, D4 BNE.S PRINT_DEC_11 RTS *-------------------------------------------------------------------------- PRINT_DEC_20 MOVE.W #3, D0 PRINT_DEC_21 DIVU.W #10, D3 SWAP D3 MOVE.B D3, -(A7) ADDQ.W #1, D4 CLR.W D3 SWAP D3 DBF D0, PRINT_DEC_21 PRINT_DEC_22 MOVE.B (A7)+, D2 MOVE.B (DIGIT_TABLE, PC, D2.W), D2 BSR PUTC SUBQ.W #1, D4 BNE.S PRINT_DEC_22 RTS *-------------------------------------------------------------------------- DIGIT_TABLE DB "0123456789ABCDEF" *-------------------------------------------------------------------------- * PRINT_HEX * * D4 = Value * D5 = Number of bytes *-------------------------------------------------------------------------- PRINT_HEX LSL.W #3, D5 ROR.L D5, D4 LSR.W #2, D5 SUBQ.W #1, D5 PRINT_HEX_1 ROL.L #4, D4 MOVE.W D4, D2 ANDI.W #15, D2 MOVE.B (DIGIT_TABLE, PC, D2.W), D2 BSR PUTC DBF D5, PRINT_HEX_1 RTS *-------------------------------------------------------------------------- * Enable Interrupt Service Routine * * D1 = Vector Number * A1 = ISR Address *-------------------------------------------------------------------------- ENABLE_ISR MOVE.W D1, D0 LSL.W #2, D0 LEA (TXRDYA_IV, A6, D0.W), A0 MOVE.L A1, (A0) MOVE.B #1, D0 LSL.B D1, D0 OR.B D0, (IMR_IMAGE, A6) MOVE.B (IMR_IMAGE, A6), (DUART_IMR).W RTS *-------------------------------------------------------------------------- * Disable Interrupt Service Routine * * D1 = Vector Number *-------------------------------------------------------------------------- DISABLE_ISR MOVE.B #1, D0 LSL.B D1, D0 NOT.B D0 AND.B D0, (IMR_IMAGE, A6) MOVE.B (IMR_IMAGE, A6), (DUART_IMR).W RTS *-------------------------------------------------------------------------- * BIOS_CALL * D0 = Function Number *-------------------------------------------------------------------------- BIOS_CALL MOVEA.L #BIOS_CALL_TABLE, A0 LSL.W #2, D0 MOVEA.L (0, A0, D0.W), A0 JSR (A0) RTE BIOS_CALL_TABLE DA GETC DA PUTC DA GETS DA PUTS DA PRINT_HEX DA PRINT_DEC DA ENABLE_ISR DA DISABLE_ISR *--------------------------------------------------------------------------