//////////////////////////////////////////////////////////////// // 割込みデータ出力 //////////////////////////////////////////////////////////////// void SUB6::OutData( void ) { switch( Status8049 ){ case D8049_JOY: // ゲーム用キー割込み データ出力 PRINTD( SUB_LOG, "[OutData JOY] Data: %02X\n", JoyCode ); WriteExt( JoyCode ); IntrFlag &= ~IR_JOY; break; case D8049_KEY1: // キー割込み1 その1 割込みベクタ出力 IntrFlag &= ~IR_KEY1; break; case D8049_KEY12: // キー割込み1 その2 割込みベクタ出力 IntrFlag &= ~IR_KEY12; break; case D8049_CMTR: // CMT READ割込み データ出力 PRINTD( SUB_LOG, "[OutData CMTR] Data: %02X\n", CmtData ); WriteExt( CmtData ); IntrFlag &= ~IR_CMTR; break; case D8049_CMTE: // CMT ERROR割込み 割込みベクタ出力 IntrFlag &= ~IR_CMTE; break; case D8049_KEY2: // キー割込み2 データ出力 PRINTD( SUB_LOG, "[OutData KEY2] Data: %02X\n", KeyCode ); WriteExt( KeyCode ); IntrFlag &= ~IR_KEY2; break; case D8049_KEY3: // キー割込み3 データ出力 PRINTD( SUB_LOG, "[OutData KEY3] Data: %02X\n", KeyCode ); WriteExt( KeyCode ); IntrFlag &= ~IR_KEY3; break; case D8049_SIO: // RS232C受信割込み データ出力 PRINTD( SUB_LOG, "[OutData SIO] Data: %02X\n", SioData ); WriteExt( SioData ); IntrFlag &= ~IR_SIO; break; case D8049_TVRR:{ // TV予約読込み割込み データ出力 BYTE tvd = TVRCnt >= (int)sizeof(TVRData) ? 0xff : TVRData[TVRCnt++]; PRINTD( SUB_LOG, "[OutData TVR] Data: %02X\n", tvd ); WriteExt( tvd ); if( tvd == 0xff ){ // FFHなら終了 IntrFlag &= ~IR_TVR; }else{ // FFH以外なら残りのデータ出力 vm->EventAdd( this, EID_DATA, WAIT_DATA, EV_LOOP|EV_STATE ); return; } break; } case D8049_DATE: // DATE割込み データ出力 PRINTD( SUB_LOG, "[OutData DATE] Data%d: %02X\n", DateCnt, DateData[DateCnt] ); WriteExt( DateData[DateCnt++] ); if( DateCnt > 4 ){ // 5回出力したら終了 IntrFlag &= ~IR_DATE; }else{ // 5回未満なら残りのデータ出力 vm->EventAdd( this, EID_DATA, WAIT_DATA, EV_LOOP|EV_STATE ); return; } break; } // 割込み処理終了 Status8049 = D8049_IDLE; // CPUに対する割込み要求をキャンセル(割込み禁止対策) vm->IntCancelIntr( IREQ_8049 ); }
static int writeData(void* _call) { WriterAVCallData_t* call = (WriterAVCallData_t*) _call; static uint8_t PesHeader[PES_MAX_HEADER_SIZE]; int32_t len = 0; uint32_t Position = 0; mpeg2_printf(10, "\n"); if (call == NULL) { mpeg2_err("call data is NULL...\n"); return 0; } mpeg2_printf(10, "VideoPts %lld\n", call->Pts); if ((call->data == NULL) || (call->len <= 0)) { mpeg2_err("parsing NULL Data. ignoring...\n"); return 0; } if (call->fd < 0) { mpeg2_err("file pointer < 0. ignoring ...\n"); return 0; } uint8_t *data = call->data; uint32_t data_len = call->len; if (!private_data && !call->private_data && data_len > 3 && !memcmp(data, "\x00\x00\x01\xb3", 4)) { bool ok = true; uint32_t pos = 4; uint32_t sheader_data_len = 0; while (pos < data_len && ok) { if (pos >= data_len) break; pos += 7; if (pos >=data_len) break; sheader_data_len = 12; if (data[pos] & 2) { // intra matrix pos += 64; if (pos >=data_len) break; sheader_data_len += 64; } if (data[pos] & 1) { // non intra matrix pos += 64; if (pos >=data_len) break; sheader_data_len += 64; } pos += 1; if (pos + 3 >=data_len) break; if (!memcmp(&data[pos], "\x00\x00\x01\xb5", 4)) { // extended start code pos += 3; sheader_data_len += 3; do { pos += 1; ++sheader_data_len; if (pos + 2 > data_len) { ok = false; break; } } while (memcmp(&data[pos], "\x00\x00\x01", 3)); if (!ok) break; } if (pos + 3 >= data_len) break; if (!memcmp(&data[pos], "\x00\x00\x01\xb2", 4)) { // private data pos += 3; sheader_data_len += 3; do { pos += 1; ++sheader_data_len; if (pos + 2 > data_len) { ok = false; break; } } while (memcmp(&data[pos], "\x00\x00\x01", 3)); if (!ok) break; } free(private_data); private_data = malloc(sheader_data_len); if (private_data) { private_size = sheader_data_len; memcpy(private_data, data + pos - sheader_data_len, sheader_data_len); } must_send_header = false; break; } } else if ((private_data || call->private_data) && must_send_header) { uint8_t *codec_data = NULL; uint32_t codec_data_size = 0; int pos = 0; if (private_data) { codec_data = private_data; codec_data_size = private_size; } else { codec_data = call->private_data; codec_data_size = call->private_size; } while (pos <= data_len - 4) { if (memcmp(&data[pos], "\x00\x00\x01\xb8", 4)) /* find group start code */ { pos++; continue; } struct iovec iov[4]; iov[0].iov_base = PesHeader; iov[0].iov_len = InsertPesHeader(PesHeader, call->len + codec_data_size, MPEG_VIDEO_PES_START_CODE, call->Pts, 0); iov[1].iov_base = data; iov[1].iov_len = pos; iov[2].iov_base = codec_data; iov[2].iov_len = codec_data_size; iov[3].iov_base = data + pos; iov[3].iov_len = data_len - pos; must_send_header = false; return call->WriteV(call->fd, iov, 4); } } struct iovec iov[2]; iov[0].iov_base = PesHeader; iov[0].iov_len = InsertPesHeader(PesHeader, call->len, MPEG_VIDEO_PES_START_CODE, call->Pts, 0); iov[1].iov_base = data; iov[1].iov_len = data_len; PesHeader[6] = 0x81; UpdatePesHeaderPayloadSize(PesHeader, data_len + iov[0].iov_len - 6); if (iov[0].iov_len != WriteExt(call->WriteV, call->fd, iov[0].iov_base, iov[0].iov_len)) return -1; if (iov[1].iov_len != WriteExt(call->WriteV, call->fd, iov[1].iov_base, iov[1].iov_len)) return -1; return 1; }
//////////////////////////////////////////////////////////////// // 割込みベクタ出力 //////////////////////////////////////////////////////////////// void SUB6::OutVector( void ) { BYTE IntrVector = IVEC_NOINTR; switch( Status8049 ){ case D8049_JOY: // ゲーム用キー割込み 割込みベクタ出力 PRINTD( SUB_LOG, "[OutVector JOY]\n" ); IntrVector = IVEC_JOY; break; case D8049_KEY1: // キー割込み1 その1 割込みベクタ出力 PRINTD( SUB_LOG, "[OutVector KEY1]\n" ); IntrVector = IVEC_KEY1; IntrFlag &= ~IR_KEY1; Status8049 = D8049_NODATA; break; case D8049_KEY12: // キー割込み1 その2 割込みベクタ出力 PRINTD( SUB_LOG, "[OutVector KEY12]\n" ); IntrVector = IVEC_KEY12; IntrFlag &= ~IR_KEY12; Status8049 = D8049_NODATA; break; case D8049_CMTR: // CMT READ割込み 割込みベクタ出力 PRINTD( SUB_LOG, "[OutVector CMTR]\n" ); IntrVector = IVEC_CMT_R; break; case D8049_CMTE: // CMT ERROR割込み 割込みベクタ出力 PRINTD( SUB_LOG, "[OutVector CMTE]\n" ); IntrVector = IVEC_CMT_E; IntrFlag &= ~IR_CMTE; Status8049 = D8049_NODATA; break; case D8049_KEY2: // キー割込み2 割込みベクタ出力 PRINTD( SUB_LOG, "[OutVector KEY2]\n" ); IntrVector = IVEC_KEY2; break; case D8049_KEY3: // キー割込み3 割込みベクタ出力 PRINTD( SUB_LOG, "[OutVector KEY3]\n" ); IntrVector = IVEC_KEY3; break; case D8049_SIO: // RS232C受信割込み 割込みベクタ出力 PRINTD( SUB_LOG, "[OutVector SIO]\n" ); IntrVector = IVEC_SIO; break; case D8049_TVRR: // TV予約割込み 割込みベクタ出力 PRINTD( SUB_LOG, "[OutVector TVR]\n" ); IntrVector = IVEC_TVR; break; case D8049_DATE: // DATE割込み 割込みベクタ出力 PRINTD( SUB_LOG, "[OutVector DATE]\n" ); IntrVector = IVEC_DATE; break; default: // どれでもなければベクタ出力なし return; } WriteExt( IntrVector ); vm->IntReqIntr( IREQ_8049 ); }